<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[147272] branches/vcs-fetch/base/src/port1.0/portfetch.tcl</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="https://trac.macports.org/changeset/147272">147272</a></dd>
<dt>Author</dt> <dd>raimue@macports.org</dd>
<dt>Date</dt> <dd>2016-03-31 19:33:19 -0700 (Thu, 31 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Include git submodules in generated tarball

If a repository for fetch.type git references additional submodules, they will
be included in the generated tarball.

If this feature should not be used in some cases, it can be disabled with
    git.fetch_submodules no</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesvcsfetchbasesrcport10portfetchtcl">branches/vcs-fetch/base/src/port1.0/portfetch.tcl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesvcsfetchbasesrcport10portfetchtcl"></a>
<div class="modfile"><h4>Modified: branches/vcs-fetch/base/src/port1.0/portfetch.tcl (147271 => 147272)</h4>
<pre class="diff"><span>
<span class="info">--- branches/vcs-fetch/base/src/port1.0/portfetch.tcl        2016-04-01 01:13:17 UTC (rev 147271)
+++ branches/vcs-fetch/base/src/port1.0/portfetch.tcl        2016-04-01 02:33:19 UTC (rev 147272)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     bzr.url bzr.revision \
</span><span class="cx">     cvs.module cvs.root cvs.password cvs.date cvs.tag cvs.method \
</span><span class="cx">     svn.url svn.revision svn.method \
</span><del>-    git.cmd git.url git.branch git.file git.file_prefix \
</del><ins>+    git.cmd git.url git.branch git.file git.file_prefix git.fetch_submodules \
</ins><span class="cx">     hg.cmd hg.url hg.tag
</span><span class="cx"> 
</span><span class="cx"> # XXX we use the command framework to buy us some useful features,
</span><span class="lines">@@ -99,6 +99,7 @@
</span><span class="cx"> default git.branch {}
</span><span class="cx"> default git.file {${distname}.${fetch.type}.tar.xz}
</span><span class="cx"> default git.file_prefix {${distname}}
</span><ins>+default git.fetch_submodules &quot;yes&quot;
</ins><span class="cx"> 
</span><span class="cx"> default hg.cmd {[findBinary hg $portutil::autoconf::hg_path]}
</span><span class="cx"> default hg.dir {${workpath}}
</span><span class="lines">@@ -457,7 +458,7 @@
</span><span class="cx"> proc portfetch::gitfetch {args} {
</span><span class="cx">     global UI_PREFIX \
</span><span class="cx">            distpath workpath worksrcpath \
</span><del>-           git.url git.branch git.file git.file_prefix git.cmd \
</del><ins>+           git.url git.branch git.fetch_submodules git.file git.file_prefix git.cmd \
</ins><span class="cx">            name distname fetch.type
</span><span class="cx"> 
</span><span class="cx">     set generatedfile &quot;${distpath}/${git.file}&quot;
</span><span class="lines">@@ -466,21 +467,44 @@
</span><span class="cx">         return 0
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    set options &quot;-q&quot;
</del><ins>+    set options &quot;&quot;
</ins><span class="cx">     if {${git.branch} eq &quot;&quot;} {
</span><del>-        # if we're just using HEAD, we can make a shallow repo
</del><ins>+        # If we're just using HEAD, we can make a shallow repo. In other cases,
+        # it might cause a failure for some repos if the requested sha1 is not
+        # reachable from any head.
</ins><span class="cx">         append options &quot; --depth=1&quot;
</span><span class="cx">     }
</span><ins>+    # XXX: this might be usable in some cases to reduce transfers, but does not always work
+    #append options &quot; --single-branch&quot;
+    #append options &quot; --branch ${git.branch}&quot;
</ins><span class="cx"> 
</span><span class="cx">     ui_info &quot;$UI_PREFIX Cloning ${fetch.type} repository&quot;
</span><span class="cx">     set tmppath [mkdtemp &quot;/tmp/macports.portfetch.${name}.XXXXXXXX&quot;]
</span><del>-    set cmdstring &quot;${git.cmd} clone $options ${git.url} ${tmppath} 2&gt;&amp;1&quot;
-    ui_debug &quot;Executing: $cmdstring&quot;
</del><ins>+    set cmdstring &quot;${git.cmd} clone -q $options ${git.url} ${tmppath} 2&gt;&amp;1&quot;
</ins><span class="cx">     if {[catch {system $cmdstring} result]} {
</span><del>-        if {[file exists &quot;${tmppath}&quot;]} {
</del><ins>+        delete ${tmppath}
+        return -code error [msgcat::mc &quot;Git clone failed&quot;]
+    }
+
+    # checkout branch
+    # required to have the right version of .gitmodules
+    if {${git.branch} ne &quot;&quot;} {
+        ui_debug &quot;Checking out branch ${git.branch}&quot;
+        set cmdstring &quot;${git.cmd} checkout -q ${git.branch} 2&gt;&amp;1&quot;
+        if {[catch {system -W $tmppath $cmdstring} result]} {
+            delete $tmppath
+            return -code error [msgcat::mc &quot;Git checkout failed&quot;]
+        }
+    }
+
+    # XXX: this does not support multiple recursive levels of submodules
+    if {[file isfile &quot;$tmppath/.gitmodules&quot;] &amp;&amp; [tbool git.fetch_submodules]} {
+        ui_info &quot;$UI_PREFIX Cloning git submodules&quot;
+        set cmdstring &quot;${git.cmd} submodule -q update --init 2&gt;&amp;1&quot;
+        if {[catch {system -W $tmppath $cmdstring} result]} {
</ins><span class="cx">             delete ${tmppath}
</span><ins>+            return -code error [msgcat::mc &quot;Git submodule init failed&quot;]
</ins><span class="cx">         }
</span><del>-        return -code error [msgcat::mc &quot;Git clone failed&quot;]
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if {![git_tarballable]} {
</span><span class="lines">@@ -488,24 +512,50 @@
</span><span class="cx">         return 0
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    # generate tarball
</del><span class="cx">     ui_info &quot;$UI_PREFIX Generating tarball ${git.file}&quot;
</span><del>-    set xz [findBinary xz ${portutil::autoconf::xz_path}]
-    set cmdstring &quot;${git.cmd} -c \&quot;tar.tar.xz.command=xz -c\&quot; archive --prefix=\&quot;${git.file_prefix}/\&quot; --format=tar.xz --output=${generatedfile}.TMP ${git.branch} 2&gt;&amp;1&quot;
-    ui_debug &quot;Executing $cmdstring&quot;
-    if {[catch {system -W ${tmppath} $cmdstring} result]} {
-        if {[file exists &quot;${generatedfile}.TMP&quot;]} {
-            delete &quot;${generatedfile}.TMP&quot;
-        }
</del><ins>+
+    # generate main tarball
+    set tardst [join [list [mktemp &quot;/tmp/macports.portfetch.${name}.XXXXXXXX&quot;] &quot;.tar&quot;] &quot;&quot;]
+    set cmdstring &quot;${git.cmd} archive --format=tar --prefix=\&quot;${git.file_prefix}/\&quot; --output=${tardst} ${git.branch} 2&gt;&amp;1&quot;
+    if {[catch {system -W $tmppath $cmdstring} result]} {
+        delete $tardst
</ins><span class="cx">         return -code error [msgcat::mc &quot;Git archive creation failed&quot;]
</span><span class="cx">     }
</span><del>-    file rename -force &quot;${generatedfile}.TMP&quot; &quot;${generatedfile}&quot;
</del><span class="cx"> 
</span><del>-    # cleanup
-    if {[file exists &quot;${tmppath}&quot;]} {
-        delete ${tmppath}
</del><ins>+    # generate tarballs for submodules and merge them into the main tarball
+    if {[file isfile &quot;$tmppath/.gitmodules&quot;] &amp;&amp; [tbool git.fetch_submodules]} {
+        set xz [findBinary xz ${portutil::autoconf::xz_path}]
+        # TODO: add dependency on libarchive, if /usr/bin/tar is not bsdtar
+        set tar [findBinary bsdtar tar]
+        set tartmp [join [list [mktemp &quot;/tmp/macports.portfetch.${name}.XXXXXXXX&quot;] &quot;.tar&quot;] &quot;&quot;]
+        set cmdstring [join [list \
+            &quot;${git.cmd} submodule -q foreach '&quot; \
+            &quot;${git.cmd} archive --format=tar --prefix=\&quot;${git.file_prefix}/\$path/\&quot; \$sha1 &quot; \
+            &quot;| tar -cf ${tartmp} @- @${tardst} &quot; \
+            &quot;&amp;&amp; mv ${tartmp} ${tardst}&quot; \
+            &quot;' 2&gt;&amp;1&quot;] &quot;&quot;]
+        if {[catch {system -W $tmppath $cmdstring} result]} {
+            delete $tardst
+            delete $tartmp
+            return -code error [msgcat::mc &quot;Git submodule archive creation failed&quot;]
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    # compress resulting tarball
+    set xz [findBinary xz ${portutil::autoconf::xz_path}]
+    set cmdstring &quot;$xz ${tardst}&quot;
+    if {[catch {system $cmdstring} result]} {
+        delete &quot;${tardst}&quot;
+        delete &quot;${tardst}.xz&quot;
+        return -code error [msgcat::mc &quot;Git submodule archive creation failed&quot;]
+    }
+    file rename -force &quot;${tardst}.xz&quot; &quot;${generatedfile}&quot;
+
+    ui_debug &quot;Created tarball for fetch.type ${fetch.type} at ${generatedfile}&quot;
+
+    # cleanup
+    delete ${tmppath}
+
</ins><span class="cx">     return 0
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>