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.
161 lines
5.7 KiB
161 lines
5.7 KiB
#punkapps app manager |
|
# deck cli |
|
|
|
namespace eval punk::mod::cli { |
|
namespace export help list run |
|
namespace ensemble create |
|
|
|
# namespace ensemble configure [namespace current] -unknown punk::mod::cli::_unknown |
|
if 0 { |
|
proc _unknown {ns args} { |
|
puts stderr "punk::mod::cli::_unknown '$ns' '$args'" |
|
puts stderr "punk::mod::cli::help $args" |
|
puts stderr "arglen:[llength $args]" |
|
punk::mod::cli::help {*}$args |
|
} |
|
} |
|
|
|
#cli must have _init method - usually used to load commandsets lazily |
|
# |
|
variable initialised 0 |
|
proc _init {args} { |
|
variable initialised |
|
if {$initialised} { |
|
return |
|
} |
|
#... |
|
set initialised 1 |
|
} |
|
|
|
proc help {args} { |
|
set basehelp [punk::mix::base help {*}$args] |
|
#namespace export |
|
return $basehelp |
|
} |
|
proc getraw {appname} { |
|
set app_folders [punk::config::configure running apps] |
|
#todo search each app folder |
|
set bases [::list] |
|
set versions [::list] |
|
set mains [::list] |
|
set appinfo [::list bases {} mains {} versions {}] |
|
|
|
foreach containerfolder $app_folders { |
|
lappend bases $containerfolder |
|
if {[file exists $containerfolder]} { |
|
if {[file exists $containerfolder/$appname/main.tcl]} { |
|
#exact match - only return info for the exact one specified |
|
set namematches $appname |
|
set parts [split $appname -] |
|
} else { |
|
set namematches [glob -nocomplain -dir $containerfolder -type d -tail ${appname}-*] |
|
set namematches [lsort $namematches] ;#todo - -ascii? -dictionary? natsort? |
|
} |
|
foreach nm $namematches { |
|
set mainfile $containerfolder/$nm/main.tcl |
|
set parts [split $nm -] |
|
if {[llength $parts] == 1} { |
|
set ver "" |
|
} else { |
|
set ver [lindex $parts end] |
|
} |
|
if {$ver ni $versions} { |
|
lappend versions $ver |
|
lappend mains $ver $mainfile |
|
} else { |
|
puts stderr "punk::apps::app version '$ver' of app '$appname' already encountered at $mainfile. (will use earliest encountered in running-config apps and ignore others of same version)" |
|
} |
|
} |
|
} else { |
|
puts stderr "punk::apps::app missing apps_folder:'$containerfolder' Ensure apps_folder is set in punk::config" |
|
} |
|
} |
|
dict set appinfo versions $versions |
|
#todo - natsort! |
|
set sorted_versions [lsort $versions] |
|
set latest [lindex $sorted_versions 0] |
|
if {$latest eq "" && [llength $sorted_versions] > 1} { |
|
set latest [lindex $sorted_versions 1] |
|
} |
|
dict set appinfo latest $latest |
|
|
|
dict set appinfo bases $bases |
|
dict set appinfo mains $mains |
|
return $appinfo |
|
} |
|
|
|
proc list {{glob *}} { |
|
set apps_folder [punk::config::configure running apps] |
|
if {[file exists $apps_folder]} { |
|
if {[file exists $apps_folder/$glob]} { |
|
#tailcall source $apps_folder/$glob/main.tcl |
|
return $glob |
|
} |
|
set apps [glob -nocomplain -dir $apps_folder -type d -tail $glob] |
|
if {[llength $apps] == 0} { |
|
if {[string first * $glob] <0 && [string first ? $glob] <0} { |
|
#no glob chars supplied - only launch if exact match for name part |
|
set namematches [glob -nocomplain -dir $apps_folder -type d -tail ${glob}-*] |
|
set namematches [lsort $namematches] ;#todo - -ascii? -dictionary? natsort? |
|
if {[llength $namematches] > 0} { |
|
set latest [lindex $namematches end] |
|
lassign $latest nm ver |
|
#tailcall source $apps_folder/$latest/main.tcl |
|
} |
|
} |
|
} |
|
|
|
return $apps |
|
} |
|
} |
|
|
|
#todo - way to launch as separate process |
|
# solo-opts only before appname - args following appname are passed to the app |
|
proc run {args} { |
|
set nameposn [lsearch -not $args -*] |
|
if {$nameposn < 0} { |
|
error "punkapp::run unable to determine application name" |
|
} |
|
set appname [lindex $args $nameposn] |
|
set controlargs [lrange $args 0 $nameposn-1] |
|
set appargs [lrange $args $nameposn+1 end] |
|
|
|
set appinfo [punk::mod::cli::getraw $appname] |
|
if {[llength [dict get $appinfo versions]]} { |
|
set ver [dict get $appinfo latest] |
|
puts stdout "info: $appinfo" |
|
set ::argc [llength $appargs] |
|
set ::argv $appargs |
|
source [dict get $appinfo mains $ver] |
|
if {"-hideconsole" in $controlargs} { |
|
puts stderr "attempting console hide" |
|
#todo - something better - a callback when window mapped? |
|
after 500 {::punkapp::hide_console} |
|
} |
|
return $appinfo |
|
} else { |
|
error "punk::mod::cli unable to run '$appname'. main.tcl not found in [dict get $appinfo bases]" |
|
} |
|
} |
|
|
|
|
|
} |
|
|
|
namespace eval punk::mod::cli { |
|
proc _cli {args} { |
|
#don't use tailcall - base uses info level to determine caller |
|
::punk::mix::base::_cli {*}$args |
|
} |
|
variable default_command help |
|
package require punk::mix::base |
|
package require punk::overlay |
|
punk::overlay::custom_from_base [namespace current] ::punk::mix::base |
|
} |
|
|
|
package provide punk::mod [namespace eval punk::mod { |
|
variable version |
|
set version 0.1 |
|
}] |
|
|
|
|
|
|
|
|