<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/f77aca31d164cf5ba0b7dd7ed3daa684793c1329">https://github.com/macports/macports-base/commit/f77aca31d164cf5ba0b7dd7ed3daa684793c1329</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit f77aca31d164cf5ba0b7dd7ed3daa684793c1329
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Mon Dec 18 23:11:44 2023 +0100
<span style='display:block; white-space:pre;color:#404040;'> macports/snapshot: Add diff implementation
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Support diffing the snapshot and the current set of installed ports.
</span><span style='display:block; white-space:pre;color:#404040;'> This will also be helpful after migration to show which ports could not
</span><span style='display:block; white-space:pre;color:#404040;'> be restored, or which ports were restored with changes.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Additionally, provide a framework to implement snapshot listing and
</span><span style='display:block; white-space:pre;color:#404040;'> deletion later.
</span>---
src/macports1.0/snapshot.tcl | 297 ++++++++++++++++++++++++++++++++++++++++++-
src/port/port.tcl | 2 +-
2 files changed, 296 insertions(+), 3 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/snapshot.tcl b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 628db3d28..64452c0b1 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -44,6 +44,110 @@ namespace eval snapshot {
</span>
array set options $opts
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {![info exists options(options_snapshot_order)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set operation "create"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set operation ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach op {list create diff delete} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set opname "ports_snapshot_$op"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[info exists options($opname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$operation ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_error "Only one of the --list, --create, --diff, and --delete options can be specified."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ error "Incorrect usage, see port snapshot --help."
</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;'>+ set operation $op
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[info exists options(ports_snapshot_help)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg "Usage: One of:"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg " port snapshot \[--create\] \[--note '<message>'\]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg " port snapshot --list"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg " port snapshot --diff <snapshot-id> \[--requested-only\]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg " port snapshot --delete <snapshot-id>"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0
</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;'>+ switch $operation {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "create" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return [create [array get options]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "list" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_error "list operation not implemented"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "diff" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set snapshot [registry::snapshot get_by_id $options(ports_snapshot_diff)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ array set diff [diff $snapshot]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set show_all [expr {[info exists options(ports_snapshot_all)]}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set note ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {!$show_all} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note "Showing differences in requested ports only. Re-run with --all to see all differences.\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach field {added removed changed} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set result {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach port $diff($field) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $port _ requested
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend result $port
</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;'>+ set diff($field) $result
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $diff(added)] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note "The following ports are installed but not in the snapshot:\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach added_port [lsort -ascii -index 0 $diff(added)] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $added_port name _ _ _ requested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested_variants ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name $requested_variants\n"
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $diff(removed)] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note "The following ports are in the snapshot but not installed:\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach removed_port [lsort -ascii -index 0 $diff(removed)] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $removed_port name _ _ _ requested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested_variants ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name $requested_variants\n"
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $diff(changed)] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note "The following ports are in the snapshot and installed, but with changes:\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach changed_port [lsort -ascii -index 0 $diff(changed)] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $changed_port name _ _ _ requested_variants changes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested_variants ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " - $name $requested_variants\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach change $changes {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $change field old new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ append note " $field changed from '$old' to '$new'\n"
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_msg [string trimright $note "\n"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "delete" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui_error "delete operation not implemented"
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ proc create {opts} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ array set options $opts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> registry::write {
# An option used by user while creating snapshot manually
# to identify a snapshot, usually followed by `port restore`
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -52,7 +156,7 @@ namespace eval snapshot {
</span> } else {
set note "snapshot created for migration"
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>- set inactive_ports [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set inactive_ports [list]
</span> foreach port [registry::entry imaged] {
if {[$port state] eq "imaged"} {
lappend inactive_ports "[$port name] @[$port version]_[$port revision] [$port variants]"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -75,8 +179,197 @@ namespace eval snapshot {
</span> }
}
set snapshot [registry::snapshot create $note]
<span style='display:block; white-space:pre;background:#ffe0e0;'>- # TODO: catch
</span> }
return $snapshot
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ proc _os_mismatch {iplatform iosmajor} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {($iplatform ne "" && $iosmajor != 0) && ($iplatform != $macports::os_platform || $iosmajor != $macports::os_major)} {
</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;'>+ return 0
</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;'>+ proc _find_best_match {port installed} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $port name requested active variants requested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set active [expr {$active eq "installed"}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set requested [expr {$requested == 1}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set best_match {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set best_match_score -1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach iport $installed {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $iport iname iversion irevision ivariants iactive iepoch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set regref [registry::open_entry $iname $iversion $irevision $ivariants $iepoch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iplatform [registry::property_retrieve $regref os_platform]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iosmajor [registry::property_retrieve $regref os_major]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested [expr {[registry::property_retrieve $regref requested] == 1}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested_variants [registry::property_retrieve $regref requested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[_os_mismatch $iplatform $iosmajor]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # ignore ports that were not built on the current macOS version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</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;'>+ set score 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$irequested_variants eq $requested_variants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ incr score
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$irequested == $requested} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ incr score
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$ivariants eq $variants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ incr score
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$active == $iactive} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ incr score
</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;'>+ if {$score > $best_match_score} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set best_match_score $score
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set best_match [list {*}$iport $irequested $irequested_variants]
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return $best_match
</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;'>+ ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Compute the difference between the given snapshot registry object, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # the currently installed ports.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Callers that do not care about differences in unrequested ports are
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # expected to filter the results themselves.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Args:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # snapshot - The snapshot object
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Returns:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # A array in list form with the three entries removed, added, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # changed. Each array value is a list with entries that were removed,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # added, or changed. The format is as follows:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # - Added entries: a 5-tuple of (name, requested, active, variants, requested variants)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # - Removed entries: a 5-tuple of (name, requested, active, variants, requested variants)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # - Changed entries: a 6-typle of (name, requested, active, variants, requested variants, changes)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # where changes is a list of 3-tuples of (changed field, old value, new value)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ proc diff {snapshot} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set portlist [$snapshot ports]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set removed {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set added {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set changed {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ array set snapshot_ports {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $port name requested active variants requested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set active [expr {$active eq "installed"}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set requested [expr {$requested == 1}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set snapshot_ports($name) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[catch {set installed [registry::installed $name]}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # registry::installed failed, the port probably isn't installed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend removed $port
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</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;'>+ if {$active} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # for ports that were active in the snapshot, always compare
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # with the installed active port, if any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set found 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach installed_port $installed {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $installed_port iname iversion irevision ivariants iactive iepoch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set regref [registry::open_entry $iname $iversion $irevision $ivariants $iepoch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iplatform [registry::property_retrieve $regref os_platform]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iosmajor [registry::property_retrieve $regref os_major]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested [expr {[registry::property_retrieve $regref requested] == 1}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested_variants [registry::property_retrieve $regref requested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[_os_mismatch $iplatform $iosmajor]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # ignore ports that were not built on the current macOS version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</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;'>+ if {$iactive} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set found 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ break
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$found} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set changes {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested_variants ne $irequested_variants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "requested variants" $requested_variants $irequested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$variants ne $ivariants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "variants" $variants $ivariants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested != $irequested} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "requested" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$requested == 1 ? "requested" : "unrequested"}] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$irequested == 1 ? "requested" : "unrequested"}]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $changes] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changed [list {*}$port $changes]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Either the port wasn't active in the snapshot, or the port is now no longer active.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # This may still mean that it is missing completely, e.g., because only the version for an older OS is installed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set best_match [_find_best_match $port $installed]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $best_match] <= 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # There is no matching port, so it seems this one is actually missing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend removed $port
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $best_match iname iversion irevision ivariants iactive iepoch irequested irequested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set changes {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested_variants ne $irequested_variants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "requested variants" $requested_variants $irequested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$variants ne $ivariants} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "variants" $variants $ivariants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$requested != $irequested} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "requested" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$requested == 1 ? "requested" : "unrequested $requested"}] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$irequested == 1 ? "requested" : "unrequested $irequested"}]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {$active != $iactive} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changes [list "state" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$active == 1 ? "installed" : "inactive"}] \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ [expr {$iactive == 1 ? "installed" : "inactive"}]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[llength $changes] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend changed [list {*}$port $changes]
</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;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ foreach port [registry::entry imaged] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lassign $installed_port iname iversion irevision ivariants iactive iepoch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set regref [registry::open_entry $iname $iversion $irevision $ivariants $iepoch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iplatform [registry::property_retrieve $regref os_platform]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set iosmajor [registry::property_retrieve $regref os_major]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested [registry::property_retrieve $regref requested]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ set irequested_variants [registry::property_retrieve $regref requested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[_os_mismatch $iplatform $iosmajor]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # port was installed on old OS, ignore
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {[info exists snapshot_ports($iname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # port was in the snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue
</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;'>+ # port was not in the snapshot, it is new
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lappend added [list $iname $irequested $iactive $ivariants $irequested_variants]
</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;'>+ return [list removed $removed added $added changed $changed]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port/port.tcl b/src/port/port.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 4d14a9af0..eb1afc7f6 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4163,7 +4163,7 @@ set cmd_opts_array [dict create {*}{
</span> reclaim {enable-reminders disable-reminders}
fetch {no-mirrors}
bump {patch}
<span style='display:block; white-space:pre;background:#ffe0e0;'>- snapshot {{note 1}}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ snapshot {create list {diff 1} all {delete 1} help {note 1}}
</span> restore {{snapshot-id 1} last}
migrate {continue}
}]
</pre><pre style='margin:0'>
</pre>