From: Anderson A. Giacomolli Date: Tue, 10 Nov 2026 00:54:15 +0000 (-0300) Subject: Version the package and command from the commit X-Git-Url: http://git.giacomolli.uk/onechat/commitdiff_plain/3b7a3676dc3614ee3099e8798b5d0c07cb116b93 Version the package and command from the commit The Nix package and the version command use the commit date and short revision, with a dirty suffix for a changed tree. Direct Go builds keep the dev version. The install check compares the binary version with the package version so a missing linker value fails the build. --- diff --git a/README.rst b/README.rst index d32c14b..16aabce 100644 --- a/README.rst +++ b/README.rst @@ -499,6 +499,9 @@ Build and run: nix build ./result/bin/onechat +``onechat version`` prints ``yyyy-mm-dd-gitshort`` for a Nix build, adds +``-dirty`` for a dirty tree, and prints ``dev`` for a direct Go build. + Format and check all files: .. code:: console diff --git a/command_test.go b/command_test.go new file mode 100644 index 0000000..3d89327 --- /dev/null +++ b/command_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "io" + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestVersionCommandPrintsBuildVersion(t *testing.T) { + original := version + version = "test-version" + t.Cleanup(func() { + version = original + }) + + require.Equal(t, "test-version\n", commandOutput(t, "version")) +} + +func TestHelpListsVersionCommand(t *testing.T) { + require.Contains(t, commandOutput(t, "help"), " version show the build version\n") +} + +func commandOutput(t *testing.T, args ...string) string { + t.Helper() + + reader, writer, err := os.Pipe() + require.NoError(t, err) + + originalArgs, originalStdout := os.Args, os.Stdout + os.Args = append([]string{"onechat"}, args...) + os.Stdout = writer + t.Cleanup(func() { + os.Args, os.Stdout = originalArgs, originalStdout + + require.NoError(t, reader.Close()) + }) + + err = run() + require.NoError(t, err) + + require.NoError(t, writer.Close()) + + output, err := io.ReadAll(reader) + require.NoError(t, err) + + return string(output) +} diff --git a/flake.nix b/flake.nix index c2ca691..670dc66 100644 --- a/flake.nix +++ b/flake.nix @@ -14,13 +14,19 @@ }: let forEachSystem = nixpkgs.lib.genAttrs (import systems); + date = self.lastModifiedDate; + revision = self.shortRev or self.dirtyShortRev or "unknown"; + version = "${builtins.substring 0 4 date}-${builtins.substring 4 2 date}-${builtins.substring 6 2 date}-${revision}"; in { packages = forEachSystem ( system: let pkgs = nixpkgs.legacyPackages.${system}; - onechat = pkgs.callPackage ./nix/package.nix { src = self; }; + onechat = pkgs.callPackage ./nix/package.nix { + src = self; + inherit version; + }; in { inherit onechat; diff --git a/main.go b/main.go index 9c1c8b9..a73407f 100644 --- a/main.go +++ b/main.go @@ -20,11 +20,15 @@ Commands: -n print the plan without model calls login log in to ChatGPT with a device code probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls + version show the build version help show this help Chat needs a running daemon. ONECHAT_DIR sets the data directory. ` +// version is set by the package build and stays dev for direct Go builds. +var version = "dev" + func main() { err := run() if err != nil { @@ -44,6 +48,11 @@ func run() error { if err != nil { return fmt.Errorf("write command help: %w", err) } + case len(args) == 1 && args[0] == "version": + _, err := fmt.Println(version) + if err != nil { + return fmt.Errorf("write build version: %w", err) + } case len(args) == 1 && args[0] == "login": err := chatgptLogin(ctx, os.Stdout) if err != nil { diff --git a/nix/package.nix b/nix/package.nix index b38dcc0..f631044 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -2,13 +2,14 @@ lib, buildGoModule, src, + version, }: buildGoModule { pname = "onechat"; - version = "0.1.0"; - inherit src; + inherit src version; subPackages = [ "." ]; + ldflags = [ "-X main.version=${version}" ]; vendorHash = "sha256-35kAjo+7gbOOzNbKJyMYUcAF11HK7WzO3m9ZcrOsqY0="; # The flake check runs the full replay. @@ -24,6 +25,7 @@ buildGoModule { installCheckPhase = '' runHook preInstallCheck [[ "$("$out/bin/onechat" help)" == "Usage: onechat "* ]] + [[ "$("$out/bin/onechat" version)" == "${version}" ]] runHook postInstallCheck '';