From b60a7f234c99bd0c53b8ba08c9f63e68039599c4 Mon Sep 17 00:00:00 2001 From: Andy Lu Date: Wed, 5 Jul 2023 10:36:18 -0400 Subject: [PATCH] Add commit command (#331) * Add commit command * fix bad refactor * fix: actually support the color flag * Squashed commit of the following: commit 814ee9f8fa7014dd4fafab12974e2edd4b8f7d73 Author: Andy Lu Date: Fri Jun 30 23:07:49 2023 -0400 Run gofmt commit 3db029502c74461b57e776a0ebc9d27c944acc5d Author: Andy Lu Date: Fri Jun 30 23:06:31 2023 -0400 Pull out statsLine and diffLine, add a commit body line commit eb1da4296e0181bae842622e0dc98ca8ca845049 Author: Andy Lu Date: Fri Jun 30 23:05:36 2023 -0400 Add flag for printing the patch only commit e76702e92b085f02427aae1c7052f235454242fd Author: Andy Lu Date: Fri Jun 30 22:50:55 2023 -0400 Add commit, author, date, and stats commit 0359b1dc49417d11f8f8b8529f8b942417d79128 Author: Andy Lu Date: Fri Jun 30 21:43:35 2023 -0400 Add commit, author, date, and stats Missing color on stats * Whitespace cleanup --- server/cmd/commit.go | 166 +++++++++++++++++++++++++++++++++++++++++++ server/cmd/repo.go | 1 + 2 files changed, 167 insertions(+) create mode 100644 server/cmd/commit.go diff --git a/server/cmd/commit.go b/server/cmd/commit.go new file mode 100644 index 0000000000000000000000000000000000000000..9b96f9103e6790ab68c133383ba24da416a61c42 --- /dev/null +++ b/server/cmd/commit.go @@ -0,0 +1,166 @@ +package cmd + +import ( + "fmt" + "strings" + "time" + + gansi "github.com/charmbracelet/glamour/ansi" + "github.com/charmbracelet/soft-serve/git" + "github.com/charmbracelet/soft-serve/server/ui/common" + "github.com/charmbracelet/soft-serve/server/ui/styles" + "github.com/muesli/termenv" + "github.com/spf13/cobra" +) + +// commitCommand returns a command that prints the contents of a commit. +func commitCommand() *cobra.Command { + var color bool + var patchOnly bool + + cmd := &cobra.Command{ + Use: "commit SHA", + Short: "Print out the contents of a diff", + Args: cobra.ExactArgs(2), + PersistentPreRunE: checkIfReadable, + RunE: func(cmd *cobra.Command, args []string) error { + cfg, _ := fromContext(cmd) + repoName := args[0] + commitSHA := args[1] + + rr, err := cfg.Backend.Repository(repoName) + if err != nil { + return err + } + + r, err := rr.Open() + if err != nil { + return err + } + + raw_commit, err := r.CommitByRevision(commitSHA) + + commit := &git.Commit{ + Commit: raw_commit, + Hash: git.Hash(commitSHA), + } + + patch, err := r.Patch(commit) + if err != nil { + return err + } + + diff, err := r.Diff(commit) + if err != nil { + return err + } + + commonStyle := styles.DefaultStyles() + style := commonStyle.Log + + s := strings.Builder{} + commitLine := "commit " + commitSHA + authorLine := "Author: " + commit.Author.Name + dateLine := "Date: " + commit.Committer.When.Format(time.UnixDate) + msgLine := strings.ReplaceAll(commit.Message, "\r\n", "\n") + statsLine := renderStats(diff, commonStyle, color) + diffLine := renderDiff(patch, color) + + if patchOnly { + cmd.Println( + diffLine, + ) + return nil + } + + if color { + s.WriteString(fmt.Sprintf("%s\n%s\n%s\n%s\n", + style.CommitHash.Render(commitLine), + style.CommitAuthor.Render(authorLine), + style.CommitDate.Render(dateLine), + style.CommitBody.Render(msgLine), + )) + } else { + s.WriteString(fmt.Sprintf("%s\n%s\n%s\n%s\n", + commitLine, + authorLine, + dateLine, + msgLine, + )) + } + + s.WriteString(fmt.Sprintf("\n%s\n%s", + statsLine, + diffLine, + )) + + cmd.Println( + s.String(), + ) + + return nil + }, + } + + cmd.Flags().BoolVarP(&color, "color", "c", false, "Colorize output") + cmd.Flags().BoolVarP(&patchOnly, "patch", "p", false, "Output patch only") + + return cmd +} + +func renderCtx() gansi.RenderContext { + return gansi.NewRenderContext(gansi.Options{ + ColorProfile: termenv.TrueColor, + Styles: common.StyleConfig(), + }) +} + +func renderDiff(patch string, color bool) string { + + c := string(patch) + + if color { + var s strings.Builder + var pr strings.Builder + + diffChroma := &gansi.CodeBlockElement{ + Code: patch, + Language: "diff", + } + + err := diffChroma.Render(&pr, renderCtx()) + + if err != nil { + s.WriteString(fmt.Sprintf("\n%s", err.Error())) + } else { + s.WriteString(fmt.Sprintf("\n%s", pr.String())) + } + + c = s.String() + } + + return c +} + +func renderStats(diff *git.Diff, commonStyle *styles.Styles, color bool) string { + style := commonStyle.Log + c := diff.Stats().String() + + if color { + s := strings.Split(c, "\n") + + for i, line := range s { + ch := strings.Split(line, "|") + if len(ch) > 1 { + adddel := ch[len(ch)-1] + adddel = strings.ReplaceAll(adddel, "+", style.CommitStatsAdd.Render("+")) + adddel = strings.ReplaceAll(adddel, "-", style.CommitStatsDel.Render("-")) + s[i] = strings.Join(ch[:len(ch)-1], "|") + "|" + adddel + } + } + + return strings.Join(s, "\n") + } + + return c +} diff --git a/server/cmd/repo.go b/server/cmd/repo.go index ae87361b585f1cc87123e32f3e410f9bce14cd4c..6371f167da813f2fe988193a16a631874d9e7bfa 100644 --- a/server/cmd/repo.go +++ b/server/cmd/repo.go @@ -18,6 +18,7 @@ func repoCommand() *cobra.Command { blobCommand(), branchCommand(), collabCommand(), + commitCommand(), createCommand(), deleteCommand(), descriptionCommand(),