From 36b903423828b2e35c9c1fde3fdc898fe2ed23ca Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Sun, 7 May 2017 22:46:38 +0200 Subject: refactor towards new cli.Interface --- pkg/rtree/repo.go | 77 ++++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 43 deletions(-) (limited to 'pkg/rtree/repo.go') diff --git a/pkg/rtree/repo.go b/pkg/rtree/repo.go index 12afee0..fba658b 100644 --- a/pkg/rtree/repo.go +++ b/pkg/rtree/repo.go @@ -19,14 +19,14 @@ package rtree import ( - "bytes" "errors" "fmt" "os" - "os/exec" "path/filepath" "regexp" "strings" + + "github.com/majewsky/gofu/pkg/cli" ) //RootPath is the directory below which all repositories are located. Its value @@ -64,23 +64,22 @@ func (r Repo) AbsolutePath() string { //NewRepoFromAbsolutePath initializes a Repo instance by scanning the existing //checkout at the given path. -func NewRepoFromAbsolutePath(path string) (repo Repo, err error) { +func NewRepoFromAbsolutePath(ci *cli.Interface, path string) (repo Repo, err error) { repo.CheckoutPath, err = filepath.Rel(RootPath, path) if err != nil { return } //list remotes - cmd := exec.Command("git", "-C", path, "config", "-l") - var buf bytes.Buffer - cmd.Stdout = &buf - cmd.Stderr = os.Stderr - err = cmd.Run() + out, err := ci.CaptureStdout(cli.Command{ + Program: []string{"git", "config", "-l"}, + WorkDir: path, + }) if err != nil { - return repo, fmt.Errorf("exec `git config -l` in %s: %s", path, err.Error()) + return } - for _, line := range strings.Split(string(buf.Bytes()), "\n") { + for _, line := range strings.Split(out, "\n") { match := remoteConfigRx.FindStringSubmatch(line) if match == nil { continue @@ -113,7 +112,7 @@ var remoteConfigRx = regexp.MustCompile(`remote\.([^=]+)\.url=(.+)`) //ForeachPhysicalRepo walks over the repository tree, executing the action //function once for every repo encountered (but *not* for repos contained //within other repos, e.g. submodules). -func ForeachPhysicalRepo(action func(repo Repo) error) error { +func ForeachPhysicalRepo(ci *cli.Interface, action func(repo Repo) error) error { return filepath.Walk(RootPath, func(path string, info os.FileInfo, err error) error { if err != nil { return err @@ -128,7 +127,7 @@ func ForeachPhysicalRepo(action func(repo Repo) error) error { } //appears to be a repo - repo, err := NewRepoFromAbsolutePath(path) + repo, err := NewRepoFromAbsolutePath(ci, path) if err == nil { err = action(repo) } @@ -142,7 +141,7 @@ func ForeachPhysicalRepo(action func(repo Repo) error) error { //Checkout creates the repo in the given path with the given remotes. The //working copy will only be initialized if there is an "origin" remote. -func (r Repo) Checkout() error { +func (r Repo) Checkout(ci *cli.Interface) error { //check if we have an "origin" remote to clone from var originURL string for _, remote := range r.Remotes { @@ -153,19 +152,17 @@ func (r Repo) Checkout() error { } if originURL == "" { - cmd := exec.Command("git", "init", r.AbsolutePath()) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() + err := ci.Run(cli.Command{ + Program: []string{"git", "init", r.AbsolutePath()}, + }) if err != nil { return err } - fmt.Fprintln(os.Stderr, "warning: will not checkout anything since there is no remote named \"origin\"") + ci.ShowWarning(`will not checkout anything since there is no remote named "origin"`) } else { - cmd := exec.Command("git", "clone", originURL, r.AbsolutePath()) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() + err := ci.Run(cli.Command{ + Program: []string{"git", "clone", originURL, r.AbsolutePath()}, + }) if err != nil { return err } @@ -174,10 +171,10 @@ func (r Repo) Checkout() error { remotesAdded := false for _, remote := range r.Remotes { if remote.Name != "origin" { - cmd := exec.Command("git", "-C", r.AbsolutePath(), "remote", "add", remote.Name, remote.URL) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Run() + err := ci.Run(cli.Command{ + Program: []string{"git", "remote", "add", remote.Name, remote.URL}, + WorkDir: r.AbsolutePath(), + }) if err != nil { return err } @@ -185,29 +182,23 @@ func (r Repo) Checkout() error { } } if remotesAdded { - cmd := exec.Command("git", "-C", r.AbsolutePath(), "remote", "update") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() + return ci.Run(cli.Command{ + Program: []string{"git", "remote", "update"}, + WorkDir: r.AbsolutePath(), + }) } return nil } -//InteractiveExec implements the meat of the `rtree exec` command. It returns +//Exec implements the meat of the `rtree exec` command. It returns //true iff the command exited successfully. -func (r Repo) InteractiveExec(command string, args ...string) (ok bool) { - fmt.Fprintf(os.Stdout, "\x1B[1;36m>> \x1B[0;36m%s\x1B[0m\n", r.AbsolutePath()) - cmd := exec.Command(command, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Dir = r.AbsolutePath() - err := cmd.Run() - if err != nil { - fmt.Fprintf(os.Stderr, "\x1B[1;31m!! \x1B[0;31m%s\x1B[0m\n", err.Error()) - return false - } - return true +func (r Repo) Exec(ci *cli.Interface, cmdline ...string) error { + ci.ShowProgress(r.AbsolutePath()) + return ci.Run(cli.Command{ + Program: cmdline, + WorkDir: r.AbsolutePath(), + }) } //Move sets the CheckoutPath to the given value and moves the existing repo -- cgit v1.3.1