summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cli/query.go3
-rw-r--r--pkg/rtree/index.go67
-rw-r--r--pkg/util/util.go39
3 files changed, 36 insertions, 73 deletions
diff --git a/pkg/cli/query.go b/pkg/cli/query.go
index a81d153..d8602bc 100644
--- a/pkg/cli/query.go
+++ b/pkg/cli/query.go
@@ -49,8 +49,7 @@ func Query(prompt string, choices ...Choice) (Choice, int) {
return Choice{}, -1
}
- //disable line wrap during doQuery(); unexpected wrapping would confuse our
- //cursor-moving code
+ //disable line wrap; unexpected wrapping would confuse our cursor-moving code
os.Stdout.Write([]byte("\x1B[?7l"))
defer os.Stdout.Write([]byte("\x1B[?7h"))
diff --git a/pkg/rtree/index.go b/pkg/rtree/index.go
index 0809fee..aa2b2a3 100644
--- a/pkg/rtree/index.go
+++ b/pkg/rtree/index.go
@@ -29,6 +29,7 @@ import (
"sort"
"strings"
+ "github.com/majewsky/gofu/pkg/cli"
"github.com/majewsky/gofu/pkg/util"
yaml "gopkg.in/yaml.v2"
@@ -131,8 +132,6 @@ func (i *Index) InteractiveRebuild() error {
}
//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" {
@@ -142,29 +141,32 @@ func (i *Index) InteractiveRebuild() error {
remoteURLs = append(remoteURLs, remote.URL)
}
- var choice string
+ var choice cli.Choice
if len(remoteURLs) == 0 {
- choice = util.Prompt(os.Stdout,
- "no remote to restore from; (d)elete from index or (s)kip?",
- []string{"d", "s"},
+ choice, _ = cli.Query(
+ fmt.Sprintf("repository %s has been deleted; no remote to restore from", filepath.Join(RootPath, repo.CheckoutPath)),
+ cli.Choice{Shortcut: 'd', Text: "delete from index"},
+ cli.Choice{Shortcut: 's', Text: "skip"},
)
} else {
- choice = util.Prompt(os.Stdout,
- fmt.Sprintf("(r)estore from %s, (d)elete from index, or (s)kip?", strings.Join(remoteURLs, " and ")),
- []string{"r", "d", "s"},
+ choice, _ = cli.Query(
+ fmt.Sprintf("repository %s has been deleted", filepath.Join(RootPath, repo.CheckoutPath)),
+ cli.Choice{Shortcut: 'r', Text: "(r)estore from " + strings.Join(remoteURLs, " and ")},
+ cli.Choice{Shortcut: 'd', Text: "delete from index"},
+ cli.Choice{Shortcut: 's', Text: "skip"},
)
}
- switch choice {
- case "r":
+ switch choice.Shortcut {
+ case 'r':
err := repo.Checkout()
if err != nil {
return err
}
newRepos = append(newRepos, repo)
- case "d":
+ case 'd':
continue
- case "s":
+ case 's':
newRepos = append(newRepos, repo)
}
}
@@ -194,8 +196,12 @@ var tenLetters = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
//disk or (if allowClone is set) clones it and adds it to the index. This
//is the meat of `rtree get`, and is also used by `rtree drop`.
func (i *Index) InteractiveFindRepo(remoteURL string, allowClone bool) *Repo {
- //NOTE: This function prints *everything* on stderr, because stdout is
- //reserved for the result path during `rtree get`.
+ //make sure that stdout is not used for prompts
+ originalStdout := os.Stdout
+ os.Stdout = os.Stderr
+ defer func() {
+ os.Stdout = originalStdout
+ }()
expandedRemoteURL := ExpandRemoteURL(remoteURL)
basename := path.Base(expandedRemoteURL)
@@ -245,15 +251,17 @@ func (i *Index) InteractiveFindRepo(remoteURL string, allowClone bool) *Repo {
if len(candidates) > 10 {
candidates = candidates[:10]
}
- prompt := "Found possible fork candidates.\n"
+ choices := make([]cli.Choice, len(candidates)+1)
for idx, repo := range candidates {
- prompt += fmt.Sprintf("\t(%s) add as remote to %s\n", tenLetters[idx], repo.AbsolutePath())
+ choices[idx] = cli.Choice{Text: "add as remote to " + repo.AbsolutePath()}
+ }
+ choices[len(candidates)] = cli.Choice{
+ Shortcut: 'n',
+ Text: "clone to " + newRepo.AbsolutePath(),
}
- prompt += fmt.Sprintf("\t(x) clone to %s\nSelect action:", newRepo.AbsolutePath())
- choices := append([]string{"x"}, tenLetters[:len(candidates)]...)
- choice := util.Prompt(os.Stderr, prompt, choices)
+ choice, choiceIdx := cli.Query("Found possible fork candidates. What to do?", choices...)
- if choice == "x" {
+ if choice.Shortcut == 'n' {
util.FatalIfError(newRepo.Checkout())
i.Repos = append(i.Repos, &newRepo)
i.Write()
@@ -261,29 +269,24 @@ func (i *Index) InteractiveFindRepo(remoteURL string, allowClone bool) *Repo {
}
//find the repo selected by the user
- var target *Repo
- for idx, str := range choices {
- if choice == str {
- target = candidates[idx-1]
- }
- }
+ target := candidates[choiceIdx]
//report the existing remotes, and ask for the name of the new remote
- fmt.Fprintln(os.Stderr, "Existing remotes:")
+ fmt.Println("Existing remotes:")
for _, remote := range target.Remotes {
- fmt.Fprintf(os.Stderr, "\t(%s) %s\n", remote.Name, remote.URL)
+ fmt.Printf("\t(%s) %s\n", remote.Name, remote.URL)
}
- fmt.Fprintf(os.Stderr, "Enter remote name for %s: ", remoteURL)
+ fmt.Printf("Enter remote name for %s: ", remoteURL)
remoteName := util.ReadLine()
cmd := exec.Command("git", "remote", "add", remoteName, remoteURL)
- cmd.Stdout = os.Stderr
+ cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = target.AbsolutePath()
util.FatalIfError(cmd.Run())
cmd = exec.Command("git", "remote", "update", remoteName)
- cmd.Stdout = os.Stderr
+ cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = target.AbsolutePath()
util.FatalIfError(cmd.Run())
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 8d2b0bf..8cdf147 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -21,7 +21,6 @@ package util
import (
"bufio"
"fmt"
- "io"
"os"
"sort"
"strings"
@@ -52,44 +51,6 @@ func FatalIfError(err error) {
var stdin = bufio.NewReader(os.Stdin)
-//Prompt prints the question, then waits for the user to press one of the
-//possible answer keys. Answer keys will automatically be converted to lower
-//case and returned as such.
-//
-// choice := Prompt("(y)es or (n)o", []string{"y","n"})
-// //choice is either "y" or "n"
-func Prompt(out io.Writer, question string, answers []string) string {
- for idx, answer := range answers {
- answers[idx] = strings.ToLower(answer)
- }
-
- out.Write([]byte(">> " + strings.TrimSpace(question) + " "))
- for {
- input, err := stdin.ReadString('\n')
- FatalIfError(err)
- input = strings.TrimSpace(input)
- for _, answer := range answers {
- if strings.ToLower(input) == answer {
- return answer
- }
- }
-
- //user typed gibberish - ask again
- out.Write([]byte("Please type "))
- for idx, answer := range answers {
- if idx > 0 {
- if idx == len(answers)-1 {
- out.Write([]byte(" or "))
- } else {
- out.Write([]byte(", "))
- }
- }
- out.Write([]byte("'" + answer + "'"))
- }
- out.Write([]byte(": "))
- }
-}
-
//ReadLine reads a line from stdin, with whitespace already trimmed.
func ReadLine() string {
input, err := stdin.ReadString('\n')