# -*- tcl -*- # Maintenance Instruction: leave the 999999.xxx.x as is and use 'pmix make' or src/make.tcl to update from -buildversion.txt # # Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem. # Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository. # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ # (C) 2023 # # @@ Meta Begin # Application punk::mix::commandset::layout 999999.0a1.0 # Meta platform tcl # Meta license # @@ Meta End # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ ## Requirements ##e.g package require frobz package require punk::args #sort of a circular dependency when commandset loaded by punk::mix::cli - that's ok, but this could theoretically be loaded by another cli and with another base package require punk::mix package require punk::mix::base package require punk::lib package require textblock # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ namespace eval punk::mix::commandset::layout { namespace export * #per layout functions proc files {{layout ""}} { set argd [punk::args::get_dict { @id -id ::punk::mix::commandset::layout::files @values -min 1 -max 1 layout -type string -minsize 1 } [list $layout]] set allfiles [lib::layout_all_files $layout] return [join $allfiles \n] } proc templatefiles {layout} { set templatefiles_and_tags [lib::layout_scan_for_template_files $layout] set flatlist [punk::lib::lmapflat v $templatefiles_and_tags {lrange $v 0 end}] #return [join $templatefiles \n] textblock::list_as_table -header {"File with tags found" "Tags"} -columns 2 $flatlist } proc templatefiles.relative {layout} { set layoutdict [lib::layouts_dict] if {![dict exists $layoutdict $layout]} { puts stderr "layout '$layout' not found." return } set layoutinfo [dict get $layoutdict $layout] set layoutfolder [dict get $layoutinfo path] set stripprefix [file normalize $layoutfolder] set templatefiles_and_tags [lib::layout_scan_for_template_files $layout] set flatlist [list] foreach entry $templatefiles_and_tags { lassign $entry templatefullpath tags lappend flatlist [punk::repo::path_strip_alreadynormalized_prefixdepth $templatefullpath $stripprefix] $tags } #return [join $tails \n] textblock::list_as_table -header {"File with tags found" "Tags"} -columns 2 $flatlist } #layout collection functions - to be imported with punk::overlay::import_commandset separately namespace eval collection { namespace export * proc _defaultx {{glob {}}} { if {![string length $glob]} { set glob * } set layouts [list] set layoutdict [punk::cap::call_handler punk.templates get_itemdict_projectlayouts] #set tplfolderdict [punk::mix::base::lib::get_template_basefolders] dict for {layoutname layoutinfo} $layoutdict { lappend layouts [list $layoutname $layoutinfo] } #return [join [lsort -index 0 $layouts] \n] return [join $layouts \n] } proc _default {args} { punk::args::get_dict [subst { @id -id ::punk::mix::commandset::layout::collection::_default @cmd -name ::punk::mix::commandset::layout::collection::_default -startdir -type string -not -type string -multiple 1 globsearches -default * -multiple 1 }] $args set tdict_low_to_high [as_dict {*}$args] #convert to screen order - with higher priority at the top set tdict [dict create] foreach k [lreverse [dict keys $tdict_low_to_high]] { dict set tdict $k [dict get $tdict_low_to_high $k] } package require overtype package require textblock #set pathinfolist [dict values $tdict] #set paths [lsearch -all -inline -index 1 -subindices $pathinfolist *] ;#relies on first key of templates_dict being path set names [dict keys $tdict] set paths [list] set pathtypes [list] dict for {nm tinfo} $tdict { lappend paths [dict get $tinfo path] lappend pathtypes [dict get $tinfo sourceinfo pathtype] } set title(path) "Path" set title(pathtype) "[a+ green]Path Type[a]" set title(name) "Layout Name" set data [list] foreach n $names pt $pathtypes p $paths { lappend data $n $pt $p } set table [textblock::list_as_table -columns 3 -header [list $title(name) $title(pathtype) $title(path)] $data] return $table } proc references {args} { set tdict_low_to_high [references_as_dict {*}$args] #convert to screen order - with higher priority at the top set tdict [dict create] foreach k [lreverse [dict keys $tdict_low_to_high]] { dict set tdict $k [dict get $tdict_low_to_high $k] } package require overtype package require textblock #set pathinfolist [dict values $tdict] #set paths [lsearch -all -inline -index 1 -subindices $pathinfolist *] ;#relies on first key of templates_dict being path set names [dict keys $tdict] set paths [list] set pathtypes [list] dict for {nm tinfo} $tdict { lappend paths [dict get $tinfo path] lappend pathtypes [dict get $tinfo sourceinfo pathtype] } set title(name) "Layout Name" set title(pathtype) "[a+ green]Path Type[a]" set title(path) "Path" set data [list] foreach n $names pt $pathtypes p $paths { #append table "[textblock::join -- [overtype::left $col(name) $n] $vsep [overtype::left $col(pathtype) $pt] $vsep [overtype::left $col(path) $p]]" \n lappend data $n $pt $p } set table [textblock::list_as_table -columns 3 -header [list $title(name) $title(pathtype) $title(path)] $data] return $table } proc as_dict {args} { tailcall punk::mix::commandset::layout::lib::layouts_dict {*}$args } proc references_as_dict {args} { package require punk::cap if {[punk::cap::capability_has_handler punk.templates]} { set ref_dict [punk::cap::call_handler punk.templates get_itemdict_projectlayoutrefs {*}$args] } else { put stderr "commandset::layout::lib::layouts_dict WARNING - no handler available for the 'punk.templates' capability - template providers will be unable to provide template locations" } return $ref_dict } } namespace eval lib { proc layouts_dict {args} { package require punk::cap if {[punk::cap::capability_has_handler punk.templates]} { set layout_dict [punk::cap::call_handler punk.templates get_itemdict_projectlayouts {*}$args] } else { put stderr "commandset::layout::lib::layouts_dict WARNING - no handler available for the 'punk.templates' capability - template providers will be unable to provide template locations" } return $layout_dict } proc layout_all_files {layout} { #todo - allow versionless layout name to pick highest version found set layoutdict [layouts_dict] if {![dict exists $layoutdict $layout]} { puts stderr "layout '$layout' not found." return } set layoutinfo [dict get $layoutdict $layout] set layoutfolder [dict get $layoutinfo path] if {![file isdirectory $layoutfolder]} { puts stderr "layout '$layout' points to path $layoutfolder - but it doesn't seem to exist" } set file_list [list] util::foreach-file $layoutfolder path { lappend file_list $path } return $file_list } # proc layout_scan_for_template_files {layout {tags {}}} { #todo JMN set layoutdict [layouts_dict] if {![dict exists $layoutdict $layout]} { puts stderr "layout '$layout' not found." return } set layoutinfo [dict get $layoutdict $layout] set layoutfolder [dict get $layoutinfo path] #use last matching layout found. review silent if multiple? if {![llength $tags]} { #todo - get standard tags from somewhere set tagnames [list project] foreach tn $tagnames { lappend tags [string cat % $tn %] ;#make sure actual tag literal doesn't appear in this source file } } set file_list [list] util::foreach-file $layoutfolder path { set fd [open $path r] fconfigure $fd -translation binary set data [read $fd] close $fd set found_tags [list] foreach tag $tags tn $tagnames { if {[string match "*$tag*" $data]} { lappend found_tags $tn } } if {[llength $found_tags]} { lappend file_list [list $path $found_tags] } } return $file_list } } } # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ ## Ready package provide punk::mix::commandset::layout [namespace eval punk::mix::commandset::layout { variable version set version 999999.0a1.0 }] return