From c9de77f620f81468f94c81c62dd2c2409dadcc9d Mon Sep 17 00:00:00 2001 From: dan9186 Date: Fri, 21 Nov 2025 11:19:51 -0800 Subject: [PATCH 1/3] add logging repos to the interface and tester --- client/clienter.go | 1 + client/testclient/client.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/client/clienter.go b/client/clienter.go index ddbc491..394564e 100644 --- a/client/clienter.go +++ b/client/clienter.go @@ -16,6 +16,7 @@ type Clienter interface { GetLogins(ctx context.Context) ([]string, error) GetRepos(ctx context.Context, name string) ([]*github.Repository, error) ListTags(ctx context.Context, repoDirs []string, args ...string) error + LogRepos(ctx context.Context, repoDirs []string, ignoreEmtpy bool, args ...string) error PullRepos(ctx context.Context, repoDirs []string, args ...string) error PushRepos(ctx context.Context, repoDirs []string, args ...string) error Remotes(ctx context.Context, repoDirs []string, args ...string) error diff --git a/client/testclient/client.go b/client/testclient/client.go index 6757a47..536b717 100644 --- a/client/testclient/client.go +++ b/client/testclient/client.go @@ -104,3 +104,9 @@ func (c *TestClient) DiffRepos(ctx context.Context, repoDirs []string, cfg *clie return nil } + +func (c *TestClient) LogRepos(ctx context.Context, repoDirs []string, ignoreEmtpy bool, args ...string) error { + c.CommandsCalled = append(c.CommandsCalled, "LogRepos") + + return nil +} From 94e9b2c052dbf3e3d48b2d6b064f9147dec54af9 Mon Sep 17 00:00:00 2001 From: dan9186 Date: Fri, 21 Nov 2025 11:20:00 -0800 Subject: [PATCH 2/3] wire in log command --- client/repos_log.go | 49 +++++++++++++++++++++++++++++++++++++++++ cmd/log.go | 53 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 client/repos_log.go create mode 100644 cmd/log.go diff --git a/client/repos_log.go b/client/repos_log.go new file mode 100644 index 0000000..cc0564b --- /dev/null +++ b/client/repos_log.go @@ -0,0 +1,49 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "os/exec" + "strings" +) + +func (c *Client) LogRepos(ctx context.Context, dirs []string, ignoreEmpty bool, args ...string) error { + args = append([]string{"log"}, args...) + + c.scrb.BeginDescribe("Command") + defer c.scrb.EndDescribe() + + c.scrb.Print(fmt.Sprintf("git %s", strings.Join(args, " "))) + + c.scrb.BeginDescribe("directories") + defer c.scrb.EndDescribe() + + for _, dir := range dirs { + out := &bytes.Buffer{} + errout := &bytes.Buffer{} + + cmd := exec.CommandContext(ctx, "git", args...) + cmd.Stdout = out + cmd.Stderr = errout + cmd.Dir = dir + + err := cmd.Run() + + if ignoreEmpty && out.Len() == 0 && err == nil { + continue + } + + c.scrb.BeginDescribe(dir) + if err != nil { + c.scrb.Error(err) + c.scrb.PrintLines(errout) + } else { + c.scrb.PrintLines(out) + } + + c.scrb.EndDescribe() + } + + return nil +} diff --git a/cmd/log.go b/cmd/log.go new file mode 100644 index 0000000..99f1282 --- /dev/null +++ b/cmd/log.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" +) + +var ( + oneline bool +) + +func init() { + RootCmd.AddCommand(logCmd) + + logCmd.Flags().BoolVar(&oneline, "oneline", false, "Show each commit on a single line") + logCmd.Flags().BoolVar(&ignoreEmtpy, "ignore-empty", false, "Ignore empty repositories") +} + +var logCmd = &cobra.Command{ + Use: "log", + Short: "Show commit logs for all repos in a directory", + Long: `Show commit logs all repos in a directory. Since commit hashes would not be the same between +multiple repos this command really only makes sense when used with two branch names or two tags.`, + PersistentPreRun: setupClient, + RunE: logFunc, +} + +func logFunc(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + repoDirs, err := clt.GetDirs(ctx, dir) + if err != nil { + cmd.SilenceUsage = true + return fmt.Errorf("get dirs: %w", err) + } + + if oneline { + args = append(args, "--oneline") + } + + // TODO: Add the option to disable color as well + args = append(args, "--color") + + err = clt.LogRepos(ctx, repoDirs, ignoreEmtpy, args...) + if err != nil { + cmd.SilenceUsage = true + return fmt.Errorf("log repos: %w", err) + } + + return nil +} From 02be87d5999a5057e162a9acfe4f36b9c8fdb7c7 Mon Sep 17 00:00:00 2001 From: dan9186 Date: Fri, 21 Nov 2025 11:28:21 -0800 Subject: [PATCH 3/3] have color by default but allow turning it off --- cmd/log.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/log.go b/cmd/log.go index 99f1282..fa0a753 100644 --- a/cmd/log.go +++ b/cmd/log.go @@ -9,12 +9,14 @@ import ( var ( oneline bool + noColor bool ) func init() { RootCmd.AddCommand(logCmd) logCmd.Flags().BoolVar(&oneline, "oneline", false, "Show each commit on a single line") + logCmd.Flags().BoolVar(&noColor, "no-color", false, "Disable color output") logCmd.Flags().BoolVar(&ignoreEmtpy, "ignore-empty", false, "Ignore empty repositories") } @@ -40,8 +42,9 @@ func logFunc(cmd *cobra.Command, args []string) error { args = append(args, "--oneline") } - // TODO: Add the option to disable color as well - args = append(args, "--color") + if !noColor { + args = append(args, "--color") + } err = clt.LogRepos(ctx, repoDirs, ignoreEmtpy, args...) if err != nil {