@ -11,9 +11,13 @@
# p a c k a g e _ m o d e p a r s i n g ( m i n t e d | o s | i n t e r n a l | s r c w i t h t h e p r o j : s c o p e p r e f i x ,
# G - 0 3 3 ) , m o d u l e - p a t h a n d a u t o _ p a t h a s s e m b l y , p u n k : : l i b u n k n o w n , s r c - m o d e
# # m o d p o d r e g i s t r a t i o n , t h e n t h e d e f a u l t s u b c o m m a n d d i s p a t c h
# ( t c l s h / s h e l l s p y / p u n k / s h e l l / s c r i p t ) e x t e n d e d b y t h e t h i n m a i n ' s d e c l a r e d
# p r o j e c t s u b c o m m a n d s ( G - 0 3 1 r e g i s t r a t i o n m o d e l - s e e t h e d i s p a t c h s e c t i o n
# n e a r t h e e n d o f t h i s f i l e ) .
# ( t c l s h / s h e l l s p y / p u n k / s h e l l / s c r i p t / b u i l d i n f o / h e l p ) e x t e n d e d b y t h e t h i n
# m a i n ' s d e c l a r e d p r o j e c t s u b c o m m a n d s ( G - 0 3 1 r e g i s t r a t i o n m o d e l - s e e t h e
# d i s p a t c h s e c t i o n n e a r t h e e n d o f t h i s f i l e ) . T h e l a u n c h s u r f a c e d o c u m e n t s
# i t s e l f v i a p u n k : : a r g s ( G - 0 3 2 ) : ' < p u n k e x e > h e l p ? s u b c o m m a n d ? ' , ' - h e l p ' a n d
# ' < s u b c o m m a n d > - h e l p ' r e n d e r t a b l e d u s a g e f r o m t h e m o d u l e d o c : : p u n k e x e
# d e f i n i t i o n s p l u s t h e l i v e r e g i s t r a t i o n s , d e g r a d i n g t o a p l a i n s u b c o m m a n d
# l i s t w h e n t h a t s t a c k i s u n a v a i l a b l e .
#
# T h e p a c k a g e _ m o d e s u r f a c e ( d o c u m e n t e d i n f u l l b y p u n k : : a r g s : : m o d u l e d o c : : p u n k e x e ) :
# a n o p t i o n a l F I R S T l a u n c h a r g u m e n t o f t h e f o r m m i n t e d | o s | i n t e r n a l | s r c o r a n y
@ -33,6 +37,11 @@
# t o t h i s f i l e ' s o w n p a t h )
# p r o j e c t _ s u b c o m m a n d s d i c t : s u b c o m m a n d n a m e - > h a n d l e r s c r i p t ( s e e t h e
# d i s p a t c h s e c t i o n ; b u i l t - i n s c a n n o t b e s h a d o w e d )
# p r o j e c t _ s u b c o m m a n d _ i n f o d i c t : s u b c o m m a n d n a m e - > i n f o d i c t w i t h
# o p t i o n a l k e y s s u m m a r y / a r g s i d / p a c k a g e / p a r s e f e e d i n g
# t h e G - 0 3 2 l a u n c h e r h e l p + d e c l a r e d - p a r s e w i r i n g
# ( s e e t h e l a u n c h e r h e l p s e c t i o n ; a n a m e w i t h o u t a n
# i n f o e n t r y k e e p s f u l l p a s s t h r o u g h s e m a n t i c s )
# l a u n c h _ d e f a u l t s d i c t : n o a r g s / u n k n o w n f i r s t ( s e e d i s p a t c h s e c t i o n )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -42,7 +51,7 @@
namespace eval : : punkboot {
# b o o t - c o r e i d e n t i t y ( G - 0 3 1 ; s t a m p e d i n t o k i t s + r e p o r t e d b y t h e G - 0 2 5
# b u i l d i n f o s u r f a c e s )
variable core_version 0.2 .1
variable core_version 0.3 .0
}
if { ! [ info exists : : punkboot::launch_args] } {
namespace eval : : punkboot [ list variable launch_args $::argv ]
@ -53,6 +62,9 @@ if {![info exists ::punkboot::main_script]} {
if { ! [ info exists : : punkboot::project_subcommands] } {
namespace eval : : punkboot { variable project_subcommands [ dict create] }
}
if { ! [ info exists : : punkboot::project_subcommand_info] } {
namespace eval : : punkboot { variable project_subcommand_info [ dict create] }
}
if { ! [ info exists : : punkboot::launch_defaults] } {
namespace eval : : punkboot { variable launch_defaults [ dict create] }
}
@ -1509,20 +1521,299 @@ if {![info exists ::punkboot::launch_defaults]} {
}
namespace eval : : punkboot [ list variable boot_state $boot_state_dict ]
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# L a u n c h e r h e l p + d e c l a r e d - p a r s e m a c h i n e r y ( G - 0 3 2 )
# T h e l a u n c h s u r f a c e d o c u m e n t s i t s e l f t h r o u g h p u n k : : a r g s ( d e f i n i t i o n i d s
# f r o m t h e p u n k : : a r g s : : m o d u l e d o c : : p u n k e x e f a m i l y ) :
# < p u n k e x e > h e l p ? s u b c o m m a n d ? t a b l e d u s a g e ; t h e t o p - l e v e l t a b l e l i s t s
# b u i l t - i n s A N D p r o j e c t - r e g i s t e r e d
# s u b c o m m a n d s w i t h s u m m a r i e s
# < p u n k e x e > - h e l p s a m e a s b a r e ' h e l p ' - o n l y o n k i t s w h o s e
# u n k n o w n f i r s t d e f a u l t i s ' s c r i p t ' ( a
# t o o l - s t y l e k i t r o u t e s f l a g s t o i t s o w n
# p r o c e s s o r ; i t s s u r f a c e s t a y s r e a c h a b l e
# v i a t h e ' h e l p ' w o r d )
# < p u n k e x e > < s u b c o m m a n d > - h e l p t h e s u b c o m m a n d ' s t a b l e d u s a g e w h e n - h e l p
# i s i t s F I R S T a r g u m e n t ( t c l s h : o n l y w h e n
# - h e l p i s t h e S O L E a r g u m e n t - s t o c k
# p a r i t y k e e p s e v e r y o t h e r d a s h f o r m i n
# : : a r g v ; p r o j e c t s u b c o m m a n d s : o n l y w h e n
# t h e r e g i s t r a t i o n d e c l a r e s a n a r g s i d )
# E v e r y t h i n g i s g u a r d e d a n d l a z y ( t h e G - 0 3 0 d e g r a d a t i o n d o c t r i n e ) : n o t h i n g
# h e r e l o a d s p u n k : : a r g s o n a n o r m a l b o o t / d i s p a t c h p a t h . W h e n p u n k : : a r g s o r
# t h e m o d u l e d o c d e f i n i t i o n s a r e u n a v a i l a b l e ( o r P U N K B O O T _ P L A I N = 1 - s a m e
# e n v h o o k a s m a k e . t c l ) , h e l p d e g r a d e s t o a p l a i n s u b c o m m a n d l i s t , p a r s e
# g a t e s d e g r a d e t o t h e h i s t o r i c s w i t c h s e m a n t i c s , a n d b o o t n e v e r f a i l s .
# T h e t a b l e d r e n d e r i n g a d d i t i o n a l l y d e p e n d s o n t h e p u n k : : a n s i / t e x t b l o c k
# s t a c k - r e n d e r i n g d e g r a d e s ( m i n i m a l e r r o r s t y l e ) i n d e p e n d e n t l y o f p a r s i n g .
# T h e p e r - k i t t o p - l e v e l u s a g e i d ( s c r i p t ) : : p u n k e x e . l a u n c h e r i s c l o n e d f r o m
# t h e s t a t i c ( s c r i p t ) : : p u n k e x e d e f i n i t i o n a t f i r s t r e n d e r , w i t h t h e
# s u b c o m m a n d c h o i c e s / c h o i c e l a b e l s r e p l a c e d b y t h i s k i t ' s L I V E s u r f a c e ;
# ( s c r i p t ) : : p u n k e x e . l a u n c h e r h e l p i s t h e s a m e c l o n e o f
# ( s c r i p t ) : : p u n k e x e : : h e l p f o r s u b j e c t v a l i d a t i o n .
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namespace eval : : punkboot {
variable help_flags [ list - help - - help - h / ? ]
variable launch_builtin_subcommands [ list ]
variable launch_subcommands [ list ]
variable launcher_punkargs_state " " ; # " " u n p r o b e d | o k | p l a i n
variable launcher_builtin_summaries [ dict create \
tclsh " R u n a s a ( n e a r ) s t o c k t c l s h - n o p u n k m o d u l e s l o a d e d . " \
script " R u n a s c r i p t n o n - i n t e r a c t i v e l y i n t h e p u n k s c r i p t e n v i r o n m e n t ; h o n e s t e x i t c o d e s . " \
shell " I n t e r a c t i v e p u n k s h e l l ( r e p l ) . " \
punk " p u n k s h e l l l a u n c h ; p i p e d - s t d i n f r i e n d l y . " \
shellspy " E x p e r i m e n t a l s h e l l s p y c o m m a n d - l i n e p r o c e s s o r . " \
buildinfo " P r i n t t h e k i t ' s b u i l d / i d e n t i t y s t a m p r e p o r t a n d e x i t ( G - 0 2 5 ) . " \
help " S h o w u s a g e f o r t h e l a u n c h s u r f a c e o r o n e o f i t s s u b c o m m a n d s ( G - 0 3 2 ) . " \
]
proc launcher_punkargs_ready { } {
# l a z y g u a r d e d c a p a b i l i t y p r o b e , o n e v e r d i c t p e r p r o c e s s . o k r e q u i r e s
# p u n k : : a r g s A N D t h e m o d u l e d o c l a u n c h d e f i n i t i o n s t o l o a d a n d r e s o l v e
# w i t h t h e s n a p s h o t a c t u a l l y a v a i l a b l e i n t h i s k i t / c o n t e x t .
variable launcher_punkargs_state
if { $launcher_punkargs_state ne " " } {
return [ expr { $launcher_punkargs_state eq " o k " } ]
}
set launcher_punkargs_state plain
if { [ info exists : : env( PUNKBOOT_PLAIN ) ] && [ string is true - strict $::env ( PUNKBOOT_PLAIN ) ] } {
return 0
}
if { [ catch {
package require punk::args
# p u n k : : a r g s ( a n d t h e p u n k : : a n s i / t e x t b l o c k r e n d e r s t a c k ) c a l l
# p u n k : : l i b w i t h o u t r e q u i r i n g i t ( k n o w n m o d u l e - w e b g a p ) : o n
# T c l 8 . 6 t h e c h o i c e s - g r i d r e n d e r p a t h n e e d s p u n k : : l i b ' s
# f o r w a r d - c o m p a t b u i l t i n s ( l p o p e t c ) . G u a r d e d - r e q u i r e o r d e r
# m a t t e r s ( p u n k : : l i b i t s e l f h a r d - r e q u i r e s p u n k : : a r g s , s o t h i s
# c a l l - t i m e d i r e c t i o n b r e a k s n o c y c l e ) ; a k i t w i t h o u t p u n k : : l i b
# s t i l l p r o b e s o k a n d r e n d e r i n g d e g r a d e s w h e r e i t m u s t .
catch { package require punk::lib}
package require punk::args::moduledoc::punkexe
if { [ punk : : args::get_spec ( script ) : : punkexe] eq " " } {
error " d e f i n i t i o n ( s c r i p t ) : : p u n k e x e d i d n o t r e s o l v e "
}
punk : : args::get_spec ( script ) : : punkexe::buildinfo
punk : : args::get_spec ( script ) : : punkexe::help
} ] } {
return 0
}
set launcher_punkargs_state ok
return 1
}
proc launcher_errstyle { } {
# t a b l e d ( s t a n d a r d ) p a r s e e r r o r s w h e n t h e r e n d e r i n g s t a c k i s
# l o a d a b l e ; m i n i m a l o t h e r w i s e - r e n d e r i n g d e g r a d e s i n d e p e n d e n t l y o f
# p a r s i n g ( t h e G - 0 3 0 s p l i t )
catch { package require punk::ansi}
catch { package require textblock}
if { [ package provide punk::ansi] ne " " && [ package provide textblock] ne " " } {
return standard
}
return minimal
}
proc launcher_subcommand_summary { name } {
# p l a i n - t e x t o n e - l i n e s u m m a r y f o r a k n o w n s u b c o m m a n d ( b u i l t - i n t a b l e
# o r t h e p r o j e c t r e g i s t r a t i o n ' s d e c l a r e d s u m m a r y )
variable launcher_builtin_summaries
variable project_subcommand_info
if { [ dict exists $launcher_builtin_summaries $name ] } {
return [ dict get $launcher_builtin_summaries $name ]
}
if { [ dict exists $project_subcommand_info $name summary] } {
return [ dict get $project_subcommand_info $name summary]
}
return " P r o j e c t - d e c l a r e d s u b c o m m a n d ( n o s u m m a r y r e g i s t e r e d ) . "
}
proc launcher_live_choices { } {
# t h i s k i t ' s s u b c o m m a n d s e t i n d i s p l a y o r d e r : t h e s t a t i c d e f i n i t i o n ' s
# c h o i c e o r d e r f i r s t ( t h e d o c u m e n t e d b u i l t - i n f a m i l y ) , t h e n ' h e l p ' ,
# t h e n p r o j e c t r e g i s t r a t i o n s i n d e c l a r a t i o n o r d e r
variable launch_subcommands
set ordered [ list ]
catch {
set spec [ punk : : args::get_spec ( script ) : : punkexe]
foreach c [ dict get $spec FORMS _default ARG_INFO subcommand - choices] {
if { $c in $launch_subcommands && $c ni $ordered } {
lappend ordered $c
}
}
}
foreach c $launch_subcommands {
if { $c ni $ordered } {
lappend ordered $c
}
}
return $ordered
}
proc launcher_overview_id { } {
# d e f i n e ( s c r i p t ) : : p u n k e x e . l a u n c h e r : t h e p e r - k i t t o p - l e v e l u s a g e -
# t h e m o d u l e d o c ( s c r i p t ) : : p u n k e x e d e f i n i t i o n w i t h t h e s u b c o m m a n d
# c h o i c e s / c h o i c e l a b e l s r e p l a c e d b y t h i s k i t ' s l i v e s u r f a c e .
# R e t u r n s t h e i d , o r " " w h e n t h e c l o n e c a n n o t b e b u i l t .
variable launch_builtin_subcommands
set id ( script ) : : punkexe.launcher
set existing " "
catch { set existing [ punk : : args::raw_def $id ] }
if { $existing ne " " } {
return $id
}
if { [ catch {
set spec [ punk : : args::get_spec ( script ) : : punkexe]
set labels [ dict get $spec FORMS _default ARG_INFO subcommand - choicelabels]
set choices [ launcher_live_choices ]
foreach c $choices {
if { $c eq " h e l p " || $c ni $launch_builtin_subcommands || ! [ dict exists $labels $c ] } {
dict set labels $c " [ l a u n c h e r _ s u b c o m m a n d _ s u m m a r y $ c ] "
}
}
set ov [ dict create \
@ id [ list - id $id ] \
subcommand [ list - choices $choices - choicelabels $labels ] \
]
punk : : args::define [ punk : : args::resolved_def - override $ov ( script ) : : punkexe]
} ] } {
return " "
}
return $id
}
proc launcher_helpdef_id { } {
# d e f i n e ( s c r i p t ) : : p u n k e x e . l a u n c h e r h e l p : t h e m o d u l e d o c
# ( s c r i p t ) : : p u n k e x e : : h e l p d e f i n i t i o n w i t h t h e s u b j e c t c h o i c e s
# r e p l a c e d b y t h e l i v e s u b c o m m a n d s e t , s o ' h e l p < n a m e > ' v a l i d a t e s
# ( a n d p r e f i x - r e s o l v e s ) a g a i n s t w h a t t h i s k i t a c t u a l l y o f f e r s .
set id ( script ) : : punkexe.launcherhelp
set existing " "
catch { set existing [ punk : : args::raw_def $id ] }
if { $existing ne " " } {
return $id
}
if { [ catch {
set ov [ dict create \
@ id [ list - id $id ] \
subject [ list - choices [ launcher_live_choices ] ] \
]
punk : : args::define [ punk : : args::resolved_def - override $ov ( script ) : : punkexe::help]
} ] } {
return " "
}
return $id
}
proc launcher_plain_help { } {
# d e g r a d e d h e l p : p l a i n s u b c o m m a n d l i s t b u i l t w i t h o u t p u n k : : a r g s
set exebase [ file rootname [ file tail [ info nameofexecutable] ] ]
set lines [ list ]
lappend lines " U s a g e : $ e x e b a s e ? p a c k a g e m o d e ? ? s u b c o m m a n d ? ? a r g . . . ? "
lappend lines " p a c k a g e m o d e : o r d e r e d d a s h - s e p a r a t e d l i s t o f i n t e r n a l | m i n t e d | o s | s r c ( d e f a u l t i n t e r n a l ) , "
lappend lines " o p t i o n a l l y s c o p e d w i t h t h e ' p r o j : ' p r e f i x ( e . g p r o j : i n t e r n a l - s r c ) "
lappend lines " s u b c o m m a n d s : "
foreach sub [ launcher_plain_choices ] {
lappend lines [ format " % - 1 2 s % s " $sub [ launcher_subcommand_summary $sub ] ]
}
lappend lines " ( ' $ e x e b a s e h e l p ? s u b c o m m a n d ? ' s h o w s d e t a i l ; p l a i n l i s t b e c a u s e t h e p u n k : : a r g s "
lappend lines " t a b l e d h e l p s t a c k i s u n a v a i l a b l e i n t h i s c o n t e x t , o r P U N K B O O T _ P L A I N i s s e t ) "
return [ join $lines \ n]
}
proc launcher_plain_choices { } {
# d i s p l a y o r d e r w i t h o u t p u n k : : a r g s : d o c u m e n t e d b u i l t - i n o r d e r , t h e n
# p r o j e c t r e g i s t r a t i o n s i n d e c l a r a t i o n o r d e r
variable launch_subcommands
set ordered [ list ]
foreach c [ list tclsh script shell punk shellspy buildinfo help] {
if { $c in $launch_subcommands } {
lappend ordered $c
}
}
foreach c $launch_subcommands {
if { $c ni $ordered } {
lappend ordered $c
}
}
return $ordered
}
proc launcher_show_help { { subject " " } } {
# r e n d e r h e l p t o s t d o u t : t h e t o p - l e v e l l a u n c h s u r f a c e ( e m p t y
# s u b j e c t ) o r o n e s u b c o m m a n d ' s u s a g e . T a b l e d v i a p u n k : : a r g s w h e n
# a v a i l a b l e ; d e g r a d e s t o t h e p l a i n l i s t / s u m m a r y . N e v e r e r r o r s .
variable launch_builtin_subcommands
variable project_subcommand_info
if { [ launcher_punkargs_ready ] } {
set id " "
if { $subject eq " " } {
set id [ launcher_overview_id ]
} elseif { $subject eq " h e l p " } {
set id [ launcher_helpdef_id ]
} elseif { $subject in $launch_builtin_subcommands } {
set id ( script ) : : punkexe::$subject
} else {
# p r o j e c t - r e g i s t e r e d : g u a r d e d r e q u i r e o f t h e d e c l a r e d
# p a c k a g e ( i f a n y ) , t h e n t h e d e c l a r e d d e f i n i t i o n i d ( i f a n y )
if { [ dict exists $project_subcommand_info $subject package] } {
catch { package require [ dict get $project_subcommand_info $subject package] }
}
if { [ dict exists $project_subcommand_info $subject argsid] } {
set id [ dict get $project_subcommand_info $subject argsid]
} else {
# h e l p b y r e g i s t r a t i o n a l o n e : t h e s u m m a r y l i n e
puts stdout " $ s u b j e c t - [ l a u n c h e r _ s u b c o m m a n d _ s u m m a r y $ s u b j e c t ] "
puts stdout " ( n o p u n k : : a r g s d e f i n i t i o n r e g i s t e r e d f o r t h i s s u b c o m m a n d - i f i t i s a n a p p l i c a t i o n e n t r y p o i n t i t m a y p r o v i d e i t s o w n - h e l p h a n d l i n g ) "
return
}
}
if { $id ne " " && ! [ catch { punk : : args::usage $id } out] } {
puts stdout $out
return
}
# f a l l t h r o u g h t o t h e p l a i n f o r m s o n a n y r e n d e r f a i l u r e
}
if { $subject eq " " } {
puts stdout [ launcher_plain_help ]
} else {
puts stdout " $ s u b j e c t - [ l a u n c h e r _ s u b c o m m a n d _ s u m m a r y $ s u b j e c t ] "
puts stdout " ( p l a i n h e l p : t h e p u n k : : a r g s t a b l e d h e l p s t a c k i s u n a v a i l a b l e i n t h i s c o n t e x t , o r P U N K B O O T _ P L A I N i s s e t ) "
}
return
}
proc launcher_unknown_first_error { word } {
# G - 0 3 2 r e c l a s s i f i c a t i o n r u l e : a n u n k n o w n f i r s t a r g u m e n t t h a t n a m e s
# n o e x i s t i n g f i l e ( a n d i s n o l i b : * s c r i p t l i b r e f e r e n c e ) i s a n
# o b v i o u s m i s t a k e - r e f u s e i t w i t h u s a g e o n s t d e r r i n s t e a d o f
# s i l e n t l y a t t e m p t i n g i t a s a s c r i p t . R e t u r n s 1 w h e n t h e r e f u s a l
# w a s e m i t t e d ( c a l l e r e x i t s 1 ) ; 0 w h e n p u n k : : a r g s i s u n a v a i l a b l e
# ( c a l l e r f a l l s b a c k t o t h e h i s t o r i c s c r i p t r e c l a s s i f i c a t i o n ) .
variable launch_subcommands
if { ! [ launcher_punkargs_ready ] } {
return 0
}
set exebase [ file rootname [ file tail [ info nameofexecutable] ] ]
puts stderr " $ e x e b a s e : u n k n o w n s u b c o m m a n d ' $ w o r d ' ( n o s u c h s u b c o m m a n d , a n d n o s u c h s c r i p t f i l e e x i s t s ) "
set id [ launcher_overview_id ]
if { $id ne " " && ! [ catch { punk : : args::usage $id } out] } {
puts stderr $out
} else {
puts stderr " k n o w n s u b c o m m a n d s : [ j o i n [ l a u n c h e r _ p l a i n _ c h o i c e s ] { , } ] "
}
puts stderr " u s e ' $ e x e b a s e h e l p ' f o r t h e l a u n c h s u r f a c e , o r ' $ e x e b a s e s c r i p t $ w o r d ? a r g . . . ? ' t o f o r c e s c r i p t i n t e r p r e t a t i o n "
return 1
}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# S u b c o m m a n d s e l e c t i o n ( G - 0 3 1 r e g i s t r a t i o n m o d e l )
# B u i l t - i n s ( t c l s h / s h e l l s p y / p u n k / s h e l l / s c r i p t ) s h i p w i t h t h i s c o r e ; a t h i n
# m a i n m a y e x t e n d t h e s e t v i a : : p u n k b o o t : : p r o j e c t _ s u b c o m m a n d s ( d i c t :
# n a m e - > h a n d l e r s c r i p t , e v a l u a t e d i n t h e d i s p a t c h b e l o w w i t h : : a r g v / : : a r g c
# h o l d i n g t h e s u b c o m m a n d ' s a r g u m e n t s ) . B u i l t - i n n a m e s c a n n o t b e s h a d o w e d -
# a c o l l i d i n g d e c l a r a t i o n i s r e p o r t e d a n d i g n o r e d .
# B u i l t - i n s ( t c l s h / s h e l l s p y / p u n k / s h e l l / s c r i p t / b u i l d i n f o / h e l p ) s h i p w i t h
# t h i s c o r e ; a t h i n m a i n m a y e x t e n d t h e s e t v i a
# : : p u n k b o o t : : p r o j e c t _ s u b c o m m a n d s ( d i c t : n a m e - > h a n d l e r s c r i p t , e v a l u a t e d
# i n t h e d i s p a t c h b e l o w w i t h : : a r g v / : : a r g c h o l d i n g t h e s u b c o m m a n d ' s
# a r g u m e n t s ) . B u i l t - i n n a m e s c a n n o t b e s h a d o w e d - a c o l l i d i n g d e c l a r a t i o n
# i s r e p o r t e d a n d i g n o r e d . : : p u n k b o o t : : p r o j e c t _ s u b c o m m a n d _ i n f o o p t i o n a l l y
# c a r r i e s p e r - n a m e h e l p / p a r s e m e t a d a t a ( s u m m a r y / a r g s i d / p a c k a g e / p a r s e - s e e
# t h e l a u n c h e r h e l p s e c t i o n a b o v e , G - 0 3 2 ) .
# : : p u n k b o o t : : l a u n c h _ d e f a u l t s k e y s ( b o t h o p t i o n a l ) :
# n o a r g s s u b c o m m a n d a s s u m e d f o r a b a r e l a u n c h ( d e f a u l t : s h e l l )
# u n k n o w n f i r s t ' s c r i p t ' t r e a t s a n o n - s u b c o m m a n d f i r s t a r g u m e n t a s a
# s c r i p t i n v o c a t i o n ( d e f a u l t ) , o r t h e n a m e o f a k n o w n
# s u b c o m m a n d t o r e c e i v e t h e w h o l e a r g l i s t a s i t s a r g u m e n t s
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set builtin_subcommands [ list tclsh shellspy punk shell script buildinfo]
set builtin_subcommands [ list tclsh shellspy punk shell script buildinfo help ]
set known_subcommands $builtin_subcommands
foreach k [ dict keys $::punkboot::project_subcommands ] {
if { $k in $builtin_subcommands } {
@ -1531,6 +1822,9 @@ if {![info exists ::punkboot::launch_defaults]} {
lappend known_subcommands $k
}
}
# p u b l i s h f o r t h e l a u n c h e r h e l p m a c h i n e r y ( a n d p o s t - b o o t p r o b e s )
set : : punkboot::launch_builtin_subcommands $builtin_subcommands
set : : punkboot::launch_subcommands $known_subcommands
if { [ dict exists $::punkboot::launch_defaults noargs] } {
set default_noargs [ dict get $::punkboot::launch_defaults noargs]
} else {
@ -1544,10 +1838,56 @@ if {![info exists ::punkboot::launch_defaults]} {
set subcommand [ lindex $arglist 0 ]
if { $subcommand in $known_subcommands } {
set subcommand_arglist [ lrange $arglist 1 end]
# G - 0 3 2 : a h e l p f l a g a s t h e s u b c o m m a n d ' s F I R S T a r g u m e n t r e n d e r s t h a t
# s u b c o m m a n d ' s u s a g e . t c l s h : o n l y w h e n i t i s t h e S O L E a r g u m e n t ( s t o c k
# p a r i t y k e e p s e v e r y o t h e r l e a d i n g - d a s h f o r m - i n c l u d i n g ' - h e l p ' w i t h
# f u r t h e r a r g u m e n t s - i n : : a r g v ) ; p r o j e c t s u b c o m m a n d s : o n l y w h e n t h e
# r e g i s t r a t i o n d e c l a r e s a n a r g s i d ( a h a n d l e r - o n l y r e g i s t r a t i o n k e e p s
# f u l l p a s s t h r o u g h - t h e a p p l i c a t i o n m a y d o i t s o w n - h e l p h a n d l i n g ) .
if { [ lindex $subcommand_arglist 0 ] in $::punkboot::help_flags } {
set do_subhelp 0
if { $subcommand eq " t c l s h " } {
if { [ llength $subcommand_arglist ] == 1 } {
set do_subhelp 1
}
} elseif { $subcommand in $builtin_subcommands } {
set do_subhelp 1
} elseif { [ dict exists $::punkboot::project_subcommand_info $subcommand argsid] } {
set do_subhelp 1
}
if { $do_subhelp } {
: : punkboot : : launcher_show_help $subcommand
exit 0
}
}
} else {
set subcommand_arglist $arglist
if { [ llength $subcommand_arglist ] } {
# G - 0 3 2 : a h e l p f l a g i n f i r s t p o s i t i o n i s a l a u n c h - s u r f a c e h e l p
# r e q u e s t o n k i t s w h o s e u n k n o w n - f i r s t d e f a u l t i s ' s c r i p t ' .
# T o o l - s t y l e k i t s ( u n k n o w n f i r s t n a m e s a p r o j e c t s u b c o m m a n d ) k e e p
# r o u t i n g f l a g s t o t h e i r p r o c e s s o r - t h e i r s u r f a c e s t a y s
# d i s c o v e r a b l e v i a t h e ' h e l p ' s u b c o m m a n d w o r d .
if { $subcommand in $::punkboot::help_flags && $default_unknownfirst eq " s c r i p t " } {
: : punkboot : : launcher_show_help
exit 0
}
set subcommand $default_unknownfirst
if { $subcommand eq " s c r i p t " } {
# G - 0 3 2 u n k n o w n - f i r s t - a r g r e c l a s s i f i c a t i o n r u l e ( r e c o r d e d i n
# g o a l s / G - 0 3 2 - l a u n c h e r - p u n k a r g s . m d ) : r e c l a s s i f y t o ' s c r i p t '
# o n l y w h e n t h e a r g u m e n t p l a u s i b l y n a m e s a s c r i p t - a n
# e x i s t i n g f i l e p a t h , o r a l i b : * s c r i p t l i b r e f e r e n c e . A n y t h i n g
# e l s e i s r e f u s e d w i t h u s a g e o n s t d e r r ( e x i t 1 ) ; w h e n
# p u n k : : a r g s i s u n a v a i l a b l e t h e r e f u s a l d e g r a d e s t o t h e
# h i s t o r i c a l w a y s - r e c l a s s i f y b e h a v i o u r .
set unknown_word [ lindex $subcommand_arglist 0 ]
if { ! ( [ file exists $unknown_word ] || [ string match - nocase lib:* $unknown_word ] ) } {
if { [ : : punkboot : : launcher_unknown_first_error $unknown_word ] } {
exit 1
}
}
}
} else {
set subcommand $default_noargs
}
@ -1726,8 +2066,20 @@ if {![info exists ::punkboot::launch_defaults]} {
# i m p l e m e n t a t i o n i s p u n k : : b u i l d i n f o - t h i s a r m i s t h e t h i n
# e x e - s u b c o m m a n d w r a p p e r . S t d o u t c a r r i e s o n l y t h e r e p o r t ; h o n e s t
# e x i t c o d e ; n o r e p l f a l l t h r o u g h ( G - 0 1 5 - c o m p a t i b l e ) .
# G - 0 3 2 : t h e a r g u m e n t c o n t r a c t ( ( s c r i p t ) : : p u n k e x e : : b u i l d i n f o ,
# @ v a l u e s - m i n 0 - m a x 0 ) i s e n f o r c e d t h r o u g h p u n k : : a r g s w h e n
# a v a i l a b l e : a n y a r g u m e n t e a r n s t h e h i s t o r i c o n e - l i n e r e f u s a l P L U S
# t h e t a b l e d u s a g e e r r o r o n s t d e r r , e x i t 2 ( b u i l d i n f o . t e s t p i n s t h e
# o n e - l i n e r a n d t h e e x i t c o d e ) . T h e e m p t y - a r g u m e n t f a s t p a t h n e v e r
# t o u c h e s p u n k : : a r g s ; a ' - h e l p ' f i r s t a r g u m e n t w a s a l r e a d y
# i n t e r c e p t e d a t s e l e c t i o n .
if { [ llength $subcommand_arglist ] } {
puts stderr " b u i l d i n f o : t a k e s n o a r g u m e n t s "
if { [ : : punkboot : : launcher_punkargs_ready] } {
if { [ catch { punk : : args::parse $subcommand_arglist - errorstyle [ : : punkboot : : launcher_errstyle] withid ( script ) : : punkexe::buildinfo} parse_msg] } {
puts stderr $parse_msg
}
}
exit 2
}
if { [ catch { package require punk::buildinfo} errM] } {
@ -1736,6 +2088,41 @@ if {![info exists ::punkboot::launch_defaults]} {
}
exit [ punk : : buildinfo::main]
}
help {
# G - 0 3 2 : l a u n c h e r h e l p s u r f a c e . B a r e ' h e l p ' r e n d e r s t h e t o p - l e v e l
# t a b l e d u s a g e ( b u i l t - i n s + p r o j e c t - r e g i s t e r e d s u b c o m m a n d s w i t h
# s u m m a r i e s ) ; ' h e l p < s u b c o m m a n d > ' r e n d e r s t h a t s u b c o m m a n d ' s u s a g e .
# S u b j e c t v a l i d a t i o n p a r s e s t h r o u g h t h e l a u n c h e r h e l p c l o n e w h e n
# p u n k : : a r g s i s a v a i l a b l e ( t a b l e d c h o i c e e r r o r s o n s t d e r r e x i t 1 ,
# u n a m b i g u o u s p r e f i x e s r e s o l v e ) ; d e g r a d e d m o d e a c c e p t s e x a c t n a m e s
# o n l y a n d r e n d e r s t h e p l a i n f o r m s . H e l p g o e s t o s t d o u t , e x i t 0
# ( G - 0 1 5 o u t p u t - c l e a n l i n e s s / e x i t - c o d e d o c t r i n e ) .
if { ! [ llength $subcommand_arglist ] } {
: : punkboot : : launcher_show_help
exit 0
}
if { [ : : punkboot : : launcher_punkargs_ready] } {
set helpdef_id [ : : punkboot : : launcher_helpdef_id]
if { $helpdef_id ne " " } {
if { [ catch { punk : : args::parse $subcommand_arglist - errorstyle [ : : punkboot : : launcher_errstyle] withid $helpdef_id } argd] } {
puts stderr $argd
exit 1
}
set help_subject " "
catch { set help_subject [ dict get $argd values subject] }
: : punkboot : : launcher_show_help $help_subject
exit 0
}
}
# d e g r a d e d : e x a c t - n a m e s u b j e c t o n l y
set help_subject [ lindex $subcommand_arglist 0 ]
if { [ llength $subcommand_arglist ] > 1 || $help_subject ni $::punkboot::launch_subcommands } {
puts stderr " h e l p : e x p e c t e d ' h e l p ? s u b c o m m a n d ? ' w i t h s u b c o m m a n d o n e o f : [ j o i n [ : : p u n k b o o t : : l a u n c h e r _ p l a i n _ c h o i c e s ] { , } ] "
exit 1
}
: : punkboot : : launcher_show_help $help_subject
exit 0
}
default {
# a p r o j e c t - d e c l a r e d s u b c o m m a n d ( t h i n - m a i n c u s t o m i z a t i o n p o i n t ) : t h e
# h a n d l e r s c r i p t r u n s i n t h i s f r a m e , : : a r g v / : : a r g c a l r e a d y h o l d t h e
@ -1743,6 +2130,30 @@ if {![info exists ::punkboot::launch_defaults]} {
# m i s d e c l a r e d l a u n c h _ d e f a u l t s v a l u e - t h e s e l e c t i o n a b o v e m a p s e v e r y
# l a u n c h f o r m t o a k n o w n s u b c o m m a n d .
if { [ dict exists $::punkboot::project_subcommands $subcommand ] } {
# G - 0 3 2 d e c l a r e d - p a r s e g a t e : a r e g i s t r a t i o n m a y o p t i t s
# a r g u m e n t s i n t o p u n k : : a r g s v a l i d a t i o n v i a
# p r o j e c t _ s u b c o m m a n d _ i n f o k e y s p a r s e = 1 + a r g s i d ( o p t i o n a l
# p a c k a g e r e q u i r e m e n t ) . A p a r s e f a i l u r e i s a t a b l e d u s a g e
# e r r o r o n s t d e r r , e x i t 1 , a n d t h e h a n d l e r i s n o t i n v o k e d .
# D e g r a d e s t o t h e h i s t o r i c n o - v a l i d a t i o n p a s s t h r o u g h w h e n
# p u n k : : a r g s ( o r t h e d e c l a r e d i d ) i s u n a v a i l a b l e .
if { [ dict exists $::punkboot::project_subcommand_info $subcommand parse]
&& [ string is true - strict [ dict get $::punkboot::project_subcommand_info $subcommand parse] ]
&& [ dict exists $::punkboot::project_subcommand_info $subcommand argsid]
&& [ : : punkboot : : launcher_punkargs_ready] } {
if { [ dict exists $::punkboot::project_subcommand_info $subcommand package] } {
catch { package require [ dict get $::punkboot::project_subcommand_info $subcommand package] }
}
set project_argsid [ dict get $::punkboot::project_subcommand_info $subcommand argsid]
set project_argsid_ok 0
catch { set project_argsid_ok [ expr { [ punk : : args::raw_def $project_argsid ] ne " " } ] }
if { $project_argsid_ok } {
if { [ catch { punk : : args::parse $subcommand_arglist - errorstyle [ : : punkboot : : launcher_errstyle] withid $project_argsid } parse_msg] } {
puts stderr $parse_msg
exit 1
}
}
}
eval [ dict get $::punkboot::project_subcommands $subcommand ]
} else {
puts stderr " m a i n . t c l : n o h a n d l e r f o r s u b c o m m a n d ' $ s u b c o m m a n d ' ( c h e c k l a u n c h _ d e f a u l t s i n t h e k i t ' s m a i n . t c l ) - k n o w n s u b c o m m a n d s : $ k n o w n _ s u b c o m m a n d s "