diff --git a/cmd/balance.go b/cmd/balance.go index dd205be..8e55dd0 100644 --- a/cmd/balance.go +++ b/cmd/balance.go @@ -23,7 +23,6 @@ import ( "path" "path/filepath" "sort" - "time" "github.com/marstr/envelopes" "github.com/sirupsen/logrus" @@ -44,22 +43,8 @@ var balanceCmd = &cobra.Command{ Aliases: []string{"bal", "b"}, Short: "Scours a baronial directory (or subdirectory) for balance information.", Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() var targetDir string if len(args) > 0 { @@ -68,6 +53,7 @@ var balanceCmd = &cobra.Command{ targetDir = "." } + var err error targetDir, err = filepath.Abs(targetDir) if err != nil { logrus.Fatal(err) diff --git a/cmd/branch.go b/cmd/branch.go index 28f943c..5ac35c0 100644 --- a/cmd/branch.go +++ b/cmd/branch.go @@ -23,7 +23,6 @@ import ( "io" "os" "path" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -40,22 +39,10 @@ var branchCmd = &cobra.Command{ Short: "Creates a branch with a given name.", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() + var err error var indexRootDir string indexRootDir, err = index.RootDirectory(".") if err != nil { diff --git a/cmd/bring-to.go b/cmd/bring-to.go index d8e44ec..e276e9b 100644 --- a/cmd/bring-to.go +++ b/cmd/bring-to.go @@ -1,9 +1,6 @@ package cmd import ( - "context" - "time" - "github.com/marstr/baronial/internal/index" "github.com/marstr/envelopes" "github.com/sirupsen/logrus" @@ -31,21 +28,8 @@ func init() { } func RunBringTo(cmd *cobra.Command, args []string) error { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() desiredBal, err := envelopes.ParseBalance([]byte(args[0])) if err != nil { diff --git a/cmd/checkout.go b/cmd/checkout.go index b9b11e5..7aeb911 100644 --- a/cmd/checkout.go +++ b/cmd/checkout.go @@ -16,9 +16,7 @@ package cmd import ( - "context" "path" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -35,24 +33,11 @@ var checkoutCmd = &cobra.Command{ Short: "Resets the index to show the balances at a particular transaction.", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() var root string + var err error root, err = index.RootDirectory(".") if err != nil { logrus.Fatal(err) diff --git a/cmd/commit.go b/cmd/commit.go index 31e1e7d..1be252b 100644 --- a/cmd/commit.go +++ b/cmd/commit.go @@ -138,22 +138,8 @@ var commitCmd = &cobra.Command{ return cobra.NoArgs(cmd, args) }, Run: func(cmd *cobra.Command, _ []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() targetDir, err := index.RootDirectory(".") if err != nil { diff --git a/cmd/credit.go b/cmd/credit.go index 9d695c3..d0715e8 100644 --- a/cmd/credit.go +++ b/cmd/credit.go @@ -16,9 +16,7 @@ package cmd import ( - "context" "fmt" - "time" "github.com/marstr/envelopes" "github.com/sirupsen/logrus" @@ -33,22 +31,8 @@ var creditCmd = &cobra.Command{ Short: "Makes funds available for one or more category of spending.", Args: creditDebitArgValidation, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() rawMagnitude := args[0] magnitude, err := envelopes.ParseBalance([]byte(rawMagnitude)) @@ -76,28 +60,14 @@ func init() { } func creditDebitArgValidation(cmd *cobra.Command, args []string) error { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() if argCount := len(args); argCount < 2 { return fmt.Errorf("too few arguments (%d). %q requires at least a balance and one budget or account", argCount, cmd.Name()) } - _, err = envelopes.ParseBalance([]byte(args[0])) + _, err := envelopes.ParseBalance([]byte(args[0])) if err != nil { return fmt.Errorf("%q not recognized as an amount", args[0]) } diff --git a/cmd/debit.go b/cmd/debit.go index 2c9f6ac..1d31dc4 100644 --- a/cmd/debit.go +++ b/cmd/debit.go @@ -16,9 +16,6 @@ package cmd import ( - "context" - "time" - "github.com/marstr/envelopes" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -32,22 +29,8 @@ var debitCmd = &cobra.Command{ Short: `Removes funds from a category of spending.`, Args: creditDebitArgValidation, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() rawMagnitude := args[0] magnitude, err := envelopes.ParseBalance([]byte(rawMagnitude)) diff --git a/cmd/diff.go b/cmd/diff.go index 3cef564..39d3262 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -21,7 +21,6 @@ import ( "context" "errors" "path" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -40,25 +39,10 @@ var diffCmd = &cobra.Command{ Args: cobra.MaximumNArgs(2), PreRunE: setPagedCobraOutput, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() - var repoRoot string - repoRoot, err = index.RootDirectory(".") + repoRoot, err := index.RootDirectory(".") if err != nil { return } diff --git a/cmd/init.go b/cmd/init.go index 9765671..d2ef6f8 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -16,9 +16,7 @@ package cmd import ( - "context" "os" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -34,22 +32,8 @@ var initCmd = &cobra.Command{ Short: "Creates a new Baronial repository in the current working directory.", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() const initCmdFailurePrefix = "unable to initialize repository: " @@ -71,8 +55,7 @@ var initCmd = &cobra.Command{ } } - var repo persist.RepositoryReaderWriter - repo, err = filesystem.OpenRepositoryWithCache(ctx, index.RepoName, 10000) + repo, err := filesystem.OpenRepositoryWithCache(ctx, index.RepoName, 10000) if err != nil { logrus.Fatal(err) } diff --git a/cmd/log.go b/cmd/log.go index ae5bd29..8a1828d 100644 --- a/cmd/log.go +++ b/cmd/log.go @@ -22,7 +22,6 @@ import ( "os" "path/filepath" "strings" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -43,25 +42,10 @@ var logCmd = &cobra.Command{ }, PreRunE: setPagedCobraOutput, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() - var root string - root, err = index.RootDirectory(".") + root, err := index.RootDirectory(".") if err != nil { logrus.Error(err) return diff --git a/cmd/rev-parse.go b/cmd/rev-parse.go index e4e6764..3270d6e 100644 --- a/cmd/rev-parse.go +++ b/cmd/rev-parse.go @@ -16,10 +16,8 @@ package cmd import ( - "context" "fmt" "path" - "time" "github.com/marstr/envelopes/persist" "github.com/marstr/envelopes/persist/filesystem" @@ -34,22 +32,8 @@ var revParseCmd = &cobra.Command{ Short: "Prints a realized transaction ID.", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() root, err := index.RootDirectory(".") if err != nil { diff --git a/cmd/revert.go b/cmd/revert.go index 898c331..51f4edf 100644 --- a/cmd/revert.go +++ b/cmd/revert.go @@ -16,11 +16,9 @@ limitations under the License. package cmd import ( - "context" "fmt" "os" "path" - "time" "github.com/marstr/baronial/internal/index" "github.com/marstr/envelopes" @@ -43,22 +41,8 @@ complicates all future tools and many may not do a good job. If you accidentally reverted a transaction, just commit a new transaction that is identical to the original.`, Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() root, err := index.RootDirectory(".") if err != nil { diff --git a/cmd/root.go b/cmd/root.go index b2cb517..9b96a65 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,10 +16,14 @@ package cmd import ( + "context" "fmt" "os" + "sync" + "time" homedir "github.com/mitchellh/go-homedir" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -49,6 +53,32 @@ to quickly create a Cobra application.`, // Run: func(cmd *cobra.Command, args []string) { }, } +var ( + parseTimeout sync.Once + rootContext context.Context + rootCancel context.CancelFunc +) + +func RootContext(cmd *cobra.Command) (context.Context, context.CancelFunc) { + parseTimeout.Do(func() { + var timeout time.Duration + var err error + timeout, err = cmd.Flags().GetDuration(timeoutFlag) + if err != nil { + logrus.Fatal(err) + } + + if timeout > 0 { + rootContext, rootCancel = context.WithTimeout(context.Background(), timeout) + + } else { + rootContext, rootCancel = context.WithCancel(context.Background()) + } + }) + + return rootContext, rootCancel +} + // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { diff --git a/cmd/show.go b/cmd/show.go index 9dfd431..4864e09 100644 --- a/cmd/show.go +++ b/cmd/show.go @@ -16,10 +16,8 @@ package cmd import ( - "context" "os" "path" - "time" "github.com/marstr/envelopes" "github.com/marstr/envelopes/persist" @@ -39,22 +37,8 @@ displayed. However, the particular impacts to accounts and budgets are hidden for the sake of brevity. This command shows all known details of a transaction.`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() root, err := index.RootDirectory(".") if err != nil { diff --git a/cmd/transfer.go b/cmd/transfer.go index ce55750..56ba84a 100644 --- a/cmd/transfer.go +++ b/cmd/transfer.go @@ -16,9 +16,6 @@ package cmd import ( - "context" - "time" - "github.com/marstr/baronial/internal/index" "github.com/marstr/envelopes" "github.com/sirupsen/logrus" @@ -31,22 +28,8 @@ var transferCmd = &cobra.Command{ Short: "Moves funds from one category of spending to another.", Args: cobra.ExactArgs(3), Run: func(cmd *cobra.Command, args []string) { - var timeout time.Duration - var err error - timeout, err = cmd.Flags().GetDuration(timeoutFlag) - if err != nil { - logrus.Fatal(err) - } - - var ctx context.Context - if timeout > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(context.Background(), timeout) - defer cancel() - - } else { - ctx = context.Background() - } + ctx, cancel := RootContext(cmd) + defer cancel() rawSrc := args[1] rawDest := args[2]