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.
 
 
 
 
 
 

306 lines
11 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 0.1.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 *
namespace eval argdoc {
proc layout_names {} {
if {[catch {punk::mix::commandset::layout::lib::layouts_dict *} ldict]} {
#REVIEW
return "punk.project"
} else {
return [dict keys $ldict]
}
}
}
#per layout functions
punk::args::define {
@dynamic
@id -id ::punk::mix::commandset::layout::files
@cmd -name punk::mix::commandset::layout::files -synopsis\
"list files in project layout"\
-help\
""
-datetime -default "%Y-%m-%dT%H:%M:%S" -help\
"Datetime format for mtime. Use empty string for no datetime output"
@values -min 1 -max 1
layout -type string -choices {${[punk::mix::commandset::layout::argdoc::layout_names]}}
}
proc files {args} {
set argd [punk::args::parse $args withid ::punk::mix::commandset::layout::files]
set layout [dict get $argd values layout]
set dtformat [dict get $argd opts -datetime]
set allfiles [lib::layout_all_files $layout]
if {$dtformat eq ""} {
return [join $allfiles \n]
} else {
set out ""
foreach f $allfiles {
set mtime [dict get [file stat $f] mtime]
append out "$f [clock format $mtime -format $dtformat]" \n
}
set out [string range $out 0 end-1]
return $out
}
}
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]
}
punk::args::define {
@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
}
proc _default {args} {
punk::args::parse $args withid ::punk::mix::commandset::layout::collection::_default
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} {
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 0.1.0
}]
return