274 lines
10 KiB

# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use 'pmix make' or src/make.tcl to update from <pkg>-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 <unspecified>
# @@ 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