mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-15 18:23:08 +03:00
141 lines
2.9 KiB
Go
141 lines
2.9 KiB
Go
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) {
|
|
// At first, try to use the first argument as a bug prefix
|
|
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, we can safely use the preselected bug if any
|
|
|
|
b, err := selected(repo)
|
|
|
|
// selected bug is invalid
|
|
if err == bug.ErrBugNotExist {
|
|
// we clear the selected bug
|
|
err = Clear(repo)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return nil, nil, ErrNoValidId
|
|
}
|
|
|
|
// another error when reading the bug
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
// bug is successfully retrieved
|
|
if b != nil {
|
|
return b, args, nil
|
|
}
|
|
|
|
// no selected bug and no valid first argument
|
|
return nil, nil, ErrNoValidId
|
|
}
|
|
|
|
// Select will select a bug for future use
|
|
func Select(repo *cache.RepoCache, id string) error {
|
|
selectPath := selectFilePath(repo)
|
|
|
|
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)
|
|
|
|
return os.Remove(selectPath)
|
|
}
|
|
|
|
func selected(repo *cache.RepoCache) (*cache.BugCache, error) {
|
|
selectPath := selectFilePath(repo)
|
|
|
|
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.RepoCommon) string {
|
|
return path.Join(repo.GetPath(), ".git", "git-bug", selectFile)
|
|
}
|