<pre style='margin:0'>
Umesh Singla (umeshksingla) pushed a commit to branch gsoc17-migrate
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/fbd490cd13d12a0d1cb65981159abf5f32ac9b6d">https://github.com/macports/macports-base/commit/fbd490cd13d12a0d1cb65981159abf5f32ac9b6d</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit fbd490cd13d12a0d1cb65981159abf5f32ac9b6d
</span>Author: Umesh Singla <umeshksingla@macports.org>
AuthorDate: Mon Aug 28 03:44:22 2017 +0530

<span style='display:block; white-space:pre;color:#404040;'>    Deactivate ports before `restore`
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Move sorting and `recover_state` procedures to restore module
</span><span style='display:block; white-space:pre;color:#404040;'>    and let migrate call the restore procedures.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Also, instead of using other APIs to uninstall/deactivate which
</span><span style='display:block; white-space:pre;color:#404040;'>    again sort the dependencies, directly make them use the API
</span><span style='display:block; white-space:pre;color:#404040;'>    registry::run_target, since this runs fetching dependencies only
</span><span style='display:block; white-space:pre;color:#404040;'>    once.
</span>---
 src/macports1.0/migrate.tcl | 272 ++++----------------------------------------
 src/macports1.0/restore.tcl | 243 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 262 insertions(+), 253 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/migrate.tcl b/src/macports1.0/migrate.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index fef36c1..409897b 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/migrate.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/migrate.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -34,6 +34,7 @@ package require macports 1.0
</span> package require registry 1.0
 package require Pextlib 1.0
 package require snapshot 1.0
<span style='display:block; white-space:pre;background:#e0ffe0;'>+package require restore 1.0
</span> package require registry_uninstall 2.0
 
 namespace eval migrate {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -51,275 +52,42 @@ namespace eval migrate {
</span>         # create a snapshot
         ui_msg "$macports::ui_prefix Taking a snapshot of the current state.."
         set snapshot [snapshot::main $opts]
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        set id [$snapshot id]
</span>         set note [$snapshot note]
         set datetime [$snapshot created_at]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "$macports::ui_prefix Done: snapshot '$note' created at $datetime"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "$macports::ui_prefix Fetching ports.."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portlist [$snapshot ports]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "$macports::ui_prefix Uninstalling all ports.."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        uninstall_installed [registry::entry imaged]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "$macports::ui_prefix Restoring the original state.."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        recover_ports_state $portlist
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # TODO: CLEAN PARTIAL BUILDS STEP HERE
</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:#ffe0e0;'>-    proc portlist_sort_dependencies_first {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 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:#ffe0e0;'>-
</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:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set new_list [list]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</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:#ffe0e0;'>-                continue
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><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 variantstr [lindex $port 3]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$variantstr eq "(null)"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set variantstr ""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set variants ""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[info exists variantstr]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                while 1 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set nextplus [string last + $variantstr]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set nextminus [string last - $variantstr]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {$nextplus > $nextminus} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set next $nextplus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set sign +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set next $nextminus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set sign -
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {$next == -1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set v [string range $variantstr [expr $next + 1] end]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend variants $v $sign
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set variantstr [string range $variantstr 0 [expr $next - 1]]
</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:#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:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {![info exists port_deps(${name},${variants})]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set port_deps(${name},${variants}) [portlist_sort_dependencies_first_helper $name $variants]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend new_list [list $name $variants $active]
</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:#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:#ffe0e0;'>-
</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;'>-                foreach {name variants active} $port break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</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},${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:#ffe0e0;'>-                        break
</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:#ffe0e0;'>-                if {$installable} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend operation_list [list $name $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 $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:#ffe0e0;'>-                }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</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:#ffe0e0;'>-            }
</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;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_first_helper {portname variant_info} {
</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)] $variant_info]} 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:#ffe0e0;'>-                }
</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:#ffe0e0;'>-        return $dependency_list
</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:#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:#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:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set portname [$port name]
</span><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:#ffe0e0;'>-                }
</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:#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;'>-
</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:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend retlist $port
</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:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc uninstall_installed {portlist} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portlist [portlist_sort_dependencies_later $portlist]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$macports::ui_prefix Done: snapshot '$id':'$note' created at $datetime"
</span> 
         if {[info exists macports::ui_options(questions_yesno)]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set msg "Migration will first uninstall all the installed ports."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set msg "Migration will first uninstall all the installed ports and then reinstall."
</span>             set retvalue [$macports::ui_options(questions_yesno) $msg "MigrationPrompt" "" {y} 0 "Would you like to continue?"]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>             if {$retvalue == 0} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set portname [$port name]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_msg "Uninstalling: $portname"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    try -pass_signal {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        # 'registry_uninstall' takes name, version, revision, variants and an options list for a port
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        registry_uninstall::uninstall [$port name] [$port version] [$port revision] [$port variants] {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    } catch {{*} eCode eMessage} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        ui_error "Error uninstalling $portname: $eMessage"
</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;'>+                ui_msg "$macports::ui_prefix Uninstalling all ports.."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                uninstall_installed [registry::entry imaged]
</span>             } else {
                 ui_msg "Not uninstalling ports."
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 0
</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;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc recover_ports_state {portlist} {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set sorted_portlist [portlist_sort_dependencies_first $portlist]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $sorted_portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            puts "$port"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "$macports::ui_prefix Fetching ports to install.."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set snapshot_portlist [$snapshot ports]
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        puts "MacPorts Version: [macports::version]"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach port $sorted_portlist {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            
</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;'>+        ui_msg "$macports::ui_prefix Restoring the original state.."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        restore::restore_state $snapshot_portlist
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {!$active} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set target install
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "Installing (not activating): $name $variations"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set target activate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "Installing (and activating): $name $variations"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # TODO: CLEAN PARTIAL BUILDS STEP HERE
</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:#ffe0e0;'>-            if {[catch {set res [mportlookup $name]} result]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                global errorInfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_debug "$errorInfo"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return -code error "lookup of port $name failed: $result"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[llength $res] < 2} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                # not in the index, but we already warned about that earlier
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc uninstall_installed {portlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portlist [portlist_sort_dependencies_later [registry::entry imaged]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg "Uninstalling: [$port name]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[registry::run_target $port uninstall]} {
</span>                 continue
<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:#ffe0e0;'>-            array unset portinfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            array set portinfo [lindex $res 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set porturl $portinfo(porturl)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set options(ports_requested) 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set options(subport) $portinfo(name)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[catch {set workername [mportopen $porturl [array get options] $variations]} 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 '$name': $result"
</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:#ffe0e0;'>-            if {[catch {set result [mportexec $workername $target]} result]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                global errorInfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                mportclose $workername
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "$errorInfo"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                return -code error "Unable to execute target 'install' for port '$name': $result"
</span>             } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                mportclose $workername
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_error "Error uninstalling [$port name]"
</span>             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            # TODO: some ports may get re-activated to fulfil dependencies - recheck?
</span>         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     }
 }
<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 9f55149..0d34b8a 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;'>@@ -43,15 +43,22 @@ namespace eval restore {
</span>             # use that snapshot
             set snapshot [fetch_snapshot $options(ports_restore_snapshot-id)]
             puts $snapshot
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts [$snapshot id]
</span>             puts [$snapshot note]
             puts [$snapshot created_at]
             puts [$snapshot ports]
         } else {
             set list [list_snapshots]
             foreach l $list {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                puts "[$l note] [$l created_at]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                puts "[$l id] : [$l note] [$l created_at]"
</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 Deactivating all ports installed.."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        deactivate_all
</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 Restoring the selected snapshot.."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        restore_state [$snapshot ports]
</span>     }
 
     proc fetch_snapshot {snapshot_id} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -61,4 +68,238 @@ namespace eval restore {
</span>     proc list_snapshots {} {
         return [registry::snapshot get_all]
     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc portlist_sort_dependencies_later {portlist} {
</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
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # 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;'>+        # 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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set portname [$port name]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend entries($portname) $port
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Avoid adding ports in loop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![info exists dependents($portname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set dependents($portname) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach result [$port dependents] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend dependents($portname) [$result name]
</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;'>+        set ret {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            portlist_sort_dependencies_later_helper $port entries dependents seen ret
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $ret
</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 portlist_sort_dependencies_later_helper {port up_entries up_dependents up_seen up_retlist} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        upvar 1 $up_seen seen
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![info exists seen($port)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set seen($port) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            upvar 1 $up_entries entries $up_dependents dependents $up_retlist retlist
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set name [$port name]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach dependent $dependents($name) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {[info exists entries($dependent)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    foreach entry $entries($dependent) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        portlist_sort_dependencies_later_helper $entry entries dependents seen retlist
</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;'>+            lappend retlist $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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc deactivate_all {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portlist [portlist_sort_dependencies_later [registry::entry imaged]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach port $portlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg "Deactivating: [$port name]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[registry::run_target $port deactivate]} {
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    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;'>+        # Sorts a list of port references such that ports appear after
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # their 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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set port_installed {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set port_deps {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set port_in_list {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set new_list [list]
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set name [lindex $port 0]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set requested [lindex $port 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {$requested eq 0} {
</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;'>+            set active 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[lindex $port 2] eq "installed"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set active 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set variantstr [lindex $port 3]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {$variantstr eq "(null)"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set variantstr ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set variants ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists variantstr]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                while 1 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set nextplus [string last + $variantstr]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set nextminus [string last - $variantstr]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {$nextplus > $nextminus} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set next $nextplus
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set sign +
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set next $nextminus
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set sign -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {$next == -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;'>+                    set v [string range $variantstr [expr $next + 1] end]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend variants $v $sign
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set variantstr [string range $variantstr 0 [expr $next - 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;'>+            if {![info exists port_in_list($name)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set port_in_list($name) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set port_installed($name) 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![info exists port_deps(${name},${variants})]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set port_deps(${name},${variants}) [portlist_sort_dependencies_first_helper $name $variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend new_list [list $name $variants $active]
</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_list [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        while {[llength $new_list] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set oldLen [llength $new_list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach port $new_list {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach {name variants active} $port break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {$active && $port_installed($name) < ($port_in_list($name) - 1)} {
</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;'>+                set installable 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach dep $port_deps(${name},${variants}) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[info exists port_installed($dep)] && $port_installed($dep) == 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set installable 0
</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;'>+                if {$installable} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend operation_list [list $name $variants $active]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    incr port_installed($name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set index [lsearch $new_list [list $name $variants $active]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set new_list [lreplace $new_list $index $index]
</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 $new_list] == $oldLen} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                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;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $operation_list
</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 portlist_sort_dependencies_first_helper {portname variant_info} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set dependency_list [list]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set port_search_result [mportlookup $portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[llength $port_search_result] < 2} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_warn "Skipping $portname (not in the ports tree)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return $dependency_list
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set portinfo [lindex $port_search_result 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[catch {set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] $variant_info]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            global errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts stderr "$errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return -code 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:#e0ffe0;'>+        array set portinfo [mportinfo $mport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        mportclose $mport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set dependency_types { depends_fetch depends_extract depends_build depends_lib depends_run }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach dependency_type $dependency_types {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists portinfo($dependency_type)] && [string length $portinfo($dependency_type)] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach dependency $portinfo($dependency_type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend dependency_list [lindex [split $dependency:] end]
</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 $dependency_list
</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 [portlist_sort_dependencies_first $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;'>+            puts "$port"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        puts "MacPorts Version: [macports::version]"
</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;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set name [string trim [lindex $port 0]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set variations [lindex $port 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set active [lindex $port 2]
</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;'>+                set target install
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "Installing (not activating): $name $variations"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set target activate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "Installing (and activating): $name $variations"
</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 {[catch {set res [mportlookup $name]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                global errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_debug "$errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return -code error "lookup of port $name failed: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[llength $res] < 2} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # not in the index, but we already warned about that earlier
</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;'>+            array unset portinfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            array set portinfo [lindex $res 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set porturl $portinfo(porturl)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set options(ports_requested) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set options(subport) $portinfo(name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[catch {set workername [mportopen $porturl [array get options] $variations]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                global errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                puts stderr "$errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return -code error "Unable to open port '$name': $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;'>+            if {[catch {set result [mportexec $workername $target]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                global errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                mportclose $workername
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "$errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return -code error "Unable to execute target 'install' for port '$name': $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                mportclose $workername
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # TODO: some ports may get re-activated to fulfil dependencies - recheck?
</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> }
\ No newline at end of file
</pre><pre style='margin:0'>

</pre>