From 55790be6ad78b37bf28622fe426846a094589796 Mon Sep 17 00:00:00 2001 From: Pete Davison Date: Sat, 5 Apr 2025 23:09:27 +0100 Subject: [PATCH] feat: better versioning (#2131) --- cmd/release/main.go | 8 +++ cmd/task/task.go | 4 +- executor_test.go | 35 ++++------ internal/version/version.go | 64 ++++++++++++++----- internal/version/version.txt | 1 + ...-subdir-included-print-task-version.golden | 1 - ...cial_vars-subdir-print-task-version.golden | 1 - ...al_vars-included-print-task-version.golden | 1 - ...ata-special_vars-print-task-version.golden | 1 - 9 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 internal/version/version.txt delete mode 100644 testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task-version.golden delete mode 100644 testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-version.golden delete mode 100644 testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-included-print-task-version.golden delete mode 100644 testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-print-task-version.golden diff --git a/cmd/release/main.go b/cmd/release/main.go index dfe0960a..85e38273 100644 --- a/cmd/release/main.go +++ b/cmd/release/main.go @@ -67,6 +67,10 @@ func release() error { return err } + if err := setVersionFile("internal/version/version.txt", version); err != nil { + return err + } + if err := setJSONVersion("package.json", version); err != nil { return err } @@ -144,6 +148,10 @@ func changelog(version *semver.Version) error { return os.WriteFile(changelogTarget, []byte(changelog), 0o644) } +func setVersionFile(fileName string, version *semver.Version) error { + return os.WriteFile(fileName, []byte(version.String()+"\n"), 0o644) +} + func setJSONVersion(fileName string, version *semver.Version) error { // Read the JSON file b, err := os.ReadFile(fileName) diff --git a/cmd/task/task.go b/cmd/task/task.go index 09c2a1e8..dcad9ca1 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -17,7 +17,7 @@ import ( "github.com/go-task/task/v3/internal/filepathext" "github.com/go-task/task/v3/internal/flags" "github.com/go-task/task/v3/internal/logger" - ver "github.com/go-task/task/v3/internal/version" + "github.com/go-task/task/v3/internal/version" "github.com/go-task/task/v3/taskfile" "github.com/go-task/task/v3/taskfile/ast" ) @@ -57,7 +57,7 @@ func run() error { } if flags.Version { - fmt.Printf("Task version: %s\n", ver.GetVersionWithSum()) + fmt.Println(version.GetVersionWithBuildInfo()) return nil } diff --git a/executor_test.go b/executor_test.go index 9b1e7839..3f4220ab 100644 --- a/executor_test.go +++ b/executor_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/sebdah/goldie/v2" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/go-task/task/v3" @@ -343,41 +342,31 @@ func TestSpecialVars(t *testing.T) { const dir = "testdata/special_vars" const subdir = "testdata/special_vars/subdir" - toAbs := func(rel string) string { - abs, err := filepath.Abs(rel) - assert.NoError(t, err) - return abs - } - tests := []struct { - target string - expected string - }{ + tests := []string{ // Root - {target: "print-task", expected: "print-task"}, - {target: "print-root-dir", expected: toAbs(dir)}, - {target: "print-taskfile", expected: toAbs(dir) + "/Taskfile.yml"}, - {target: "print-taskfile-dir", expected: toAbs(dir)}, - {target: "print-task-version", expected: "unknown"}, - {target: "print-task-dir", expected: toAbs(dir) + "/foo"}, + "print-task", + "print-root-dir", + "print-taskfile", + "print-taskfile-dir", + "print-task-dir", // Included - {target: "included:print-task", expected: "included:print-task"}, - {target: "included:print-root-dir", expected: toAbs(dir)}, - {target: "included:print-taskfile", expected: toAbs(dir) + "/included/Taskfile.yml"}, - {target: "included:print-taskfile-dir", expected: toAbs(dir) + "/included"}, - {target: "included:print-task-version", expected: "unknown"}, + "included:print-task", + "included:print-root-dir", + "included:print-taskfile", + "included:print-taskfile-dir", } for _, dir := range []string{dir, subdir} { for _, test := range tests { NewExecutorTest(t, - WithName(fmt.Sprintf("%s-%s", dir, test.target)), + WithName(fmt.Sprintf("%s-%s", dir, test)), WithExecutorOptions( task.WithDir(dir), task.WithSilent(true), task.WithVersionCheck(true), ), - WithTask(test.target), + WithTask(test), WithPostProcessFn(PPRemoveAbsolutePaths), ) } diff --git a/internal/version/version.go b/internal/version/version.go index 6fc06006..091abb83 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,33 +1,67 @@ package version import ( - "fmt" + _ "embed" "runtime/debug" + "strings" ) var ( - version = "" - sum = "" + //go:embed version.txt + version string + commit string + dirty bool ) func init() { - info, ok := debug.ReadBuildInfo() - if !ok || info.Main.Version == "(devel)" || info.Main.Version == "" { - version = "unknown" - } else { - if version == "" { - version = info.Main.Version - } - if sum == "" { - sum = info.Main.Sum - } + version = strings.TrimSpace(version) + // Attempt to get build info from the Go runtime. We only use this if not + // built from a tagged version. + if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version == "(devel)" { + commit = getCommit(info) + dirty = getDirty(info) } } +func getDirty(info *debug.BuildInfo) bool { + for _, setting := range info.Settings { + if setting.Key == "vcs.modified" { + return setting.Value == "true" + } + } + return false +} + +func getCommit(info *debug.BuildInfo) string { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" { + return setting.Value[:7] + } + } + return "" +} + +// GetVersion returns the version of Task. By default, this is retrieved from +// the embedded version.txt file which is kept up-to-date by our release script. +// However, it can also be overridden at build time using: +// -ldflags="-X 'github.com/go-task/task/v3/internal/version.version=vX.X.X'". func GetVersion() string { return version } -func GetVersionWithSum() string { - return fmt.Sprintf("%s (%s)", version, sum) +// GetVersionWithBuildInfo is the same as [GetVersion], but it also includes +// the commit hash and dirty status if available. This will only work when built +// within inside of a Git checkout. +func GetVersionWithBuildInfo() string { + var buildInfo string + if commit != "" { + buildInfo += commit + } + if dirty { + buildInfo += "-dirty" + } + if buildInfo != "" { + return version + "-" + buildInfo + } + return version } diff --git a/internal/version/version.txt b/internal/version/version.txt new file mode 100644 index 00000000..e339122b --- /dev/null +++ b/internal/version/version.txt @@ -0,0 +1 @@ +3.42.1 diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task-version.golden b/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task-version.golden deleted file mode 100644 index 35466456..00000000 --- a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-included-print-task-version.golden +++ /dev/null @@ -1 +0,0 @@ -unknown diff --git a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-version.golden b/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-version.golden deleted file mode 100644 index 35466456..00000000 --- a/testdata/special_vars/subdir/testdata/TestSpecialVars-testdata-special_vars-subdir-print-task-version.golden +++ /dev/null @@ -1 +0,0 @@ -unknown diff --git a/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-included-print-task-version.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-included-print-task-version.golden deleted file mode 100644 index 35466456..00000000 --- a/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-included-print-task-version.golden +++ /dev/null @@ -1 +0,0 @@ -unknown diff --git a/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-print-task-version.golden b/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-print-task-version.golden deleted file mode 100644 index 35466456..00000000 --- a/testdata/special_vars/testdata/TestSpecialVars-testdata-special_vars-print-task-version.golden +++ /dev/null @@ -1 +0,0 @@ -unknown