aboutsummaryrefslogtreecommitdiffstats
path: root/commands/select/select.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-09-18 12:49:16 +0200
committerMichael Muré <batolettre@gmail.com>2018-09-18 12:49:16 +0200
commit0d5998eb67f9bbf146e15a127a2d6a89aa14eab9 (patch)
tree1f9a61040bc5f84ef2b78199a9adf922b7f0441f /commands/select/select.go
parent5eaf9e83e7cd56b8bb4915193d13adfb60575b21 (diff)
downloadgit-bug-0d5998eb67f9bbf146e15a127a2d6a89aa14eab9.tar.gz
commands: add a package to handle implicit bug selection
Diffstat (limited to 'commands/select/select.go')
-rw-r--r--commands/select/select.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/commands/select/select.go b/commands/select/select.go
new file mode 100644
index 00000000..5d6cee7f
--- /dev/null
+++ b/commands/select/select.go
@@ -0,0 +1,125 @@
+package _select
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+
+ "github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/repository"
+ "github.com/MichaelMure/git-bug/util/git"
+ "github.com/pkg/errors"
+)
+
+const selectFile = "select"
+
+var ErrNoValidId = errors.New("you must provide a bug id")
+
+// ResolveBug first try to resolve a bug using the first argument of the command
+// line. If it fails, it fallback to the select mechanism.
+//
+// Returns:
+// - the bug if any
+// - the new list of command line arguments with the bug prefix removed if it
+// has been used
+// - an error if the process failed
+func ResolveBug(repo *cache.RepoCache, args []string) (*cache.BugCache, []string, error) {
+ if len(args) > 0 {
+ b, err := repo.ResolveBugPrefix(args[0])
+
+ if err == nil {
+ return b, args[1:], nil
+ }
+
+ if err != bug.ErrBugNotExist {
+ return nil, nil, err
+ }
+ }
+
+ // first arg is not a valid bug prefix
+
+ b, err := selected(repo)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if b != nil {
+ return b, args, nil
+ }
+
+ return nil, nil, ErrNoValidId
+}
+
+// Select will select a bug for future use
+func Select(repo *cache.RepoCache, id string) error {
+ selectPath := selectFilePath(repo.Repository())
+
+ f, err := os.OpenFile(selectPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+ if err != nil {
+ return err
+ }
+
+ _, err = f.WriteString(id)
+ if err != nil {
+ return err
+ }
+
+ return f.Close()
+}
+
+// Clear will clear the selected bug, if any
+func Clear(repo *cache.RepoCache) error {
+ selectPath := selectFilePath(repo.Repository())
+
+ return os.Remove(selectPath)
+}
+
+func selected(repo *cache.RepoCache) (*cache.BugCache, error) {
+ selectPath := selectFilePath(repo.Repository())
+
+ f, err := os.Open(selectPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ } else {
+ return nil, err
+ }
+ }
+
+ buf, err := ioutil.ReadAll(io.LimitReader(f, 100))
+ if err != nil {
+ return nil, err
+ }
+ if len(buf) == 100 {
+ return nil, fmt.Errorf("the select file should be < 100 bytes")
+ }
+
+ h := git.Hash(buf)
+ if !h.IsValid() {
+ err = os.Remove(selectPath)
+ if err != nil {
+ return nil, errors.Wrap(err, "error while removing invalid select file")
+ }
+
+ return nil, fmt.Errorf("select file in invalid, removing it")
+ }
+
+ b, err := repo.ResolveBug(string(h))
+ if err != nil {
+ return nil, err
+ }
+
+ err = f.Close()
+ if err != nil {
+ return nil, err
+ }
+
+ return b, nil
+}
+
+func selectFilePath(repo repository.Repo) string {
+ return path.Join(repo.GetPath(), ".git", "git-bug", selectFile)
+}