<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/72478b1d37d896c59a4f2b699c052cfa6127ab25">https://github.com/macports/macports-base/commit/72478b1d37d896c59a4f2b699c052cfa6127ab25</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 72478b1d37d896c59a4f2b699c052cfa6127ab25
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Mon Dec 18 23:09:24 2023 +0100

<span style='display:block; white-space:pre;color:#404040;'>    macports/restore: Skip ports when deps failed
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    When a dependency fails to build, do not attempt to install its
</span><span style='display:block; white-space:pre;color:#404040;'>    dependents, but skip them instead.
</span>---
 src/macports1.0/restore.tcl | 97 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 76 insertions(+), 21 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 c8eaeb4bd..34e399341 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;'>@@ -36,8 +36,9 @@ package require migrate 1.0
</span> package require registry 1.0
 package require snapshot 1.0
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-package require struct::graph
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-package require struct::graph::op
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require struct::graph 2.4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require struct::graph::op 0.11
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require lambda 1
</span> 
 namespace eval restore {
     proc main {opts} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -91,10 +92,19 @@ namespace eval restore {
</span> 
         ui_msg "$macports::ui_prefix Restoring snapshot '[$snapshot note]' created at [$snapshot created_at]"
         set snapshot_portlist [$snapshot ports]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        restore_state [$snapshot ports]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set failed [restore_state [$snapshot ports]]
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # TODO Check whether all ports have been restored; print an analysis of
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # ports that have not been restored if errors did occur.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[array size failed] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set note "Migration finished with errors.\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set note "Migration finished.\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[info exists macports::ui_options(notifications_system)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            $macports::ui_options(notifications_system) $note
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_msg $note
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span> 
         return 0
     }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -206,7 +216,8 @@ namespace eval restore {
</span>     #       portlist - the list of port references
     #
     # Returns:
<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;'>+    #       The list in dependency-sorted order
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #       The dependency graph, to be destroyed by calling $dependencies destroy
</span>     proc resolve_dependencies {portlist} {
         array set ports {}
         array set dep_ports {}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -402,13 +413,35 @@ namespace eval restore {
</span>             }
         }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        $dependencies destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [list $operations $dependencies]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        return $operations
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc _handle_failure {failedName dependencies portname reason} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        upvar $failedName failed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set failed($portname) [list "failed" $reason]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set level "#[info level]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        $dependencies walk $portname \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            -type dfs \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            -order pre \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            -dir backward \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            -command [lambda {level mode dependencies node} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {$mode eq "enter"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    uplevel $level [subst -nocommands {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set failed($node) [list "skipped" "dependency \$portname failed"]
</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;'>+            } $level]
</span>     }
 
     proc restore_state {snapshot_portlist} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set sorted_snapshot_portlist [resolve_dependencies $snapshot_portlist]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lassign [resolve_dependencies $snapshot_portlist] sorted_snapshot_portlist dependencies
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # map from port name to an entry describing why the port failed or was
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # skipped
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        array set failed {}
</span> 
         set index 0
         set length [llength $sorted_snapshot_portlist]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -421,6 +454,24 @@ namespace eval restore {
</span>             } else {
                 ui_msg "$macports::ui_prefix $index/$length Restoring $name from snapshot"
             }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info exists failed($name)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                lassign $failed($name) type reason
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                switch $type {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    skipped {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_msg "$macports::ui_prefix Skipping $name because its $reason"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    failed {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_msg "$macports::ui_prefix Skipping $name because it failed previously: $reason"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    default {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_msg "$macports::ui_prefix Skipping $name: $reason"
</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;'>+                continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span>             if {!$active} {
                 set target install
             } else {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -428,12 +479,13 @@ namespace eval restore {
</span>             }
 
             if {[catch {set res [mportlookup $name]} result]} {
<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:#e0ffe0;'>+                ui_debug "$::errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                _handle_failure failed $dependencies $name "lookup of port $name failed: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                continue
</span>             }
             if {[llength $res] < 2} {
                 # not in the index, but we already warned about that earlier
<span style='display:block; white-space:pre;background:#e0ffe0;'>+                _handle_failure failed $dependencies $name "port $name not found in the port index"
</span>                 continue
             }
             array unset portinfo
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -445,19 +497,22 @@ namespace eval restore {
</span>             set variations [variants_to_variations_arr $variants]
 
             if {[catch {set workername [mportopen $porturl [array get options] $variations]} result]} {
<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:#e0ffe0;'>+                ui_msg $::errorInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                _handle_failure failed $dependencies $name "unable to open port $name: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                continue
</span>             }
 
             if {[catch {set result [mportexec $workername $target]} result]} {
<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><span style='display:block; white-space:pre;background:#ffe0e0;'>-            } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                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;'>+                _handle_failure failed $dependencies $name "Unable to execute target $target for port $name: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif {$result != 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                _handle_failure failed $dependencies $name "Failed to $target $name"
</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;'>+        $dependencies destroy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [array get failed]
</span>     }
 }
</pre><pre style='margin:0'>

</pre>