<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/ff2840ff3aed2bea329ece8f1624afa89abd3f90">https://github.com/macports/macports-base/commit/ff2840ff3aed2bea329ece8f1624afa89abd3f90</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit ff2840ff3aed2bea329ece8f1624afa89abd3f90
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Sun Jan 7 15:30:30 2018 +0100

<span style='display:block; white-space:pre;color:#404040;'>    migrate: Upgrade base first, automatically restart
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    In case a macOS upgrade breaks uninstallation of ports or using the
</span><span style='display:block; white-space:pre;color:#404040;'>    database, we should upgrade MacPorts base before saving the list of
</span><span style='display:block; white-space:pre;color:#404040;'>    ports and starting port migration.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Move rebuilding MacPorts to the front of 'port migrate', guard it with
</span><span style='display:block; white-space:pre;color:#404040;'>    a check indicating whether a rebuild is necessary and add user
</span><span style='display:block; white-space:pre;color:#404040;'>    interaction questions for the base rebuild. Deal with the case of users
</span><span style='display:block; white-space:pre;color:#404040;'>    with a pre-release version of MacPorts installed and avoid trashing
</span><span style='display:block; white-space:pre;color:#404040;'>    their installations.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    After base was upgraded, automatically re-invoke 'port migrate' with the
</span><span style='display:block; white-space:pre;color:#404040;'>    '--continue' flag that will pick up migration where it left off. If
</span><span style='display:block; white-space:pre;color:#404040;'>    'port migrate' is invoked without '--continue' (e.g. when a user
</span><span style='display:block; white-space:pre;color:#404040;'>    manually recompiled their base installation), ask for confirmation
</span><span style='display:block; white-space:pre;color:#404040;'>    before uninstalling all ports.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Change selfupdate to also update the ports tree just in case users have
</span><span style='display:block; white-space:pre;color:#404040;'>    not used MacPorts in a while and the new ports tree contains build fixes
</span><span style='display:block; white-space:pre;color:#404040;'>    for the new macOS release.
</span>---
 src/macports1.0/macports.tcl |  14 +++--
 src/macports1.0/migrate.tcl  | 126 ++++++++++++++++++++++++++++++++-----------
 src/port/port.tcl            |   8 +++
 3 files changed, 108 insertions(+), 40 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index c353019..3f51d06 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/macports.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4559,15 +4559,13 @@ proc macports::restore_main {opts} {
</span>     return [restore::main $opts]
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Calls the main function for the 'port migrate' command.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# @returns 0 on success, -999 when MacPorts base has been upgraded and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          caller should re-run itself and invoke migration with the --continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          flag set.
</span> proc macports::migrate_main {opts} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # Calls the main function for the 'port migrate' command.
</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;'>-    #           None
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    # Returns:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    #           0 on successful execution.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>     return [migrate::main $opts]
 }
 
<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 d878704..54fc0db 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;'>@@ -37,16 +37,57 @@ package require restore 1.0
</span> package require selfupdate 1.0
 
 namespace eval migrate {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # The main function. Calls each individual step in order.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # @returns 0 on success, -999 when MacPorts base has been upgraded and the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #          caller should re-run itself and invoke migration with the --continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #          flag set.
</span>     proc main {opts} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # The main function. Calls each individual step in order.
</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;'>-        #           opts - options array.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Returns:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        #           0 if success
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>         array set options $opts
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[needs_migration]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists macports::ui_options(questions_yesno)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set msg "Migration will first upgrade MacPorts and then reinstall all installed ports."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set retvalue [$macports::ui_options(questions_yesno) $msg "MigrationPrompt" "" {y} 0 "Would you like to continue?"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {$retvalue == 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    # quit as user answered 'no'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_msg "Aborting migration. You can re-run 'sudo port migrate' later or follow the migration instructions: https://trac.macports.org/wiki/Migration"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg "Upgrading MacPorts..."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set success no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[catch {set success [upgrade_port_command]} 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_error "Upgrading port command failed. Try running 'sudo port -v selfupdate' and then 'sudo port migrate'."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {!$success} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_error "Upgrading port command failed or was not attempted. Please re-install MacPorts manually and then run 'sudo port migrate' again."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # MacPorts successfully upgraded, automatically re-run migration
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # from the new MacPorts installation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return -999
</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 port migrate was not called with --continue, the user probably did
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # that manually and we do not have confirmation to run migration yet;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # do that now.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set continuation [expr {[info exists options(ports_migration_continue)] && $options(ports_migration_continue)}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {!$continuation && [info exists macports::ui_options(questions_yesno)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set msg "Migration will reinstall all installed ports."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set retvalue [$macports::ui_options(questions_yesno) $msg "MigrationContinuationPrompt" "" {y} 0 "Would you like to continue?"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {$retvalue == 1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # quit as user answered 'no'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_msg "Aborting migration. You can re-run 'sudo port migrate' later or follow the migration instructions: https://trac.macports.org/wiki/Migration"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>         # create a snapshot
         ui_msg "Taking a snapshot of the current state..."
         set snapshot [snapshot::main $opts]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -55,50 +96,71 @@ namespace eval migrate {
</span>         set datetime [$snapshot created_at]
         ui_msg "Done: Snapshot '$id' : '$note' created at $datetime"
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[info exists macports::ui_options(questions_yesno)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set msg "Migration will first uninstall all the installed ports, upgrade MacPorts and then reinstall them again."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set retvalue [$macports::ui_options(questions_yesno) $msg "MigrationPrompt" "" {y} 0 "Would you like to continue?"]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$retvalue == 1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                # quit as user answered 'no'
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                ui_msg "Not uninstalling ports."
</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;'>-
</span>         ui_msg "Uninstalling all ports..."
         uninstall_installed
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "Upgrading MacPorts..."
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[catch {upgrade_port_command} result]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_debug $::errorInfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            ui_msg "Upgrading port command failed. Try running 'sudo port -v selfupdate' and then, 'sudo port restore --last'"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_msg "Restoring ports..."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [restore_snapshot]
</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;'>+    # Check whether the current platform is the one this installation was
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # configured for. Returns true, if migration is needed, false otherwise.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # @return true iff the migration procedure is needed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc needs_migration {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$macports::os_platform ne $macports::autoconf::os_platform} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$macports::os_major != $macports::autoconf::os_major} {
</span>             return 1
         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        ui_msg "You need to run 'port restore --last' to complete the migration."
</span>         return 0
     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Uninstall all installed ports for migration
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # @return void on success, raises an error on failure
</span>     proc uninstall_installed {} {
         set options {}
         set portlist [restore::portlist_sort_dependencies_later [registry::entry imaged]]
         foreach port $portlist {
             ui_msg "Uninstalling: [$port name]"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[registry::run_target $port uninstall $options]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                continue
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![registry::run_target $port uninstall $options]} {
</span>                 ui_error "Error uninstalling [$port name]"
             }
         }
     }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    ##
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Restore the list of ports from the latest snapshot using the equivalent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # of 'port restore --last'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # @return 0 on success, an error on failure
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc restore_snapshot {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set options {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set options(ports_restore_last) yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [restore::main [array get options]]
</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;'>+    # Run MacPorts selfupdate, but avoid downgrading pre-release installations
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # Will return true on success, false if no error occured but MacPorts was
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # not re-installed (e.g. because the currently installed version is newer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # than the downloaded release). If reinstallation fails, an error is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # raised.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # @return true on success, false if no update was performed, an error on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #         failure.
</span>     proc upgrade_port_command {} {
         array set optionslist {}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # forced selfupdate
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set optionslist(ports_force) 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # shouldn't sync ports tree
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set optionslist(ports_selfupdate_nosync) 1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set updatestatusvar {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return [uplevel [list selfupdate::main [array get optionslist] $updatestatusvar]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # Force rebuild, but do not allow downgrade
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set optionslist(ports_selfupdate_migrate) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        uplevel [list selfupdate::main [array get optionslist] base_updated]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $base_updated
</span>     }
 }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port/port.tcl b/src/port/port.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 88cef4e..67d92fa 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port/port.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2840,6 +2840,13 @@ proc action_restore { action portlist opts } {
</span> 
 proc action_migrate { action portlist opts } {
     return [macports::migrate_main $opts]
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    set result [macports::migrate_main $opts]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {$result = -999} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # MacPorts base was upgraded, re-execute migrate with the --continue flag
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        execl $::argv0 [list {*}$::argv "--continue"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "Would have executed $::argv0 $::argv --continue"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "Failed to re-execute MacPorts migration, please run 'sudo port migrate' manually."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> }
 
 proc action_upgrade { action portlist opts } {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -4487,6 +4494,7 @@ array set cmd_opts_array {
</span>     fetch       {no-mirrors}
     snapshot    {{note 1}}
     restore     {{snapshot-id 1} last}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    migrate     {continue}
</span> }
 
 ##
</pre><pre style='margin:0'>

</pre>