From 0eb2609693c7ce8d4e26b6036be1b87e97aec892 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 7 Jan 2025 06:10:25 +0800 Subject: [PATCH 07/16] Hierarchical portgroup search Credits @RJVB --- src/macports1.0/macports.tcl | 43 +++++++++++++++++++++++++++++++++++- src/port1.0/portutil.tcl | 34 ++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl index 7c5539666..534cd9752 100644 --- a/src/macports1.0/macports.tcl +++ b/src/macports1.0/macports.tcl @@ -1184,7 +1184,7 @@ proc mportinit {{up_ui_options {}} {up_options {}} {up_variations {}}} { if {[regexp $sources_conf_source_re $line _ url flags]} { set flags [split $flags ,] foreach flag $flags { - if {$flag ni [list nosync default]} { + if {$flag ni [list nosync default own_portgroups_first]} { ui_warn "$sources_conf source '$line' specifies invalid flag '$flag'" } if {$flag eq "default"} { @@ -2021,6 +2021,9 @@ proc macports::worker_init {workername portpath porturl portbuildpath options va $workername alias getportresourcepath macports::getportresourcepath $workername alias getportlogpath macports::getportlogpath $workername alias getdefaultportresourcepath macports::getdefaultportresourcepath + $workername alias getlocalporttreelist macports::getlocalporttreelist + $workername alias getlocaltreeoptions macports::getlocaltreeoptions + $workername alias getallporttrees macports::getallporttrees $workername alias getprotocol macports::getprotocol $workername alias getportdir macports::getportdir $workername alias findBinary macports::findBinary @@ -2398,6 +2401,44 @@ proc macports::getdefaultportresourcepath {{path {}}} { return $proposedpath } +## +# @return the list of local port trees +# +proc macports::getlocalporttreelist {} { + global macports::sources + set sourcetreelist {} + foreach source $sources { + if {[macports::getprotocol $source] eq "file"} { + lappend sourcetreelist [string range [lindex ${source} 0] 7 end] + } + } + return ${sourcetreelist} +} + +## +# @return the options for local port tree @param tree +# +proc macports::getlocaltreeoptions {path} { + global macports::sources + set sourcetreelist {} + set path [file normalize ${path}] + foreach source $sources { + set spath [file normalize [string range [lindex ${source} 0] 7 end]] + if {${spath} eq ${path}} { + return [lrange ${source} 1 end] + } + } + return {} +} + +proc macports::getallporttrees {} { + global macports::sources + set sourcetreelist {} + foreach source $sources { + lappend sourcetreelist [lindex ${source} 0] + } + return ${sourcetreelist} +} ## # Opens a MacPorts portfile specified by a URL. The URL can be local (starting diff --git a/src/port1.0/portutil.tcl b/src/port1.0/portutil.tcl index 4b52d019e..fd3f002b8 100644 --- a/src/port1.0/portutil.tcl +++ b/src/port1.0/portutil.tcl @@ -2656,14 +2656,44 @@ proc PortGroup {group version} { } } - set groupFile [getportresourcepath $porturl "port1.0/group/${group}-${version}.tcl"] + # optionally look first in the port's own tree (the old default behaviour) + set ownfirst [lsearch [getlocaltreeoptions [file dirname [getportresourcepath $porturl]]] own_portgroups_first] + if {${ownfirst} >= 0} { + # check if the requested PortGroup exists in the current port's ports tree, but + # don't return a fallback variant. + set groupFile [getportresourcepath $porturl "port1.0/group/${group}-${version}.tcl" no] + } + if {![info exists groupFile] || ![file exists ${groupFile}]} { + # no luck, scan the ports tree list in much the same way port lookup works: + # test each tree in the order they are listed in sources.conf, until a hit is found. + set lsources [getlocalporttreelist] + foreach source ${lsources} { + set groupFile [file join ${source} _resources port1.0/group/${group}-${version}.tcl] + if {[file exists ${groupFile}]} { + ui_debug "PortGroup ${group} ${version} found in $source" + break + } + } + if {![info exists groupFile] || ![file exists ${groupFile}]} { + # still nothing; redo the resource lookup but this time with a fallback. + # This should catch situations where port trees are configured with a + # protocol that is not "file://". + set groupFile [getportresourcepath $porturl "port1.0/group/${group}-${version}.tcl"] + } + } else { + ui_debug "Custom PortGroup ${group} ${version} found: $groupFile" + } if {[file exists $groupFile]} { lappend PortInfo(portgroups) [list $group $version $groupFile] uplevel [list source $groupFile] - ui_debug "Sourcing PortGroup $group $version from $groupFile" + ui_debug "Sourced PortGroup $group $version from $groupFile" } else { ui_error "${subport}: PortGroup ${group} ${version} could not be located. ${group}-${version}.tcl does not exist." + ui_info " Trees checked: [getallporttrees]" + if {${ownfirst} >= 0} { + ui_info " Also checked for [getportresourcepath $porturl "port1.0/group/${group}-${version}.tcl" no]" + } return -code error "PortGroup not found" } } -- 2.49.0