writeonce/compiler/src
shoney.arickathil edf67d532a feat(woc): dependency resolver + multi-root builds (iter 15 Tasks 2+3)
[deps] entries now resolve to fetched, locked checkouts and compile as
module roots.

- resolve_deps (driver): .wo-deps/<name>/ cache beside wo.toml, wo.lock
  pinning name -> commit SHA. Cold+unlocked: clone at the manifest rev,
  record HEAD. Cold+locked: clone and checkout the LOCKED sha — a moved tag
  cannot change the build. Warm+locked: HEAD==lock -> zero network.
  Divergence is WO-E106 "lock drift" naming both SHAs and pointing at
  --update-deps; every git failure (missing binary, bad URL, bad rev,
  missing locked commit) is WO-E106 naming the dep and step. Guard rails:
  fetched dep must be a writeonce project; a dep with its own [deps] is
  refused (flat-only); dep name colliding with a local module dir is
  WO-E107. All git via the git binary (Sys.command; output reads through a
  temp file) — no network code in the compiler. Full clone, not --depth 1
  (a locked SHA must be reachable regardless of tag movement) — recorded
  deviation from the plan's clone sketch.
- woc --update-deps <dir>: re-fetch at manifest revs, rewrite the lock.
- Multi-root compile: compile_image gains ~deps; app files first then deps
  sorted by name; module_of_multi maps a dep file to `<name>` /
  `<name>/<sub>`, so existing use/pub/collision machinery works across the
  boundary unchanged. The app root's walk skips .wo-deps via the existing
  dot-rule.
- Entry restriction: Emit.emit gains ?entry_ok (default true — test helpers
  untouched); the driver excludes dep files, so a dependency's fn main is
  never the entry.

Verified end to end against local file:// remotes: cold fetch + lock; `use
niceframework` + `use niceframework/strutil` build and run; offline rebuild
with the remote deleted; moved tag -> cold rebuild stays at the locked SHA;
--update-deps follows the tag and rewrites the lock; cache/lock drift,
transitive [deps], and name collision each produce their named diagnostic;
the dep's fn main (returning 99) never becomes the entry. woc-test 540/0;
oop-e2e 87/0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:19:57 +02:00
..
ast.ml feat(compiler): update-through-row + delete statement (9b cont.) 2026-08-16 05:24:58 +02:00
CODE-LOGIC.md docs: CODE-LOGIC files reflect the 7b collector and inference pass 2026-08-19 17:12:52 +02:00
diag.ml feat: milestone 1 complete — .wob emitter, conformance corpus, single binary; GC redesign specced 2026-08-11 19:31:26 +02:00
disasm.ml feat: retire RC from the emitter and the format — .wob v4 (7b Phase 3b) 2026-08-19 17:07:43 +02:00
dump.ml feat: retire RC from the emitter and the format — .wob v4 (7b Phase 3b) 2026-08-19 17:07:43 +02:00
dune refactor(compiler): inference is one library pass, Gcinfer.infer 2026-08-18 19:00:11 +02:00
emit.ml feat(woc): dependency resolver + multi-root builds (iter 15 Tasks 2+3) 2026-08-19 19:19:57 +02:00
gcinfer.ml fix(compiler): demand promotion targets the escaping projection's class 2026-08-18 19:07:10 +02:00
lexer.ml fix: net.Conn is a scalar, \r escape, map[k] is optional, interp node ids 2026-08-14 17:47:45 +02:00
owner.ml feat: retire RC from the emitter and the format — .wob v4 (7b Phase 3b) 2026-08-19 17:07:43 +02:00
parser.ml feat(compiler): doctrine reject rows — WO-E105 (iter 5 strictness) 2026-08-19 17:57:36 +02:00
token.ml feat: json encode/decode + as, .wob v2 class metadata — log-watcher compiles 2026-08-14 17:08:46 +02:00
types.ml feat(compiler): doctrine reject rows — WO-E105 (iter 5 strictness) 2026-08-19 17:57:36 +02:00