From 9799f2ebac6b99d57736c61c6a0ba0ab55a76b62 Mon Sep 17 00:00:00 2001 From: im10furry Date: Sun, 5 Jul 2026 14:06:23 -0500 Subject: [PATCH] fix: make release version injectable --- internal/cli/cli.go | 10 +++++---- internal/cmd/build-bundle/main.go | 1 + internal/doctor/doctor.go | 1 + internal/registry/bundle.go | 26 +++++++++++++++++++++++ internal/registry/canonical_test.go | 21 ++++++++++++++++++ internal/version/version.go | 33 ++++++++++++++++++++++++++++- 6 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 internal/registry/canonical_test.go diff --git a/internal/cli/cli.go b/internal/cli/cli.go index fc44c17..28ddf27 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -289,9 +289,11 @@ func (a *App) runVersion(args []string, stdout, stderr io.Writer) int { return 1 } + currentVersion := version.Current() + currentCommit := version.CurrentCommit() out := map[string]string{ - "version": version.Version, - "commit": version.Commit, + "version": currentVersion, + "commit": currentCommit, "registryVersion": a.reg.Index.Version, "bundleHash": a.reg.Manifest.BundleHash, } @@ -299,8 +301,8 @@ func (a *App) runVersion(args []string, stdout, stderr io.Writer) int { _ = json.NewEncoder(stdout).Encode(out) return 0 } - _, _ = fmt.Fprintf(stdout, "scion %s\n", version.Version) - _, _ = fmt.Fprintf(stdout, "commit: %s\n", version.Commit) + _, _ = fmt.Fprintf(stdout, "scion %s\n", currentVersion) + _, _ = fmt.Fprintf(stdout, "commit: %s\n", currentCommit) _, _ = fmt.Fprintf(stdout, "registry: %s\n", a.reg.Index.Version) _, _ = fmt.Fprintf(stdout, "bundle: %s\n", a.reg.Manifest.BundleHash) return 0 diff --git a/internal/cmd/build-bundle/main.go b/internal/cmd/build-bundle/main.go index f0c3e7a..9761831 100644 --- a/internal/cmd/build-bundle/main.go +++ b/internal/cmd/build-bundle/main.go @@ -79,6 +79,7 @@ func run(root, outDir string) error { if err != nil { return err } + data = registry.CanonicalFileBytes(rel, data) header := &zip.FileHeader{ Name: rel, Method: zip.Store, diff --git a/internal/doctor/doctor.go b/internal/doctor/doctor.go index be0d1e3..0272311 100644 --- a/internal/doctor/doctor.go +++ b/internal/doctor/doctor.go @@ -173,6 +173,7 @@ func checkManifestFreshness(reg *registry.Bundle, root string, add func(string, add("error", file.Module, "bundle is stale: missing "+path) continue } + data = registry.CanonicalFileBytes(path, data) sum := sha256.Sum256(data) if hex.EncodeToString(sum[:]) != file.SHA256 { add("error", file.Module, "bundle is stale: hash mismatch for "+path) diff --git a/internal/registry/bundle.go b/internal/registry/bundle.go index eab083d..ad58016 100644 --- a/internal/registry/bundle.go +++ b/internal/registry/bundle.go @@ -216,3 +216,29 @@ func matchesAny(patterns []string, rel string) bool { } return false } + +func CanonicalFileBytes(name string, data []byte) []byte { + if !isTextBundlePath(name) || !bytes.Contains(data, []byte{'\r'}) { + return data + } + data = bytes.ReplaceAll(data, []byte("\r\n"), []byte("\n")) + data = bytes.ReplaceAll(data, []byte("\r"), []byte("\n")) + return data +} + +func isTextBundlePath(name string) bool { + base := strings.ToLower(path.Base(name)) + switch base { + case ".gitignore", "dockerfile", "license", "makefile": + return true + } + + switch strings.ToLower(path.Ext(name)) { + case ".css", ".env", ".go", ".html", ".js", ".json", ".jsx", ".md", + ".mod", ".sql", ".sum", ".tmpl", ".tpl", ".ts", ".tsx", ".txt", + ".yaml", ".yml": + return true + default: + return false + } +} diff --git a/internal/registry/canonical_test.go b/internal/registry/canonical_test.go new file mode 100644 index 0000000..638c728 --- /dev/null +++ b/internal/registry/canonical_test.go @@ -0,0 +1,21 @@ +package registry + +import ( + "bytes" + "testing" +) + +func TestCanonicalFileBytesNormalizesTextLineEndings(t *testing.T) { + data := CanonicalFileBytes("registry/cache/README.md", []byte("a\r\nb\rc\n")) + if string(data) != "a\nb\nc\n" { + t.Fatalf("unexpected canonical text: %q", data) + } +} + +func TestCanonicalFileBytesLeavesBinaryExtensionsUnchanged(t *testing.T) { + in := []byte{0x89, 'P', 'N', 'G', '\r', '\n'} + out := CanonicalFileBytes("registry/assets/logo.png", in) + if !bytes.Equal(out, in) { + t.Fatalf("binary data changed: %v", out) + } +} diff --git a/internal/version/version.go b/internal/version/version.go index 448d21e..73327dd 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -1,7 +1,38 @@ package version -const ( +import ( + "runtime/debug" + "strings" +) + +var ( // Version and Commit are overridden by release builds with -ldflags. Version = "0.1.0-dev" Commit = "dev" ) + +func Current() string { + if Version != "" && !strings.HasSuffix(Version, "-dev") { + return Version + } + if info, ok := debug.ReadBuildInfo(); ok { + if info.Main.Version != "" && info.Main.Version != "(devel)" { + return info.Main.Version + } + } + return Version +} + +func CurrentCommit() string { + if Commit != "" && Commit != "dev" { + return Commit + } + if info, ok := debug.ReadBuildInfo(); ok { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" && setting.Value != "" { + return setting.Value + } + } + } + return Commit +}