From f8f36163acd4150222d7e371e8a35daa3ea52034 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sun, 17 Dec 2023 10:16:44 +1100 Subject: [PATCH] pkg::cap fixes --- src/make.tcl | 2 + src/mixtemplates/layouts/basic/src/make.tcl | 2 + src/modules/punk/cap-999999.0a1.0.tm | 63 ++++++++++++++++--- .../cap/handlers/templates-999999.0a1.0.tm | 3 +- src/modules/punk/mix-0.2.tm | 2 +- src/modules/punk/mix/cli-0.3.tm | 3 +- .../punk/mix/templates-999999.0a1.0.tm | 14 +++-- .../templates/layouts/project/src/make.tcl | 2 + 8 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/make.tcl b/src/make.tcl index ce8124f..547b880 100644 --- a/src/make.tcl +++ b/src/make.tcl @@ -407,6 +407,8 @@ if {$::punkmake::command eq "bootsupport"} { if {$::punkmake::command ne "project"} { puts stderr "Command $::punkmake::command not implemented - aborting." + flush stderr + after 100 exit 1 } diff --git a/src/mixtemplates/layouts/basic/src/make.tcl b/src/mixtemplates/layouts/basic/src/make.tcl index ce8124f..547b880 100644 --- a/src/mixtemplates/layouts/basic/src/make.tcl +++ b/src/mixtemplates/layouts/basic/src/make.tcl @@ -407,6 +407,8 @@ if {$::punkmake::command eq "bootsupport"} { if {$::punkmake::command ne "project"} { puts stderr "Command $::punkmake::command not implemented - aborting." + flush stderr + after 100 exit 1 } diff --git a/src/modules/punk/cap-999999.0a1.0.tm b/src/modules/punk/cap-999999.0a1.0.tm index 948dd6d..4ca144c 100644 --- a/src/modules/punk/cap-999999.0a1.0.tm +++ b/src/modules/punk/cap-999999.0a1.0.tm @@ -53,11 +53,44 @@ namespace eval punk::cap { } } oo::class create [namespace current]::interface_capprovider.provider { - method register {{capabilityname_glob *}} { + variable provider_pkg + variable registrationobj + constructor {providerpkg} { + variable provider_pkg + if {$providerpkg in [list "" "::"]} { + error "interface_capprovider.provider constructor error. Invalid provider '$providerpkg'" + } + if {![namespace exists ::$providerpkg]} { + error "interface_capprovider.provider constructor error. Invalid provider '$providerpkg' - matching namespace not found" + } + + set registrationobj ::${providerpkg}::capsystem::capprovider.registration + if {[info commands $registrationobj] eq ""} { + error "capprovider.provider constructor error. Missing capprovider.registration interface at '$obj' (command not found) interface_capprovider.regstration instantiation must precede interface_capprovider.provider" + } + + set provider_pkg [string trim $providerpkg ""] } + method register {{capabilityname_glob *}} { + variable provider_pkg + set all_decls [$registrationobj get_declarations] + set register_decls [lsearch -all -inline -index 0 $all_decls $capabilityname_glob] + punk::cap::register_package $provider_pkg $register_decls + } method capabilities {} { + variable provider_pkg + variable registrationobj + set capabilities [list] + set decls [$registrationobj get_declarations] + foreach decl $decls { + lassign $decl capname capdict + if {$capname ni $capabilities} { + lappend capabilities $capname + } + } + return $capname } } } @@ -188,6 +221,11 @@ namespace eval punk::cap { if {[string match ::* $pkg]} { set pkg [string range $pkg 2 end] } + if {[dict exists $pkgcapsaccepted $pkg]} { + set pkg_already_accepted [dict get $pkgcapsaccepted $pkg] + } else { + set pkg_already_accepted [list] + } #for each capability # - ensure 1st element is a single word # - ensure that if 2nd element (capdict) is present - it is dict shaped @@ -199,6 +237,11 @@ namespace eval punk::cap { if {[expr {[llength $capdict] %2 != 0}]} { error "register_package error. pkg:'$pkg' The second element for capname:'$capname' doesn't appear to be a valid dict. Problematic entry: '$capspec'" } + if {$capspec in $pkg_already_accepted} { + #review - multiple handlers? if so - will need to record which handler(s) accepted the capspec + puts stderr "register_package pkg $pkg already has capspec marked as accepted: $capspec" + continue + } if {[dict exists $caps $capname]} { set cap_pkgs [dict get $caps $capname providers] } else { @@ -219,17 +262,23 @@ namespace eval punk::cap { dict lappend pkgcapsaccepted $pkg $capspec ;#if pkg is being registered prior to handler-registration - the handler may undo this entry } } - #another call to register_pkg with same pkg may have been made (most likely with different capname) so we must append + #another call to register_pkg with same pkg may have been made (most likely with different capname) so we must append - but check not already present #dict lappend pkgcapsdeclared $pkg $capabilitylist if {[dict exists $pkgcapsdeclared $pkg]} { - set caps [dict get $pkgcapsdeclared $pkg] - lappend caps {*}$capabilitylist - dict set pkgcapsdeclared $pkg $caps + set capspecs [dict get $pkgcapsdeclared $pkg] + foreach spec $capspecs { + if {$spec ni $capspecs} { + lappend capspecs $spec + } + } + dict set pkgcapsdeclared $pkg $capspecs } else { dict set pkgcapsdeclared $pkg $capabilitylist } } - proc unregister_package {pkg} { + + #todo! + proc unregister_package {pkg {capname *}} { variable pkgcapsdeclared variable caps if {[string match ::* $pkg]} { @@ -250,7 +299,7 @@ namespace eval punk::cap { # it seems not useful to allow the callback to block this unregister action #the pkg may have multiple datasets for each capname so callback will only be called for first dataset we encounter #vetoing unregister would make this more complex for no particular advantage - #if per capability deregistration required this should probably be a separate thing (e.g disable_capability?) + #if per dataset deregistration required this should probably be a separate thing $capreg pkg_unregister $pkg } set pkglist [lreplace $pkglist $posn $posn] diff --git a/src/modules/punk/cap/handlers/templates-999999.0a1.0.tm b/src/modules/punk/cap/handlers/templates-999999.0a1.0.tm index cc4e488..ce739f1 100644 --- a/src/modules/punk/cap/handlers/templates-999999.0a1.0.tm +++ b/src/modules/punk/cap/handlers/templates-999999.0a1.0.tm @@ -52,11 +52,12 @@ namespace eval punk::cap::handlers::templates { set tpath [file normalize [file join $tmfile [dict get $capdict relpath]]] ;#relpath is relative to the tm *file* - not it's containing folder if {![file isdirectory $tpath]} { puts stderr "punk::cap::handlers::templates::capsystem pkg_register WARNING - unable to validate relpath location [dict get $capdict relpath] ($tpath) for package '$pkg' which is attempting to register with punk::cap as a provider of '$capname' capability" + return 0 } if {$capname ni $::punk::cap::handlers::templates::handled_caps} { lappend ::punk::cap::handlers::templates::handled_caps $capname } - if {[info commands punk::cap::handlers::templates::$capname] eq ""} { + if {[info commands ::punk::cap::handlers::templates::$capname] eq ""} { punk::cap::handlers::templates::api create ::punk::cap::handlers::templates::$capname $capname } set cname [string map [list . _] $capname] diff --git a/src/modules/punk/mix-0.2.tm b/src/modules/punk/mix-0.2.tm index d09dfca..482c79a 100644 --- a/src/modules/punk/mix-0.2.tm +++ b/src/modules/punk/mix-0.2.tm @@ -5,7 +5,7 @@ package require punk::cap::handlers::templates ;#handler for templates cap punk::cap::register_capabilityname punk.templates ::punk::cap::handlers::templates package require punk::mix::templates ;#registers as provider pkg for 'punk.templates' capability with punk::cap -#punk::mix::templates::provider register * +punk::mix::templates::provider register * package require punk::mix::base package require punk::mix::cli diff --git a/src/modules/punk/mix/cli-0.3.tm b/src/modules/punk/mix/cli-0.3.tm index 6967226..790cfc6 100644 --- a/src/modules/punk/mix/cli-0.3.tm +++ b/src/modules/punk/mix/cli-0.3.tm @@ -170,7 +170,8 @@ namespace eval punk::mix::cli { } cd $sourcefolder #use run so that stdout visible as it goes - if {![catch {run --timeout=5000 -debug [info nameofexecutable] $sourcefolder/make.tcl {*}$args} exitinfo]} { + if {![catch {run --timeout=55000 -debug [info nameofexecutable] $sourcefolder/make.tcl {*}$args} exitinfo]} { + #todo - notify if exit because of timeout! puts stderr "exitinfo: $exitinfo" set exitcode [dict get $exitinfo exitcode] } else { diff --git a/src/modules/punk/mix/templates-999999.0a1.0.tm b/src/modules/punk/mix/templates-999999.0a1.0.tm index f8ae512..7a0654e 100644 --- a/src/modules/punk/mix/templates-999999.0a1.0.tm +++ b/src/modules/punk/mix/templates-999999.0a1.0.tm @@ -26,17 +26,19 @@ namespace eval punk::mix::templates { variable pkg punk::mix::templates variable cap_provider - punk::cap::register_package punk::mix::templates [list\ - {punk.templates {relpath ../templates}}\ - ] + #punk::cap::register_package punk::mix::templates [list\ + # {punk.templates {relpath ../templates}}\ + #] + namespace eval capsystem { if {[info commands capprovider.registration] eq ""} { punk::cap::interface_capprovider.registration create capprovider.registration oo::objdefine capprovider.registration { method get_declarations {} { set decls [list] - lappend decls punk.templates {relpath ../templates} - lappend decls punk.templates {relpath ../templates2} + lappend decls [list punk.templates {relpath ../templates}] + lappend decls [list punk.templates {relpath ../templates2}] + lappend decls [list punk.test {something blah}] return $decls } } @@ -44,7 +46,7 @@ namespace eval punk::mix::templates { } if {[info commands provider] eq ""} { - punk::cap::interface_capprovider.provider create provider + punk::cap::interface_capprovider.provider create provider punk::mix::templates oo::objdefine provider { method register {{capabilityname_glob *}} { #puts registering punk::mix::templates $capabilityname diff --git a/src/modules/punk/mix/templates/layouts/project/src/make.tcl b/src/modules/punk/mix/templates/layouts/project/src/make.tcl index ce8124f..547b880 100644 --- a/src/modules/punk/mix/templates/layouts/project/src/make.tcl +++ b/src/modules/punk/mix/templates/layouts/project/src/make.tcl @@ -407,6 +407,8 @@ if {$::punkmake::command eq "bootsupport"} { if {$::punkmake::command ne "project"} { puts stderr "Command $::punkmake::command not implemented - aborting." + flush stderr + after 100 exit 1 }