aboutsummaryrefslogtreecommitdiffstats
path: root/commands/env.go
diff options
context:
space:
mode:
Diffstat (limited to 'commands/env.go')
-rw-r--r--commands/env.go150
1 files changed, 150 insertions, 0 deletions
diff --git a/commands/env.go b/commands/env.go
new file mode 100644
index 00000000..c3596c2d
--- /dev/null
+++ b/commands/env.go
@@ -0,0 +1,150 @@
+package commands
+
+import (
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/spf13/cobra"
+
+ "github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/MichaelMure/git-bug/repository"
+ "github.com/MichaelMure/git-bug/util/interrupt"
+)
+
+// Env is the environment of a command
+type Env struct {
+ repo repository.ClockedRepo
+ backend *cache.RepoCache
+ out out
+ err out
+}
+
+func newEnv() *Env {
+ return &Env{
+ repo: nil,
+ out: out{Writer: os.Stdout},
+ err: out{Writer: os.Stderr},
+ }
+}
+
+type out struct {
+ io.Writer
+}
+
+func (o out) Printf(format string, a ...interface{}) {
+ _, _ = fmt.Fprintf(o, format, a...)
+}
+
+func (o out) Print(a ...interface{}) {
+ _, _ = fmt.Fprint(o, a...)
+}
+
+func (o out) Println(a ...interface{}) {
+ _, _ = fmt.Fprintln(o, a...)
+}
+
+// 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()
+ if err != nil {
+ return fmt.Errorf("unable to get the current working directory: %q", err)
+ }
+
+ env.repo, err = repository.NewGitRepo(cwd, []repository.ClockLoader{bug.ClockLoader})
+ if err == repository.ErrNotARepo {
+ return fmt.Errorf("%s must be run from within a git repo", rootCommandName)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+// loadRepoEnsureUser is the same as loadRepo, but also ensure that the user has configured
+// an identity. Use this pre-run function when an error after using the configured user won't
+// do.
+func loadRepoEnsureUser(env *Env) func(*cobra.Command, []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ err := loadRepo(env)(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ _, err = identity.GetUserIdentity(env.repo)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+// loadBackend is a pre-run function that load the repository and the backend for use in a command
+// When using this function you also need to use closeBackend as a post-run
+func loadBackend(env *Env) func(*cobra.Command, []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ err := loadRepo(env)(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ env.backend, err = cache.NewRepoCache(env.repo)
+ if err != nil {
+ return err
+ }
+
+ cleaner := func(env *Env) interrupt.CleanerFunc {
+ return func() error {
+ if env.backend != nil {
+ err := env.backend.Close()
+ env.backend = nil
+ return err
+ }
+ return nil
+ }
+ }
+
+ // Cleanup properly on interrupt
+ interrupt.RegisterCleaner(cleaner(env))
+ return nil
+ }
+}
+
+// loadBackendEnsureUser is the same as loadBackend, but also ensure that the user has configured
+// an identity. Use this pre-run function when an error after using the configured user won't
+// do.
+func loadBackendEnsureUser(env *Env) func(*cobra.Command, []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ err := loadRepo(env)(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ _, err = identity.GetUserIdentity(env.repo)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
+}
+
+// closeBackend is a post-run function that will close the backend properly
+// if it has been opened.
+func closeBackend(env *Env) func(*cobra.Command, []string) error {
+ return func(cmd *cobra.Command, args []string) error {
+ if env.backend == nil {
+ return nil
+ }
+ err := env.backend.Close()
+ env.backend = nil
+ return err
+ }
+}