From a72e39606b052957e52a62538206752dc327ceb0 Mon Sep 17 00:00:00 2001 From: Florian Kinder Date: Sun, 12 Apr 2026 13:03:41 +0200 Subject: [PATCH 1/2] refactor: use Go native build info for commit and date Replace ldflags injection of commit and date with runtime/debug.ReadBuildInfo(), which Go embeds automatically from VCS. Only version remains as an ldflag since there is no native way to get the git tag at runtime. This aligns the build pattern across all three CLIs (esq, atl, n8nctl). --- .goreleaser.yml | 2 -- cmd/atl/main.go | 15 ++----------- internal/cmd/root.go | 52 +++++++++++++++++++++++++++++--------------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 0dd6daa..eee5244 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -17,8 +17,6 @@ builds: ldflags: - -s -w - -X main.version={{.Version}} - - -X main.commit={{.ShortCommit}} - - -X main.date={{.Date}} archives: - formats: diff --git a/cmd/atl/main.go b/cmd/atl/main.go index e545e18..7f3d77a 100644 --- a/cmd/atl/main.go +++ b/cmd/atl/main.go @@ -7,21 +7,10 @@ import ( "github.com/enthus-appdev/atl-cli/internal/iostreams" ) -// Build information set by ldflags -var ( - version = "dev" - commit = "none" - date = "unknown" -) +var version = "dev" func main() { - buildInfo := cmd.BuildInfo{ - Version: version, - Commit: commit, - Date: date, - } - ios := iostreams.System() - code := cmd.Execute(ios, buildInfo) + code := cmd.Execute(ios, version) os.Exit(code) } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 5ab74c2..ab10b9d 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "runtime/debug" "github.com/spf13/cobra" @@ -13,16 +14,9 @@ import ( "github.com/enthus-appdev/atl-cli/internal/iostreams" ) -// BuildInfo contains version and build information. -type BuildInfo struct { - Version string - Commit string - Date string -} - // Execute runs the root command and returns an exit code. -func Execute(ios *iostreams.IOStreams, buildInfo BuildInfo) int { - rootCmd := NewRootCmd(ios, buildInfo) +func Execute(ios *iostreams.IOStreams, version string) int { + rootCmd := NewRootCmd(ios, version) if err := rootCmd.Execute(); err != nil { fmt.Fprintf(ios.ErrOut, "Error: %s\n", err) return 1 @@ -31,7 +25,8 @@ func Execute(ios *iostreams.IOStreams, buildInfo BuildInfo) int { } // NewRootCmd creates the root command for the CLI. -func NewRootCmd(ios *iostreams.IOStreams, buildInfo BuildInfo) *cobra.Command { +func NewRootCmd(ios *iostreams.IOStreams, version string) *cobra.Command { + commit, date := vcsInfo() cmd := &cobra.Command{ Use: "atl", Short: "Atlassian CLI - Work with Jira and Confluence from the command line", @@ -47,12 +42,12 @@ Environment variables: ATL_DEBUG=1 Enable debug logging (shows API requests/responses)`, SilenceUsage: true, SilenceErrors: true, - Version: buildInfo.Version, + Version: version, } // Set custom version template - cmd.SetVersionTemplate(fmt.Sprintf("atl version %s\ncommit: %s\nbuilt: %s\n", - buildInfo.Version, buildInfo.Commit, buildInfo.Date)) + cmd.SetVersionTemplate(fmt.Sprintf("atl version %s\ncommit: %s\nbuilt: %s\n", + version, commit, date)) // Set I/O streams cmd.SetIn(ios.In) @@ -65,25 +60,46 @@ Environment variables: cmd.AddCommand(boardCmd.NewCmdBoard(ios)) cmd.AddCommand(confluenceCmd.NewCmdConfluence(ios)) cmd.AddCommand(configCmd.NewCmdConfig(ios)) - cmd.AddCommand(newVersionCmd(ios, buildInfo)) + cmd.AddCommand(newVersionCmd(ios, version, commit, date)) cmd.AddCommand(newCompletionCmd(ios)) return cmd } // newVersionCmd creates the version command. -func newVersionCmd(ios *iostreams.IOStreams, buildInfo BuildInfo) *cobra.Command { +func newVersionCmd(ios *iostreams.IOStreams, version, commit, date string) *cobra.Command { return &cobra.Command{ Use: "version", Short: "Print version information", Run: func(cmd *cobra.Command, args []string) { - fmt.Fprintf(ios.Out, "atl version %s\n", buildInfo.Version) - fmt.Fprintf(ios.Out, "commit: %s\n", buildInfo.Commit) - fmt.Fprintf(ios.Out, "built: %s\n", buildInfo.Date) + fmt.Fprintf(ios.Out, "atl version %s\n", version) + fmt.Fprintf(ios.Out, "commit: %s\n", commit) + fmt.Fprintf(ios.Out, "built: %s\n", date) }, } } +func vcsInfo() (commit, date string) { + commit, date = "unknown", "unknown" + info, ok := debug.ReadBuildInfo() + if !ok { + return + } + for _, s := range info.Settings { + switch s.Key { + case "vcs.revision": + if len(s.Value) >= 7 { + commit = s.Value[:7] + } else { + commit = s.Value + } + case "vcs.time": + date = s.Value + } + } + return +} + // newCompletionCmd creates the completion command for shell autocompletion. func newCompletionCmd(ios *iostreams.IOStreams) *cobra.Command { cmd := &cobra.Command{ From 3921fda164e5615ca144ac9b78431ca93e935385 Mon Sep 17 00:00:00 2001 From: Florian Kinder Date: Sun, 12 Apr 2026 13:09:28 +0200 Subject: [PATCH 2/2] fix: append -dirty suffix when built from modified worktree --- internal/cmd/root.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index ab10b9d..143d21b 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -81,6 +81,7 @@ func newVersionCmd(ios *iostreams.IOStreams, version, commit, date string) *cobr func vcsInfo() (commit, date string) { commit, date = "unknown", "unknown" + var modified bool info, ok := debug.ReadBuildInfo() if !ok { return @@ -88,15 +89,20 @@ func vcsInfo() (commit, date string) { for _, s := range info.Settings { switch s.Key { case "vcs.revision": - if len(s.Value) >= 7 { + if len(s.Value) > 7 { commit = s.Value[:7] } else { commit = s.Value } case "vcs.time": date = s.Value + case "vcs.modified": + modified = s.Value == "true" } } + if modified { + commit += "-dirty" + } return }