Browse Source

Build outputs: layout->modpod templates sync + bootsupport refresh

punk.project modpod layout copy receives the G-146 .fossil-settings payloads
(binary-glob new, crlf-glob updated); bootsupport punk::mix templates-0.2.0.tm
rebuilt carrying them; bootsupport punk::args snapshot advanced 0.13.0 ->
0.14.0 (the G-152 bump, pending from that arc's closeout). Punkcheck-managed
build outputs batched per src/AGENTS.md.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 7 days ago
parent
commit
dc55f1764b
  1. 186
      src/bootsupport/modules/punk/args-0.14.0.tm
  2. BIN
      src/bootsupport/modules/punk/mix/templates-0.2.0.tm
  3. 5
      src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/.fossil-settings/binary-glob
  4. 7
      src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/.fossil-settings/crlf-glob

186
src/bootsupport/modules/punk/args-0.13.0.tm → src/bootsupport/modules/punk/args-0.14.0.tm

@ -8,7 +8,7 @@
# (C) 2024
#
# @@ Meta Begin
# Application punk::args 0.13.0
# Application punk::args 0.14.0
# Meta platform tcl
# Meta license <unspecified>
# @@ Meta End
@ -18,7 +18,7 @@
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin punkshell_module_punk::args 0 0.13.0]
#[manpage_begin punkshell_module_punk::args 0 0.14.0]
#[copyright "2024"]
#[titledesc {args parsing}] [comment {-- Name section and table of contents description --}]
#[moddesc {args to nested dict of opts and values}] [comment {-- Description at end of page heading --}]
@ -6528,6 +6528,31 @@ tcl::namespace::eval punk::args {
punk::args::define). When -form permits several forms, the form that
auto-selection settled on is reported here, and a formstatus key is added
recording each attempted form's outcome (see punk::args::parse_status).
Multiform failure contract (stable, machine-readable):
when a multi-form candidacy attempt matches no form, the raised error
carries the errorcode
PUNKARGS VALIDATION {noformmatch forms <fidlist> classes <classlist>}
-formerrors <records> -argspecs <spec>
where 'forms' lists the candidate form names ranked best-candidate
first and 'classes' holds one suffix-viability verdict per listed
form (same order) from the vocabulary:
incomplete - VIABLE: every supplied word was validly consumed as
a prefix of that form and parsing stopped only from
exhaustion at end-of-input - appending further
words can still satisfy the form
invalid - NOT viable: something already supplied contradicts
the form - no appended words can satisfy it
-formerrors holds one record per form (same ranked order) with keys
status/failureclass/badarg/message - 'status' is the same verdict.
The verdict is conservative for arguments whose -type is a
multi-member clause: input ending inside such a clause reports
invalid even when the partial clause words match.
Arguments matching several forms cleanly raise errorcode
PUNKARGS VALIDATION {multipleformmatches forms <fidlist>}
Consumers (form narrowing, interactive completion) should select
candidate forms from these channels rather than parsing message
text.
}
@form -form {withid withdef}
@leaders -min 1 -max 1
@ -6934,7 +6959,10 @@ tcl::namespace::eval punk::args {
}
noformmatch {
#G-041 multi-form candidacy: payload is: forms <fids> classes <per-form statuses>
#incomplete when some candidate form needs only more words
#G-152: the classes are sound per-form suffix-viability verdicts (candidacy
#confirms each 'incomplete' by a viability-mode re-parse before raising) -
#overall incomplete therefore means at least one form is still satisfiable
#by appending words
if {"incomplete" in [Dict_getdef $payload classes {}]} {
return incomplete
}
@ -7176,6 +7204,10 @@ tcl::namespace::eval punk::args {
#G-041: order a formfailures dict (fid -> {status .. failureclass .. badarg .. message ..})
#best-candidate first: literal affinity desc, then incomplete before invalid, then the
#incoming (declaration) order. Returns the re-ordered dict.
#order a noformmatch failure's per-form records best-candidate first: leading-literal
#affinity with the supplied words, then status incomplete before invalid, then
#declaration order (stable sort). G-152: status is the confirmed suffix-viability
#verdict, so the class tiebreak ranks still-satisfiable forms above impossible ones.
proc private::rank_form_failures {argspecs rawargs formfailures} {
set scored [list]
dict for {fid finfo} $formfailures {
@ -7676,7 +7708,14 @@ tcl::namespace::eval punk::args {
failing its -type check can also surface as
an allocation shortfall (missingrequiredvalue)
- badarg and the per-argument statuses carry
the specifics in both situations.
the specifics in both situations. For a
single-form parse this is the engine failure
classification, NOT a viability verdict -
read formstatus for that. For a multiform
noformmatch failure incomplete does carry
verdict weight: it means at least one
candidate form is still viable (its
formstatus status is incomplete).
scheme suggested display scheme: info (ok) | error (failure)
message empty | the validation failure message
errorcode empty | the -errorcode of the validation failure with
@ -7695,14 +7734,33 @@ tcl::namespace::eval punk::args {
then incomplete before invalid, then declaration
order).
formstatus dict keyed by candidate form name - each value a
dict with at least the key 'status'
(valid | incomplete | invalid) and for failed
dict with at least the key 'status' and for failed
candidates failureclass, badarg and message.
'status' is a per-form suffix-viability verdict
(stable consumer contract):
valid - the supplied words satisfy the form
incomplete - VIABLE: every supplied word was
validly consumed as a prefix of the
form and parsing stopped only from
exhaustion at end-of-input -
appending further words can still
satisfy the form
invalid - NOT viable: something already
supplied contradicts the form - no
appended words can satisfy it
The verdict is conservative for arguments whose
-type is a multi-member clause (e.g
{literal(elseif) expr script}): input ending
inside such a clause reports invalid even when
the partial clause words match.
Single-form parses report their one form; when
multi-form candidacy ran, every attempted form is
reported - partial-arglist consumers (e.g command
completion/hinting) can read per-form
compatibility from this key.
completion/hinting, cmdhelp form narrowing) can
select the still-satisfiable form(s) from this
key. The raising parse exposes the same verdicts
in its noformmatch errorcode - see
punk::args::parse.
receivednames received argument names normalized to definition
argument names (opt aliases folded to their
-alias|-name optionset)
@ -7848,7 +7906,17 @@ tcl::namespace::eval punk::args {
}
}
default {
set formstatus [dict create $fid [dict create status $status failureclass $failureclass badarg $badarg message $r]]
#G-152: formstatus statuses are suffix-viability verdicts. The overall
#status above keeps the engine failure classification (it drives the
#display scheme), but the per-form record must not report 'incomplete'
#unless the supplied words are a valid prefix of the form - confirm by
#a viability-mode re-parse exactly as multiform candidacy does.
set formverdict $status
if {$formverdict eq "incomplete"
&& [catch {private::get_dict_form $spec_dict $fid $arglist 1}]} {
set formverdict invalid
}
set formstatus [dict create $fid [dict create status $formverdict failureclass $failureclass badarg $badarg message $r]]
}
}
#the -argspecs payload (the whole resolved spec) is display machinery - too bulky
@ -9512,8 +9580,21 @@ tcl::namespace::eval punk::args {
}
set classinfo [lindex $ecode 2]
set failureclass [lindex $classinfo 0]
set formverdict [private::parse_status_classify $failureclass [lrange $classinfo 1 end]]
#G-152: a per-form 'incomplete' is a suffix-viability verdict - it must hold
#only when every supplied word was validly consumed as a prefix of the form
#and the failure is pure exhaustion at end-of-input. The failure class alone
#cannot witness that (count and missing-required classes fire before final
#validation sees the consumed words), so confirm by re-parsing in viability
#mode: exhaustion raises are skipped there while validation of the consumed
#words still applies - a raise means something already supplied contradicts
#the form.
if {$formverdict eq "incomplete"
&& [catch {private::get_dict_form $argspecs $fid $rawargs 1}]} {
set formverdict invalid
}
dict set formfailures $fid [dict create\
status [private::parse_status_classify $failureclass [lrange $classinfo 1 end]]\
status $formverdict\
failureclass $failureclass\
badarg [Dict_getdef [lrange $ecode 3 end] -badarg ""]\
message [lindex [split $fresult \n] 0]\
@ -9547,7 +9628,16 @@ tcl::namespace::eval punk::args {
set classes [lmap finfo [dict values $formfailures] {dict get $finfo status}]
set msg "Bad arguments for %caller%. No form of the command matches the supplied arguments. Candidate forms: $candidate_fids"
dict for {fid finfo} $formfailures {
append msg \n " form '$fid': [dict get $finfo message]"
#G-152: visibly distinguish forms still satisfiable by appending words
#(status incomplete - the confirmed suffix-viability verdict) from
#forms nothing appended can satisfy. Keep the "form '<fid>':" prefix
#intact - consumers/tests anchor on it.
if {[dict get $finfo status] eq "incomplete"} {
set verdicttag "(viable - needs more arguments)"
} else {
set verdicttag "(not viable)"
}
append msg \n " form '$fid': $verdicttag [dict get $finfo message]"
}
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list noformmatch forms $candidate_fids classes $classes] -argspecs $argspecs -formerrors $formfailures]] $msg
}
@ -9562,7 +9652,23 @@ tcl::namespace::eval punk::args {
#body, extracted verbatim from get_dict when multi-form candidacy landed (G-041).
#argspecs is a RESOLVED spec dict (get_dict resolves the deflist in its caller's
#context before selecting forms - nothing here touches the caller's frame).
proc private::get_dict_form {argspecs fid rawargs} {
#
#viabilitycheck (G-152): when 1, run as a suffix-viability probe - the question
#answered is not "do these arguments satisfy the form" but "are these arguments a
#valid PREFIX of the form" (could appending further words still satisfy it). The
#probe suppresses exactly the raises that represent pure exhaustion at
#end-of-input (below-minimum count checks and missing-required checks, each
#guarded by position conditions ensuring appended words could actually reach the
#missing element, and an option's value lying beyond the supplied words) and lets
#every other raise stand - including the final validation of the words actually
#consumed, which is the soundness backstop: a probe raise means something already
#supplied contradicts the form. Callers only test raised-vs-returned; the
#returned dict of a probe run is partial and must be discarded.
#Known conservatism (documented in the parse/parse_status contracts): input
#ending INSIDE a multi-member type clause raises (clause allocation cannot
#affirm the partial words) - such prefixes report non-viable even when the
#partial clause words match.
proc private::get_dict_form {argspecs fid rawargs {viabilitycheck 0}} {
#puts "-arg_info->$arg_info"
set flagsreceived [list] ;#for checking if required flags satisfied
set solosreceived [list]
@ -10564,6 +10670,15 @@ tcl::namespace::eval punk::args {
tcl::dict::set arg_checks $a $OPT_CHECKS_DEFAULTS
#assert -type value has llength 1 (multitype clauses not allowed for opts)
if {[tcl::dict::get $argstate $a -type] ne "none"} {
if {$viabilitycheck && $i == $maxidx} {
#G-152 viability probe: the adhoc option's value lies beyond
#the supplied words - pure end-of-input exhaustion. End the
#opts scan; the unfinished flag stays unassigned (required
#checks are position-guarded in probe mode).
set arglist [lrange $remaining_rawargs 0 $i-1]
set post_values {}
break
}
if {[tcl::dict::get $argstate $a -multiple]} {
tcl::dict::lappend opts $a $flagval
if {$a ni $multisreceived} {
@ -11172,14 +11287,29 @@ tcl::namespace::eval punk::args {
}
#-----------------------------------------------------
#G-152 viability probe: a below-minimum count is pure end-of-input exhaustion -
#satisfiable by appending words - only while the parse position can still reach
#that section: the leaders section only when nothing was consumed beyond it (no
#option words, no value words - appended words land after those and cannot fill
#a leader); the trailing values always (values end the argument list and the
#loops above consumed every supplied word). The probe skips those raises so
#final validation can pass verdict on the words actually consumed.
#Above-maximum counts are contradictions in any mode.
if {$viabilitycheck} {
set skip_leadershortfall [expr {![llength $flagsreceived] && ![llength $values]}]
set skip_valueshortfall 1
} else {
set skip_leadershortfall 0
set skip_valueshortfall 0
}
if {$leadermax == -1} {
#only check min
if {$num_leaders < $leadermin} {
if {$num_leaders < $leadermin && !$skip_leadershortfall} {
set msg "Bad number of leading values for %caller%. Got $num_leaders leaders. Expected at least $leadermin"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list leadingvaluecount $num_leaders min $leadermin max $leadermax] -argspecs $argspecs]] $msg
}
} else {
if {$num_leaders < $leadermin || $num_leaders > $leadermax} {
if {($num_leaders < $leadermin && !$skip_leadershortfall) || $num_leaders > $leadermax} {
if {$leadermin == $leadermax} {
set msg "Bad number of leading values for %caller%. Got $num_leaders leaders. Expected exactly $leadermin"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list leadingvaluecount $num_leaders min $leadermin max $leadermax] -argspecs $argspecs]] $msg
@ -11192,12 +11322,12 @@ tcl::namespace::eval punk::args {
if {$valmax == -1} {
#only check min
if {$num_values < $valmin} {
if {$num_values < $valmin && !$skip_valueshortfall} {
set msg "Bad number of trailing values for %caller%. Got $num_values values. Expected at least $valmin"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list trailingvaluecount $num_values min $valmin max $valmax] -argspecs $argspecs]] $msg
}
} else {
if {$num_values < $valmin || $num_values > $valmax} {
if {($num_values < $valmin && !$skip_valueshortfall) || $num_values > $valmax} {
if {$valmin == $valmax} {
set msg "Bad number of trailing values for %caller%. Got $num_values values. Expected exactly $valmin"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list trailingvaluecount $num_values min $valmin max $valmax] -argspecs $argspecs]] $msg
@ -11230,14 +11360,30 @@ tcl::namespace::eval punk::args {
# error "Required value missing for [Get_caller]. missing values $missing marked with -optional false - so must be present"
#}
#for now (2024-06) punk::lib::ldiff is a better compromise across normal/safe interps e.g 0.7/0.8us
if {[llength $LEADER_REQUIRED]} {
#G-152 viability probe: a missing required argument is pure end-of-input
#exhaustion - satisfiable by appending words - only while the parse position
#can still reach its argument class: a required leader only when no option or
#value words followed the leaders; a required option only while no value words
#have begun and no eopts marker (--) has closed the options; a required value
#always (values end the argument list). The probe skips those raises in that
#situation; otherwise the absence stands as a contradiction even in probe mode.
if {$viabilitycheck} {
set skip_leadermissing [expr {![llength $flagsreceived] && ![llength $values]}]
set skip_optionmissing [expr {![llength $values] && "--" ni $flagsreceived}]
set skip_valuemissing 1
} else {
set skip_leadermissing 0
set skip_optionmissing 0
set skip_valuemissing 0
}
if {[llength $LEADER_REQUIRED] && !$skip_leadermissing} {
if {[llength [set missing [punk::args::system::punklib_ldiff $LEADER_REQUIRED $leadernames_received]]]} {
set msg "Required leader missing for %caller%. missing values: '$missing' marked with -optional false - so must be present"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list leadermissing $missing received $leadernames_received] -argspecs $argspecs]] $msg
#arg_error "Required leader missing for [Get_caller]. missing values: '$missing' marked with -optional false - so must be present" $argspecs
}
}
if {[llength $OPT_REQUIRED]} {
if {[llength $OPT_REQUIRED] && !$skip_optionmissing} {
#broken e.g
#punk::args::define {@id -id ::spud} @opts {-x -parsekey -coord -optional 0} {-y -parsekey -coord -optional 0}
#error is:
@ -11259,7 +11405,7 @@ tcl::namespace::eval punk::args {
#arg_error "Required option missing for [Get_caller]. missing flags: '$missing' are marked with -optional false - so must be present " $argspecs
}
}
if {[llength $VAL_REQUIRED]} {
if {[llength $VAL_REQUIRED] && !$skip_valuemissing} {
if {[llength [set missing [punk::args::system::punklib_ldiff $VAL_REQUIRED $valnames_received]]]} {
set msg "Required value missing for %caller%. missing values: '$missing' marked with -optional false - so must be present"
return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list valuemissing $missing received $valnames_received] -argspecs $argspecs]] $msg
@ -14113,7 +14259,7 @@ package provide punk::args [tcl::namespace::eval punk::args {
tcl::namespace::path {::punk::args::lib ::punk::args::system}
variable pkg punk::args
variable version
set version 0.13.0
set version 0.14.0
}]
return

BIN
src/bootsupport/modules/punk/mix/templates-0.2.0.tm

Binary file not shown.

5
src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/.fossil-settings/binary-glob vendored

@ -0,0 +1,5 @@
#Allow binary checkins by default - no fossil commit warnings/prompts for binary content.
#Generated projects carry binary payloads from generation time: zip-based .tm modules
#injected into src/bootsupport by the generating shell, and layout-carried binaries
#(e.g bin/sdx.kit) where the layout ships them.
*

7
src/modules/punk/mix/#modpod-templates-999999.0a1.0/templates/project_layouts/vendor/punk/project-0.1/.fossil-settings/crlf-glob vendored

@ -1 +1,8 @@
#Suppress fossil CRLF commit warnings/prompts for trees whose content arrives with
#endings the generated project's owner does not author: bootsupport module/lib
#snapshots injected at generation time inherit the generating shell's file endings,
#src/embedded holds generated docs, and bin/ carries layout-shipped utility scripts.
#Authored project files outside these trees still get fossil's CRLF warning.
src/embedded/*
src/bootsupport/*
bin/*

Loading…
Cancel
Save