Browse Source

package_mode 'dev' -> 'minted' (clean break, no alias) - punkshell 0.43.0

Stage-true mode set: src / minted / internal / os. Both _config mains
(all_package_modes, mode gates, proj: rebind, comments; unix /dev path and
'dev modules' magic-version prose untouched), punkexe moduledoc 0.2.0,
bin/ARCHITECTURE/vfs AGENTS docs, make.tcl K7 + guidance. Layout _config
copies hand-swept incl the previously-missed G-155 _bake comment fixes
(_config is outside the thin-layout sync channel - G-027/G-156 note).
Also fixed a stray _build residue in src/AGENTS.md bakelist prose.
Versioning: minor by deliberate alpha exception despite changed launch
invocation (user-directed).

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 1 week ago
parent
commit
731532fdb5
  1. 6
      ARCHITECTURE.md
  2. 15
      CHANGELOG.md
  3. 6
      bin/AGENTS.md
  4. 2
      punkproject.toml
  5. 2
      src/AGENTS.md
  6. 13
      src/make.tcl
  7. 10
      src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm
  8. 3
      src/modules/punk/args/moduledoc/punkexe-buildversion.txt
  9. 52
      src/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl
  10. 52
      src/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punk_main.tcl
  11. 4
      src/vfs/AGENTS.md
  12. 46
      src/vfs/_config/project_main.tcl
  13. 60
      src/vfs/_config/punk_main.tcl

6
ARCHITECTURE.md

@ -25,7 +25,7 @@ bin/<kit>.exe = Tcl runtime (zipfs/metakit) + <name>.vfs payload
| boots
v
src/vfs/_config/punk_main.tcl
- package mode: dev / os / src / internal (which module sources to trust)
- package mode: minted / os / src / internal (which module sources to trust)
- subcommand: shell / script / punk / tclsh / shellspy
|
v
@ -42,8 +42,8 @@ app package from src/lib/ (app-punkshell, app-punkscript, app-repl, app-shellsp
## Boot and launch chain
- **Kit anatomy.** Each `src/vfs/*.vfs` folder is a runtime payload; `src/runtime/mapvfs.toml` (G-024, tomlish-parsed; deprecated `mapvfs.config` line format still readable) maps payload folders to platform runtimes under `bin/runtime/<platform>/` as named kit outputs, with named groups and generative version-named schemes; an optional sibling `src/vfs/<name>.vfs.toml` declares payload packages materialized INTO the folder with drop-in-wins precedence (G-115 - spec: `src/vfs/README.md`); `src/vfs/_vfscommon.vfs/` is a generated merge of common libraries (never hand-edited); `src/vfs/_config/` holds the entry scripts. Sources: `src/vfs/AGENTS.md`, `src/runtime/AGENTS.md`.
- **Entry point.** `src/vfs/_config/punk_main.tcl`. An optional first argument is a dash-delimited package mode composed of tokens from `dev`, `os`, `src`, `internal` (`internal` is always appended when absent), optionally scoped with the `proj:` prefix (G-033: `dev`/`src` resolve against the project containing the cwd - walk-up to the nearest git/fossil repo root with a punkshell-style src tree - instead of the executable's own project; discovery is always reported, never a silent rebind). The next argument is the subcommand: `shell`, `script`, `punk`, `tclsh`, `shellspy`. Any other first argument is treated as a script invocation; no arguments at all means interactive shell. Subcommands map to app packages under `src/lib/` (`app-punkshell`, `app-punkscript`, `app-repl`, `app-shellspy`).
- **Package modes pick module provenance.** `internal` uses module snapshots baked into the kit at bake time; `dev` loads minted outputs from repo-root `modules/` and `lib/`; `src` loads the unbuilt working tree (`src/modules`, `src/lib`, `src/bootsupport`, `src/vendormodules`) with `package prefer latest` so magic-version dev modules (`999999.0a1.0`) beat stamped snapshots. `src` mode is the standard way to verify working-tree changes without a rebuild. Source: `bin/AGENTS.md` "Launch package modes".
- **Entry point.** `src/vfs/_config/punk_main.tcl`. An optional first argument is a dash-delimited package mode composed of tokens from `minted`, `os`, `src`, `internal` (`internal` is always appended when absent; `minted` was named `dev` pre-0.43.0), optionally scoped with the `proj:` prefix (G-033: `minted`/`src` resolve against the project containing the cwd - walk-up to the nearest git/fossil repo root with a punkshell-style src tree - instead of the executable's own project; discovery is always reported, never a silent rebind). The next argument is the subcommand: `shell`, `script`, `punk`, `tclsh`, `shellspy`. Any other first argument is treated as a script invocation; no arguments at all means interactive shell. Subcommands map to app packages under `src/lib/` (`app-punkshell`, `app-punkscript`, `app-repl`, `app-shellspy`).
- **Package modes pick module provenance.** `internal` uses module snapshots baked into the kit at bake time; `minted` loads the mint output trees at repo-root `modules/` and `lib/`; `src` loads the unbuilt working tree (`src/modules`, `src/lib`, `src/bootsupport`, `src/vendormodules`) with `package prefer latest` so magic-version dev modules (`999999.0a1.0`) beat stamped snapshots. `src` mode is the standard way to verify working-tree changes without a rebuild. Source: `bin/AGENTS.md` "Launch package modes".
- **Payload mount derivation (G-129, achieved).** The boot keys zipfs presence on `tcl::zipfs::mount` and derives where the executable's attached archive actually mounted from the mount table itself (the entry whose archive file is the executable; fallback: the mount containing the boot script) instead of assuming `tcl::zipfs::root` + `//zipfs:/app`. Modern runtimes still answer `//zipfs:/app`; the androwish/undroidwish 8.6 backport has no `root` command, mounts at the executable's own path, and boots the same payload through its `app/main.tcl` in-archive hook (`src/vfs/punk8win.vfs` carries fauxlinks for both conventions). A mounted archive the boot cannot attribute is reported on stderr rather than silently yielding no internal paths. The derivation procs stay defined post-boot (`::punkboot::zipfs_kit_mountbase`). Sources: `src/vfs/AGENTS.md`, `bin/AGENTS.md` "Kit-wrappable runtime requirements", `src/tests/shell/testsuites/punkexe/kitmountpoint.test`.
- **Static package capture (G-058, achieved).** Boot probe-loads the runtime's statically linked packages in a throwaway interp and records what each provides; every interp the shell fabricates (boot, codethread, shellthread workers) seeds `package ifneeded <name> <ver> {load {} <prefix>}` from that record, and `punk::packagepreference` resolves static-vs-bundled version-aware. Sources: `src/vfs/AGENTS.md`, `goals/archive/G-058-static-runtime-packages.md`.
- **`script` subcommand (G-015, achieved).** The lean non-interactive path: default punk shell module/alias environment, no shellfilter stacks/transforms, honest exit codes, launch plumbing emits nothing on stdout/stderr (exec-style callers see only the script's own output). Supports `lib:<name>` scriptlib resolution. App package: `src/lib/app-punkscript/`.

15
CHANGELOG.md

@ -5,6 +5,21 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy.
## [0.43.0] - 2026-08-02
- Launch package_mode `dev` renamed `minted` (clean break, NO alias): the mode
that loads the mint output trees (<projectroot>/modules, lib etc) now names
what it consumes, completing the stage-true set - src (unbuilt working tree)
/ minted (mint outputs) / internal (baked-in snapshots) / os (system
packages) - and ending the overload with the `dev` shell command, the
`-dev` kit scheme role and "dev modules" (magic-version sources), which all
keep their names. `<kit> dev` on current kits now falls through to
subcommand handling; old kits accept only `dev` until rebaked. Both boot
mains, the punk::args punkexe moduledoc (0.2.0) and docs updated; layout
_config copies hand-swept (they are outside the thin-layout sync channel).
Deliberate versioning exception (alpha): recorded as minor despite the
changed launch invocation.
## [0.42.0] - 2026-08-02
- Stage-true vocabulary part 2 (G-155): make.tcl speaks strict stage verbs -

6
bin/AGENTS.md

@ -97,7 +97,7 @@ platform-specific difference left in examples is path separator style
### Launch package modes (built punk shells)
The first argument to a built punk shell may be a dash-delimited package mode composed of tokens from `dev`, `os`, `src`, `internal` (e.g. `punksys src`, `punk902z dev-os`), optionally scoped with the `proj:` prefix (e.g. `punk91 proj:internal-src`). `internal` is the default and is always appended when absent. A first argument that is not a valid mode list is treated as a subcommand instead (a `proj:` prefix on a non-mode string is not consumed either). Implementation: `src/vfs/_config/punk_main.tcl` (search `all_package_modes`). The full packagemode contract (block meanings, ordering, proj: examples) is the punk::args documentation at id `(script)::punkexe` (module `punk::args::moduledoc::punkexe`).
The first argument to a built punk shell may be a dash-delimited package mode composed of tokens from `minted`, `os`, `src`, `internal` (e.g. `punksys src`, `punk902z minted-os`), optionally scoped with the `proj:` prefix (e.g. `punk91 proj:internal-src`). (`minted` was named `dev` before punkshell 0.43.0 - clean rename, no alias: old kits accept only `dev`, current kits only `minted`.) `internal` is the default and is always appended when absent. A first argument that is not a valid mode list is treated as a subcommand instead (a `proj:` prefix on a non-mode string is not consumed either). Implementation: `src/vfs/_config/punk_main.tcl` (search `all_package_modes`). The full packagemode contract (block meanings, ordering, proj: examples) is the punk::args documentation at id `(script)::punkexe` (module `punk::args::moduledoc::punkexe`).
`src` mode is the one that matters for verifying working-tree changes:
@ -105,10 +105,10 @@ The first argument to a built punk shell may be a dash-delimited package mode co
- Prepends `src/modules`, `src/modules_tcl<N>`, `src/bootsupport/modules{,_tcl<N>}` and `src/vendormodules{,_tcl<N>}` to the module path, sets `package prefer latest` so dev-numbered `999999.0a1.0` source modules beat kit-stamped snapshots on unversioned `package require`, and registers `#modpod` modules from `src/modules` (startup notice: `src mode: registered N #modpod modules from .../src/modules`).
- Consequence: `punksys src` / `punk902z src` exercises current working-tree source with no kit rebuild; a plain launch (`punksys`) exercises the module snapshots baked into the kit at build time. `package present <pkg>` reporting `999999.0a1.0` (vs a release version like `0.7.1`) tells you which set a session is running - runbooks with version expectations must state the intended launch mode.
`proj:` scope (G-033, achieved - see goals/archive/G-033-proj-mode-cwd-project.md) makes `dev`/`src` resolve against the project containing the CURRENT DIRECTORY instead of the executable's own project - visitor mode for an installed/standalone punk binary exploring a project that builds no shell of its own (the project may be modules-only, e.g. tomlish):
`proj:` scope (G-033, achieved - see goals/archive/G-033-proj-mode-cwd-project.md) makes `minted`/`src` resolve against the project containing the CURRENT DIRECTORY instead of the executable's own project - visitor mode for an installed/standalone punk binary exploring a project that builds no shell of its own (the project may be modules-only, e.g. tomlish):
- Root discovery walks up from the cwd to the nearest git/fossil repo root that looks like a punkshell-style project (has `./src` plus one of `src/modules`, `src/vfs`, `src/scriptapps`, or `punkproject.toml` - a lean boot mirror of `punk::repo::is_project_root`).
- The launch always reports the detected root and effective mode precedence on stderr; when no project is found it warns and proceeds with dev/src unbound (never a silent or false rebind, no exe-relative fallback). `proj:` with no dev/src block warns that it has no effect.
- The launch always reports the detected root and effective mode precedence on stderr; when no project is found it warns and proceeds with minted/src unbound (never a silent or false rebind, no exe-relative fallback). `proj:` with no minted/src block warns that it has no effect.
- Canonical visitor invocation: `<punkexe> proj:internal-src shell` - kit copies win same-version ties, protecting the visiting shell's own infrastructure. `proj:src` is the faithful-vintage variant where the visited project's copies win ties. The project's genuinely-own code (dev-versioned or absent from the kit) loads from the project in either order.
### Kit-wrappable runtime requirements (G-129)

2
punkproject.toml

@ -1,6 +1,6 @@
[project]
name = "punkshell"
version = "0.42.0"
version = "0.43.0"
license = "BSD-2-Clause"
url = "https://www.gitea1.intx.com.au/jn/punkshell"
#packager: declared identity for published artifacts (declarative, not proof -

2
src/AGENTS.md

@ -75,7 +75,7 @@ Recovery after a wrong path guess:
- **Payload/target consistency checks (G-133), both ADVISORY** - warnings are recapped `BAKE-WARNING`s and the kit still bakes and deploys (unlike the G-125 gate). (a) **Binary-arch scan**, at the same post-merge seam as the gate: every binary library (`*.dll`/`*.so`/`*.dylib`) in the merged tree is classified by header bytes (`punkboot::utils::binary_arch_classify` - PE Machine field, ELF e_machine, Mach-O incl. universal; unclassifiable content is honestly `unknown` and never warned about) against the kit's target platform. Structural and non-executing, so it runs for cross-target kits too (measured ~30-140ms per kit, avg ~93ms across the 12 assembled trees). Libraries under a platform-discriminated subdir - canonical `<os>-<cpu>` platform-dir names, the universal `macosx` folder, or a recognised vendor spelling (`win-x64` etc; the lists are namespace variables in `punkboot::utils`) - are exempt: multi-arch payloads are legitimate there. First real sweep (2026-07-27) found a true latent instance: `zint.dll` 2.13.0 in `src/vfs/punk8win.vfs/lib_tcl8/` is 32-bit (i386) and can never load in the x64 tcl8 kits (punk86/punkbi/punksys) that carry it - those bakes warn until the payload is fixed. (b) **Smoke-require probe**: a kit declaring packages in `src/runtime/mapvfs.toml` (`smokerequire` key - see `src/runtime/AGENTS.md`) has each one plain-`package require`d INSIDE the freshly built artifact via its tclsh subcommand, which exits cleanly even on runtimes whose full repl teardown is fragile. This is the only check that observes actual package RESOLUTION - the punkluck86 2026-07-27 incident class (a higher-versioned wrong-arch Thread shadowing the runtime's working copy on plain require) is invisible to structural checks because the working file exists too. Failures are recapped naming kit, package and the actual error; cross-target kits skip with a stated reason; undeclared kits run nothing new; the probe only runs when the kit actually rebakes. **What the checks do NOT guarantee:** statically linked packages, pure-tcl packages whose binary dependency lives elsewhere, and version-preference outcomes are visible only to the smoke probe - and only for the declared package set; the arch scan proves nothing about loadability beyond architecture, and an `unknown` classification is silence, not a pass. Both degrade to a NOTE when the bootsupport `punkboot::utils` snapshot is stale (same guarded require as the G-125 gate); `tclsh src/make.tcl check` reports the scan's ACTIVE/UNAVAILABLE state and the currently declared smoke-require kits.
- **Kit offset-style pin (G-134), ADVISORY** - at the same seam family, every ASSEMBLED kit image is probed with `punk::zip::archive_info` (via `punkboot::utils::kit_offsetstyle_report`, same guarded-require degradation to a NOTE; `make.tcl check` reports ACTIVE/UNAVAILABLE): a FILE-relative attached zip payload earns a recapped `BAKE-WARNING` naming the kit, because the pipeline emits ARCHIVE-relative by construction and the G-128 stamper refuses file-relative by default - a warning here means an assembly path regressed the output convention. **What the pin does NOT cover:** `plain` and `none` results (a bare zip, or no attached zip at all - the metakit kit shape, and any unreadable input) are silence, never warnings - the pin asserts the offset CONVENTION of an attached zip, not the presence of one; and it asserts only what make.tcl's own assembly paths EMIT - `punk::zip::mkzip -offsettype file` (and modpod's equivalent) remain available for deliberate manual creation of file-relative artifacts, and file-relative INPUT artifacts remain tolerated by the G-124 reader and normalized by any re-bake.
- Kit bakes consume the punk-runtime WORKING COPIES under `bin/runtime/<platform>/`: `make.tcl bake`/`bakehouse` emit a `BAKE-WARNING:` (recapped at end of run) when a wrapped runtime's beside-toml revision is older than an `-r<N>` artifact present in the same folder - the forgot-to-switch-back guard for deliberate `punk-runtime use <old-rN>` testing excursions. Heed it before trusting freshly baked family kits; `bin/punk-runtime.cmd use <artifact-r<N>>` (`.exe` suffix optional) re-materializes the working copy.
- `tclsh src/make.tcl bakelist ?kitname|@group ...?` (G-121/G-024) reports the kit outputs configured in `src/runtime/mapvfs.toml`: kit name, kit type, runtime (with presence in the runtime store), vfs folder, and the deployed state of `bin/<kit>` vs the `src/_bake` build product (`current|stale|absent|nobake`), with anomalies (`runtime=missing`, `vfs=missing`, `rtrev=r<cur><r<max>` materialization staleness), the cross-target marker `target=<platform>`, groups (`group=<name>`), full-bake exclusion (`default=no`) and scheme roles (`scheme=versioned|dev|release`) in a trailing notes column. A nonexistent store tier is flagged loudly per tier actually referenced (header `(FOLDER MISSING)` for the default tier + stderr derivation; bake's no-runtimes exit self-diagnoses the same way). Name/@group arguments filter the report and add a per-kit detail block (resolved store tier, target and provenance of the target, config entry, group, paths/sizes/mtimes). `make.tcl bake ?kitname|@group ...?` bakes and deploys only the named kits - other kits' `_build`/`bin` artifacts and punkcheck records are untouched and the vfslibs phase narrows to the named kits' vfs folders; flags go before kit names (`make.tcl bake -confirm 0 punk91`). Kitname arguments are DECLARED restricted choices (2026-08-02, declaration-authoritative per the G-143 arc): an unknown name is rejected at dispatch with the punk::args choice error (before any build; the choices list the configured names + `@groups`), unambiguous prefixes resolve to canonical names, and the dry-run help mirrors the verdict. The handlers' own validation remains the backstop where the declarations cannot gate: `PUNKBOOT_PLAIN=1` degraded mode, and a definition-time mapping-read failure (the choices clause is then omitted). Bare `bake` processes all configured kits except `bake_default=false` entries; a `versioned`-scheme release output (plain `punk<gen>` name) is created when absent and otherwise skipped - a normal bake never overwrites it (the explicit release step is G-023's). Both surfaces consume the shared parsed-mapping helpers (`::punkboot::lib::mapvfs_*`) rather than the file format (G-024: toml reader canonical, deprecated `mapvfs.config` line reader retained as fallback; `PUNK_MAPVFS_CONFIG` env points at an alternate config for characterization), and all mapping consumers - the definition-time choices and every handler - share one memoized read per invocation (`mapvfs_model`; success cached, a throwing parse diagnoses fresh per caller). Piped characterization: `src/tests/shell/testsuites/punkexe/maketclbakelist.test`.
- `tclsh src/make.tcl bakelist ?kitname|@group ...?` (G-121/G-024) reports the kit outputs configured in `src/runtime/mapvfs.toml`: kit name, kit type, runtime (with presence in the runtime store), vfs folder, and the deployed state of `bin/<kit>` vs the `src/_bake` build product (`current|stale|absent|nobake`), with anomalies (`runtime=missing`, `vfs=missing`, `rtrev=r<cur><r<max>` materialization staleness), the cross-target marker `target=<platform>`, groups (`group=<name>`), full-bake exclusion (`default=no`) and scheme roles (`scheme=versioned|dev|release`) in a trailing notes column. A nonexistent store tier is flagged loudly per tier actually referenced (header `(FOLDER MISSING)` for the default tier + stderr derivation; bake's no-runtimes exit self-diagnoses the same way). Name/@group arguments filter the report and add a per-kit detail block (resolved store tier, target and provenance of the target, config entry, group, paths/sizes/mtimes). `make.tcl bake ?kitname|@group ...?` bakes and deploys only the named kits - other kits' `_bake`/`bin` artifacts and punkcheck records are untouched and the vfslibs phase narrows to the named kits' vfs folders; flags go before kit names (`make.tcl bake -confirm 0 punk91`). Kitname arguments are DECLARED restricted choices (2026-08-02, declaration-authoritative per the G-143 arc): an unknown name is rejected at dispatch with the punk::args choice error (before any build; the choices list the configured names + `@groups`), unambiguous prefixes resolve to canonical names, and the dry-run help mirrors the verdict. The handlers' own validation remains the backstop where the declarations cannot gate: `PUNKBOOT_PLAIN=1` degraded mode, and a definition-time mapping-read failure (the choices clause is then omitted). Bare `bake` processes all configured kits except `bake_default=false` entries; a `versioned`-scheme release output (plain `punk<gen>` name) is created when absent and otherwise skipped - a normal bake never overwrites it (the explicit release step is G-023's). Both surfaces consume the shared parsed-mapping helpers (`::punkboot::lib::mapvfs_*`) rather than the file format (G-024: toml reader canonical, deprecated `mapvfs.config` line reader retained as fallback; `PUNK_MAPVFS_CONFIG` env points at an alternate config for characterization), and all mapping consumers - the definition-time choices and every handler - share one memoized read per invocation (`mapvfs_model`; success cached, a throwing parse diagnoses fresh per caller). Piped characterization: `src/tests/shell/testsuites/punkexe/maketclbakelist.test`.
- **Host vs target platform (G-122).** Everything a bake EMITS is keyed by the artifact's TARGET platform, never by the driving tclsh's personality: the `bin/runtime/<tier>` store the runtime is read from, `.exe` suffixing of runtime files and kit outputs, the presence checks behind `runtime=missing`, and whether the pre-deploy process sweep uses `tasklist`/`taskkill` or `ps`/`kill`. Host semantics - copy commands, path handling, filesystem case rules, prompts - stay keyed to the host. The default target is the host's own platform canon, EXCEPT a cygwin-family host (an msys2/cygwin-runtime tclsh, which reports `tcl_platform(platform)` `unix` on windows and canonizes as `msys-x86_64`/`cygwin-x86_64`), which targets `win32-x86_64`: such a host now drives the identical kit set, names and store addressing as a native tclsh. `tclsh src/make.tcl check` prints the derivation on one `platform (G-122): host=... target=... store=... exe-suffix=... process-tooling=...` line. A mapvfs entry may declare its own target platform (`target` key - see `src/runtime/AGENTS.md`), which is then read from that platform's tier, named with that platform's executable convention, and skipped by the process sweep (its processes are not visible to this host). Traps this closes, all field-verified 2026-07-26: msys `ps` cannot see a natively-launched kit (only `tasklist` can), and msys2 rewrites arguments that look like absolute posix paths when spawning a native windows program - so `taskkill /PID <n>` arrived as `taskkill C:/<msysroot>/PID <n>`; native-windows command lines therefore go through `::punkboot::exec_nativeargs` (sets `MSYS2_ARG_CONV_EXCL=*`, inert elsewhere). Also note a cygwin-family tclsh is a POSIX Tcl: name the script the way that shell spells paths (`tclsh /c/repo/.../src/make.tcl`, not `C:/repo/...`, which it resolves relative to the cwd) - make.tcl diagnoses the windows-spelling case. Piped characterization: `src/tests/shell/testsuites/punkexe/maketclplatform.test` (the cygwin-host tests self-gate on finding and probing a real msys/cygwin tclsh; `PUNK_MSYS_TCLSH` names one explicitly).
- **Target-keyed kit OUTPUT locations (G-127) - the output half of the G-122 split.** A kit for the host's default target builds to `src/_bake/<kit>` and deploys to `bin/<kit>` exactly as always; any other target's kit builds under `src/_bake/kits/<platform>/` and deploys under `bin/kits/<platform>/` (per-tier `.punkcheck` ledger; the merged `.vfs` image, resource sidecar, arch scan, offset probe, smoke probe and process-sweep guards all follow the per-kit location). Same-named kits for different targets coexist - the artifact path is a pure function of (name, target) and `.exe` suffixing follows the target - so separate selective bakes can never overwrite each other's cross-target artifacts; only a same-name same-TARGET duplicate keeps the `<name>_<runtime>` disambiguation. A kit NAME matching several targets' entries selects all of them (bakelist and selective bake). Per-.vfs payload declarations gain the same axis: a `[payload.*]` source containing `%platform%` materializes once per CONSUMING kit target into `_targets/<platform>/` staging inside the `.vfs` folder (VCS-ignored), and each kit's merged image receives only its own target's subtree upstream of the arch scan and G-125 gate (`src/vfs/README.md` "Per-platform entries"). Characterization: `src/tests/shell/testsuites/punkexe/maketclkitlocations.test`; output-tier contract for consumers: `bin/AGENTS.md` "Cross-target kit outputs".
- Zip-type kit assembly does not require zipfs in the driving tcl (G-122): with `tcl::zipfs::mkimg` present it is used as before, otherwise the image is assembled by concatenation (raw-runtime split + `punk::zip::mkzip` + append, the same `::punkboot::assemble_zipcat_image` helper the `zipcat` kit type uses). Both mount identically - tcl zipfs reads the archive with archive-start-relative offsets.

13
src/make.tcl

@ -2618,7 +2618,7 @@ proc ::punkboot::punkboot_gethelp {args} {
append h " - canonical origin trusted by default; other servers (incl. PUNKBIN_URL overrides) require -trust-server" \n \n
append h " $scriptname vfscommonupdate" \n
append h " - promotion gate: update the src/vfs/_vfscommon.vfs kit payload from the minted <projectdir> module/lib trees" \n
append h " - before calling this (followed by '$scriptname bake') - you can test using '<builtexe>(.exe) dev'" \n
append h " - before calling this (followed by '$scriptname bake') - you can test using '<builtexe>(.exe) minted'" \n
append h " this will load modules from your <projectdir>/module <projectdir>/lib paths instead of from the kit/zipkit" \n \n
append h " $scriptname info" \n
append h " - show the name and base folder of the project" \n \n
@ -2919,9 +2919,10 @@ KEY / NOTES
[K7] Testing hooks along the way:
- src/tests/runtests.tcl exercises the src/ trees directly (dev modules).
- '<builtkit>.exe dev' (or '<builtkit> src') runs a built shell against the
project dev modules - useful for testing minted packages before they are
baked into kits via vfscommonupdate + bake.
- '<builtkit>.exe minted' runs a built shell against the mint output trees
(<projectroot>/modules etc) - useful for testing minted packages before
they are baked into kits via vfscommonupdate + bake; '<builtkit> src'
runs against the unbuilt src/ dev modules.
[K8] What is VCS-tracked where (checkin targets after a make.tcl run):
tracked: src/** (sources, src/bootsupport, src/project_layouts copies,
@ -3053,7 +3054,7 @@ proc ::punkboot::punkboot_availability_note {} {
}
#todo? process and remove first arg dev os internal (and combinations such as dev-os etc)
#todo? process and remove first arg minted os internal (and combinations such as minted-os etc)
##############################################################################################################
##############################################################################################################
##############################################################################################################
@ -3263,7 +3264,7 @@ if {[info exists ::env(PUNKBOOT_PLAIN)] && [string is true -strict $::env(PUNKBO
"
Update the src/vfs/_vfscommon.vfs from compiled src/modules and src/lib etc.
Before calling this (followed by 'make.tcl bake') - you can test using
'<builtexe>(.exe) dev' - this will load modules from your <projectdir>/modules,
'<builtexe>(.exe) minted' - this will load modules from your <projectdir>/modules,
<projectdir>/lib paths instead of from the kit/zipkit.
Replacing the _vfscommon.vfs contents requires confirmation - see -confirm."
info

10
src/modules/punk/args/moduledoc/punkexe-999999.0a1.0.tm

@ -90,9 +90,9 @@ tcl::namespace::eval punk::args::moduledoc::punkexe {
project's kit).
An optional FIRST argument selects package modes: one or more of
the tokens dev, os, src, internal joined with '-' when combined
(e.g 'dev', 'src', 'dev-src'), optionally scoped with the
'proj:' prefix (e.g 'proj:internal-src') so dev/src resolve
the tokens minted, os, src, internal joined with '-' when combined
(e.g 'minted', 'src', 'minted-src'), optionally scoped with the
'proj:' prefix (e.g 'proj:internal-src') so minted/src resolve
against the project containing the current directory instead of
the executable's own (G-033 visitor mode). Modes decide which
module sources the shell trusts and their precedence; 'internal'
@ -113,11 +113,11 @@ tcl::namespace::eval punk::args::moduledoc::punkexe {
Blocks (each adds a group of module/library paths):
internal - paths inside the executable's kit (always included;
appended last unless listed explicitly)
dev - the project's built output (<projectroot>/modules ...)
minted - the project's minted output trees (<projectroot>/modules ...)
src - the project's unbuilt source (src/modules,
src/bootsupport/modules, src/vendormodules, src/lib)
os - ad-hoc .tm paths from the current directory/environment
Without 'proj:', dev/src resolve against the executable's own
Without 'proj:', minted/src resolve against the executable's own
project (executable in <projectroot>/bin). With 'proj:', they
resolve against the nearest project root at or above the current
directory (a git or fossil repository root) - for an installed

3
src/modules/punk/args/moduledoc/punkexe-buildversion.txt

@ -1,3 +1,4 @@
0.1.1
0.2.0
#First line must be a semantic version number
#all other lines are ignored.
#0.2.0 - package_mode 'dev' renamed 'minted' (clean break, no alias - stage-true vocabulary follow-on to G-155): mode docs updated; the built-output mode now names what it consumes (mint output trees)

52
src/project_layouts/vendor/punk/project-0.1/src/vfs/_config/project_main.tcl vendored

@ -1,8 +1,8 @@
#source is at /src/vfs/_config/project_main.tcl
#This main script will consume a first argument of the form dev|os|internal
# or any dash-delimited combination such as dev-os
#This main script will consume a first argument of the form minted|os|internal
# or any dash-delimited combination such as minted-os
#
#The default when omitted is 'internal' which limits the auto_path and tcl::tm::path to packages
#provided from within the executable's vfs (either metakit or zipkit based)
@ -20,7 +20,7 @@
# a metakit data portion seems to need to be add the end of the file (from looking at sdx.kit code)
# - todo - investigate if zipfs can be inserted between starkit head executable and metakit tail data
#The logic below will add appropriate package paths from starkit and zipfs vfs paths
# - and restrict package paths to those coming from a vfs (if not launched with 'dev' or 'os' first arg which allows external paths to remain)
# - and restrict package paths to those coming from a vfs (if not launched with 'minted' or 'os' first arg which allows external paths to remain)
apply { args {
set tclmajorv [lindex [split [info tclversion] .] 0]
@ -315,7 +315,7 @@ apply { args {
#our internal 'quick' search for starkit failed.
#either we are in a pure zipfs system, or cookfs - or the starkit package is somewhere more devious
#for pure zipfs or cookfs - it's a little wasteful to perform exhaustive search for starkit
#review - only keep searching if not 'dev' first arg?
#review - only keep searching if not 'minted' first arg?
#Initially we've done no scans of auto_path/tcl::tm::list - but there will already be a core set of packages known by the kit
#retain it so we can 'forget' the difference after our first 'package require' forces a full scan which includes some paths we may not wish to include or at least include with different preferences
@ -373,7 +373,7 @@ apply { args {
#firstly it includes env(TCLLIBPATH)
#then it adds the tcl_library folder and its parent
#e.g //zipfs:/app/tcl_library and //zipfs:/app
#when 'dev' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#when 'minted' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#so that everything is self-contained in the kit/zipkit
#puts "\x1b\[1\;33m main.tcl original auto_path: $::auto_path"
@ -458,35 +458,35 @@ apply { args {
# -----------------------------------------------------------------------------------------------------------
# dev - refers to module and library paths relative to the project (executable path)
# minted - refers to module and library paths relative to the project (executable path)
# os - refers to modules and library paths gleaned from ::env (TCLLIBPATH and TCL<MAJOR>_<MINOR>_TM_PATH)
# internal - refers to modules and libraries supplied from the mounted filesystem of a kit or zipfs based executable
# -----------------------------------------------------------------------------------------------------------
# Note that unlike standard 'package unknown' punk::libunknown does not stop searching for packages when a .tm file is found that matches requirements,
# The auto_path is still examined. (avoids quirks where higher versioned pkgIndex based package not always found)
# -----------------------------------------------------------------------------------------------------------
set all_package_modes [list dev os internal]
#package_mode is specified as a dash-delimited ordered value e.g dev-os
set all_package_modes [list minted os internal]
#package_mode is specified as a dash-delimited ordered value e.g minted-os
#"internal" is the default and if not present is always added to the list
#i.e "dev-os" is equivalent to "dev-os-internal"
#i.e "minted-os" is equivalent to "minted-os-internal"
#"os" is equivalent to "os-internal"
#"internal-os" and "internal" are left as is.
#The effective package_mode has 1 2 or 3 members.
# The only case where it has 1 member is if just "internal" is specified.
#This gives the number of permutations as how many ways to choose 3 items plus how many ways to choose 2 of the 3 items (one must be 'internal') plus the sole allowable way to choose 1
#for a total of 11 possible final orderings.
#(16 possible values for package_mode argument when you include the short-forms "",os,dev,os-dev,dev-os which always have 'internal' appended)
#(16 possible values for package_mode argument when you include the short-forms "",os,minted,os-minted,minted-os which always have 'internal' appended)
set test_package_mode [lindex $args 0]
switch -exact -- $test_package_mode {
internal -
os-internal - dev-internal - internal-os - internal-dev -
os-dev-internal - os-internal-dev - dev-os-internal - dev-internal-os - internal-os-dev - internal-dev-os {
os-internal - minted-internal - internal-os - internal-minted -
os-minted-internal - os-internal-minted - minted-os-internal - minted-internal-os - internal-os-minted - internal-minted-os {
#fully specified ('internal' is present)
set package_modes [split $test_package_mode -]
set arglist [lrange $args 1 end]
}
os - dev - os-dev - dev-os {
os - minted - os-minted - minted-os {
#partially specified - 'internal' ommitted but implied at tail
set package_modes [list {*}[split $test_package_mode -] internal]
set arglist [lrange $args 1 end]
@ -518,7 +518,7 @@ apply { args {
#It may be desired for performance or testing reasons to preference the library outside of the kit - and raising the version number may not always be possible/practical.
#If the executable is a kit - we don't know what packages it contains or whether it allows loading from env based external paths.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'dev' is earlier in the list, even if the version number is the same.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'minted' is earlier in the list, even if the version number is the same.
#(these are the 'info nameofexecutable' or 'info script' or 'pwd' relative paths that are added here)
#Some kits will remove lib/module paths (from auto_path & tcl::tm::list) that have been added via TCLLIBPATH / TCLX_Y_TM_PATH environment variables
#Some kits will remove those env-provided lib paths but fail to remove the env-provided module paths
@ -538,7 +538,7 @@ apply { args {
#original tm list at this point consists of whatever the kit decided + some prepended internal kit paths that punk decided on.
#we want to bring the existing external paths to the position specified by package_mode (probably from the kit looking at various env TCL* values)
#we want to maintain the order of the internal paths.
#we want to add our external dev paths to the position specified by package_mode
#we want to add our external minted paths to the position specified by package_mode
#assert [llength [package names]] should be small at this point ~ <10 ?
@ -584,7 +584,7 @@ apply { args {
#case differences could represent different paths on unix-like platforms.
#It's perhaps a little unwise to configure matching paths with only case differences for a cross-platform tool .. but we should support it for those who use it and have no interest in windows - todo! review
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set normexe_dir [file dirname $normexe]
if {[file tail $normexe_dir] eq "bin"} {
#underlying exe in a bin dir - backtrack 1
@ -609,7 +609,7 @@ apply { args {
# set lc_external_tm_dirs [string tolower $external_tm_dirs]
# set lc_modulefolder [string tolower $modulefolder]
# if {$lc_modulefolder in [string tolower $original_external_tm_dirs]} {
# #perhaps we have an env var set pointing to one of our dev foldersl. We don't want to rely on how the kit ordered it.
# #perhaps we have an env var set pointing to one of our minted foldersl. We don't want to rely on how the kit ordered it.
# #bring to front if not already there.
# #assert it must be present in $lc_external_tm_dirs if it's in $original_external_tm_dirs
# set posn [lsearch $lc_external_tm_dirs $lc_modulefolder]
@ -691,7 +691,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $tm_additions_dev {
if {$n ni $new_tm_path} {
lappend new_tm_path $n
@ -717,7 +717,7 @@ apply { args {
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'dev' mode (dev as first argument on launch) we preference external modules
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'minted' mode (minted as first argument on launch) we preference external modules
##note use of lreverse to maintain same order
#foreach p [lreverse $internal_tm_dirs] {
# if {$p ni [tcl::tm::list]} {
@ -749,7 +749,7 @@ apply { args {
#we can't rely on builtin ledit (tcl9+) or loadable version such as punk::lib::compat::ledit at this point
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
@ -839,7 +839,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $auto_path_additions_dev {
if {$n ni $new_auto_path} {
lappend new_auto_path $n
@ -901,7 +901,7 @@ apply { args {
tcl::tm::add {*}[lreverse $new_tm_list]
#If it looks like we are running the vfs/_build/exename.vfs/main.tcl from an external tclsh - try to use vfs folders to simulate kit state
#If it looks like we are running the vfs/_bake/exename.vfs/main.tcl from an external tclsh - try to use vfs folders to simulate kit state
#set script_relative_lib [file normalize [file join [file dirname [info script]] lib]]
#set scriptdir [file dirname [info script]]
set scriptdir [file dirname $normscript]
@ -917,9 +917,9 @@ apply { args {
#presumably running the vfs/xxx.vfs/main.tcl script using a non-kit tclsh that doesn't have starkit lib or mounted zipfs/cookfs available.. lets see if we can move forward anyway
set vfscontainer [file normalize [file dirname $scriptdir]]
#set vfscommon [file join $vfscontainer _vfscommon]
#we shouldn't be targetting the src/vfs folders - use src/_build/exename.vfs instead
#we shouldn't be targetting the src/vfs folders - use src/_bake/exename.vfs instead
set vfsdir [file normalize $scriptdir]
set projectroot [file dirname [file dirname $vfscontainer]] ;#back below src/_build/exename.vfs/main.tcl
set projectroot [file dirname [file dirname $vfscontainer]] ;#back below src/_bake/exename.vfs/main.tcl
puts stdout "no starkit. projectroot?: $projectroot executable:[info nameofexecutable]"
puts stdout "info lib: [info library]"
@ -1009,9 +1009,9 @@ apply { args {
#Now that new 'package unknown' mechanism is in place - we can use package require
#assert arglist has had 'dev|os|os-dev etc' first arg removed if it was present.
#assert arglist has had 'minted|os|os-minted etc' first arg removed if it was present.
if {[lindex $arglist 0] eq "tclsh"} {
#called as <executable> dev tclsh ?script? ?args...? or <executable> tclsh ...
#called as <executable> minted tclsh ?script? ?args...? or <executable> tclsh ...
#we would like to drop through to standard tclsh repl without launching another process
#tclMain.c doesn't allow it unless patched (TCLSH_PIPEREPL piperepl patch).
#This branch mirrors the punk_main.tcl tclsh subcommand dispatch (G-118 parity).

52
src/project_layouts/vendor/punk/project-0.1/src/vfs/_config/punk_main.tcl vendored

@ -1,8 +1,8 @@
#source is at src/vfs/_config/punk_main.tcl
#This main script will consume a first argument of the form dev|os|internal
# or any dash-delimited combination such as dev-os
#This main script will consume a first argument of the form minted|os|internal
# or any dash-delimited combination such as minted-os
#
#The default when omitted is 'internal' which limits the auto_path and tcl::tm::path to packages
#provided from within the executable's vfs (either metakit or zipkit based)
@ -20,7 +20,7 @@
# a metakit data portion seems to need to be add the end of the file (from looking at sdx.kit code)
# - todo - investigate if zipfs can be inserted between starkit head executable and metakit tail data
#The logic below will add appropriate package paths from starkit and zipfs vfs paths
# - and restrict package paths to those coming from a vfs (if not launched with 'dev' or 'os' first arg which allows external paths to remain)
# - and restrict package paths to those coming from a vfs (if not launched with 'minted' or 'os' first arg which allows external paths to remain)
apply { args {
set ::punkargv $args
@ -446,7 +446,7 @@ apply { args {
#our internal 'quick' search for starkit failed.
#either we are in a pure zipfs system, or cookfs - or the starkit package is somewhere more devious
#for pure zipfs or cookfs - it's a little wasteful to perform exhaustive search for starkit
#review - only keep searching if not 'dev' first arg?
#review - only keep searching if not 'minted' first arg?
#Initially we've done no scans of auto_path/tcl::tm::list - but there will already be a core set of packages known by the kit
#retain it so we can 'forget' the difference after our first 'package require' forces a full scan which includes some paths we may not wish to include or at least include with different preferences
@ -506,7 +506,7 @@ apply { args {
#firstly it includes env(TCLLIBPATH)
#then it adds the tcl_library folder and its parent
#e.g //zipfs:/app/tcl_library and //zipfs:/app
#when 'dev' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#when 'minted' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#so that everything is self-contained in the kit/zipkit
#puts "\x1b\[1\;33m main.tcl original auto_path: $::auto_path"
@ -591,7 +591,7 @@ apply { args {
# -----------------------------------------------------------------------------------------------------------
# dev - refers to module and library paths relative to the project (executable path)
# minted - refers to module and library paths relative to the project (executable path)
# os - refers to modules and library paths gleaned from ::env (TCLLIBPATH and TCL<MAJOR>_<MINOR>_TM_PATH)
# internal - refers to modules and libraries supplied from the mounted filesystem of a kit or zipfs based executable
# src - refers to unbuilt modules and libraries under the project's src/ tree (src/modules, src/lib, src/bootsupport, src/vendormodules)
@ -599,10 +599,10 @@ apply { args {
# Note that unlike standard 'package unknown' punk::libunknown does not stop searching for packages when a .tm file is found that matches requirements,
# The auto_path is still examined. (avoids quirks where higher versioned pkgIndex based package not always found)
# -----------------------------------------------------------------------------------------------------------
set all_package_modes [list dev os internal src]
#package_mode is specified as a dash-delimited ordered value e.g dev-os
set all_package_modes [list minted os internal src]
#package_mode is specified as a dash-delimited ordered value e.g minted-os
#"internal" is the default and if not present is always added to the list
#i.e "dev-os" is equivalent to "dev-os-internal"
#i.e "minted-os" is equivalent to "minted-os-internal"
#"os" is equivalent to "os-internal"
#"internal-os" and "internal" are left as is.
#The effective package_mode has 1 2 3 or 4 members.
@ -655,7 +655,7 @@ apply { args {
#It may be desired for performance or testing reasons to preference the library outside of the kit - and raising the version number may not always be possible/practical.
#If the executable is a kit - we don't know what packages it contains or whether it allows loading from env based external paths.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'dev' is earlier in the list, even if the version number is the same.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'minted' is earlier in the list, even if the version number is the same.
#(these are the 'info nameofexecutable' or 'info script' or 'pwd' relative paths that are added here)
#Some kits will remove lib/module paths (from auto_path & tcl::tm::list) that have been added via TCLLIBPATH / TCLX_Y_TM_PATH environment variables
#Some kits will remove those env-provided lib paths but fail to remove the env-provided module paths
@ -675,7 +675,7 @@ apply { args {
#original tm list at this point consists of whatever the kit decided + some prepended internal kit paths that punk decided on.
#we want to bring the existing external paths to the position specified by package_mode (probably from the kit looking at various env TCL* values)
#we want to maintain the order of the internal paths.
#we want to add our external dev paths to the position specified by package_mode
#we want to add our external minted paths to the position specified by package_mode
#assert [llength [package names]] should be small at this point ~ <10 ?
@ -721,7 +721,7 @@ apply { args {
#case differences could represent different paths on unix-like platforms.
#It's perhaps a little unwise to configure matching paths with only case differences for a cross-platform tool .. but we should support it for those who use it and have no interest in windows - todo! review
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set normexe_dir [file dirname $normexe]
if {[file tail $normexe_dir] eq "bin"} {
#underlying exe in a bin dir - backtrack 1
@ -746,7 +746,7 @@ apply { args {
# set lc_external_tm_dirs [string tolower $external_tm_dirs]
# set lc_modulefolder [string tolower $modulefolder]
# if {$lc_modulefolder in [string tolower $original_external_tm_dirs]} {
# #perhaps we have an env var set pointing to one of our dev foldersl. We don't want to rely on how the kit ordered it.
# #perhaps we have an env var set pointing to one of our minted foldersl. We don't want to rely on how the kit ordered it.
# #bring to front if not already there.
# #assert it must be present in $lc_external_tm_dirs if it's in $original_external_tm_dirs
# set posn [lsearch $lc_external_tm_dirs $lc_modulefolder]
@ -773,10 +773,10 @@ apply { args {
}
#src mode: discover the project's src/ tree and add unbuilt module paths.
#Unlike dev mode (which points at built output in <projectroot>/modules),
#Unlike minted mode (which points at built output in <projectroot>/modules),
#src mode points at the unbuilt source in <projectroot>/src/modules etc.
if {"src" in $package_modes} {
#reuse the dev-mode project root discovery (exe in bin/ -> backtrack 1)
#reuse the minted-mode project root discovery (exe in bin/ -> backtrack 1)
set src_project_root ""
set normexe_dir_for_src [file dirname $normexe]
if {[file tail $normexe_dir_for_src] eq "bin"} {
@ -876,7 +876,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $tm_additions_dev {
if {$n ni $new_tm_path} {
lappend new_tm_path $n
@ -909,7 +909,7 @@ apply { args {
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'dev' mode (dev as first argument on launch) we preference external modules
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'minted' mode (minted as first argument on launch) we preference external modules
##note use of lreverse to maintain same order
#foreach p [lreverse $internal_tm_dirs] {
# if {$p ni [tcl::tm::list]} {
@ -941,7 +941,7 @@ apply { args {
#we can't rely on builtin ledit (tcl9+) or loadable version such as punk::lib::compat::ledit at this point
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
@ -1067,7 +1067,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $auto_path_additions_dev {
if {$n ni $new_auto_path} {
lappend new_auto_path $n
@ -1136,7 +1136,7 @@ apply { args {
tcl::tm::add {*}[lreverse $new_tm_list]
#If it looks like we are running the vfs/_build/exename.vfs/main.tcl from an external tclsh - try to use vfs folders to simulate kit state
#If it looks like we are running the vfs/_bake/exename.vfs/main.tcl from an external tclsh - try to use vfs folders to simulate kit state
#set script_relative_lib [file normalize [file join [file dirname [info script]] lib]]
#set scriptdir [file dirname [info script]]
set scriptdir [file dirname $normscript]
@ -1152,9 +1152,9 @@ apply { args {
#presumably running the vfs/xxx.vfs/main.tcl script using a non-kit tclsh that doesn't have starkit lib or mounted zipfs/cookfs available.. lets see if we can move forward anyway
set vfscontainer [file normalize [file dirname $scriptdir]]
#set vfscommon [file join $vfscontainer _vfscommon]
#we shouldn't be targetting the src/vfs folders - use src/_build/exename.vfs instead
#we shouldn't be targetting the src/vfs folders - use src/_bake/exename.vfs instead
set vfsdir [file normalize $scriptdir]
set projectroot [file dirname [file dirname $vfscontainer]] ;#back below src/_build/exename.vfs/main.tcl
set projectroot [file dirname [file dirname $vfscontainer]] ;#back below src/_bake/exename.vfs/main.tcl
puts stdout "no starkit. projectroot?: $projectroot executable:[info nameofexecutable]"
puts stdout "info lib: [info library]"
@ -1243,7 +1243,7 @@ apply { args {
#--------------------------------------------------------
#Now that new 'package unknown' mechanism is in place - we can use package require
#assert arglist has had 'dev|os|os-dev etc' first arg removed if it was present.
#assert arglist has had 'minted|os|os-minted etc' first arg removed if it was present.
#--------------------------------------------------------
@ -1267,8 +1267,8 @@ apply { args {
#recursive glob for #modpod-* directories (Tcl 8.6+ supports ** in glob)
set modpod_dirs [list]
foreach found [glob -nocomplain -type d -directory $src_modules_dir ** #modpod-*] {
#skip _build subdirectories
if {[string match "*_build*" $found]} { continue }
#skip staging subdirectories (_mint; legacy _build; _bake defensively)
if {[string match "*_build*" $found] || [string match "*_mint*" $found] || [string match "*_bake*" $found]} { continue }
lappend modpod_dirs $found
}
foreach modpod_dir $modpod_dirs {
@ -1344,7 +1344,7 @@ apply { args {
switch -- $subcommand {
tclsh {
#called as <executable> dev tclsh or <executable> tclsh
#called as <executable> minted tclsh or <executable> tclsh
#we would like to drop through to standard tclsh repl without launching another process
#tclMain.c doesn't allow it unless patched.
if {![info exists ::env(TCLSH_PIPEREPL)]} {

4
src/vfs/AGENTS.md

@ -23,13 +23,13 @@ VFS (Virtual File System) folders define the runtime payloads that get wrapped i
override; shared across a kit definition's targets). Record format and skip
semantics: bin/AGENTS.md "Kit resource record sidecar + embedded icon".
- `_vfscommon.vfs/` is an auto-generated merge of common libraries; manually editing it will be overwritten.
- `_config/punk_main.tcl` accepts an optional package_mode argument before the subcommand. Valid modes are `dev`, `os`, `internal`, and `src`, dash-delimited in priority order (e.g `src-internal`). `internal` is always appended if omitted. An optional `proj:` prefix (G-033, e.g `proj:internal-src`) makes `dev`/`src` resolve against the project containing the cwd (walk-up to the nearest git/fossil repo root with a punkshell-style src tree, via `::punkboot::proj_root_find`) instead of the executable's own project; discovery outcome is always reported on stderr and a failed discovery leaves dev/src unbound rather than falling back exe-relative.
- `_config/punk_main.tcl` accepts an optional package_mode argument before the subcommand. Valid modes are `minted`, `os`, `internal`, and `src`, dash-delimited in priority order (e.g `src-internal`; `minted` was named `dev` pre-0.43.0, clean rename with no alias). An optional `proj:` prefix (G-033, e.g `proj:internal-src`) makes `minted`/`src` resolve against the project containing the cwd (walk-up to the nearest git/fossil repo root with a punkshell-style src tree, via `::punkboot::proj_root_find`) instead of the executable's own project; discovery outcome is always reported on stderr and a failed discovery leaves minted/src unbound rather than falling back exe-relative.
- `_config/punk_main.tcl` captures the runtime's static/builtin packages at boot (G-058): empty-filename `info loaded` prefixes are probe-loaded in a throwaway interp (denylist `::punkboot::static_probe_denylist`, default `tk* vfs mk4tcl vlerq tdbc*` - side-effecting or composite inits) and each package a probe-load actually PROVIDES is recorded in `::punkboot::static_packages` {pkgname {version <v> prefix <p>}} with `::punkboot::static_prefixes` alongside. The boot interp and every punkshell-fabricated interp/thread (punk::lib::interp_sync_package_paths / snapshot_package_paths, repl codethread, shellthread workers) seed `package ifneeded <name> <ver> {load {} <prefix>}` from it, and punk::packagepreference resolves static-vs-bundled version-aware. Composite statics whose script layer lived in the runtime's own (replaced) zipfs provide nothing under the probe and are correctly left to bundled copies.
- `src` mode loads unbuilt modules and libraries from the project's `src/` tree (`src/modules`, `src/lib`, `src/bootsupport`, `src/vendormodules`) instead of built output. It also runs an inline `#modpod` package-ifneeded scanner (using Tcl builtins only, since no punk modules are loaded at boot time) and sets `package prefer latest` so `999999.0a1.0` dev modules are preferred over stable bootsupport/vendored copies.
- `_config/punk_main.tcl` and `_config/project_main.tcl` derive the kit's payload location from the runtime's own zipfs mount table (G-129): zipfs presence keys on `tcl::zipfs::mount` (not `tcl::zipfs::root`, which the androwish/undroidwish 8.6 backport lacks), the mount base is the table entry whose archive file is `[info nameofexecutable]` (fallback: the mount containing the boot script), `//zipfs:/app` stays the expected modern answer rather than a compiled-in assumption, and a mounted archive that cannot be attributed to the executable is reported on stderr. The derivation lives in `::punkboot` procs (`zipfs_kit_mountbase`, `zipfs_mount_pairs`, `path_within`) that remain defined after boot for probing and tests. Both files carry identical copies of this logic (G-031 is the planned consolidation). Characterization: `src/tests/shell/testsuites/punkexe/kitmountpoint.test`.
- `punk8win.vfs` carries TWO startup-script fauxlinks resolving to `_config/punk_main.tcl`: root `main.tcl` (modern zipfs and metakit convention) and `app/main.tcl` (the undroidwish family sources `app/main.tcl` INSIDE the attached archive; the file is inert in kits whose runtime does not look for it). Fauxlink targets are link-location-relative (symlink semantics): `make.tcl`'s `merge_over` resolves them against the link file's own directory, which is indistinguishable from the old vfs-root-relative resolution for root-level links.
- `punk8min.vfs` / `punk9min.vfs` are MINIMAL payloads for the win32-ix86 verification kits (punkluck86 / punk91ix86 in `src/runtime/mapvfs.toml`, group `verify-ix86`): both startup fauxlinks plus directory fauxlinks to MULTI-ARCH binary packages only - packages whose own tree carries a `win32-ix86` platform subdir (iocp-2.0.2 for both majors, twapi-5.0b1 for tcl8), linked from their existing homes in sibling `.vfs` folders so no binary is duplicated in VCS. Everything pure-tcl arrives via the `_vfscommon.vfs` overlay (which deliberately contains no dlls). Composition rule: an x64-only binary package must NOT be added to these payloads - a higher-versioned wrong-arch copy silently shadows a runtime's own working 32-bit package on plain `package require` (measured 2026-07-27: payload Thread 2.8.12 x64 beat the LUCK runtime's 2.8.5 and broke the repl), and wrong-arch-only packages surface as "couldn't load from current filesystem" at require time.
- `dev` mode loads built output from `<projectroot>/modules` and `<projectroot>/lib`; `src` mode loads unbuilt source from `<projectroot>/src/modules` etc. Use `src-dev-internal` to combine both with src priority.
- `minted` mode loads the mint output trees from `<projectroot>/modules` and `<projectroot>/lib`; `src` mode loads unbuilt source from `<projectroot>/src/modules` etc. Use `src-minted-internal` to combine both with src priority.
## Work Guidance

46
src/vfs/_config/project_main.tcl

@ -1,8 +1,8 @@
#source is at /src/vfs/_config/project_main.tcl
#This main script will consume a first argument of the form dev|os|internal
# or any dash-delimited combination such as dev-os
#This main script will consume a first argument of the form minted|os|internal
# or any dash-delimited combination such as minted-os
#
#The default when omitted is 'internal' which limits the auto_path and tcl::tm::path to packages
#provided from within the executable's vfs (either metakit or zipkit based)
@ -20,7 +20,7 @@
# a metakit data portion seems to need to be add the end of the file (from looking at sdx.kit code)
# - todo - investigate if zipfs can be inserted between starkit head executable and metakit tail data
#The logic below will add appropriate package paths from starkit and zipfs vfs paths
# - and restrict package paths to those coming from a vfs (if not launched with 'dev' or 'os' first arg which allows external paths to remain)
# - and restrict package paths to those coming from a vfs (if not launched with 'minted' or 'os' first arg which allows external paths to remain)
apply { args {
set tclmajorv [lindex [split [info tclversion] .] 0]
@ -315,7 +315,7 @@ apply { args {
#our internal 'quick' search for starkit failed.
#either we are in a pure zipfs system, or cookfs - or the starkit package is somewhere more devious
#for pure zipfs or cookfs - it's a little wasteful to perform exhaustive search for starkit
#review - only keep searching if not 'dev' first arg?
#review - only keep searching if not 'minted' first arg?
#Initially we've done no scans of auto_path/tcl::tm::list - but there will already be a core set of packages known by the kit
#retain it so we can 'forget' the difference after our first 'package require' forces a full scan which includes some paths we may not wish to include or at least include with different preferences
@ -373,7 +373,7 @@ apply { args {
#firstly it includes env(TCLLIBPATH)
#then it adds the tcl_library folder and its parent
#e.g //zipfs:/app/tcl_library and //zipfs:/app
#when 'dev' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#when 'minted' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#so that everything is self-contained in the kit/zipkit
#puts "\x1b\[1\;33m main.tcl original auto_path: $::auto_path"
@ -458,35 +458,35 @@ apply { args {
# -----------------------------------------------------------------------------------------------------------
# dev - refers to module and library paths relative to the project (executable path)
# minted - refers to module and library paths relative to the project (executable path)
# os - refers to modules and library paths gleaned from ::env (TCLLIBPATH and TCL<MAJOR>_<MINOR>_TM_PATH)
# internal - refers to modules and libraries supplied from the mounted filesystem of a kit or zipfs based executable
# -----------------------------------------------------------------------------------------------------------
# Note that unlike standard 'package unknown' punk::libunknown does not stop searching for packages when a .tm file is found that matches requirements,
# The auto_path is still examined. (avoids quirks where higher versioned pkgIndex based package not always found)
# -----------------------------------------------------------------------------------------------------------
set all_package_modes [list dev os internal]
#package_mode is specified as a dash-delimited ordered value e.g dev-os
set all_package_modes [list minted os internal]
#package_mode is specified as a dash-delimited ordered value e.g minted-os
#"internal" is the default and if not present is always added to the list
#i.e "dev-os" is equivalent to "dev-os-internal"
#i.e "minted-os" is equivalent to "minted-os-internal"
#"os" is equivalent to "os-internal"
#"internal-os" and "internal" are left as is.
#The effective package_mode has 1 2 or 3 members.
# The only case where it has 1 member is if just "internal" is specified.
#This gives the number of permutations as how many ways to choose 3 items plus how many ways to choose 2 of the 3 items (one must be 'internal') plus the sole allowable way to choose 1
#for a total of 11 possible final orderings.
#(16 possible values for package_mode argument when you include the short-forms "",os,dev,os-dev,dev-os which always have 'internal' appended)
#(16 possible values for package_mode argument when you include the short-forms "",os,minted,os-minted,minted-os which always have 'internal' appended)
set test_package_mode [lindex $args 0]
switch -exact -- $test_package_mode {
internal -
os-internal - dev-internal - internal-os - internal-dev -
os-dev-internal - os-internal-dev - dev-os-internal - dev-internal-os - internal-os-dev - internal-dev-os {
os-internal - minted-internal - internal-os - internal-minted -
os-minted-internal - os-internal-minted - minted-os-internal - minted-internal-os - internal-os-minted - internal-minted-os {
#fully specified ('internal' is present)
set package_modes [split $test_package_mode -]
set arglist [lrange $args 1 end]
}
os - dev - os-dev - dev-os {
os - minted - os-minted - minted-os {
#partially specified - 'internal' ommitted but implied at tail
set package_modes [list {*}[split $test_package_mode -] internal]
set arglist [lrange $args 1 end]
@ -518,7 +518,7 @@ apply { args {
#It may be desired for performance or testing reasons to preference the library outside of the kit - and raising the version number may not always be possible/practical.
#If the executable is a kit - we don't know what packages it contains or whether it allows loading from env based external paths.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'dev' is earlier in the list, even if the version number is the same.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'minted' is earlier in the list, even if the version number is the same.
#(these are the 'info nameofexecutable' or 'info script' or 'pwd' relative paths that are added here)
#Some kits will remove lib/module paths (from auto_path & tcl::tm::list) that have been added via TCLLIBPATH / TCLX_Y_TM_PATH environment variables
#Some kits will remove those env-provided lib paths but fail to remove the env-provided module paths
@ -538,7 +538,7 @@ apply { args {
#original tm list at this point consists of whatever the kit decided + some prepended internal kit paths that punk decided on.
#we want to bring the existing external paths to the position specified by package_mode (probably from the kit looking at various env TCL* values)
#we want to maintain the order of the internal paths.
#we want to add our external dev paths to the position specified by package_mode
#we want to add our external minted paths to the position specified by package_mode
#assert [llength [package names]] should be small at this point ~ <10 ?
@ -584,7 +584,7 @@ apply { args {
#case differences could represent different paths on unix-like platforms.
#It's perhaps a little unwise to configure matching paths with only case differences for a cross-platform tool .. but we should support it for those who use it and have no interest in windows - todo! review
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set normexe_dir [file dirname $normexe]
if {[file tail $normexe_dir] eq "bin"} {
#underlying exe in a bin dir - backtrack 1
@ -609,7 +609,7 @@ apply { args {
# set lc_external_tm_dirs [string tolower $external_tm_dirs]
# set lc_modulefolder [string tolower $modulefolder]
# if {$lc_modulefolder in [string tolower $original_external_tm_dirs]} {
# #perhaps we have an env var set pointing to one of our dev foldersl. We don't want to rely on how the kit ordered it.
# #perhaps we have an env var set pointing to one of our minted folders. We don't want to rely on how the kit ordered it.
# #bring to front if not already there.
# #assert it must be present in $lc_external_tm_dirs if it's in $original_external_tm_dirs
# set posn [lsearch $lc_external_tm_dirs $lc_modulefolder]
@ -691,7 +691,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $tm_additions_dev {
if {$n ni $new_tm_path} {
lappend new_tm_path $n
@ -717,7 +717,7 @@ apply { args {
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'dev' mode (dev as first argument on launch) we preference external modules
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'minted' mode (minted as first argument on launch) we preference external modules
##note use of lreverse to maintain same order
#foreach p [lreverse $internal_tm_dirs] {
# if {$p ni [tcl::tm::list]} {
@ -749,7 +749,7 @@ apply { args {
#we can't rely on builtin ledit (tcl9+) or loadable version such as punk::lib::compat::ledit at this point
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
@ -839,7 +839,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $auto_path_additions_dev {
if {$n ni $new_auto_path} {
lappend new_auto_path $n
@ -1009,9 +1009,9 @@ apply { args {
#Now that new 'package unknown' mechanism is in place - we can use package require
#assert arglist has had 'dev|os|os-dev etc' first arg removed if it was present.
#assert arglist has had 'minted|os|os-minted etc' first arg removed if it was present.
if {[lindex $arglist 0] eq "tclsh"} {
#called as <executable> dev tclsh ?script? ?args...? or <executable> tclsh ...
#called as <executable> minted tclsh ?script? ?args...? or <executable> tclsh ...
#we would like to drop through to standard tclsh repl without launching another process
#tclMain.c doesn't allow it unless patched (TCLSH_PIPEREPL piperepl patch).
#This branch mirrors the punk_main.tcl tclsh subcommand dispatch (G-118 parity).

60
src/vfs/_config/punk_main.tcl

@ -1,8 +1,8 @@
#source is at src/vfs/_config/punk_main.tcl
#This main script will consume a first argument of the form dev|os|internal
# or any dash-delimited combination such as dev-os
#This main script will consume a first argument of the form minted|os|internal
# or any dash-delimited combination such as minted-os
#
#The default when omitted is 'internal' which limits the auto_path and tcl::tm::path to packages
#provided from within the executable's vfs (either metakit or zipkit based)
@ -20,7 +20,7 @@
# a metakit data portion seems to need to be add the end of the file (from looking at sdx.kit code)
# - todo - investigate if zipfs can be inserted between starkit head executable and metakit tail data
#The logic below will add appropriate package paths from starkit and zipfs vfs paths
# - and restrict package paths to those coming from a vfs (if not launched with 'dev' or 'os' first arg which allows external paths to remain)
# - and restrict package paths to those coming from a vfs (if not launched with 'minted' or 'os' first arg which allows external paths to remain)
apply { args {
set ::punkargv $args
@ -485,7 +485,7 @@ apply { args {
#our internal 'quick' search for starkit failed.
#either we are in a pure zipfs system, or cookfs - or the starkit package is somewhere more devious
#for pure zipfs or cookfs - it's a little wasteful to perform exhaustive search for starkit
#review - only keep searching if not 'dev' first arg?
#review - only keep searching if not 'minted' first arg?
#Initially we've done no scans of auto_path/tcl::tm::list - but there will already be a core set of packages known by the kit
#retain it so we can 'forget' the difference after our first 'package require' forces a full scan which includes some paths we may not wish to include or at least include with different preferences
@ -545,7 +545,7 @@ apply { args {
#firstly it includes env(TCLLIBPATH)
#then it adds the tcl_library folder and its parent
#e.g //zipfs:/app/tcl_library and //zipfs:/app
#when 'dev' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#when 'minted' or 'os' is not supplied - any non internal paths (usually those from env(TCLLIBPATH) will be stripped
#so that everything is self-contained in the kit/zipkit
#puts "\x1b\[1\;33m main.tcl original auto_path: $::auto_path"
@ -630,7 +630,7 @@ apply { args {
# -----------------------------------------------------------------------------------------------------------
# dev - refers to module and library paths relative to the project (executable path)
# minted - refers to module and library paths relative to the project (executable path)
# os - refers to modules and library paths gleaned from ::env (TCLLIBPATH and TCL<MAJOR>_<MINOR>_TM_PATH)
# internal - refers to modules and libraries supplied from the mounted filesystem of a kit or zipfs based executable
# src - refers to unbuilt modules and libraries under the project's src/ tree (src/modules, src/lib, src/bootsupport, src/vendormodules)
@ -638,10 +638,10 @@ apply { args {
# Note that unlike standard 'package unknown' punk::libunknown does not stop searching for packages when a .tm file is found that matches requirements,
# The auto_path is still examined. (avoids quirks where higher versioned pkgIndex based package not always found)
# -----------------------------------------------------------------------------------------------------------
set all_package_modes [list dev os internal src]
#package_mode is specified as a dash-delimited ordered value e.g dev-os
set all_package_modes [list minted os internal src]
#package_mode is specified as a dash-delimited ordered value e.g minted-os
#"internal" is the default and if not present is always added to the list
#i.e "dev-os" is equivalent to "dev-os-internal"
#i.e "minted-os" is equivalent to "minted-os-internal"
#"os" is equivalent to "os-internal"
#"internal-os" and "internal" are left as is.
#The effective package_mode has 1 2 3 or 4 members.
@ -653,7 +653,7 @@ apply { args {
#split the first arg on dash and validate each token against the known mode set.
#This scales to any number of modes without enumerating every permutation.
#G-033: an optional 'proj:' prefix on the mode string (e.g proj:internal-src)
#scopes WHICH project the dev/src blocks resolve against - the project containing
#scopes WHICH project the minted/src blocks resolve against - the project containing
#the cwd instead of the executable's own. The prefix sits outside the ordered
#dash-list, whose block order remains the same-version tie-break dial.
set proj_scope 0
@ -698,7 +698,7 @@ apply { args {
#assert: package_modes is now a list of at least length 1 (in which case the only possible value is: internal)
#--------------------------------------------------------
#G-033 proj: scope - resolve dev/src against the project containing the cwd
#G-033 proj: scope - resolve minted/src against the project containing the cwd
#(walk-up to the nearest VCS repo root, the punk::repo::is_project_root marker)
#instead of the executable's own project. Explicit prefix = opt-in; discovery and
#its outcome are always reported on stderr (a rebind must never be silent), and a
@ -706,12 +706,12 @@ apply { args {
#--------------------------------------------------------
set proj_root ""
if {$proj_scope} {
if {!("dev" in $package_modes || "src" in $package_modes)} {
puts stderr "proj: WARNING - 'proj:' has no effect: package mode list '[join $package_modes -]' contains no project-root-using block (dev or src)"
if {!("minted" in $package_modes || "src" in $package_modes)} {
puts stderr "proj: WARNING - 'proj:' has no effect: package mode list '[join $package_modes -]' contains no project-root-using block (minted or src)"
} else {
set proj_root [::punkboot::proj_root_find [pwd]]
if {$proj_root eq ""} {
puts stderr "proj: WARNING - no project root found walking up from [pwd] (nearest git/fossil repo root with a punkshell-style src tree) - dev/src blocks are not bound to any project (proceeding; internal/os paths unaffected)"
puts stderr "proj: WARNING - no project root found walking up from [pwd] (nearest git/fossil repo root with a punkshell-style src tree) - minted/src blocks are not bound to any project (proceeding; internal/os paths unaffected)"
} else {
puts stderr "proj: project root detected (walk-up from [pwd]): $proj_root"
puts stderr "proj: effective package mode precedence: [join $package_modes -] (earlier blocks win same-version ties)"
@ -729,7 +729,7 @@ apply { args {
#It may be desired for performance or testing reasons to preference the library outside of the kit - and raising the version number may not always be possible/practical.
#If the executable is a kit - we don't know what packages it contains or whether it allows loading from env based external paths.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'dev' is earlier in the list, even if the version number is the same.
#For app-punk projects - the lib/module paths based on the project being run should take preference if 'minted' is earlier in the list, even if the version number is the same.
#(these are the 'info nameofexecutable' or 'info script' or 'pwd' relative paths that are added here)
#Some kits will remove lib/module paths (from auto_path & tcl::tm::list) that have been added via TCLLIBPATH / TCLX_Y_TM_PATH environment variables
#Some kits will remove those env-provided lib paths but fail to remove the env-provided module paths
@ -749,7 +749,7 @@ apply { args {
#original tm list at this point consists of whatever the kit decided + some prepended internal kit paths that punk decided on.
#we want to bring the existing external paths to the position specified by package_mode (probably from the kit looking at various env TCL* values)
#we want to maintain the order of the internal paths.
#we want to add our external dev paths to the position specified by package_mode
#we want to add our external minted paths to the position specified by package_mode
#assert [llength [package names]] should be small at this point ~ <10 ?
@ -795,13 +795,13 @@ apply { args {
#case differences could represent different paths on unix-like platforms.
#It's perhaps a little unwise to configure matching paths with only case differences for a cross-platform tool .. but we should support it for those who use it and have no interest in windows - todo! review
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set exe_module_folders [list]
if {$proj_scope} {
#G-033: dev module paths resolve against the cwd-walk-up project root
#G-033: minted module paths resolve against the cwd-walk-up project root
#only - no exe-relative fallback (a proj: launch must never silently
#rebind to the executable's own project; a failed discovery was
#already warned above and the dev block then contributes nothing).
#already warned above and the minted block then contributes nothing).
if {$proj_root ne ""} {
lappend exe_module_folders $proj_root/modules
lappend exe_module_folders $proj_root/modules_tcl$tclmajorv
@ -832,7 +832,7 @@ apply { args {
# set lc_external_tm_dirs [string tolower $external_tm_dirs]
# set lc_modulefolder [string tolower $modulefolder]
# if {$lc_modulefolder in [string tolower $original_external_tm_dirs]} {
# #perhaps we have an env var set pointing to one of our dev foldersl. We don't want to rely on how the kit ordered it.
# #perhaps we have an env var set pointing to one of our minted folders. We don't want to rely on how the kit ordered it.
# #bring to front if not already there.
# #assert it must be present in $lc_external_tm_dirs if it's in $original_external_tm_dirs
# set posn [lsearch $lc_external_tm_dirs $lc_modulefolder]
@ -862,7 +862,7 @@ apply { args {
}
#src mode: discover the project's src/ tree and add unbuilt module paths.
#Unlike dev mode (which points at built output in <projectroot>/modules),
#Unlike minted mode (which points at built output in <projectroot>/modules),
#src mode points at the unbuilt source in <projectroot>/src/modules etc.
if {"src" in $package_modes} {
set src_project_root ""
@ -872,7 +872,7 @@ apply { args {
#never an exe-relative fallback rebind.
set src_project_root $proj_root
} else {
#reuse the dev-mode project root discovery (exe in bin/ -> backtrack 1)
#reuse the minted-mode project root discovery (exe in bin/ -> backtrack 1)
set normexe_dir_for_src [file dirname $normexe]
if {[file tail $normexe_dir_for_src] eq "bin"} {
set src_project_root [file dirname $normexe_dir_for_src]
@ -979,7 +979,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $tm_additions_dev {
if {$n ni $new_tm_path} {
lappend new_tm_path $n
@ -1012,7 +1012,7 @@ apply { args {
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'dev' mode (dev as first argument on launch) we preference external modules
##tcl::tm::add internals first (so they end up at the end of the tmlist) as in 'minted' mode (minted as first argument on launch) we preference external modules
##note use of lreverse to maintain same order
#foreach p [lreverse $internal_tm_dirs] {
# if {$p ni [tcl::tm::list]} {
@ -1044,15 +1044,15 @@ apply { args {
#we can't rely on builtin ledit (tcl9+) or loadable version such as punk::lib::compat::ledit at this point
#so we prepend to auto_path using a slightly inefficient method. Should be fine on relatively small list like this
#eventually it should just be something like 'ledit ::auto_path -1 -1 $libfolder'
if {"dev" in $package_modes} {
if {"minted" in $package_modes} {
set platform [::punkboot::platform_punk]
#on windows - case differences dont matter - but can stop us finding path in auto_path
#on other platforms, case differences could represent different paths
#review
set process_folders [list]
if {$proj_scope} {
#G-033: dev lib paths resolve against the cwd-walk-up project root
#only (no exe-relative or cwd-relative candidates - see the dev
#G-033: minted lib paths resolve against the cwd-walk-up project root
#only (no exe-relative or cwd-relative candidates - see the minted
#module-path block above for rationale).
if {$proj_root ne ""} {
foreach libsub [list lib_tcl$tclmajorv lib] {
@ -1184,7 +1184,7 @@ apply { args {
}
}
}
dev {
minted {
foreach n $auto_path_additions_dev {
if {$n ni $new_auto_path} {
lappend new_auto_path $n
@ -1360,7 +1360,7 @@ apply { args {
#--------------------------------------------------------
#Now that new 'package unknown' mechanism is in place - we can use package require
#assert arglist has had 'dev|os|os-dev etc' first arg removed if it was present.
#assert arglist has had 'minted|os|os-minted etc' first arg removed if it was present.
#--------------------------------------------------------
@ -1461,7 +1461,7 @@ apply { args {
switch -- $subcommand {
tclsh {
#called as <executable> dev tclsh or <executable> tclsh
#called as <executable> minted tclsh or <executable> tclsh
#we would like to drop through to standard tclsh repl without launching another process
#tclMain.c doesn't allow it unless patched.
if {![info exists ::env(TCLSH_PIPEREPL)]} {

Loading…
Cancel
Save