fix(tooling): cargo_binary rebuilds a stale binary, not only a missing one
core.process.cargo_binary built the Rust binary only when it was absent, a behaviour inherited from the three bash wrappers it replaced (tooling/atlas, generate-brands, generate-corporations). After an edit to the Rust source it went on running the old binary. For generate_brands this breaks the one promise the systems.db stamp makes. `make regen-db` stamps the SHA of the NEW brand sources onto generated_brands.toml produced by the OLD code, so the gate reports fresh and the output is stale. It had already happened: the committed binary wrote "Re-run: reach generate brands" while main.rs still said tooling/generate-brands, so what was on disk had not been built from the committed source. It now always runs `cargo build --bin <name>` and lets cargo decide. An up-to-date build is incremental and fast; a real rebuild is announced as an event, since a silent ninety-second compile reads as a hang. Proven on generate_brands (T-1253): with the old header restored, the rebuilt binary reproduces generated_brands.toml byte-for-byte (sha256 e748531…). With the new header it differs by exactly that one line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+24
-19
@@ -147,34 +147,39 @@ def run(
|
|||||||
|
|
||||||
|
|
||||||
def cargo_binary(name: str, *args: str, capture: bool = True) -> str:
|
def cargo_binary(name: str, *args: str, capture: bool = True) -> str:
|
||||||
"""Run a Rust binary from `server/`, building it first if it is absent.
|
"""Run a Rust binary from `server/`, building it first if it is stale.
|
||||||
|
|
||||||
Three scripts wrote this by hand — `tooling/atlas`, `generate-brands`,
|
Three scripts wrote this by hand — `tooling/atlas`, `generate-brands`,
|
||||||
`generate-corporations` — each ~24 lines of identical bash: check for the
|
`generate-corporations` — each ~24 lines of identical bash: check for the
|
||||||
debug binary, `cargo build --bin` it if missing, `exec` it with every
|
debug binary, `cargo build --bin` it if missing, `exec` it with every
|
||||||
argument. Three copies of one idea is a substrate, so it lives here.
|
argument. Three copies of one idea is a substrate, so it lives here.
|
||||||
|
|
||||||
Build-if-missing is kept because it is genuinely useful on a cold checkout,
|
It ALWAYS asks cargo to build, and lets cargo decide whether anything is
|
||||||
but it is announced rather than silent: a first run that takes ninety
|
stale. The copies all built only when the binary was MISSING, so an edit
|
||||||
seconds with no explanation reads as a hang.
|
to the Rust source ran the old binary — and for generate_brands that meant
|
||||||
|
`make regen-db` stamped the new source SHA onto output the old code
|
||||||
|
produced, the one thing the stamp exists to prevent (found T-1253: a header
|
||||||
|
change to main.rs did not reach generated_brands.toml). An up-to-date build
|
||||||
|
is incremental and fast; a real rebuild is announced, since ninety silent
|
||||||
|
seconds reads as a hang.
|
||||||
"""
|
"""
|
||||||
binary = config.path("server", "target", "debug", name)
|
from tooling.core import console
|
||||||
if not binary.is_file():
|
|
||||||
from tooling.core import console
|
|
||||||
|
|
||||||
console.event(f"building the {name} binary (first run)", level="warn")
|
binary = config.path("server", "target", "debug", name)
|
||||||
build = run(
|
build = run(
|
||||||
["cargo", "build", "--bin", name],
|
["cargo", "build", "--bin", name],
|
||||||
cwd=config.path("server"),
|
cwd=config.path("server"),
|
||||||
check=False,
|
check=False,
|
||||||
missing_fix="install Rust — make setup-rust",
|
missing_fix="install Rust — make setup-rust",
|
||||||
|
)
|
||||||
|
if build.returncode != 0:
|
||||||
|
raise ReachError(
|
||||||
|
f"could not build {name}\n{(build.stderr or '').strip()}",
|
||||||
|
fix=f"cd server && cargo build --bin {name} — for the full error",
|
||||||
|
exit_code=build.returncode,
|
||||||
)
|
)
|
||||||
if build.returncode != 0:
|
if "Compiling" in (build.stderr or ""):
|
||||||
raise ReachError(
|
console.event(f"rebuilt the {name} binary — its source changed since the last build", level="warn")
|
||||||
f"could not build {name}\n{(build.stderr or '').strip()}",
|
|
||||||
fix=f"cd server && cargo build --bin {name} — for the full error",
|
|
||||||
exit_code=build.returncode,
|
|
||||||
)
|
|
||||||
|
|
||||||
result = run([str(binary), *args], check=False, capture=capture)
|
result = run([str(binary), *args], check=False, capture=capture)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user