turbo-editors/turbo-corepublic Fork 0
v1.0.1
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

📦 Turbo Core f3ade8d · on v1.0.1 · k33g · 13h ago
README.md · 70 lines · 4.0 KBmarkdown
Blame HistoryOpen raw

version

Tells the editor what build of itself it is: a number, and — when the build recorded them — the commit it came from and when it was linked.

Imports two things from the standard library and nothing else. No tcell, no ui, no files read, no commands run, so asking costs nothing and can be done from anywhere.

There is no version constant

There used to be, in app, and it was wrong for the fourteen commits after somebody last edited it. Nothing in committing, tagging or installing touches a Go constant, and an About box is exactly where a number nobody set gets believed.

So three sources are consulted in order, and the first that answers wins:

Order Source Set by
1 stamp, commit, built -ldflags -X, from the Makefile and scripts/install.sh
2 runtime/debug.ReadBuildInfo() The Go tool
3 unknown Nothing

unknown is deliberately not a number. The failure being designed against is a plausible-looking version nobody set, and a fallback of 0.1.0 would be exactly that.

Two things the build system cannot do

It does not read git tags. A plain go build . can never report 0.1.0-14-g88a4c38, however the code is written. It reports devel plus the commit, and the documentation says so rather than implying every build is equal. Anything that wants a tag has to be stamped, which is why the Makefile and the installer both do it.

What it reports instead is a pseudo-versionv0.1.1-0.20260831165958-88a4c3859bf3 — which isPseudoVersion recognises and fromBuildInfo reports as devel. Shown as written it would claim a 0.1.1 patch release that does not exist. All three of the Go tool's forms end in the same 28-character tail; the character before the timestamp is a dash when no tag precedes the commit and a dot when one does, because the base then ends in -0. or -pre.0.. Getting that wrong is why the check has a test naming each form.

vcs.time is not a build date

It is when the commit was made. Every binary is linked later than the commit it was built from, so labelling it "Built" would be false on all of them. A build date appears only when a build stamped one, which is the same rule the About box follows: a fact nobody recorded gets no line rather than an empty one.

Why resolve is separate from Current

Current reads package-level variables the linker wrote and whatever the Go tool recorded — neither of which a test binary can be built into having. resolve(stamp, commit, built, info) takes all four as arguments, so every combination in the table above is an ordinary table-driven test with no build flags anywhere.

Public API

Name What it does
Info{Number, Commit, Built} What a binary knows about its own build; Commit and Built are empty when nothing recorded them
Current() Info What this binary knows about itself
(Info) String() string Every known part on one line, for -version
(Info) BuiltAt() string Built rendered for a person: 2026-08-31 18:04 UTC
info := version.Current()
fmt.Printf("%s %s\n", app.Name, info) // Turbo Go 0.2.0 (88a4c38, built …)

if info.Commit != "" {
    fmt.Println("Commit:", info.Commit)
}

Stamp it like this — the Makefile and scripts/install.sh both do:

go build -ldflags "-X 'rickub.com/turbo-editors/turbo-core/version.stamp=$(git describe --tags --dirty)'" .

Anything that ships has to be stamped

Removing the constant moved a cost that used to be invisible: a build with no -ldflags used to carry the last number somebody typed, and now carries devel. That is better everywhere except in a cross-compile, where nothing else would have noticed — the host binary is stamped and correct while the five downloads say devel.

So 03-build-releases.sh stamps every platform, taking the flags from make ldflags rather than repeating the -X paths, and runs the staged binary for its own machine before calling the release built. release_test.go holds that line.

Tests

make test
go test ./version/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# version

Tells the editor what build of itself it is: a number, and — when the build recorded them — the commit it came from and when it was linked.

Imports two things from the standard library and nothing else. No tcell, no `ui`, no files read, no commands run, so asking costs nothing and can be done from anywhere.

## There is no version constant

There used to be, in `app`, and it was wrong for the fourteen commits after somebody last edited it. Nothing in committing, tagging or installing touches a Go constant, and an About box is exactly where a number nobody set gets believed.

So three sources are consulted in order, and the first that answers wins:

| Order | Source | Set by |
| --- | --- | --- |
| 1 | `stamp`, `commit`, `built` | `-ldflags -X`, from the Makefile and `scripts/install.sh` |
| 2 | `runtime/debug.ReadBuildInfo()` | The Go tool |
| 3 | `unknown` | Nothing |

`unknown` is deliberately **not** a number. The failure being designed against is a plausible-looking version nobody set, and a fallback of `0.1.0` would be exactly that.

## Two things the build system cannot do

**It does not read git tags.** A plain `go build .` can never report `0.1.0-14-g88a4c38`, however the code is written. It reports `devel` plus the commit, and the documentation says so rather than implying every build is equal. Anything that wants a tag has to be stamped, which is why the Makefile and the installer both do it.

**What it reports instead is a pseudo-version**`v0.1.1-0.20260831165958-88a4c3859bf3` — which `isPseudoVersion` recognises and `fromBuildInfo` reports as `devel`. Shown as written it would claim a `0.1.1` patch release that does not exist. All three of the Go tool's forms end in the same 28-character tail; the character before the timestamp is a dash when no tag precedes the commit and a **dot** when one does, because the base then ends in `-0.` or `-pre.0.`. Getting that wrong is why the check has a test naming each form.

## `vcs.time` is not a build date

It is when the *commit* was made. Every binary is linked later than the commit it was built from, so labelling it "Built" would be false on all of them. A build date appears only when a build stamped one, which is the same rule the About box follows: a fact nobody recorded gets no line rather than an empty one.

## Why resolve is separate from Current

`Current` reads package-level variables the linker wrote and whatever the Go tool recorded — neither of which a test binary can be built into having. `resolve(stamp, commit, built, info)` takes all four as arguments, so every combination in the table above is an ordinary table-driven test with no build flags anywhere.

## Public API

| Name | What it does |
| --- | --- |
| `Info{Number, Commit, Built}` | What a binary knows about its own build; `Commit` and `Built` are empty when nothing recorded them |
| `Current() Info` | What *this* binary knows about itself |
| `(Info) String() string` | Every known part on one line, for `-version` |
| `(Info) BuiltAt() string` | `Built` rendered for a person: `2026-08-31 18:04 UTC` |

```go
info := version.Current()
fmt.Printf("%s %s\n", app.Name, info) // Turbo Go 0.2.0 (88a4c38, built …)

if info.Commit != "" {
    fmt.Println("Commit:", info.Commit)
}
```

Stamp it like this — the Makefile and `scripts/install.sh` both do:

```sh
go build -ldflags "-X 'rickub.com/turbo-editors/turbo-core/version.stamp=$(git describe --tags --dirty)'" .
```

## Anything that ships has to be stamped

Removing the constant moved a cost that used to be invisible: a build with no `-ldflags` used to carry the last number somebody typed, and now carries `devel`. That is better everywhere except in a **cross-compile**, where nothing else would have noticed — the host binary is stamped and correct while the five downloads say `devel`.

So `03-build-releases.sh` stamps every platform, taking the flags from `make ldflags` rather than repeating the `-X` paths, and runs the staged binary for its own machine before calling the release built. `release_test.go` holds that line.

## Tests

```sh
make test
go test ./version/
```