diff --git a/CHANGELOG.md b/CHANGELOG.md index 939d0d8c..f344d292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ 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.12.12] - 2026-07-12 + +- punk::ns 0.3.0: 'i ' with no argument words again signals when the command cannot be called bare - e.g 'i if' shows "Bad number of trailing values for if. Got 0 values. Expected at least 2" in the error scheme above the usage table (regression vs older builds, reported by the user). The G-046-era suppression of that render existed because the old message carried internal-looking attribution ("for punk::args::parse ..."); the G-049 -caller attribution fixed the message wording, so the suppression was reversed rather than reworded - the original 'i string is' complaint case now renders an accurate "Bad number of leading values for string is ..." instead of being hidden. + ## [0.12.11] - 2026-07-12 - G-071 achieved: punk::args 0.9.0 allocation choice screen - optional arguments with restricted choice sets no longer greedily consume non-choice words at allocation time, so noise-word grammars parse correctly with the noise word omitted. 'i lseq 0 10 2' (and the '0 10 by 2' / '1 5 by 0' shapes) now parse and render correctly against the tclcore moduledoc; genuinely invalid arglists report a plain excess-values error instead of blaming an unrelated optional argument. Correction recorded: parse_status already accepted -form before the withid/withdef tail per its documented synopsis - the earlier 'missing -form' finding was an argument-order mistake, now pinned by test. diff --git a/punkproject.toml b/punkproject.toml index 5f2a1f6f..319a0de7 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,4 +1,4 @@ [project] name = "punkshell" -version = "0.12.11" +version = "0.12.12" license = "BSD-2-Clause" diff --git a/src/modules/punk/ns-999999.0a1.0.tm b/src/modules/punk/ns-999999.0a1.0.tm index 0e6cfcb3..f43b9787 100644 --- a/src/modules/punk/ns-999999.0a1.0.tm +++ b/src/modules/punk/ns-999999.0a1.0.tm @@ -5605,15 +5605,14 @@ y" {return quirkykeyscript} #-caller attributes any failure message to the queried command rather than #an internal parse call site. set pstatus [punk::args::parse_status $queryargs -form $opt_form -caller $querycommand withid $rootdoc] - #With NO supplied args a failure only reflects missing required - #leaders/values - nothing to mark and nothing wrong with the user's (absent) - #input, so we show plain usage in the info scheme instead of the - #internal-looking parse error (G-046 item 5). + #A failing advisory parse renders with the error scheme and its + #message even when NO args were supplied - see the matching site in + #the main cmdhelp body for the history (G-046 item 5 suppression + #reversed 2026-07-12 after the G-049 -caller attribution made the + #messages accurate). if {$opt_return eq "dict"} { if {$scheme_received} { dict set pstatus scheme [dict get $opts -scheme] - } elseif {![dict get $pstatus ok] && ![llength $queryargs]} { - dict set pstatus scheme info } return [dict create origin $rootorigin docid $rootdoc cmdtype $rootorigintype args_remaining $queryargs parsestatus $pstatus] } @@ -5623,11 +5622,6 @@ y" {return quirkykeyscript} dict set nextopts -scheme info } set result [punk::args::arg_error "" [punk::args::get_spec $rootdoc] {*}$nextopts -aserror 0 -parsestatus $pstatus] - } elseif {![llength $queryargs]} { - if {!$scheme_received} { - dict set nextopts -scheme info - } - set result [punk::args::arg_error "" [punk::args::get_spec $rootdoc] {*}$nextopts -aserror 0] } else { set result [punk::args::arg_error [dict get $pstatus message] [punk::args::get_spec $rootdoc] {*}$nextopts -aserror 0 -parsestatus $pstatus] } @@ -5712,15 +5706,17 @@ y" {return quirkykeyscript} #-errorstyle minimal so no usage table is built inside a discarded error and #dynamically updated ensembles are reflected). set pstatus [punk::args::parse_status $args_remaining -form $opt_form -caller $caller_display withid $origindoc] - #With NO supplied trailing args a failure only reflects missing required - #leaders/values (e.g 'i string is') - nothing to mark and nothing wrong with the - #user's (absent) input, so we show plain usage in the info scheme instead of the - #internal-looking parse error (G-046 item 5). + #A failing advisory parse renders with the error scheme and its message even + #when NO trailing args were supplied: 'i if' indicating "Bad number of + #trailing values for if. Got 0 values. Expected at least 2" is useful signal + #that the command cannot be called bare. (History: G-046 item 5 suppressed + #this path because the pre-G-049 message was internal-looking - "for + #punk::args::parse $args_remaining" - but the G-049 -caller attribution made + #the messages accurate, so the suppression was reversed 2026-07-12 by user + #direction, restoring the pre-G-046 indication with the improved messages.) if {$opt_return eq "dict"} { if {$scheme_received} { dict set pstatus scheme [dict get $opts -scheme] - } elseif {![dict get $pstatus ok] && ![llength $args_remaining]} { - dict set pstatus scheme info } return [dict create origin $origin docid $origindoc cmdtype $origintype args_remaining $args_remaining parsestatus $pstatus] } @@ -5730,11 +5726,6 @@ y" {return quirkykeyscript} dict set nextopts -scheme info } set result [punk::args::arg_error "" [punk::args::get_spec $origindoc] {*}$nextopts -aserror 0 -parsestatus $pstatus] - } elseif {![llength $args_remaining]} { - if {!$scheme_received} { - dict set nextopts -scheme info - } - set result [punk::args::arg_error "" [punk::args::get_spec $origindoc] {*}$nextopts -aserror 0] } else { set result [punk::args::arg_error [dict get $pstatus message] [punk::args::get_spec $origindoc] {*}$nextopts -aserror 0 -parsestatus $pstatus] } diff --git a/src/modules/punk/ns-buildversion.txt b/src/modules/punk/ns-buildversion.txt index 71a831fc..2845c9a0 100644 --- a/src/modules/punk/ns-buildversion.txt +++ b/src/modules/punk/ns-buildversion.txt @@ -1,6 +1,7 @@ -0.2.0 +0.3.0 #First line must be a semantic version number #all other lines are ignored. +#0.3.0 - reversal of the G-046-item-5 no-supplied-words suppression (user direction 2026-07-12): cmdhelp's advisory parse failing with NO supplied argument words renders the failure message and error scheme again (both the alias path and the main path; dict returns no longer rewrite the scheme to info), so 'i if'/'i while'/'i foreach' once more signal that the command cannot be called bare - e.g "Bad number of trailing values for if. Got 0 values. Expected at least 2". Rationale: the suppression (ns 0.1.4) existed because the pre-G-049 message was internal-looking ("... for punk::args::parse $args_remaining ..."); the G-049 -caller attribution (ns 0.2.0) made bare-query messages accurate - including the original 'i string is' complaint case, which now reads "Bad number of leading values for string is. Got 0 leaders. Expected exactly 1". Tests: cmdhelp_leader_required_no_args_plain_usage flipped to cmdhelp_leader_required_no_args_error_render; cmdhelp_return_dict_scheme expects scheme error for the bare-query failure. #0.2.0 - G-049: cmdhelp -return dict - machine-parsable return carrying resolution info (origin/docid/cmdtype/args_remaining) plus the parse-status structure of the supplied argument words (punk::args::parse_status shape; empty for undocumented commands); the scheme field reflects an explicit -scheme and the G-046-item-5 no-supplied-words suppression. cmdhelp's advisory parse now runs via punk::args::parse_status on both the alias path and the main path: an explicit -scheme is honoured on the parse-failure render (previously only on success/tableobject - failures returned parse's internally rendered error with the default error scheme), failure renders consume the structure via arg_error -parsestatus (badarg marking now covers type/allocation failures via the structure), and the failure message names the queried command (parse -caller: querycommand + consumed subcommand words) instead of whatever the %caller% frame walk found - at top call depth that was cmdhelp's own raw 'punk::args::parse $args_remaining ...' source text. Tests: cmdhelp.test G-049 GAP pins flipped + cmdhelp_return_dict_* added #0.1.4 - G-046 item 5: cmdhelp's advisory goodargs parse failing with NO supplied argument words (e.g 'i string is' where the definition requires leaders) now shows plain info-scheme usage instead of the internal-looking "Bad number of leading values for punk::args::parse ..." error output (both the alias path and the main path; error display for supplied-but-invalid words unchanged). The no-supplied-words advisory parse runs with -errorstyle minimal so its failure doesn't render the full usage table inside the discarded error - large argdocs (e.g 'i punk::args::define') render the table once, not twice (verified parity with pre-G-046 timings: ~5.3s first/~4.1s repeat on punk91 src, table construction dominant). Test: cmdhelp.test cmdhelp_leader_required_no_args_plain_usage #0.1.3 - documentation-only: cmdhelp 'subcommand' argument help rewritten to match actual behaviour (was described as ensemble-subcommands-only; also covers tcl::oo methods and argument words, whose validity drives the info/error scheme and received-argument marking of the usage display) diff --git a/src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test b/src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test index 23e568e0..e8c99577 100644 --- a/src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test +++ b/src/tests/modules/punk/ns/testsuites/ns/cmdhelp.test @@ -420,19 +420,22 @@ namespace eval ::testspace { }\ -result [list 0 incomplete error {}] - test cmdhelp_return_dict_scheme {the dict scheme field reflects an explicit -scheme, and the no-supplied-words suppression (G-046 item 5) reports info}\ + test cmdhelp_return_dict_scheme {the dict scheme field reflects an explicit -scheme, and a bare-query failure reports the error scheme}\ -setup $common -body { set d [punk::ns::cmdhelp -return dict -scheme error ::testspace::helpfix v1 0 1] lappend result [dict get [dict get $d parsestatus] scheme] - #leader-requiring definition with no argument words - failure reflects only the - #absent input, reported with the info scheme the display path would use + #leader-requiring definition with no argument words - the failing advisory + #parse reports the error scheme like any other failure (the G-046 item 5 + #info-scheme suppression was reversed 2026-07-12: the G-049 -caller + #attribution made bare-query failure messages accurate, so 'i ' on a + #command that cannot be called bare shows that signal again) set d [punk::ns::cmdhelp -return dict ::testspace::helpstr] set ps [dict get $d parsestatus] lappend result [dict get $ps ok] [dict get $ps scheme] }\ -cleanup { }\ - -result [list error 0 info] + -result [list error 0 error] #--- GAP pins: pseudo-command cmdtype + space-delimited docid prefixes (G-051) ------------ @@ -546,7 +549,14 @@ namespace eval ::testspace { }\ -result [list {{::testspace::helpfix v1} [-flag] firstval lastval}] - #--- leader-requiring definition, no supplied args (G-046 item 5) -------------------------- + #--- leader-requiring definition, no supplied args ----------------------------------------- + #History: G-046 item 5 suppressed the failing advisory parse for bare queries + #because the pre-G-049 message was internal-looking ("Bad number of leading values + #for punk::args::parse $args_remaining ..."). The G-049 -caller attribution made + #the messages accurate ("... for ..."), so the suppression was + #reversed 2026-07-12 (user direction): a bare 'i ' on a command that cannot + #be called with no arguments shows the failure message and error scheme again - + #with the message attributed to the queried command, never the internal parse. namespace eval ::testspace::leaderhelp {} punk::args::define { @@ -562,16 +572,17 @@ namespace eval ::testspace { } proc ::testspace::leaderhelp::classy {zzclass} {return $zzclass} - test cmdhelp_leader_required_no_args_plain_usage {cmdhelp with no argument words for a leader-requiring definition shows plain usage - the advisory goodargs parse failure ('Bad number of leading values for punk::args::parse ...') is suppressed (G-046 item 5, the 'i string is' shape)}\ + test cmdhelp_leader_required_no_args_error_render {cmdhelp with no argument words for a leader-requiring definition shows the failure message attributed to the queried command (suppression reversed; was cmdhelp_leader_required_no_args_plain_usage)}\ -setup $common -body { set out [punk::ansi::ansistrip [punk::ns::cmdhelp -return string ::testspace::leaderhelp::classy]] lappend result [string match "*Bad number of leading values*" $out] + #attribution is the queried command - never the internal parse call lappend result [string match "*punk::args::parse*" $out] lappend result [string match "*zzclass*" $out] }\ -cleanup { }\ - -result [list 0 0 1] + -result [list 1 0 1] #--- ensemble autodef with lazily-registered subcommand argdocs ---------------------------- #Integration surface of the defect pinned unit-level in