@@ -37,16 +37,57 @@ package require restore 1.0
package require selfupdate 1.0
namespace eval migrate {
# #
# The main function. Calls each individual step in order.
#
# @returns 0 on success, -999 when MacPorts base has been upgraded and the
# caller should re-run itself and invoke migration with the --continue
# flag set.
proc main {opts} {
# The main function. Calls each individual step in order.
#
# Args:
# opts - options array.
# Returns:
# 0 if success
array set options $opts
if {[needs_migration]} {
if {[info exists macports::ui_options(questions_yesno)]} {
set msg " Migration will first upgrade MacPorts and then reinstall all installed ports."
set retvalue [$macports::ui_options(questions_yesno) $msg " MigrationPrompt" " " {y} 0 " Would you like to continue?" ]
if {$retvalue == 1} {
# quit as user answered 'no'
ui_msg " Aborting migration. You can re-run 'sudo port migrate' later or follow the migration instructions: https://trac.macports.org/wiki/Migration"
return 0
}
}
ui_msg " Upgrading MacPorts..."
set success no
if {[catch {set success [upgrade_port_command]} result]} {
ui_debug $::errorInfo
ui_error " Upgrading port command failed. Try running 'sudo port -v selfupdate' and then 'sudo port migrate'."
return 1
}
if {!$success } {
ui_error " Upgrading port command failed or was not attempted. Please re-install MacPorts manually and then run 'sudo port migrate' again."
return 1
}
# MacPorts successfully upgraded, automatically re-run migration
# from the new MacPorts installation
return -999
}
# If port migrate was not called with --continue, the user probably did
# that manually and we do not have confirmation to run migration yet;
# do that now.
set continuation [expr {[info exists options(ports_migration_continue)] && $options(ports_migration_continue) }]
if {!$continuation && [info exists macports::ui_options(questions_yesno)]} {
set msg " Migration will reinstall all installed ports."
set retvalue [$macports::ui_options(questions_yesno) $msg " MigrationContinuationPrompt" " " {y} 0 " Would you like to continue?" ]
if {$retvalue == 1} {
# quit as user answered 'no'
ui_msg " Aborting migration. You can re-run 'sudo port migrate' later or follow the migration instructions: https://trac.macports.org/wiki/Migration"
return 0
}
}
# create a snapshot
ui_msg " Taking a snapshot of the current state..."
set snapshot [snapshot::main $opts ]
@@ -55,50 +96,71 @@ namespace eval migrate {
set datetime [$snapshot created_at]
ui_msg " Done: Snapshot '$id ' : '$note ' created at $datetime "
if {[info exists macports::ui_options(questions_yesno)]} {
set msg " Migration will first uninstall all the installed ports, upgrade MacPorts and then reinstall them again."
set retvalue [$macports::ui_options(questions_yesno) $msg " MigrationPrompt" " " {y} 0 " Would you like to continue?" ]
if {$retvalue == 1} {
# quit as user answered 'no'
ui_msg " Not uninstalling ports."
return 0
}
}
ui_msg " Uninstalling all ports..."
uninstall_installed
ui_msg " Upgrading MacPorts..."
if {[catch {upgrade_port_command} result]} {
ui_debug $::errorInfo
ui_msg " Upgrading port command failed. Try running 'sudo port -v selfupdate' and then, 'sudo port restore --last'"
ui_msg " Restoring ports..."
return [restore_snapshot]
}
# #
# Check whether the current platform is the one this installation was
# configured for. Returns true, if migration is needed, false otherwise.
#
# @return true iff the migration procedure is needed
proc needs_migration {} {
if {$macports::os_platform ne $macports::autoconf::os_platform } {
return 1
}
if {$macports::os_major != $macports::autoconf::os_major } {
return 1
}
ui_msg " You need to run 'port restore --last' to complete the migration."
return 0
}
# #
# Uninstall all installed ports for migration
#
# @return void on success, raises an error on failure
proc uninstall_installed {} {
set options {}
set portlist [restore::portlist_sort_dependencies_later [registry ::entry imaged]]
foreach port $portlist {
ui_msg " Uninstalling: [ $port name] "
if {[registry ::run_target $port uninstall $options ]} {
continue
} else {
if {![registry ::run_target $port uninstall $options ]} {
ui_error " Error uninstalling [ $port name] "
}
}
}
# #
# Restore the list of ports from the latest snapshot using the equivalent
# of 'port restore --last'
#
# @return 0 on success, an error on failure
proc restore_snapshot {} {
array set options {}
set options(ports_restore_last) yes
return [restore::main [array get options]]
}
# #
# Run MacPorts selfupdate, but avoid downgrading pre-release installations
#
# Will return true on success, false if no error occured but MacPorts was
# not re-installed (e.g. because the currently installed version is newer
# than the downloaded release). If reinstallation fails, an error is
# raised.
#
# @return true on success, false if no update was performed, an error on
# failure.
proc upgrade_port_command {} {
array set optionslist {}
# forced selfupdate
set optionslist(ports_force) 1
# shouldn't sync ports tree
set optionslist(ports_selfupdate_nosync) 1
set updatestatusvar {}
return [uplevel [list selfupdate::main [array get optionslist] $updatestatusvar ]]
# Force rebuild, but do not allow downgrade
set optionslist(ports_selfupdate_migrate) 1
uplevel [list selfupdate::main [array get optionslist] base_updated]
return $base_updated
}
}