feat(cli): allow an alternate Git repository path to be specified

Steve Moyer created

A  flag was added that shares the same semantics as the Git's  flag

Resolves #1467O

Change summary

commands/execenv/env.go     | 11 ++++++-----
commands/execenv/loading.go | 19 ++++++++++++++++---
commands/root.go            |  7 ++++---
3 files changed, 26 insertions(+), 11 deletions(-)

Detailed changes

commands/execenv/env.go 🔗

@@ -19,11 +19,12 @@ const gitBugNamespace = "git-bug"
 
 // Env is the environment of a command
 type Env struct {
-	Repo    repository.ClockedRepo
-	Backend *cache.RepoCache
-	In      In
-	Out     Out
-	Err     Out
+	Repo     repository.ClockedRepo
+	Backend  *cache.RepoCache
+	In       In
+	Out      Out
+	Err      Out
+	RepoPath []string
 }
 
 func NewEnv() *Env {

commands/execenv/loading.go 🔗

@@ -3,6 +3,7 @@ package execenv
 import (
 	"fmt"
 	"os"
+	"path/filepath"
 
 	"github.com/spf13/cobra"
 	"github.com/vbauerster/mpb/v8"
@@ -17,15 +18,15 @@ import (
 // LoadRepo is a pre-run function that load the repository for use in a command
 func LoadRepo(env *Env) func(*cobra.Command, []string) error {
 	return func(cmd *cobra.Command, args []string) error {
-		cwd, err := os.Getwd()
+		repoPath, err := getRepoPath(env)
 		if err != nil {
-			return fmt.Errorf("unable to get the current working directory: %q", err)
+			return err
 		}
 
 		// Note: we are not loading clocks here because we assume that LoadRepo is only used
 		//  when we don't manipulate entities, or as a child call of LoadBackend which will
 		//  read all clocks anyway.
-		env.Repo, err = repository.OpenGoGitRepo(cwd, gitBugNamespace, nil)
+		env.Repo, err = repository.OpenGoGitRepo(repoPath, gitBugNamespace, nil)
 		if err == repository.ErrNotARepo {
 			return fmt.Errorf("%s must be run from within a git Repo", RootCommandName)
 		}
@@ -171,3 +172,15 @@ func CacheBuildProgressBar(env *Env, events chan cache.BuildEvent) error {
 
 	return nil
 }
+
+func getRepoPath(env *Env) (string, error) {
+	if len(env.RepoPath) > 0 {
+		return filepath.Join(env.RepoPath...), nil
+	}
+
+	cwd, err := os.Getwd()
+	if err != nil {
+		return "", fmt.Errorf("unable to get the current working directory: %q", err)
+	}
+	return cwd, nil
+}

commands/root.go 🔗

@@ -5,10 +5,10 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"github.com/git-bug/git-bug/commands/bridge"
-	"github.com/git-bug/git-bug/commands/bug"
+	bridgecmd "github.com/git-bug/git-bug/commands/bridge"
+	bugcmd "github.com/git-bug/git-bug/commands/bug"
 	"github.com/git-bug/git-bug/commands/execenv"
-	"github.com/git-bug/git-bug/commands/user"
+	usercmd "github.com/git-bug/git-bug/commands/user"
 )
 
 func NewRootCommand(version string) *cobra.Command {
@@ -55,6 +55,7 @@ the same git remote you are already using to collaborate with other people.
 	}
 
 	env := execenv.NewEnv()
+	cmd.PersistentFlags().StringArrayVarP(&env.RepoPath, "repo-path", "C", []string{}, "Path to the git repository")
 
 	addCmdWithGroup(bugcmd.NewBugCommand(env), entityGroup)
 	addCmdWithGroup(usercmd.NewUserCommand(env), entityGroup)