<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository mpbb.

</pre>
<p><a href="https://github.com/macports/mpbb/commit/b8313c9e9155c65b875b0855f3aefe76de7a9989">https://github.com/macports/mpbb/commit/b8313c9e9155c65b875b0855f3aefe76de7a9989</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new b8313c9  Add option to retry fetch after mirroring completes
</span>b8313c9 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit b8313c9e9155c65b875b0855f3aefe76de7a9989
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Wed Apr 23 06:45:25 2025 +1000

<span style='display:block; white-space:pre;color:#404040;'>    Add option to retry fetch after mirroring completes
</span>---
 mpbb                      |  2 ++
 mpbb-install-port         | 29 ++++++++++++++++++++++++-----
 tools/mirror-multi.tcl    | 43 ++-----------------------------------------
 tools/mirrordb.tcl        | 43 +++++++++++++++++++++++++++++++++++++++++++
 tools/wait-for-mirror.tcl | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 109 insertions(+), 46 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/mpbb b/mpbb
</span><span style='display:block; white-space:pre;color:#808080;'>index 8d4d47c..7dfeabc 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mpbb
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/mpbb
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -59,6 +59,8 @@ parseopt prefix:,work-dir: "$@" || exit
</span> }
 option_failcache_dir=${option_work_dir}/failcache
 option_license_db_dir=${option_work_dir}/license_db
<span style='display:block; white-space:pre;background:#e0ffe0;'>+option_mirrordb_url=""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+option_mirrordb_credentials=""
</span> 
 # Inform the user if old repositories are still present.
 if [[ -d ${option_work_dir}/tools/.svn ]]; then
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/mpbb-install-port b/mpbb-install-port
</span><span style='display:block; white-space:pre;color:#808080;'>index 01b831d..86e0d53 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/mpbb-install-port
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/mpbb-install-port
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -67,15 +67,34 @@ install-port() {
</span>     local time_start
     local time_stop
     time_start=$(date +%s)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    FETCHFAILED=0
</span>     # $option_prefix is set in mpbb
     # shellcheck disable=SC2154
     if ! "${option_prefix}/bin/port" -d fetch "$@"; then
         echo "Fetch of '$port' failed."
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        # log: summary for the portwatcher
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        echo "Fetching '$port' ... [ERROR] maintainers: $(get-maintainers "$port")." >> "$log_subports_progress"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # Do not add to failcache. This could be a temporary problem that will
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # be resolved once the file appears on mirrors.
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if [ -n "$option_mirrordb_url" ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            echo "Waiting for '$port' to be mirrored."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if "$(readlink "${option_prefix}/bin/port-tclsh")" "${thisdir}/tools/wait-for-mirror.tcl" \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    "$option_mirrordb_url" "$option_mirrordb_credentials" "$port"; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                echo "Mirroring of '$port' done. Retrying fetch."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if ! "${option_prefix}/bin/port" -d fetch "$@"; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    echo "Second fetch of '$port' failed."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    FETCHFAILED=1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                echo "Timed out waiting for '$port' to be mirrored."
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                FETCHFAILED=1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            FETCHFAILED=1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fi
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if [ "$FETCHFAILED" -eq 1 ]; then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # log: summary for the portwatcher
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            echo "Fetching '$port' ... [ERROR] maintainers: $(get-maintainers "$port")." >> "$log_subports_progress"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # Do not add to failcache. This could be a temporary problem that will
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # be resolved once the file appears on mirrors.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        fi
</span>     fi
     # $option_prefix is set in mpbb
     # shellcheck disable=SC2154
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/tools/mirror-multi.tcl b/tools/mirror-multi.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 0f8514d..1d63a96 100755
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/tools/mirror-multi.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/tools/mirror-multi.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -35,6 +35,8 @@
</span> package require macports
 package require fetch_common
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+source [file join [file dirname [info script]] mirrordb.tcl]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> set ui_options(ports_verbose) yes
 if {[catch {mportinit ui_options "" ""} result]} {
    ui_error "$errorInfo"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -62,31 +64,6 @@ set deptypes [list depends_fetch depends_extract depends_patch depends_build dep
</span> set processed [dict create]
 set mirror_done [dict create]
 set distfiles_results [dict create]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-set portname_portfile_map [dict create]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-set portfile_hash_cache [dict create]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-proc get_portfile_hash {portname} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    global portfile_hash_cache portname_portfile_map
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[dict exists $portname_portfile_map $portname]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portfile [dict get $portname_portfile_map $portname]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set result [mportlookup $portname]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[llength $result] < 2} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            return {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portinfo [lindex $result 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portfile [file join [macports::getportdir [dict get $portinfo porturl]] Portfile]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        dict set portname_portfile_map $portname $portfile
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[dict exists $portfile_hash_cache $portfile]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return [dict get $portfile_hash_cache $portfile]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } elseif {[file isfile $portfile]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set portfile_hash [sha256 file $portfile]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        dict set portfile_hash_cache $portfile $portfile_hash
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return $portfile_hash
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span> 
 proc check_mirror_done_local {portname} {
     global mirror_done
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -122,22 +99,6 @@ proc check_mirror_done_local {portname} {
</span>     return 0
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc get_remote_db_value {key} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     global mirrorcache_baseurl mirrorcache_credentials
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     set fullurl ${mirrorcache_baseurl}GET/${key}?type=txt
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-     try {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        curl fetch -u $mirrorcache_credentials $fullurl mirror_db_response
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set fd [open mirror_db_response r]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        gets $fd result
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        close $fd
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } on error {} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set result {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    } finally {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        file delete mirror_db_response
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return $result
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> proc check_mirror_done_remote {portname} {
     global mirror_done
     if {[dict exists $mirror_done $portname]} {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/tools/mirrordb.tcl b/tools/mirrordb.tcl
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..d024701
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/tools/mirrordb.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,43 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# common code for mirror database
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set portfile_hash_cache [dict create]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set portname_portfile_map [dict create]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc get_portfile_hash {portname} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global portfile_hash_cache portname_portfile_map
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[dict exists $portname_portfile_map $portname]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portfile [dict get $portname_portfile_map $portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set result [mportlookup $portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[llength $result] < 2} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portinfo [lindex $result 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portfile [file join [macports::getportdir [dict get $portinfo porturl]] Portfile]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict set portname_portfile_map $portname $portfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[dict exists $portfile_hash_cache $portfile]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [dict get $portfile_hash_cache $portfile]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {[file isfile $portfile]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set portfile_hash [sha256 file $portfile]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict set portfile_hash_cache $portfile $portfile_hash
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return $portfile_hash
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return {}
</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 get_remote_db_value {key} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     global mirrorcache_baseurl mirrorcache_credentials
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     set fullurl ${mirrorcache_baseurl}GET/${key}?type=txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        curl fetch -u $mirrorcache_credentials $fullurl mirror_db_response
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set fd [open mirror_db_response r]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        gets $fd result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        close $fd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } on error {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set result {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } finally {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        file delete mirror_db_response
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return $result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/tools/wait-for-mirror.tcl b/tools/wait-for-mirror.tcl
</span>new file mode 100755
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..148d491
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/tools/wait-for-mirror.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,38 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!/usr/bin/env port-tclsh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# Check a remote database to see if mirroring has been attempted for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# the current version of the given port, and if not, wait and check
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# periodically until it has been, or timeout is reached.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {$argc != 3} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    error "Usage: wait-for-mirror.tcl mirrorcache_baseurl mirrorcache_credentials portname"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+lassign $argv mirrorcache_baseurl mirrorcache_credentials portname
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require macports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+source [file join [file dirname [info script]] mirrordb.tcl]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set ui_options(ports_verbose) yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {[catch {mportinit ui_options "" ""} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ui_error "$errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   ui_error "Failed to initialize ports system: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   exit 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;'>+proc main {portname} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set portfile_hash [get_portfile_hash $portname]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set key mirror.sha256.${portname}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set start [clock seconds]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while {[get_remote_db_value $key] ne $portfile_hash} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # 1h timeout
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[clock seconds] - $start >= 3600} {
</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;'>+        # 10s delay between queries
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        after 10000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</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;'>+main $portname
</span></pre><pre style='margin:0'>

</pre>