<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/4317a32103cd26141621acf54fa2fa4870dd9992">https://github.com/macports/macports-base/commit/4317a32103cd26141621acf54fa2fa4870dd9992</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 4317a32103cd26141621acf54fa2fa4870dd9992
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Thu Nov 30 20:48:08 2023 +0100

<span style='display:block; white-space:pre;color:#404040;'>    macports/restore: Fix dependency calculation
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Improve dependency calculation to take the requested variants from the
</span><span style='display:block; white-space:pre;color:#404040;'>    snapshot into account and fix it so that all dependencies that are
</span><span style='display:block; white-space:pre;color:#404040;'>    needed on the current system are considered. Because a new OS may have
</span><span style='display:block; white-space:pre;color:#404040;'>    to compile from source for a while, these dependencies can significantly
</span><span style='display:block; white-space:pre;color:#404040;'>    differ from the previously installed packages.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Note that this code does attempt to deal with alternative providers for
</span><span style='display:block; white-space:pre;color:#404040;'>    certain functionality (such as the certsync port as an alternative for
</span><span style='display:block; white-space:pre;color:#404040;'>    curl-ca-bundle, or -devel ports that can be installed in place of
</span><span style='display:block; white-space:pre;color:#404040;'>    a non-devel port), but this code does not yet seem to work correctly.
</span><span style='display:block; white-space:pre;color:#404040;'>    More testing is needed.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Additionally, there should be code to deal with build failures so that
</span><span style='display:block; white-space:pre;color:#404040;'>    ports whose dependencies failed to compile are skipped with a useful
</span><span style='display:block; white-space:pre;color:#404040;'>    message. At the moment, the attempt to install the dependent port
</span><span style='display:block; white-space:pre;color:#404040;'>    instead prompts to re-install the dependency, which (a) interrupts the
</span><span style='display:block; white-space:pre;color:#404040;'>    automated flow because it waits for a user prompt and (b) is pointless,
</span><span style='display:block; white-space:pre;color:#404040;'>    because the dependency will just fail to build again.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Improve the output formatting so that it matches MacPorts' style by
</span><span style='display:block; white-space:pre;color:#404040;'>    using $macports::ui_prefix where appropriate.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    What's missing for this to be ready for release is:
</span><span style='display:block; white-space:pre;color:#404040;'>     - A check at the end that compares the installed requested ports with
</span><span style='display:block; white-space:pre;color:#404040;'>       the requested ports in the snapshot and informs the user if ports are
</span><span style='display:block; white-space:pre;color:#404040;'>       missing (and explains why they are missing).
</span><span style='display:block; white-space:pre;color:#404040;'>     - Help output that instructs the user how to re-attempt the migration
</span><span style='display:block; white-space:pre;color:#404040;'>       if it fails (e.g., by running port restore --last)
</span><span style='display:block; white-space:pre;color:#404040;'>     - Manpages and documentation
</span><span style='display:block; white-space:pre;color:#404040;'>     - Some usability improvements for snapshot management. There is
</span><span style='display:block; white-space:pre;color:#404040;'>       currently no way to list all snapshots or delete old snapshots.
</span>---
 src/macports1.0/restore.tcl | 391 +++++++++++++++++++++++++++-----------------
 1 file changed, 245 insertions(+), 146 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/restore.tcl b/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 13ebbc91a..6cfeef0ef 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -31,10 +31,14 @@
</span> package provide restore 1.0
 
 package require macports 1.0
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require macports_dlist 1.0
</span> package require migrate 1.0
 package require registry 1.0
 package require snapshot 1.0
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require struct::graph
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require struct::graph::op
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> namespace eval restore {
     proc main {opts} {
         # The main function. If the action is provided a snapshot id, then it deactivates
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -62,11 +66,11 @@ namespace eval restore {
</span>         if {[info exists options(ports_restore_snapshot-id)]} {
             # use the specified snapshot
             set snapshot [fetch_snapshot $options(ports_restore_snapshot-id)]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Deactivating all ports installed.."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            deactivate_all
</span>         } elseif {[info exists options(ports_restore_last)]} {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            # use the last snapshot
</span>             set snapshot [fetch_snapshot_last]
         } else {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            # ask the user to select a snapshot
</span>             set snapshots [list_snapshots]
             set human_readable_snapshots {}
             foreach snapshot $snapshots {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -80,19 +84,18 @@ namespace eval restore {
</span> 
             set retstring [$macports::ui_options(questions_singlechoice) "Select any one snapshot to restore:" "" $human_readable_snapshots]
             set snapshot [lindex $snapshots $retstring]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Deactivating all ports installed.."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            deactivate_all
</span>         }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "Restoring snapshot '[$snapshot note]' created at [$snapshot created_at]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$macports::ui_prefix Deactivating all installed ports"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        deactivate_all
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "Fetching ports to install..."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$macports::ui_prefix Restoring snapshot '[$snapshot note]' created at [$snapshot created_at]"
</span>         set snapshot_portlist [$snapshot ports]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "Restoring the selected snapshot.."
</span>         restore_state [$snapshot ports]
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        # TODO Check whether all ports have been restored; print an analysis of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # ports that have not been restored if errors did occur.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         return 0
     }
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -108,197 +111,293 @@ namespace eval restore {
</span>         return [registry::snapshot get_all]
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_later {portlist} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Sorts a list of port references such that ports come before
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # their dependencies. Ideal for uninstalling a port.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Sorts a list of port references such that ports come before their
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # dependencies. Ideal for uninstalling all ports.
</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;'>+    #       portlist - the list of port references
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Returns:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #       the list in order such that leaves are first
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc deactivation_order {portlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Create a graph where each edge means "is dependent of". A topological
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # sort of this graph should return leaves (i.e., ports which have no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # dependents) first.
</span>         #
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Args:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #       portlist - the list of port references
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Returns:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #       the list in dependency-sorted order
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # We're going to use Tarjan's algorithm for this, which also deals
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # which potential cycles.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set dependents [::struct::graph]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set entries {}
</span> 
         foreach port $portlist {
             set portname [$port name]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend entries($portname) $port
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # Avoid adding ports in loop
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {![info exists dependents($portname)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set dependents($portname) {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach result [$port dependents] {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend dependents($portname) [$result name]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set entries($portname) $port
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![$dependents node exists $portname]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                $dependents node insert $portname
</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 dependent [$port dependents] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set dependent_name [$dependent name]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {![$dependents node exists $dependent_name]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    $dependents node insert $dependent_name
</span>                 }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                $dependents arc insert $portname $dependent_name
</span>             }
         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set ret {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            portlist_sort_dependencies_later_helper $port entries dependents seen ret
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return $ret
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_later_helper {port up_entries up_dependents up_seen up_retlist} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        upvar 1 $up_seen seen
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {![info exists seen($port)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set seen($port) 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            upvar 1 $up_entries entries $up_dependents dependents $up_retlist retlist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set name [$port name]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            foreach dependent $dependents($name) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {[info exists entries($dependent)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    foreach entry $entries($dependent) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        portlist_sort_dependencies_later_helper $entry entries dependents seen retlist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Compute a list of strongly connected components using Tarjan's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # algorithm. This list should contain one-element lists (unless there
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # are dependency cycles).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portlist_sccs [::struct::graph::op::tarjan $dependents]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set operations {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach scc $portlist_sccs {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach portname $scc {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                lappend operations $entries($portname)
</span>             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend retlist $port
</span>         }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $dependents destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $operations
</span>     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Deactivate all installed ports in reverse dependency order so that as few
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # warnings as possible will be printed.
</span>     proc deactivate_all {} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portlist [portlist_sort_dependencies_later [registry::entry imaged]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portlist [deactivation_order [registry::entry imaged]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         foreach port $portlist {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Deactivating: [$port name]"
</span>             if {[$port state] eq "installed"} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {[registry::run_target $port deactivate {}]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {![registry::run_target $port deactivate {ports_force 1}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[catch {portimage::deactivate [$port name] [$port version] [$port revision] [$port variants] {ports_force 1}} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_debug $::errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_warn "Failed to deactivate [$port name]: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span>                 }
             }
         }
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_first {portlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Convert a variant string into a serialized array of variations suitable for passing to mportopen
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc variants_to_variations_arr {variantstr} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set split_variants_re {([-+])([[:alpha:]_]+[\w\.]*)}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set result {}
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Sorts a list of port references such that ports appear after
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # their dependencies. Ideal for installing a port.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Args:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #       portlist - the list of port references
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Returns:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #       the list in dependency-sorted order
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach {match sign variant} [regexp -all -inline -- $split_variants_re $variantstr] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend result $variant $sign
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        array set port_installed {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        array set port_deps {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        array set port_in_list {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set new_list [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Sorts a list of port references such that ports appear after their
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # dependencies. Ideal for installing a port.
</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;'>+    #       portlist - the list of port references
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Returns:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #       the list in dependency-sorted order
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc resolve_dependencies {portlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set ports {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set dep_ports {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set dependencies [::struct::graph]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg -nonewline "$macports::ui_prefix Computing dependency order. This will take a while, please be patient"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        flush stdout
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[macports::ui_isset ports_debug]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg {}
</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;'>+        # Populate $ports so that we can look up requested variants given the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # port name.
</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
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # bool-ify active
</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 ports($name) [list $requested $active $variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Iterate over the requested ports to calculate the dependency tree.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Use a worklist so that we can push items to the front to do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # depth-first dependency resolution.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set worklist [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set seen [list]
</span>         foreach port $portlist {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            lassign $port name requested _ _ _
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set name [lindex $port 0]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set requested [lindex $port 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$requested eq 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {!$requested} {
</span>                 continue
             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set active 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[lindex $port 2] eq "installed"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set active 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set requested_variants [lindex $port 4]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {![info exists port_in_list($name)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set port_in_list($name) 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set port_installed($name) 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                incr port_in_list($name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend worklist $name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        while {[llength $worklist] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set worklist [lassign $worklist portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # If we've already seen this port, continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[lsearch -sorted -exact $seen $portname] != -1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                continue
</span>             }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend seen $portname
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set seen [lsort -ascii $seen]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "Dependency calculation for port $portname"
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {![info exists port_deps(${name},${requested_variants})]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set port_deps(${name},${requested_variants}) [portlist_sort_dependencies_first_helper $name $requested_variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Find the port
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set port [mportlookup $portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[llength $port] < 2} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_warn "Port $portname not found, skipping"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                continue
</span>             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend new_list [list $name $requested_variants $active]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set operation_list [list]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        while {[llength $new_list] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists ports($portname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                lassign $ports($portname) requested _ variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif {[info exists dep_ports($portname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set variants $dep_ports($portname)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set requested 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set variants ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set requested 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {($requested || [macports::ui_isset ports_verbose]) && ![macports::ui_isset ports_debug]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # Print a progress indicator if this is a requested port (or
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # for every port if in verbose mode).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg -nonewline "."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                flush stdout
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set oldLen [llength $new_list]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            foreach port $new_list {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                lassign $port name requested_variants active
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Open the port with the requested variants from the snapshot
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set variations [variants_to_variations_arr $variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            array set portinfo [lindex $port 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[catch {set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] $variations]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                error "Unable to open port '$portname': $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            array unset portinfo
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {$active && $port_installed($name) < ($port_in_list($name) - 1)} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    continue
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set installable 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach dep $port_deps(${name},${requested_variants}) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {[info exists port_installed($dep)] && $port_installed($dep) == 0} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set installable 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Check whether any of ports in the snapshot conflicts with this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # port. If that's the case, then the port in the snapshot is likely
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # an alternative provider for the functionality of this port (like
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # for example certsync is for curl-ca-bundle) and the user had this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # alternative installed.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            array set portinfo [mportinfo $mport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists portinfo(conflicts)] && [llength $portinfo(conflicts)] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set conflict_found 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach conflictport $portinfo(conflicts) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[info exists ports($conflictport)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # The conflicting port was installed in the snapshot.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # Identify all ports that depend on this port, and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # change their dependency to the port in the snapshot.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_debug "Snapshot contains $conflictport, which conflicts with dependency $portinfo(name)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        if {![$dependencies node exists $conflictport]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            $dependencies node insert $conflictport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set arcs [$dependencies arcs -in $portinfo(name)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        foreach arc $arcs {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            ui_debug "Changing dependency [$dependencies arc source $arc]->[$dependencies arc target $arc] to [$dependencies arc source $arc]->$conflictport"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            $dependencies arc move-target $arc $conflictport
</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 worklist [linsert $worklist 0 $conflictport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set conflict_found 1
</span>                         break
                     }
                 }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {$installable} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend operation_list [list $name $requested_variants $active]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    incr port_installed($name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set index [lsearch $new_list [list $name $requested_variants $active]]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set new_list [lreplace $new_list $index $index]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {$conflict_found} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    mportclose $mport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    continue
</span>                 }
             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[llength $new_list] == $oldLen} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return -code error "Stuck in loop"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Compute the dependencies for the 'install' target. Do not recurse
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # into the dependencies: we'll do that here manually in order to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  (1) keep our dependency graph updated
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  (2) use the requested variants when opening the dependencies
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  (3) identify if an alternative provider was used based on the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  snapshot and the conflicts information (such as for example when
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  a port depends on curl-ca-bundle, but the snapshot contains
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            #  certsync, which conflicts with curl-ca-bundle).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[mportdepends $mport install 0] != 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                error "Unable to determine dependencies for port '$portname'"
</span>             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return $operation_list
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_first_helper {portname requested_variants} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set dependency_list [list]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set port_search_result [mportlookup $portname]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[llength $port_search_result] < 2} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_warn "Skipping $portname (not in the ports tree)"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return $dependency_list
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        array set portinfo [lindex $port_search_result 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[catch {set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] $requested_variants]} result]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            global errorInfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            puts stderr "$errorInfo"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return -code error "Unable to open port '$portname': $result"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        array unset portinfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        array set portinfo [mportinfo $mport]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        mportclose $mport
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set dependency_types { depends_fetch depends_extract depends_build depends_lib depends_run }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach dependency_type $dependency_types {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[info exists portinfo($dependency_type)] && [string length $portinfo($dependency_type)] > 0} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach dependency $portinfo($dependency_type) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend dependency_list [lindex [split $dependency:] end]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set provides [ditem_key $mport provides]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![$dependencies node exists $provides]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                $dependencies node insert $provides
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach dependency [ditem_key $mport requires] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {![$dependencies node exists $dependency]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    $dependencies node insert $dependency
</span>                 }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+                lassign [dlist_search $macports::open_mports provides $dependency] dep_ditem
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set dependency_requested_variants [[ditem_key $dep_ditem workername] eval {set requested_variants}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set dep_ports($dependency) $dependency_requested_variants
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                $dependencies arc insert $provides $dependency
</span>             }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            set worklist [linsert $worklist 0 {*}[ditem_key $mport requires]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            mportclose $mport
</span>         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        return $dependency_list
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc restore_state {snapshot_portlist} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "Installing ports:"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set snapshot_portlist [lsort -index 0 -nocase $snapshot_portlist]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $snapshot_portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # 0: port name
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # 1: requested (0/1)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # 2: state (imaged/installed, i.e. inactive/active)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # 3: variants
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            # 4: requested_variants
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[lindex $port 1] == 1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                # Hide unrequested ports
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                if {[lindex $port 2] eq "installed"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_msg "   [lindex $port 0] [lindex $port 3] (requested: [lindex $port 4])"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![macports::ui_isset ports_debug]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$macports::ui_prefix Sorting dependency tree"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Compute a list of stronly connected components using Tarjan's
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # algorithm. The result should be a list of one-element sets (unless
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # there are cylic dependencies, which there shouldn't be). Because of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # how Tarjan's algorithm works, this list should be in topological
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # order, though. This is what we need for installation.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portlist_sccs [::struct::graph::op::tarjan $dependencies]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set operations {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach scc $portlist_sccs {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach name $scc {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {[info exists ports($name)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend operations [list $name {*}$ports($name)]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } elseif {[info exists dep_ports($name)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend operations [list $name 0 1 $dep_ports($name)]
</span>                 } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_msg "   [lindex $port 0] [lindex $port 3] (requested: [lindex $port 4]) (inactive)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend operations [list $name 0 1 {}]
</span>                 }
             }
         }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set sorted_snapshot_portlist [portlist_sort_dependencies_first $snapshot_portlist]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $sorted_snapshot_portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $dependencies destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $operations
</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 restore_state {snapshot_portlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set sorted_snapshot_portlist [resolve_dependencies $snapshot_portlist]
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set name [string trim [lindex $port 0]]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set variations [lindex $port 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set active [lindex $port 2]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set index 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set length [llength $sorted_snapshot_portlist]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach port $sorted_snapshot_portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            incr index
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lassign $port name requested active variants
</span> 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {$variants ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "$macports::ui_prefix $index/$length Restoring $name $variants from snapshot"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "$macports::ui_prefix $index/$length Restoring $name from snapshot"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span>             if {!$active} {
                 set target install
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "Installing (not activating): $name $variations"
</span>             } else {
                 set target activate
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "Installing (and activating): $name $variations"
</span>             }
 
             if {[catch {set res [mportlookup $name]} result]} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -314,8 +413,9 @@ namespace eval restore {
</span>             array set portinfo [lindex $res 1]
             set porturl $portinfo(porturl)
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set options(ports_requested) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set options(ports_requested) $requested
</span>             set options(subport) $portinfo(name)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            set variations [variants_to_variations_arr $variants]
</span> 
             if {[catch {set workername [mportopen $porturl [array get options] $variations]} result]} {
                 global errorInfo
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -331,7 +431,6 @@ namespace eval restore {
</span>             } else {
                 mportclose $workername
             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            # TODO: some ports may get re-activated to fulfil dependencies - recheck?
</span>         }
     }
 }
</pre><pre style='margin:0'>

</pre>