diff options
author | Maciej Wereski <m.wereski@partner.samsung.com> | 2017-03-07 12:31:57 +0100 |
---|---|---|
committer | Maciej Wereski <m.wereski@partner.samsung.com> | 2017-08-17 08:53:00 +0200 |
commit | 1a7c29ab68d6dd3262d440642cb35df1ad19b016 (patch) | |
tree | e4aa6d5b5e7d71e8181f4cf86d2d7f70516ecd84 | |
parent | f0e22844a344ddeff1fe1f3d3e13865cc3351f99 (diff) | |
download | snapsync-1a7c29ab68d6dd3262d440642cb35df1ad19b016.tar.gz snapsync-1a7c29ab68d6dd3262d440642cb35df1ad19b016.tar.bz2 snapsync-1a7c29ab68d6dd3262d440642cb35df1ad19b016.zip |
Add reporting, editing and ask user about actions
Show report after doing comparison step. Ask user about proceeding.
User may also choose option to edit list of repositories to be
submitted. Editor setting from configuration file is used or $EDITOR if
setting is missing. Only repositories that may be synchronized (new and
outdated repositories) are shown in editor. User should only delete
unwanted repositories.
Change-Id: I17c0b6cc11c8fd2ab6f098c2a8ca4032178a8523
Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
-rw-r--r-- | config/config.go | 1 | ||||
-rw-r--r-- | snapsync.conf | 1 | ||||
-rw-r--r-- | snapsync.go | 140 |
3 files changed, 138 insertions, 4 deletions
diff --git a/config/config.go b/config/config.go index 5495d8e..c13ae30 100644 --- a/config/config.go +++ b/config/config.go @@ -36,6 +36,7 @@ type General struct { Workers int Timeout string BlacklistFile string `ini:"Blacklist"` + Editor string } // Repos represents Repos section in config file. diff --git a/snapsync.conf b/snapsync.conf index 558d6f6..664f706 100644 --- a/snapsync.conf +++ b/snapsync.conf @@ -2,6 +2,7 @@ #workers = 4 timeout = 3s blacklist = /usr/share/snapsync/blacklist +editor = vim [Repos] sourceURL = http://download.tizen.org/snapshots/tizen/ diff --git a/snapsync.go b/snapsync.go index 92c0cf4..11ed8c9 100644 --- a/snapsync.go +++ b/snapsync.go @@ -17,15 +17,20 @@ package main import ( + "bufio" + "bytes" "flag" "fmt" + "io/ioutil" "log" "net/url" "os" + "os/exec" "runtime" "strings" "sync" "time" + "unicode" "git.tizen.org/tools/snapsync/config" gitMgr "git.tizen.org/tools/snapsync/git" @@ -59,6 +64,8 @@ var ( configFile string // path to file with list of ignored repositories (regexp) blacklistFile string + // editor which will be used to edit report + editor string // number of Git Job workers numWorkers int @@ -66,6 +73,123 @@ var ( timeout time.Duration ) +// report prints git repositories summary (if given) and asks user what to do. Returns answer. +func report(repos *map[string]*gitMgr.GitRepo) (bool, error) { + var ans rune +start: + // print summary of git repositories if those were given. + if repos != nil { + for k, v := range *repos { + fmt.Printf("%s: %s - %s\n", k, v.SourceCommit, v.Status) + } + } + for { + fmt.Println("What would you like to do? ") + // empty map means that there's no list to edit + if repos == nil { + fmt.Println("([c]ontinue / [a]bort)") + } else { + fmt.Println("([c]ontinue / [e]dit / [a]bort)") + } + _, err := fmt.Scanf("%c\n", &ans) + if err != nil { + return false, err + } + ans = unicode.ToLower(ans) + if repos == nil && ans == 'e' { + continue + } + switch ans { + case 'c': + return true, nil + case 'a': + return false, nil + case 'e': + r, err := editReport(*repos) + if err != nil { + return false, err + } + *repos = r + // after editing ask show new summary and ask again what to do + goto start + } + } +} + +// editReport runs external text editor, so user can remove not needed repositories. +func editReport(repos map[string]*gitMgr.GitRepo) (map[string]*gitMgr.GitRepo, error) { + // create temporary file for list + tmpfile, err := ioutil.TempFile(os.TempDir(), "snapsync") + if err != nil { + return nil, err + } + fname := tmpfile.Name() + + defer os.Remove(fname) + defer tmpfile.Close() + + writer := bufio.NewWriter(tmpfile) + + for k, v := range repos { + // only new and updated repositories are used by snapsync + if v.Status == gitMgr.New || v.Status == gitMgr.OK { + _, err = writer.WriteString(fmt.Sprintf("%s: %v\n", k, v.Status)) + if err != nil { + return nil, err + } + } + } + err = writer.Flush() + if err != nil { + return nil, err + } + + var stderr bytes.Buffer + // Use external editor + editorCmd := exec.Command(editor, fname) + editorCmd.Stdin = os.Stdin + editorCmd.Stdout = os.Stdout + // We want to intercept standard error + editorCmd.Stderr = &stderr + err = editorCmd.Run() + if err != nil { + if _, ok := err.(*exec.ExitError); ok { + // print editor error output if it failed + log.Println(&stderr) + } + return nil, err + } + + _, err = tmpfile.Seek(0, 0) + if err != nil { + return nil, err + } + + // get contents of file to new map + ret := make(map[string]*gitMgr.GitRepo, len(repos)) + scanner := bufio.NewScanner(tmpfile) + for scanner.Scan() { + s := strings.Split(scanner.Text(), ":")[0] + ret[s] = repos[s] + } + if err = scanner.Err(); err != nil { + return nil, err + } + + // return new map with git repositories + return ret, nil +} + +// exitOnFalse exits to OS if it was passed false value and nil error. It's used +// to check if user decided to abort in report() and if there were no errors. +func exitOnFalse(val bool, err error) error { + if err == nil && !val { + log.Println("Aborting.") + os.Exit(0) + } + return err +} + func init() { flag.StringVar(&configFile, "config", "", "configuration file") flag.StringVar(&blacklistFile, "blacklist", "", "file with repositories which should be omitted") @@ -124,7 +248,11 @@ func setup() error { blacklistFile, err = config.FindFPath(blacklistFile, "blacklist") if err != nil { log.Println("Unable to read blacklist file: ", err) + if exitOnFalse(report(nil)) != nil { + return err + } } + editor = getValue(settings.G.Editor, os.Getenv("EDITOR"), false) // Repos target = getValue(target, settings.R.Target, true) @@ -164,6 +292,9 @@ func setup() error { return fmt.Errorf("Either -target or -tag must be set") } log.Println("Target wasn't set - probably new profile/project.") + if exitOnFalse(report(nil)) != nil { + return err + } } return nil @@ -270,11 +401,12 @@ func main() { dispatchAndGather(gitMgr.Compare) } + err = exitOnFalse(report(&repos)) + if err != nil { + log.Fatalln("Report error: ", err) + } + dispatchAndGather(gitMgr.AddRemote) dispatchAndGather(gitMgr.Tag) dispatchAndGather(gitMgr.Push) - log.Println("REPOS:") - for _, repo := range repos { - fmt.Println(repo) - } } |