You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
6.6 KiB
156 lines
6.6 KiB
#family_artifacts.tcl (G-103): emit punkbin-layout artifact copies + per-artifact |
|
#toml metadata + sha1sums for the verified runtime kit family members. |
|
# |
|
#Deliberately run UNDER THE PLAIN FAMILY KIT itself (not the builder shell): the |
|
#sha1 digests come from the kit's attached tcllib/tcllibc, so every emission run |
|
#doubles as a proof that the family runtime executes real tooling self-contained. |
|
# |
|
#Artifact tier naming (G-103 naming decision): <workingname minus .exe>-r<N>.exe - |
|
#immutable punkbin names; the -r<N> assembly revision comes from the invocation |
|
#(-rev, suite option -Dfamilyrev). The emitted tree mirrors a punkbin platform |
|
#folder: <outdir>/<artifact>.exe + <artifact>.toml + sha1sums.txt (punkbin |
|
#format: '<sha1> *<filename>'). Publication to the real punkbin repo is a |
|
#deliberate user step (copy + build_sha1sums.tcl there); it is DEFERRED per the |
|
#goal notes until the family shape is accepted. |
|
# |
|
#args: -outdir <dir> -rev <N> -target <punkbin platform, e.g win32-x86_64> |
|
# -suite <name> -tclpatch <patchlevel> -zig <version> -optimize <mode> |
|
# -components {<name> <ver> ...} (attached battery versions, all variants) |
|
# -bicomponents {<name> <ver> ...} (additional bi-only batteries) |
|
# -provenance {<name> <uuid> ...} (source checkout uuids) |
|
# -testreports <dir> (G-107 evidence summaries; optional) |
|
# -kits {<variant> <workingexepath> ...} |
|
|
|
proc fail {msg} {puts stderr "family_artifacts FAIL: $msg"; flush stderr; exit 1} |
|
proc note {msg} {puts stdout "family_artifacts: $msg"; flush stdout} |
|
|
|
array set opt { |
|
-outdir {} -rev 1 -target {} -suite {} -tclpatch {} -zig {} -optimize {} |
|
-components {} -bicomponents {} -provenance {} -testreports {} -kits {} |
|
} |
|
foreach {k v} $argv { |
|
if {![info exists opt($k)]} {fail "unknown option '$k'"} |
|
set opt($k) $v |
|
} |
|
foreach req {-outdir -target -suite -tclpatch -zig -optimize -components -kits} { |
|
if {$opt($req) eq ""} {fail "missing required option $req"} |
|
} |
|
if {![string is integer -strict $opt(-rev)] || $opt(-rev) < 1} {fail "-rev must be a positive integer"} |
|
|
|
if {[catch {package require sha1} sha1ver]} { |
|
fail "package require sha1 failed under [info nameofexecutable] - the family kit must carry tcllib: $sha1ver" |
|
} |
|
|
|
proc toml_str {s} { |
|
#basic toml string: escape backslash and double-quote (values here are names, |
|
#versions, uuids, iso dates - no control chars expected) |
|
return "\"[string map {\\ \\\\ \" \\\"} $s]\"" |
|
} |
|
|
|
proc exe_split {name} { |
|
#{root ext} splitting only a .exe suffix - dotted tcl patchlevels make |
|
#[file rootname] wrong for extensionless (unix) artifact names |
|
#(tclsh9.0.5-punk-r1 would truncate at the last version dot) |
|
if {[string match -nocase "*.exe" $name]} { |
|
return [list [string range $name 0 end-4] .exe] |
|
} |
|
return [list $name ""] |
|
} |
|
|
|
file mkdir $opt(-outdir) |
|
set built [clock format [clock seconds] -format %Y-%m-%dT%H:%M:%SZ -timezone :UTC] |
|
set sha1lines {} |
|
set emitted {} |
|
|
|
foreach {variant kitpath} $opt(-kits) { |
|
set kitpath [file normalize $kitpath] |
|
if {![file exists $kitpath]} {fail "kit exe not found: $kitpath"} |
|
set working [file tail $kitpath] |
|
lassign [exe_split $working] wroot wext |
|
set artifact "$wroot-r$opt(-rev)$wext" |
|
set dest [file join $opt(-outdir) $artifact] |
|
file delete -force $dest |
|
file copy $kitpath $dest |
|
set sha1 [sha1::sha1 -hex -file $dest] |
|
set size [file size $dest] |
|
lappend sha1lines "$sha1 *$artifact" |
|
|
|
set components $opt(-components) |
|
if {$variant eq "punk-bi"} {lappend components {*}$opt(-bicomponents)} |
|
set batteries {} |
|
foreach {n v} $components {lappend batteries [toml_str "$n $v"]} |
|
|
|
set m {} |
|
lappend m "#punkshell runtime artifact metadata (G-103) - generated by family_artifacts.tcl" |
|
lappend m "\[artifact\]" |
|
lappend m "name = [toml_str $artifact]" |
|
lappend m "class = \"runtime\"" |
|
lappend m "variant = [toml_str $variant]" |
|
lappend m "working_name = [toml_str $working]" |
|
lappend m "revision = $opt(-rev)" |
|
lappend m "target = [toml_str $opt(-target)]" |
|
lappend m "sha1 = [toml_str $sha1]" |
|
lappend m "size = $size" |
|
lappend m "built = [toml_str $built]" |
|
lappend m "" |
|
lappend m "\[runtime\]" |
|
lappend m "tcl_patchlevel = [toml_str $opt(-tclpatch)]" |
|
set pr [expr {$variant ne "plain"}] |
|
lappend m "piperepl = [expr {$pr ? "true" : "false"}]" |
|
if {$pr} { |
|
lappend m "piperepl_default = \"on\"" |
|
lappend m "piperepl_opt_out = \"TCLSH_PIPEREPL=0\"" |
|
} |
|
lappend m "attached_batteries = \[[join $batteries {, }]\]" |
|
lappend m "" |
|
lappend m "\[provenance\]" |
|
lappend m "suite = [toml_str $opt(-suite)]" |
|
lappend m "toolchain = [toml_str "zig $opt(-zig)"]" |
|
lappend m "optimize = [toml_str $opt(-optimize)]" |
|
foreach {n uuid} $opt(-provenance) { |
|
lappend m "${n}_checkout = [toml_str $uuid]" |
|
} |
|
#G-107 evidence summaries available at emission time (result lines only; the |
|
#full line-record summaries stay the canonical evidence artifacts) |
|
if {$opt(-testreports) ne "" && [file isdirectory $opt(-testreports)]} { |
|
set tlines {} |
|
foreach sf [lsort [glob -nocomplain -directory $opt(-testreports) *.summary]] { |
|
set rec [dict create] |
|
set f [open $sf r] |
|
foreach line [split [read $f] \n] { |
|
set line [string trim $line] |
|
if {$line eq "" || [string index $line 0] eq "#"} continue |
|
if {[catch {llength $line} n] || $n < 2} continue |
|
dict set rec [lindex $line 0] [lrange $line 1 end] |
|
} |
|
close $f |
|
if {![dict exists $rec library] || ![dict exists $rec result]} continue |
|
set lib [dict get $rec library] |
|
set parts [list "result=[dict get $rec result]"] |
|
foreach fkey {mode total passed skipped failed} { |
|
if {[dict exists $rec $fkey]} {lappend parts "$fkey=[dict get $rec $fkey]"} |
|
} |
|
lappend tlines "$lib = [toml_str [join $parts { }]]" |
|
} |
|
if {[llength $tlines]} { |
|
lappend m "" |
|
lappend m "\[tests\]" |
|
lappend m {*}$tlines |
|
} |
|
} |
|
set mf [file join $opt(-outdir) "[lindex [exe_split $artifact] 0].toml"] |
|
set f [open $mf w] |
|
fconfigure $f -translation lf |
|
puts $f [join $m \n] |
|
close $f |
|
lappend emitted "$variant -> $artifact" |
|
note "emitted $artifact (sha1 $sha1, [expr {$size/1024}] KB) + [file tail $mf]" |
|
} |
|
|
|
set f [open [file join $opt(-outdir) sha1sums.txt] w] |
|
fconfigure $f -translation lf |
|
puts $f [join $sha1lines \n] |
|
close $f |
|
note "sha1sums.txt written ([llength $sha1lines] artifacts)" |
|
puts "family_artifacts OK: [join $emitted {; }] -> $opt(-outdir)" |
|
exit 0
|
|
|