aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2017-05-02 20:37:39 +0200
committerStefan Majewsky <majewsky@gmx.net>2017-05-02 20:37:39 +0200
commit6b382c55ed7885857a6232a0c8b086ab1f64985e (patch)
tree7a7bda45f42ab4040e4a4104a0cc5157e984204b
parentba69181d4d892aecfc35f9f30fe190d946662284 (diff)
downloadgofu-6b382c55ed7885857a6232a0c8b086ab1f64985e.tar.gz
move code out of main.go into the model types
-rw-r--r--index.go89
-rw-r--r--main.go103
-rw-r--r--repo.go16
3 files changed, 114 insertions, 94 deletions
diff --git a/index.go b/index.go
index c56c2e1..b579e7e 100644
--- a/index.go
+++ b/index.go
@@ -24,6 +24,8 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "sort"
+ "strings"
yaml "gopkg.in/yaml.v2"
)
@@ -83,9 +85,17 @@ func ReadIndex() *Index {
if !valid {
FatalIfError(errors.New("index file is corrupted; see errors above"))
}
+
+ sort.Sort(reposByAbsPath(index.Repos))
return &index
}
+type reposByAbsPath []*Repo
+
+func (r reposByAbsPath) Len() int { return len(r) }
+func (r reposByAbsPath) Less(i, j int) bool { return r[i].AbsolutePath() < r[j].AbsolutePath() }
+func (r reposByAbsPath) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+
//Write writes the index file to disk.
func (i *Index) Write() {
buf, err := yaml.Marshal(i)
@@ -94,3 +104,82 @@ func (i *Index) Write() {
FatalIfError(os.MkdirAll(filepath.Dir(path), 0755))
FatalIfError(ioutil.WriteFile(path, buf, 0644))
}
+
+//InteractiveRebuild implements the `rtree index` subcommand.
+func (i *Index) InteractiveRebuild() error {
+ //check if existing index entries are still checked out
+ existingRepos := make(map[string]*Repo)
+ var newRepos []*Repo
+ for _, repo := range i.Repos {
+ gitDirPath := filepath.Join(repo.AbsolutePath(), ".git")
+ fi, err := os.Stat(gitDirPath)
+ if err == nil {
+ if fi.IsDir() {
+ //everything okay with this repo
+ existingRepos[repo.CheckoutPath] = repo
+ newRepos = append(newRepos, repo)
+ continue
+ }
+ return fmt.Errorf("%s is not a directory: I'm seriously confused", gitDirPath)
+ }
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ //repo has been deleted - ask what to do
+ fmt.Printf("repository %s has been deleted\n", filepath.Join(RootPath, repo.CheckoutPath))
+
+ var remoteURLs []string
+ for _, remote := range repo.Remotes {
+ if remote.Name == "origin" {
+ remoteURLs = []string{remote.URL}
+ break
+ }
+ remoteURLs = append(remoteURLs, remote.URL)
+ }
+
+ var choice string
+ if len(remoteURLs) == 0 {
+ choice = Prompt(
+ "no remote to restore from; (d)elete from index or (s)kip?",
+ []string{"d", "s"},
+ )
+ } else {
+ choice = Prompt(
+ fmt.Sprintf("(r)estore from %s, (d)elete from index, or (s)kip?", strings.Join(remoteURLs, " and ")),
+ []string{"r", "d", "s"},
+ )
+ }
+
+ switch choice {
+ case "r":
+ err := repo.Checkout()
+ if err != nil {
+ return err
+ }
+ newRepos = append(newRepos, repo)
+ case "d":
+ continue
+ case "s":
+ newRepos = append(newRepos, repo)
+ }
+ }
+
+ //index new repos
+ err := ForeachPhysicalRepo(func(newRepo Repo) error {
+ repo, exists := existingRepos[newRepo.CheckoutPath]
+ if exists {
+ //update the existing index entry with the new remotes
+ repo.Remotes = newRepo.Remotes
+ } else {
+ newRepos = append(newRepos, &newRepo)
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ i.Repos = newRepos
+ return nil
+}
diff --git a/main.go b/main.go
index 63b5f6c..40e6630 100644
--- a/main.go
+++ b/main.go
@@ -21,10 +21,6 @@ package main
import (
"fmt"
"os"
- "os/exec"
- "path/filepath"
- "sort"
- "strings"
)
func main() {
@@ -73,76 +69,9 @@ func usageAndExit() {
}
func commandIndex() {
- oldIndex := ReadIndex()
- var newIndex Index
-
- //check if existing index entries are still checked out
- existingRepos := make(map[string]*Repo)
- for _, repo := range oldIndex.Repos {
- gitDirPath := filepath.Join(repo.AbsolutePath(), ".git")
- fi, err := os.Stat(gitDirPath)
- if err == nil {
- if fi.IsDir() {
- //everything okay with this repo
- existingRepos[repo.CheckoutPath] = repo
- newIndex.Repos = append(newIndex.Repos, repo)
- continue
- }
- FatalIfError(fmt.Errorf("%s is not a directory: I'm seriously confused", gitDirPath))
- }
- if !os.IsNotExist(err) {
- FatalIfError(err)
- }
-
- //repo has been deleted - ask what to do
- fmt.Printf("repository %s has been deleted\n", filepath.Join(RootPath, repo.CheckoutPath))
-
- var remoteURLs []string
- for _, remote := range repo.Remotes {
- if remote.Name == "origin" {
- remoteURLs = []string{remote.URL}
- break
- }
- remoteURLs = append(remoteURLs, remote.URL)
- }
-
- var choice string
- if len(remoteURLs) == 0 {
- choice = Prompt(
- "no remote to restore from; (d)elete from index or (s)kip?",
- []string{"d", "s"},
- )
- } else {
- choice = Prompt(
- fmt.Sprintf("(r)estore from %s, (d)elete from index, or (s)kip?", strings.Join(remoteURLs, " and ")),
- []string{"r", "d", "s"},
- )
- }
-
- switch choice {
- case "r":
- FatalIfError(repo.Checkout())
- newIndex.Repos = append(newIndex.Repos, repo)
- case "d":
- continue
- case "s":
- newIndex.Repos = append(newIndex.Repos, repo)
- }
- }
-
- //index new repos
- FatalIfError(ForeachPhysicalRepo(func(newRepo Repo) error {
- repo, exists := existingRepos[newRepo.CheckoutPath]
- if exists {
- //update the existing index entry with the new remotes
- repo.Remotes = newRepo.Remotes
- } else {
- newIndex.Repos = append(newIndex.Repos, &newRepo)
- }
- return nil
- }))
-
- newIndex.Write()
+ index := ReadIndex()
+ FatalIfError(index.InteractiveRebuild())
+ index.Write()
}
func commandRepos() {
@@ -166,29 +95,15 @@ func commandRemotes() {
}
func commandEach(command string, args []string) {
- index := ReadIndex()
-
- var paths []string
- for _, repo := range index.Repos {
- paths = append(paths, repo.AbsolutePath())
- }
- sort.Strings(paths)
-
- hadErrors := false
- for _, path := range paths {
- fmt.Fprintf(os.Stdout, "\x1B[1;36m>> \x1B[0;36m%s\x1B[0m\n", path)
- cmd := exec.Command(command, args...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Dir = path
- err := cmd.Run()
- if err != nil {
- fmt.Fprintf(os.Stderr, "\x1B[1;31m!! \x1B[0;31m%s\x1B[0m\n", err.Error())
- hadErrors = true
+ allOK := true
+ for _, repo := range ReadIndex().Repos {
+ ok := repo.InteractiveExec(command, args...)
+ if !ok {
+ allOK = false
}
}
- if hadErrors {
+ if !allOK {
os.Exit(1)
}
}
diff --git a/repo.go b/repo.go
index f0c2491..532b5d1 100644
--- a/repo.go
+++ b/repo.go
@@ -178,3 +178,19 @@ func (r Repo) Checkout() error {
return nil
}
+
+//InteractiveExec 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
+}