summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Wereski <m.wereski@partner.samsung.com>2017-03-07 12:31:57 +0100
committerMaciej Wereski <m.wereski@partner.samsung.com>2017-08-17 08:53:00 +0200
commit1a7c29ab68d6dd3262d440642cb35df1ad19b016 (patch)
treee4aa6d5b5e7d71e8181f4cf86d2d7f70516ecd84
parentf0e22844a344ddeff1fe1f3d3e13865cc3351f99 (diff)
downloadsnapsync-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.go1
-rw-r--r--snapsync.conf1
-rw-r--r--snapsync.go140
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)
- }
}