Browse Source
Stage 4 - documented overlay semantics implemented (commandset::layout 0.2.0): layout_materialize resolves a layout to its overlay chain (vendor tier then custom tier per store+vendor, <name>@<base> derived-layout folders expanding their base chain first, cycle-guarded) and composes multi-folder chains into a disposable staging dir applying <item>.anti deletion markers (zero-byte marker files recommended - committable, unlike the originally documented empty marker folders, which are also accepted). Single-folder chains with no markers are used in place, so punk.project (store and zipfs modpod) behaviour is unchanged. project.new (commandset::project 0.4.0) copies from the materialized path and the layout listing/scanning commands show the effective merged view. Fixtures: punk.othersample is now a live derived layout (new custom-deck fauxlink ref + .gitignore.anti demo marker); extra.txt/store README rewritten to the implemented semantics. New tcltest suite src/tests/modules/punk/mix/testsuites/layout/materialize.test (20 tests). Anti markers deliberately stay a plain filename convention rather than tag-bearing fauxlinks: a fauxlink is a reference tooling may follow (fcat auto-follows), a marker is a tombstone with no target. Stage 5 - retirements and generated-project version seeding: - The empty unimplemented child-side src/PROJECT_LAYOUTS_CREATE_FROM_... marker folder is deleted along with its project.new and make.tcl sync exclusions. - The vendor/custom x _project matrix collapses for layouts: custom/<vendor> is the one override level; _project folders join no overlay chain (the pseudo-vendor remains for decktemplates module/utility templates only). - project.new seeds generated projects post-materialization (only-if-missing, never from payload): punkproject.toml ([project] name + 0.1.0), a matching CHANGELOG.md ## [0.1.0] header, and punkorigin.toml - an interim generation provenance baseline (utc, layout name + resolved store target, punk::mix::templates version, punkshell version when derivable, origin path) for the G-027 pull design to adopt (noted in G-027). Also: script-mode/programmatic project.new robustness (explicit shellrun require; punk::mix::util askuser/do_in_path/foreach-file fully qualified - the util:: shorthand exists only after cli commandset import). Includes the concurrently-landed (other session, previously uncommitted) 0.3.1 early module-name validation fix in project.new, shipped within the 0.4.0 bump. G-087 flipped achieved 2026-07-19 (verification in the detail file; archive move follows in the next commit). punkshell 0.16.0 -> 0.17.0. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
19 changed files with 1193 additions and 100 deletions
@ -1,4 +1,4 @@
|
||||
[project] |
||||
name = "punkshell" |
||||
version = "0.16.0" |
||||
version = "0.17.0" |
||||
license = "BSD-2-Clause" |
||||
|
||||
@ -1,4 +1,6 @@
|
||||
0.1.1 |
||||
0.2.0 |
||||
#First line must be a semantic version number |
||||
#all other lines are ignored. |
||||
#0.2.0 - G-087 stage 4: overlay merge primitive in lib - layout_materialize (entry point returning the effective content folder; fast path returns the store folder untouched for single-source chains with no .anti markers), layout_resolve_chain (vendor-then-custom tier chain with <name>@<base> derived-layout expansion, cycle-guarded), layout_stage_chain (staging-dir composition applying .anti deletion markers; #layout_staging marker guards against clobbering non-staging dirs), plus private helpers _dir_entries/_find_anti_relpaths/_merge_copy_into. The _project pseudo-vendor participates in no chain (retired for layouts - G-087 stage 5 decision). |
||||
#0.2.0 - new lib::layoutfolder_scan_for_template_files (path-based core of layout_scan_for_template_files); layout_scan_for_template_files, layout_all_files and templatefiles.relative now operate on the overlay-materialized content rather than the primary store folder only (the staging marker file is excluded from listings/scans). |
||||
#0.1.1 - fix: no-handler warning paths in collection::references_as_dict and lib::layouts_dict used 'put' instead of 'puts' and then errored on an unset dict variable; they now warn correctly and return an empty dict. references_as_dict warning message no longer misattributes itself to layouts_dict. |
||||
|
||||
@ -1,11 +1,33 @@
|
||||
example of an additional file added to a vendor layout |
||||
|
||||
All files/folders from the vendor/layoutname tree are included unless they are over-ridden by a file of the same name in custom/vendor/layoutname or unless there is a file/folder of the same name except suffixed with .anti |
||||
|
||||
For example, to completely replace src/modules in a vendor layout; |
||||
create an empty custom/vendor/layoutname/src/modules.anti folder |
||||
Then create a custom/vendor/layoutname/src/modules folder with your custom contents. |
||||
|
||||
To just override a single module in vendor/layoutname/src/modules - just put a replacement module with the same name (or named with a later version) in custom/vendor/layoutname/src/modules. |
||||
All the existing modules from vendor/layoutname/src/modules will then be present in the resulting layout along with your modified/new module. |
||||
|
||||
example of an additional file added to a vendor layout |
||||
|
||||
Overlay/merge semantics (implemented by punk::mix::commandset::layout::lib::layout_materialize, |
||||
used by dev project.new - G-087 stage 4): |
||||
|
||||
All files/folders from the vendor/<vendorname>/<layoutname> tree are included unless they are |
||||
over-ridden by a file of the same name in custom/<vendorname>/<layoutname> or deleted by a |
||||
marker of the same name suffixed with .anti. Same-name folders merge recursively; the layer |
||||
order is vendor then custom, so custom content wins. |
||||
|
||||
.anti markers: |
||||
- A zero-byte FILE named <item>.anti is the recommended marker form (empty folders cannot be |
||||
committed to git/fossil). A marker FOLDER named <item>.anti is also accepted, matching the |
||||
originally documented form. Either deletes <item> - file or folder - as contributed by |
||||
lower layers, and the marker itself never appears in the composed layout. |
||||
- To completely replace src/modules from a vendor layout: put a zero-byte |
||||
custom/<vendorname>/<layoutname>/src/modules.anti marker file alongside a |
||||
custom/<vendorname>/<layoutname>/src/modules folder with your custom contents. The marker |
||||
is applied before the same layer's own content is copied. |
||||
- To just override a single module in vendor/<layoutname>/src/modules - put a replacement |
||||
module with the same name in custom/<vendorname>/<layoutname>/src/modules. All the existing |
||||
modules from the vendor layer will then be present in the resulting layout along with your |
||||
modified/new module. |
||||
|
||||
Derived layouts: |
||||
- A folder named <newname>@<baselayoutname> presents as its own layout (given a layout ref |
||||
naming it). Its content starts from the base layout's full overlay chain with the derived |
||||
folder's own content (and .anti markers) applied on top. See ../othersample@sample-0.1 for |
||||
a working example (it also demonstrates a .anti deletion). |
||||
|
||||
Composition happens in a disposable staging directory at generation time - the store folders |
||||
are never modified, and a layout whose chain is a single folder with no .anti markers is used |
||||
in place without any copying. |
||||
|
||||
@ -0,0 +1,370 @@
|
||||
package require tcltest |
||||
|
||||
package require punk::mix::commandset::layout |
||||
|
||||
#added 2026-07-19 (agent, G-087) - stage 4 overlay merge primitive: layout_resolve_chain / |
||||
#layout_stage_chain / layout_materialize in punk::mix::commandset::layout::lib, exercised |
||||
#against synthetic stores (no punk.templates capability context needed - layout_materialize |
||||
#is fed -layoutinfo directly). The repo fixtures (vendor/custom punk/sample-0.1 + |
||||
#othersample@sample-0.1) are exercised end-to-end via dev project.new - see the G-087 detail |
||||
#file verification records. |
||||
|
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
|
||||
variable BASE [makeDirectory g087_materialize] |
||||
|
||||
proc fwrite {path content} { |
||||
file mkdir [file dirname $path] |
||||
set fd [open $path w] |
||||
fconfigure $fd -translation lf |
||||
puts -nonewline $fd $content |
||||
close $fd |
||||
} |
||||
proc fread {path} { |
||||
set fd [open $path r] |
||||
set data [read $fd] |
||||
close $fd |
||||
return $data |
||||
} |
||||
#relative sorted listing of all files (not dirs) below a folder - forward slashes |
||||
proc treefiles {folder} { |
||||
set files [list] |
||||
set queue [list ""] |
||||
while {[llength $queue]} { |
||||
set rel [lindex $queue 0] |
||||
set queue [lrange $queue 1 end] |
||||
set here [expr {$rel eq "" ? $folder : [file join $folder $rel]}] |
||||
foreach entry [lsort -unique [glob -nocomplain -dir $here -tails * .*]] { |
||||
if {$entry in {. ..}} {continue} |
||||
set relentry [expr {$rel eq "" ? $entry : "$rel/$entry"}] |
||||
if {[file isdirectory [file join $here $entry]]} { |
||||
lappend queue $relentry |
||||
} else { |
||||
lappend files $relentry |
||||
} |
||||
} |
||||
} |
||||
return [lsort $files] |
||||
} |
||||
#build a fresh synthetic store under $BASE/<name> and return its path |
||||
proc make_store {name} { |
||||
variable BASE |
||||
set store [file join $BASE $name] |
||||
file delete -force $store |
||||
file mkdir $store |
||||
return $store |
||||
} |
||||
|
||||
variable common { |
||||
set result "" |
||||
} |
||||
|
||||
# -- --- --- layout_resolve_chain --- --- -- |
||||
|
||||
test resolve_chain_vendor_only {single vendor folder yields single-entry chain}\ |
||||
-setup $common -body { |
||||
set store [make_store s1] |
||||
file mkdir $store/vendor/punk/basic |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk basic] |
||||
lappend result [llength $chain] |
||||
lappend result [expr {[lindex $chain 0] eq [file join $store vendor punk basic]}] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 1 1] |
||||
|
||||
test resolve_chain_custom_over_vendor {vendor tier precedes custom tier in chain order}\ |
||||
-setup $common -body { |
||||
set store [make_store s2] |
||||
file mkdir $store/vendor/punk/sample $store/custom/punk/sample |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
lappend result [llength $chain] |
||||
lappend result [expr {[lindex $chain 0] eq [file join $store vendor punk sample]}] |
||||
lappend result [expr {[lindex $chain 1] eq [file join $store custom punk sample]}] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 2 1 1] |
||||
|
||||
test resolve_chain_derived {name@base folder expands base chain first, derived folder last}\ |
||||
-setup $common -body { |
||||
set store [make_store s3] |
||||
file mkdir $store/vendor/punk/sample $store/custom/punk/sample "$store/custom/punk/other@sample" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk other@sample] |
||||
lappend result [llength $chain] |
||||
lappend result [expr {[lindex $chain 0] eq [file join $store vendor punk sample]}] |
||||
lappend result [expr {[lindex $chain 1] eq [file join $store custom punk sample]}] |
||||
lappend result [expr {[lindex $chain 2] eq [file join $store custom punk other@sample]}] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 3 1 1 1] |
||||
|
||||
test resolve_chain_recursive_base {derivation chains recurse (a@b where b is b@c)}\ |
||||
-setup $common -body { |
||||
set store [make_store s4] |
||||
file mkdir $store/vendor/punk/c "$store/custom/punk/b@c" "$store/custom/punk/a@b" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk a@b] |
||||
lappend result [llength $chain] |
||||
lappend result [expr {[lindex $chain 0] eq [file join $store vendor punk c]}] |
||||
lappend result [expr {[lindex $chain 1] eq [file join $store custom punk b@c]}] |
||||
lappend result [expr {[lindex $chain 2] eq [file join $store custom punk a@b]}] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 3 1 1 1] |
||||
|
||||
test resolve_chain_cycle {derivation cycle terminates with each folder listed once}\ |
||||
-setup $common -body { |
||||
set store [make_store s5] |
||||
file mkdir "$store/custom/punk/a@b" "$store/custom/punk/b@a" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk a@b] |
||||
#cycle guard stops the b->a expansion; both folders appear exactly once |
||||
lappend result [llength $chain] |
||||
lappend result [llength [lsort -unique $chain]] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 2 2] |
||||
|
||||
test resolve_chain_missing {nonexistent layout name yields empty chain}\ |
||||
-setup $common -body { |
||||
set store [make_store s6] |
||||
file mkdir $store/vendor/punk |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk nosuch] |
||||
llength $chain |
||||
}\ |
||||
-cleanup {}\ |
||||
-result 0 |
||||
|
||||
# -- --- --- layout_stage_chain --- --- -- |
||||
|
||||
test stage_override_and_add {custom same-name file wins, extra file added, folders merge}\ |
||||
-setup $common -body { |
||||
set store [make_store s7] |
||||
fwrite $store/vendor/punk/sample/README.md "vendor-readme" |
||||
fwrite $store/vendor/punk/sample/src/modules/mod.txt "vendor-mod" |
||||
fwrite $store/custom/punk/sample/README.md "custom-readme" |
||||
fwrite $store/custom/punk/sample/extra.txt "extra" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
set sres [punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging] |
||||
lappend result [fread $staging/README.md] |
||||
lappend result [fread $staging/extra.txt] |
||||
lappend result [fread $staging/src/modules/mod.txt] |
||||
lappend result [dict get $sres copied] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list custom-readme extra vendor-mod 4] |
||||
|
||||
test stage_anti_file_deletes_file {zero-byte <name>.anti file marker deletes lower-layer file}\ |
||||
-setup $common -body { |
||||
set store [make_store s8] |
||||
fwrite $store/vendor/punk/sample/.gitignore "ignore-content" |
||||
fwrite $store/vendor/punk/sample/keep.txt "keep" |
||||
file mkdir $store/custom/punk/sample |
||||
fwrite $store/custom/punk/sample/.gitignore.anti "" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
set sres [punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging] |
||||
lappend result [file exists $staging/.gitignore] |
||||
lappend result [file exists $staging/keep.txt] |
||||
lappend result [dict get $sres deletions] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 1 .gitignore] |
||||
|
||||
test stage_anti_markers_never_copied {no .anti entries appear in the composed staging}\ |
||||
-setup $common -body { |
||||
set store [make_store s9] |
||||
fwrite $store/vendor/punk/sample/a.txt "a" |
||||
fwrite $store/custom/punk/sample/a.txt.anti "" |
||||
fwrite $store/custom/punk/sample/sub/b.txt.anti "" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
set antis [list] |
||||
foreach f [treefiles $staging] { |
||||
if {[string match *.anti $f]} {lappend antis $f} |
||||
} |
||||
lappend result $antis |
||||
lappend result [file exists $staging/a.txt] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list {} 0] |
||||
|
||||
test stage_anti_folder_replace {folder.anti marker plus replacement folder in same layer fully replaces}\ |
||||
-setup $common -body { |
||||
set store [make_store s10] |
||||
fwrite $store/vendor/punk/sample/src/modules/old1.txt "old1" |
||||
fwrite $store/vendor/punk/sample/src/modules/old2.txt "old2" |
||||
#marker as zero-byte FILE (recommended - committable), replacement folder alongside |
||||
fwrite $store/custom/punk/sample/src/modules.anti "" |
||||
fwrite $store/custom/punk/sample/src/modules/new.txt "new" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
lappend result [treefiles $staging/src/modules] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list new.txt] |
||||
|
||||
test stage_anti_dir_marker_form {a directory named <name>.anti also acts as a deletion marker}\ |
||||
-setup $common -body { |
||||
set store [make_store s11] |
||||
fwrite $store/vendor/punk/sample/src/modules/old.txt "old" |
||||
file mkdir $store/custom/punk/sample/src/modules.anti |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
lappend result [file exists $staging/src/modules] |
||||
lappend result [file exists $staging/src/modules.anti] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 0] |
||||
|
||||
test stage_type_conflicts {higher-layer entry wins on file/folder type conflicts}\ |
||||
-setup $common -body { |
||||
set store [make_store s12] |
||||
fwrite $store/vendor/punk/sample/thing "vendor-file" |
||||
fwrite $store/vendor/punk/sample/other/nested.txt "vendor-nested" |
||||
fwrite $store/custom/punk/sample/thing/inner.txt "custom-inner" |
||||
fwrite $store/custom/punk/sample/other "custom-file" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
lappend result [file isdirectory $staging/thing] |
||||
lappend result [fread $staging/thing/inner.txt] |
||||
lappend result [expr {![file isdirectory $staging/other]}] |
||||
lappend result [fread $staging/other] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 1 custom-inner 1 custom-file] |
||||
|
||||
test stage_empty_dir_preserved {empty folders in a layer are created in staging}\ |
||||
-setup $common -body { |
||||
set store [make_store s13] |
||||
file mkdir $store/vendor/punk/sample/emptydir |
||||
fwrite $store/vendor/punk/sample/a.txt "a" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
file isdirectory $staging/emptydir |
||||
}\ |
||||
-cleanup {}\ |
||||
-result 1 |
||||
|
||||
test stage_refuse_clobber {existing non-empty dir without staging marker is refused}\ |
||||
-setup $common -body { |
||||
set store [make_store s14] |
||||
fwrite $store/vendor/punk/sample/a.txt "a" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store precious] |
||||
fwrite $staging/important.txt "do-not-delete" |
||||
set code [catch {punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging} emsg] |
||||
lappend result $code |
||||
lappend result [file exists $staging/important.txt] |
||||
lappend result [string match "*refusing to delete*" $emsg] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 1 1 1] |
||||
|
||||
test stage_restage_over_marker {a previous staging composition (marker present) is replaced}\ |
||||
-setup $common -body { |
||||
set store [make_store s15] |
||||
fwrite $store/vendor/punk/sample/a.txt "one" |
||||
set chain [punk::mix::commandset::layout::lib::layout_resolve_chain $store punk sample] |
||||
set staging [file join $store staging] |
||||
punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging |
||||
fwrite $store/vendor/punk/sample/b.txt "two" |
||||
set code [catch {punk::mix::commandset::layout::lib::layout_stage_chain $chain $staging} sres] |
||||
lappend result $code |
||||
lappend result [file exists $staging/a.txt] |
||||
lappend result [file exists $staging/b.txt] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 1 1] |
||||
|
||||
# -- --- --- layout_materialize --- --- -- |
||||
|
||||
test materialize_fastpath {single-folder chain with no .anti markers returns the store folder unstaged}\ |
||||
-setup $common -body { |
||||
set store [make_store s16] |
||||
fwrite $store/vendor/punk/solo/a.txt "a" |
||||
set linfo [list path [file join $store vendor punk solo] basefolder $store sourceinfo {}] |
||||
set mat [punk::mix::commandset::layout::lib::layout_materialize punk.solo -layoutinfo $linfo] |
||||
lappend result [dict get $mat staged] |
||||
lappend result [expr {[dict get $mat path] eq [file join $store vendor punk solo]}] |
||||
lappend result [llength [dict get $mat chain]] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 1 1] |
||||
|
||||
test materialize_single_with_antis {a single folder containing .anti markers is staged with markers stripped}\ |
||||
-setup $common -body { |
||||
set store [make_store s17] |
||||
fwrite $store/vendor/punk/solo/a.txt "a" |
||||
fwrite $store/vendor/punk/solo/ghost.txt.anti "" |
||||
set linfo [list path [file join $store vendor punk solo] basefolder $store sourceinfo {}] |
||||
set staging [file join $store staging] |
||||
set mat [punk::mix::commandset::layout::lib::layout_materialize punk.solo -layoutinfo $linfo -stagingdir $staging] |
||||
lappend result [dict get $mat staged] |
||||
lappend result [file exists [dict get $mat path]/a.txt] |
||||
lappend result [file exists [dict get $mat path]/ghost.txt.anti] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 1 1 0] |
||||
|
||||
test materialize_opaque_path {a layout folder outside the tier/vendor store shape stays an opaque single-folder chain}\ |
||||
-setup $common -body { |
||||
set store [make_store s18] |
||||
fwrite $store/somewhere/deep/layoutx/a.txt "a" |
||||
set linfo [list path [file join $store somewhere deep layoutx] basefolder $store sourceinfo {}] |
||||
set mat [punk::mix::commandset::layout::lib::layout_materialize punk.layoutx -layoutinfo $linfo] |
||||
lappend result [dict get $mat staged] |
||||
lappend result [llength [dict get $mat chain]] |
||||
lappend result [expr {[dict get $mat path] eq [file join $store somewhere deep layoutx]}] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 1 1] |
||||
|
||||
test materialize_project_pseudovendor_opaque {_project pseudo-vendor folders take no part in overlay chains}\ |
||||
-setup $common -body { |
||||
set store [make_store s19] |
||||
fwrite $store/vendor/_project/sample/a.txt "proj-a" |
||||
fwrite $store/custom/_project/sample/a.txt "proj-custom-a" |
||||
set linfo [list path [file join $store vendor _project sample] basefolder $store sourceinfo {}] |
||||
set mat [punk::mix::commandset::layout::lib::layout_materialize sample -layoutinfo $linfo] |
||||
lappend result [dict get $mat staged] |
||||
lappend result [llength [dict get $mat chain]] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 0 1] |
||||
|
||||
test materialize_derived_full {derived layout materializes base chain content with overrides and .anti deletions}\ |
||||
-setup $common -body { |
||||
set store [make_store s20] |
||||
fwrite $store/vendor/punk/sample/README.md "vendor-readme" |
||||
fwrite $store/vendor/punk/sample/.gitignore "gitignore" |
||||
fwrite $store/vendor/punk/sample/src/modules/README.md "modules-readme" |
||||
fwrite $store/custom/punk/sample/README.md "custom-readme" |
||||
fwrite $store/custom/punk/sample/extra.txt "extra" |
||||
fwrite "$store/custom/punk/other@sample/README.md" "derived-readme" |
||||
fwrite "$store/custom/punk/other@sample/.gitignore.anti" "" |
||||
set linfo [list path [file join $store custom punk other@sample] basefolder $store sourceinfo {}] |
||||
set staging [file join $store staging] |
||||
set mat [punk::mix::commandset::layout::lib::layout_materialize punk.other -layoutinfo $linfo -stagingdir $staging] |
||||
set effective [dict get $mat path] |
||||
lappend result [dict get $mat staged] |
||||
lappend result [llength [dict get $mat chain]] |
||||
lappend result [fread $effective/README.md] |
||||
lappend result [fread $effective/extra.txt] |
||||
lappend result [fread $effective/src/modules/README.md] |
||||
lappend result [file exists $effective/.gitignore] |
||||
lappend result [dict get $mat deletions] |
||||
}\ |
||||
-cleanup {}\ |
||||
-result [list 1 3 derived-readme extra modules-readme 0 .gitignore] |
||||
|
||||
variable BASE |
||||
file delete -force $BASE |
||||
|
||||
cleanupTests |
||||
} |
||||
namespace delete ::testspace |
||||
Loading…
Reference in new issue