<pre style='margin:0'>
Rainer Müller (raimue) pushed a commit to branch vcs-fetch
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/e23b9d00c505d9f40d7b0c51d72df7bdb1de978c">https://github.com/macports/macports-base/commit/e23b9d00c505d9f40d7b0c51d72df7bdb1de978c</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit e23b9d00c505d9f40d7b0c51d72df7bdb1de978c
</span>Author: Rainer Müller <raimue@macports.org>
AuthorDate: Mon Mar 12 18:51:11 2018 +0100

<span style='display:block; white-space:pre;color:#404040;'>    fetch: Enable tarball generation for svn
</span>---
 src/port1.0/portfetch.tcl | 143 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 134 insertions(+), 9 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port1.0/portfetch.tcl b/src/port1.0/portfetch.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 98f3058..9806849 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port1.0/portfetch.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port1.0/portfetch.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -51,7 +51,7 @@ options master_sites patch_sites extract.suffix distfiles patchfiles use_bzip2 u
</span>     master_sites.mirror_subdir patch_sites.mirror_subdir \
     bzr.url bzr.revision \
     cvs.module cvs.root cvs.password cvs.date cvs.tag cvs.method \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    svn.url svn.revision svn.method \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    svn.url svn.revision svn.method svn.file svn.file_prefix \
</span>     git.cmd git.url git.branch git.file git.file_prefix git.fetch_submodules \
     hg.cmd hg.url hg.tag
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -92,6 +92,8 @@ default svn.env {}
</span> default svn.pre_args {"--non-interactive --trust-server-cert"}
 default svn.args ""
 default svn.post_args ""
<span style='display:block; white-space:pre;background:#e0ffe0;'>+default svn.file {${distname}.${fetch.type}.tar.xz}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default svn.file_prefix {${distname}}
</span> 
 default git.cmd {[portfetch::find_git_path]}
 default git.dir {${workpath}}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -323,6 +325,59 @@ proc compressfile {file} {
</span>     return "${file}.xz"
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# Create a reproducible tarball of the contents of a directory
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portfetch::mktar {tarfile dir mtime} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set mtreefile "${tarfile}.mtree"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # write the list of files in sorted order to mtree file with the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # permissions and ownership we want
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set mtreefd [open $mtreefile w]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    puts $mtreefd "#mtree"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    puts $mtreefd "/set uname=root uid=0 gname=root gid=0 time=$mtime"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fs-traverse -tails f $dir {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set fpath [file join $dir $f]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$f ne "."} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # use user permissions only, ignore the rest
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set mode [format "%o" [expr [file attributes $fpath -permissions] & 0700]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # map type from Tcl to mtree
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set type [file type $fpath]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            array set typemap {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    file file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    directory dir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    characterSpecial char
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    blockSpecial block
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    fifo fifo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    link link
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    socket socket
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![info exists typemap($type)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               return -code error "unknown file type $type"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set type $typemap($type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # add entry to mtree output
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            puts $mtreefd "$f type=$type mode=$mode"
</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;'>+    close $mtreefd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # TODO: add dependency on libarchive, if /usr/bin/tar is not bsdtar
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tar [findBinary bsdtar tar]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set cmdstring "${tar} -cf $tarfile @$mtreefile 2>&1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[catch {system -W $dir $cmdstring} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        delete $mtreefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        delete $tarfile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error [msgcat::mc "Subversion archive creation 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;'>+    delete $mtreefile
</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 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> # Perform a bzr fetch
 proc portfetch::bzrfetch {args} {
     global env
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -432,7 +487,16 @@ proc portfetch::svn_proxy_args {url} {
</span> 
 # Perform an svn fetch
 proc portfetch::svnfetch {args} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    global svn.args svn.method svn.revision svn.url
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global UI_PREFIX \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           distpath workpath worksrcpath \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           svn.cmd svn.args svn.method svn.revision svn.url svn.file svn.file_prefix \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           name distname fetch.type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set generatedfile "${distpath}/${svn.file}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[svn_tarballable] && [file isfile "${generatedfile}"]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span> 
     if {[regexp {\s} ${svn.url}]} {
         return -code error [msgcat::mc "Subversion URL cannot contain whitespace"]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -443,12 +507,42 @@ proc portfetch::svnfetch {args} {
</span>     }
 
     set proxy_args [svn_proxy_args ${svn.url}]
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    set svn.args "${svn.args} ${proxy_args}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_info "$UI_PREFIX Checking out ${fetch.type} repository"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tmppath [mkdtemp "/tmp/macports.portfetch.${name}.XXXXXXXX"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tmpxprt [file join ${tmppath} export]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set cmdstring "${svn.cmd} ${svn.method} ${svn.args} ${svn.url} ${tmpxprt}/${svn.file_prefix} 2>&1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[catch {system $cmdstring} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        delete ${tmppath}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error [msgcat::mc "Subversion checkout 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;'>+    if {![svn_tarballable]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        file rename ${tmppath} ${worksrcpath}
</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:#ffe0e0;'>-    set svn.args "${svn.method} ${svn.args} ${proxy_args} ${svn.url}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_info "$UI_PREFIX Generating tarball ${svn.file}"
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {[catch {command_exec svn "" "2>&1"} result]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        return -code error [msgcat::mc "Subversion check out failed"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # get timestamp of latest revision
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set cmdstring "${svn.cmd} info --show-item last-changed-date ${svn.args} ${proxy_args} ${svn.url} 2>&1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[catch {exec -ignorestderr sh -c $cmdstring} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error [msgcat::mc "Subversion info failed"]
</span>     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tstamp $result
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set mtime [clock scan [lindex [split $tstamp "."] 0] -format "%Y-%m-%dT%H:%M:%S" -timezone "UTC"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tardst [join [list [mktemp "/tmp/macports.portfetch.${name}.XXXXXXXX"] ".tar"] ""]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    mktar $tardst $tmpxprt $mtime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set compressed [compressfile ${tardst}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    file rename -force ${compressed} ${generatedfile}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_debug "Created tarball for fetch.type ${fetch.type} at ${generatedfile}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # cleanup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    delete ${tmppath}
</span> 
     return 0
 }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -463,6 +557,16 @@ proc portfetch::git_tarballable {args} {
</span>     }
 }
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# Check if a tarball can be produced for svn
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portfetch::svn_tarballable {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global svn.revision
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {${svn.revision} eq ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return yes
</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> # Returns true if port is fetched from VCS and can be put into a tarball
 proc portfetch::tarballable {args} {
     global fetch.type
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -470,6 +574,9 @@ proc portfetch::tarballable {args} {
</span>         git {
             return [git_tarballable]
         }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        svn {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return [svn_tarballable]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span>     }
     return no
 }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -478,7 +585,8 @@ proc portfetch::tarballable {args} {
</span> proc portfetch::mirrorable {args} {
     global fetch.type
     switch -- "${fetch.type}" {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        git {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        git -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        svn {
</span>             if {[option checksums] eq ""} {
                 ui_debug "port cannot be mirrored, no checksums for ${fetch.type}"
                 return no
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -692,7 +800,7 @@ proc portfetch::fetchfiles {args} {
</span> 
 # Utility function to delete fetched files.
 proc portfetch::fetch_deletefiles {args} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    global distpath git.file fetch.type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global distpath fetch.type svn.file git.file
</span>     variable fetch_urls
     foreach {url_var distfile} $fetch_urls {
         if {[file isfile $distpath/$distfile]} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -701,6 +809,11 @@ proc portfetch::fetch_deletefiles {args} {
</span>     }
 
     switch -- "${fetch.type}" {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        svn {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[file isfile "${distpath}/${svn.file}"]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                file delete -force "${distpath}/${svn.file}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span>         git {
             if {[file isfile "${distpath}/${git.file}"]} {
                 file delete -force "${distpath}/${git.file}"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -711,7 +824,7 @@ proc portfetch::fetch_deletefiles {args} {
</span> 
 # Utility function to add files to a list of fetched files.
 proc portfetch::fetch_addfilestomap {filemapname} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    global distpath fetch.type git.file $filemapname
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global distpath fetch.type svn.file git.file $filemapname
</span>     variable fetch_urls
     foreach {url_var distfile} $fetch_urls {
         if {[file isfile $distpath/$distfile]} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -720,6 +833,11 @@ proc portfetch::fetch_addfilestomap {filemapname} {
</span>     }
 
     switch -- "${fetch.type}" {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        svn {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[svn_tarballable] && [file isfile "${distpath}/${svn.file}"]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                filemap set $filemapname ${distpath}/${svn.file} 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span>         git {
             if {[git_tarballable] && [file isfile "${distpath}/${git.file}"]} {
                 filemap set $filemapname ${distpath}/${git.file} 1
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -730,12 +848,19 @@ proc portfetch::fetch_addfilestomap {filemapname} {
</span> 
 # Initialize fetch target and call checkfiles.
 proc portfetch::fetch_init {args} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    global fetch.type distname git.branch git.file all_dist_files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global fetch.type distname all_dist_files \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           git.file svn.file
</span>     variable fetch_urls
 
     portfetch::checkfiles fetch_urls
 
     switch -- "${fetch.type}" {
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        svn {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[svn_tarballable]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                lappend all_dist_files ${svn.file}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                distfiles-append ${svn.file}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span>         git {
             if {[git_tarballable]} {
                 lappend all_dist_files ${git.file}
</pre><pre style='margin:0'>

</pre>