From 482936dc005099159adc4dd63ef8b318060ea382 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Tue, 21 Jul 2026 04:01:29 +1000 Subject: [PATCH] make.tcl bootsupport re-vendor: punk::lib 0.5.1 (fixed compat lpop for the runner's toplevel boot); project 0.17.4 The runtests toplevel guard loads the bootsupport punk::lib snapshot - this re-vendor puts the parity-fixed compat family there (the testinterp guard already resolved the dev module via prefer-latest). punkproject.toml 0.17.4 + CHANGELOG entry. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- CHANGELOG.md | 5 ++++ punkproject.toml | 2 +- .../punk/{lib-0.5.0.tm => lib-0.5.1.tm} | 25 +++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) rename src/bootsupport/modules/punk/{lib-0.5.0.tm => lib-0.5.1.tm} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index a207bc22..9f46a805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ 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.17.4] - 2026-07-21 + +- punk::lib 0.5.1: `punk::lib::compat::lpop` now matches the 8.7/9 builtin exactly on error paths too - out-of-range errors use the builtin's message and `{TCL VALUE INDEX OUTOFRANGE}` errorcode (previously a nonstandard `tcl_lpop ...` message), and variable-access failures (unset variable, whole-array name, missing array element) reproduce the builtin's message and errorcode naming the caller's variable. Validated by a differential parity matrix against the real builtin, pinned in the punk::lib compat testsuite; no known divergence remains (8.6's index parser already accepts TIP-176 `M+N` arithmetic). +- runtests (test tooling, rides this release): the harness now runs under a native Tcl 8.6 tclsh - guarded `punk::lib` compat loads (lpop family) at both boot levels, no-ops on Tcl 9 (fast `-discover-only` boot unchanged). Full-suite mode parity re-verified on Tcl 9.0.3 (`PARITY: ok`, baseline exec-14.3 only). + ## [0.17.3] - 2026-07-21 - punkcheck 0.6.0 (G-095, goal achieved): concurrent writers to one `.punkcheck` file can no longer corrupt it or silently erase each other's records, and readers never see torn content. Saves are write-temp-then-atomic-rename (with reader-side retry for the Windows replace-window open denial); whole installer events hold an advisory sibling `.punkcheck.lock` (new `punkcheck::lock` namespace - holder pid/host/installer/timestamp in the lockfile, backoff-retry acquisition to a timeout that errors naming the holder, stale-break on provably-dead holder pid or age, in-process reference-counted re-acquisition; env overrides `PUNKCHECK_LOCK_TIMEOUT`/`PUNKCHECK_LOCK_STALEAGE`); deferred flushes merge own records into freshly-loaded file state; an mtime/size tripwire warns on protocol-bypassing writers; the duplicate-INSTALLER recovery raises a clean actionable error instead of prompting when stdin is non-interactive. Verified by a new concurrency suite (real child installer processes) on Windows Tcl 9.0.3 + 8.6.17 and linux (WSL tclsh 8.6.14). diff --git a/punkproject.toml b/punkproject.toml index fb909703..388d41f3 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,4 +1,4 @@ [project] name = "punkshell" -version = "0.17.3" +version = "0.17.4" license = "BSD-2-Clause" diff --git a/src/bootsupport/modules/punk/lib-0.5.0.tm b/src/bootsupport/modules/punk/lib-0.5.1.tm similarity index 99% rename from src/bootsupport/modules/punk/lib-0.5.0.tm rename to src/bootsupport/modules/punk/lib-0.5.1.tm index 24576228..7013a8e5 100644 --- a/src/bootsupport/modules/punk/lib-0.5.0.tm +++ b/src/bootsupport/modules/punk/lib-0.5.1.tm @@ -8,7 +8,7 @@ # (C) 2024 # # @@ Meta Begin -# Application punk::lib 0.5.0 +# Application punk::lib 0.5.1 # Meta platform tcl # Meta license BSD # @@ Meta End @@ -18,7 +18,7 @@ # doctools header # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ #*** !doctools -#[manpage_begin punkshell_module_punk::lib 0 0.5.0] +#[manpage_begin punkshell_module_punk::lib 0 0.5.1] #[copyright "2024"] #[titledesc {punk general utility functions}] [comment {-- Name section and table of contents description --}] #[moddesc {punk library}] [comment {-- Description at end of page heading --}] @@ -295,7 +295,7 @@ tcl::namespace::eval punk::lib::check { if {$replversion eq ""} { #not loaded - determine what version would be provided, without loading it: #an unsatisfiable require triggers the package unknown scan (registering ifneeded - #scripts) then fails before any load (0.5.0 dev modules are alpha - below 999999). + #scripts) then fails before any load (0.5.1 dev modules are alpha - below 999999). catch {package require punk::repl 999999} set available [package versions punk::repl] if {[llength $available]} { @@ -613,9 +613,20 @@ tcl::namespace::eval punk::lib::compat { } proc lpop {lvar args} { #*** !doctools - #[call [fun lpop] [arg listvar] [opt {index}]] + #[call [fun lpop] [arg listvar] [opt {index ...}]] #[para] Forwards compatible lpop for versions 8.6 or less to support equivalent 8.7 lpop - #upvar $lvar l + #[para] Index forms come from the running Tcl's core index parser (lindex/lrange/lreplace), + #[para] which accepts the same integer?\[+-]integer? / end?\[+-]integer? grammar on 8.6 + #[para] (TIP 176) as 8.7/9. Behaviour - results, final list state, error messages and + #[para] errorcodes - matches the builtin; pinned by the compat testsuite (compat.test). + if {[catch {uplevel 1 [list ::set $lvar]} lreaderr lreadopts]} { + #variable access failed (unset variable, whole-array name, or missing array element). + #Probing with a plain read in the caller's frame - BEFORE creating the upvar link - + #reproduces the builtin's message and errorcode exactly (through a link, or once a link + #exists, the detail flattens: e.g 'no such variable' loses its TCL LOOKUP errorcode and + #a missing array element misreports as 'no such variable'). + return -code error -errorcode [dict get $lreadopts -errorcode] $lreaderr + } upvar 1 $lvar l if {![llength $args]} { set args [list end] @@ -628,7 +639,7 @@ tcl::namespace::eval punk::lib::compat { for {set i 0} {$i < [llength $args]} {incr i} { set idx [lindex $args $i] if {![llength [lrange $subl $idx $idx]]} { - error "tcl_lpop index \"$idx\" out of range" + return -code error -errorcode [list TCL VALUE INDEX OUTOFRANGE] "index \"$idx\" out of range" } lappend path [lindex $args $i] set subl [lindex $l {*}$path] @@ -9379,7 +9390,7 @@ namespace eval ::punk::args::register { package provide punk::lib [tcl::namespace::eval punk::lib { variable pkg punk::lib variable version - set version 0.5.0 + set version 0.5.1 }] return