<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.
</pre>
<p><a href="https://github.com/macports/macports-base/commit/2140176c2482393f03934f5a8a041dc907ffb4cf">https://github.com/macports/macports-base/commit/2140176c2482393f03934f5a8a041dc907ffb4cf</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new 2140176c2 _activate_contents improvements
</span>2140176c2 is described below
<span style='display:block; white-space:pre;color:#808000;'>commit 2140176c2482393f03934f5a8a041dc907ffb4cf
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Fri Jun 21 09:09:34 2024 +1000
<span style='display:block; white-space:pre;color:#404040;'> _activate_contents improvements
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Handle directories separately, which saves a file type call per dir and
</span><span style='display:block; white-space:pre;color:#404040;'> allows only the directory list to be sorted, rather than all files. Use
</span><span style='display:block; white-space:pre;color:#404040;'> dicts to avoid list searches, one of which was unsorted.
</span>---
src/registry2.0/portimage.tcl | 98 ++++++++++++++++++++++++-------------------
1 file changed, 55 insertions(+), 43 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/portimage.tcl b/src/registry2.0/portimage.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 92750c79e..cc7c94c2f 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/portimage.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/portimage.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -316,14 +316,14 @@ proc _check_registry {name version revision variants {return_all 0}} {
</span> throw registry::invalid "Registry error: ${name}${composite_spec} is not installed."
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-## Activates a file from an image into the filesystem. Deals with symlinks,
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-## directories and files.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+## Activates a file from an image into the filesystem. Deals with symlinks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+## and regular files.
</span> ##
## @param [in] srcfile path to file in image
## @param [in] dstfile path to activate file to
## @return 1 if file needs to be explicitly deleted if we have to roll back, 0 otherwise
proc _activate_file {srcfile dstfile} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[catch {set filetype [::file type $srcfile]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {::file type $srcfile} result]} {
</span> # this can happen if the archive was built on case-sensitive and we're case-insensitive
# we know any existing dstfile is ours because we checked for conflicts earlier
if {![catch {file type $dstfile}]} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -333,30 +333,30 @@ proc _activate_file {srcfile dstfile} {
</span> error $result
}
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>- switch $filetype {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- directory {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Don't recursively copy directories
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ui_debug "activating directory: $dstfile"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # Don't do anything if the directory already exists.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if { ![::file isdirectory $dstfile] } {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ::file mkdir $dstfile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # fix attributes on the directory.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[getuid] == 0} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ::file attributes $dstfile {*}[::file attributes $srcfile]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # not root, so can't set owner/group
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ::file attributes $dstfile -permissions {*}[::file attributes $srcfile -permissions]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- # set mtime on installed element
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ::file mtime $dstfile [::file mtime $srcfile]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- return 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- default {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ui_debug "activating file: $dstfile"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ::file rename $srcfile $dstfile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_debug "activating file: $dstfile"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::file rename $srcfile $dstfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+## Activates a directory from an image into the filesystem.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+## @param [in] srcdir path to dir in image
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+## @param [in] dstdir path to activate dir to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc _activate_directory {srcdir dstdir} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Don't recursively copy directories
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_debug "activating directory: $dstdir"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Don't do anything if the directory already exists.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {![::file isdirectory $dstdir]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::file mkdir $dstdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # fix attributes on the directory.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[getuid] == 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::file attributes $dstdir {*}[::file attributes $srcdir]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # not root, so can't set owner/group
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::file attributes $dstdir -permissions {*}[::file attributes $srcdir -permissions]
</span> }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ # set mtime on installed element
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::file mtime $dstdir [::file mtime $srcdir]
</span> }
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -571,7 +571,7 @@ proc _activate_contents {port {rename_list {}}} {
</span> variable progress_step
variable progress_total_steps
<span style='display:block; white-space:pre;background:#ffe0e0;'>- set files [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set filesdict [dict create]
</span> set baksuffix .mp_[clock seconds]
set portname [$port name]
set location [$port location]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -581,6 +581,7 @@ proc _activate_contents {port {rename_list {}}} {
</span> set extracted_dir [extract_archive_to_tmpdir $location]
set backups [list]
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ set seendirs [dict create]
</span> # This is big and hairy and probably could be done better.
# First, we need to check the source file, make sure it exists
# Then we remove the $location from the path of the file in the contents
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -598,11 +599,11 @@ proc _activate_contents {port {rename_list {}}} {
</span> _progress update $progress_step $progress_total_steps
set srcfile "${extracted_dir}${file}"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- # To be able to install links, we test if we can lstat the file to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # To be able to install links, we test if 'file type' errors to
</span> # figure out if the source file exists (file exists will return
# false for symlinks on files that do not exist)
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if { [catch {::file lstat $srcfile dummystatvar}] } {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- throw registry::image-error "Image error: Source file $srcfile does not appear to exist (cannot lstat it). Unable to activate port ${portname}."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {::file type $srcfile}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ throw registry::image-error "Image error: Source file $srcfile does not appear to exist. Unable to activate port ${portname}."
</span> }
set owner [registry::entry owner $file]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -619,7 +620,7 @@ proc _activate_contents {port {rename_list {}}} {
</span> }
if {$owner ne "replaced"} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if { [string is true -strict $force] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$force} {
</span> # if we're forcing the activation, then we move any existing
# files to a backup file, both in the filesystem and in the
# registry
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -661,8 +662,8 @@ proc _activate_contents {port {rename_list {}}} {
</span> # we'll set the directory attributes properly for all
# directories.
set directory [::file dirname $file]
<span style='display:block; white-space:pre;background:#ffe0e0;'>- while {$directory ni $files} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- lappend files $directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while {![dict exists $seendirs $directory]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dict set seendirs $directory 1
</span> # Any add here will mean an additional step in the second
# phase of activation. We could just update this once after
# this foreach loop is complete, but that could make the
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -674,33 +675,38 @@ proc _activate_contents {port {rename_list {}}} {
</span> }
# Also add the filename to the imagefile list.
<span style='display:block; white-space:pre;background:#ffe0e0;'>- lappend files $file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dict set filesdict $file 1
</span> }
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ set directories [dict keys $seendirs]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unset seendirs
</span>
# deactivate ports replaced_by this one
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ set deactivate_options [dict create ports_nodepcheck 1]
</span> foreach owner $todeactivate {
_progress intermission
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {$noexec || ![registry::run_target $owner deactivate [list ports_nodepcheck 1]]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- deactivate [$owner name] "" "" 0 [list ports_nodepcheck 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$noexec || ![registry::run_target $owner deactivate $deactivate_options]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ deactivate [$owner name] "" "" 0 $deactivate_options
</span> }
}
# Sort the list in forward order, removing duplicates.
# Since the list is sorted in forward order, we're sure that
<span style='display:block; white-space:pre;background:#ffe0e0;'>- # directories are before their elements.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # parent directories are before their elements.
</span> # We don't have to do this as mentioned above, but it makes the
# debug output of activate make more sense.
<span style='display:block; white-space:pre;background:#ffe0e0;'>- set files [lsort -increasing -unique $files]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set directories [lsort -increasing -unique $directories]
</span> # handle files that are to be renamed
set confirmed_rename_list [list]
foreach {src dest} $rename_list {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- set index [lsearch -exact -sorted $files $src]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if {$index != -1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- set files [lreplace $files $index $index]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[dict exists $filesdict $src]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dict unset filesdict $src
</span> lappend confirmed_rename_list $src $dest
}
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ set files [dict keys $filesdict]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unset filesdict
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> set rollback_filelist [list]
registry::write {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -708,8 +714,14 @@ proc _activate_contents {port {rename_list {}}} {
</span>
try {
$port activate $imagefiles
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach dir $directories {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ _activate_directory ${extracted_dir}${dir} $dir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ _progress update $progress_step $progress_total_steps
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ incr progress_step
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> foreach file $files {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if {[_activate_file "${extracted_dir}${file}" $file] == 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[_activate_file ${extracted_dir}${file} $file] == 1} {
</span> lappend rollback_filelist $file
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -779,7 +791,7 @@ proc _activate_contents {port {rename_list {}}} {
</span> # reactivate deactivated ports
foreach entry $todeactivate {
if {[$entry state] eq "imaged" && ($noexec || ![registry::run_target $entry activate ""])} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- activate [$entry name] [$entry version] [$entry revision] [$entry variants] [list ports_activate_no-exec $noexec]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ activate [$entry name] [$entry version] [$entry revision] [$entry variants] [dict create ports_activate_no-exec $noexec]
</span> }
}
} finally {
</pre><pre style='margin:0'>
</pre>