feat(binary): check zuur/binary package.lua version against constraints
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
Warning
|
||||
Warning ## Warning for package tofu ##
|
||||
Warning
|
||||
Warning The following compiler flags have been specified in the package description
|
||||
Warning file. They are handled by DUB and direct use in packages is discouraged.
|
||||
Warning Alternatively, you can set the DFLAGS environment variable to pass custom flags
|
||||
Warning to the compiler, or use one of the suggestions below:
|
||||
Warning
|
||||
Warning warningsAsErrors: Use "buildRequirements" to control the warning level
|
||||
Warning
|
||||
Starting Performing "debug" build using /usr/bin/dmd for x86_64.
|
||||
Up-to-date toml 1.0.0: target for configuration [library] is up to date.
|
||||
Building tofu ~main: building configuration [application]
|
||||
Linking tofu
|
||||
Finished To force a rebuild of up-to-date targets, run again with --force
|
||||
Warning: malformed TOML config at /tmp/tofu-test-config-bad-190867.toml: Invalid table key declaration (2:0)
|
||||
Warning: invalid TOFU_DEFAULT_JOBS 'not-a-number', using default 1
|
||||
7 modules passed unittests
|
||||
[2m . checking binary firefox ...[0m
|
||||
- binary firefox-2.1.0 satisfies firefox>=2.0
|
||||
[2m . checking binary libfoo ...[0m
|
||||
- binary libfoo-1.9 does not satisfy libfoo>=2.0
|
||||
[2m . checking binary noexist ...[0m
|
||||
[2m . checking binary brokenpkg ...[0m
|
||||
[2m . checking binary badpkg ...[0m
|
||||
[2m . checking binary testpkg ...[0m
|
||||
- binary testpkg-2.1.0 satisfies testpkg
|
||||
@@ -183,6 +183,58 @@ _Auto-scaffolded by /start-work. Append new entries below - never overwrite._
|
||||
|
||||
---
|
||||
|
||||
## Task 10 — `tofu.binary` (zuur/binary package.lua version checking)
|
||||
|
||||
### Architecture
|
||||
- Module `tofu.binary` depends on: `tofu.types` (BinaryCheckResult, DepConstraint), `tofu.http` (get, HttpException), `tofu.config` (Config, binaryManifestUrl), `tofu.vercmp` (satisfies), `tofu.log` (logDetail, logInfo).
|
||||
- `checkBinaryVersion(name, constraint, cfg)` fetches the package.lua manifest from zuur/binary via HTTP, parses the version, and checks satisfaction.
|
||||
|
||||
### Key logic — 404 vs other errors
|
||||
- HTTP 404 → binary doesn't exist (recipe-only). Return `BinaryCheckResult(false, "", false)`.
|
||||
- Any other HttpException (500, timeout, connection failure) → **rethrow** — network problems must propagate, not be silently swallowed.
|
||||
- Detection: `e.msg.canFind("404")` — the HttpException format is `"HTTP %d fetching <url>"`.
|
||||
|
||||
### Version extraction from Lua package.lua
|
||||
- Light parse: scan for `version = "..."` in the manifest body.
|
||||
- Word-boundary check on "version" keyword (preceding char must be whitespace/`{`/`,`/`;`, following char must be whitespace/`=`).
|
||||
- If version field not found or malformed → `BinaryException`.
|
||||
- This avoids a full Lua parser — package.lua manifests are flat key-value tables.
|
||||
- Empty version string (e.g. `version = ""`) also throws BinaryException.
|
||||
|
||||
### Memoization
|
||||
- Module-level `BinaryCheckResult[string] _versionCache` — keyed by package name.
|
||||
- On cache hit: recompute satisfaction against caller's constraint (same version, different constraint possible).
|
||||
- On 404: cache the "not found" result so subsequent calls don't re-fetch.
|
||||
- Lifetime: one command run. Tests use distinct package names to avoid cross-state contamination.
|
||||
- The cache stores `exists` and `ver`; `satisfies` is always recomputed per-constraint.
|
||||
|
||||
### `version` keyword trap (again)
|
||||
- Local variable `version` conflicts with D keyword. Used `ver` instead. Same pattern as types.d where struct field is `ver`.
|
||||
|
||||
### Test infrastructure
|
||||
- Reused local one-shot TCP server pattern from http.d:
|
||||
- `bindAndSpawn(response)` — bind ephemeral port, spawn thread, return URL.
|
||||
- `oneShotResponder(listener, response)` — accept one connection, send canned HTTP response, exit.
|
||||
- `httpResponse(code, reason, body)` — build minimal HTTP/1.1 response with Content-Length.
|
||||
- `testConfig(baseUrl)` — create a Config pointing zuurUrl at the test server.
|
||||
|
||||
### Test cases (6/6 pass)
|
||||
1. Binary exists, version 2.1.0, constraint ge 2.0 → satisfies:true ✓
|
||||
2. Binary exists, version 1.9, constraint ge 2.0 → satisfies:false ✓
|
||||
3. 404 → exists:false, ver:"", satisfies:false ✓
|
||||
4. 500 → HttpException rethrown (not swallowed) ✓
|
||||
5. Manifest without version field → BinaryException ✓
|
||||
6. Version 2.1.0 with unconstrained dep (op none) → satisfies:true ✓
|
||||
|
||||
### `@safe` annotation consistency
|
||||
- `checkBinaryVersion` and all helpers marked `@safe`. The function calls `http.get()` (which is `@safe`), `satisfies` (`@safe`), and log functions (`@safe`). No `@trusted` blocks needed in production code.
|
||||
- Test helpers (`oneShotResponder`, `bindAndSpawn`, `httpResponse`) are `@trusted` since they use `std.socket`.
|
||||
|
||||
### Note: pre-existing fetch.d compile issue
|
||||
- `fetch.d` (from parallel task 7) has a missing `std.algorithm.searching : canFind` import that blocks `dub test`. `dub build` passes (fetch.d is excluded via `.skip` extension renames by the parallel agent). Binary.d tests verified via standalone `dmd -I... -i -main -unittest` compilation — all 7 modules pass.
|
||||
|
||||
---
|
||||
|
||||
## Task 7 — `tofu.index` (ZUUR index fetch & sandboxed Lua parse)
|
||||
|
||||
### Security: whitelist sandbox (NOT blacklist)
|
||||
|
||||
Reference in New Issue
Block a user