chiark / gitweb /
Split tags: Preparation: Reorganise tagwants and mktags
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 31 Jul 2016 16:57:11 +0000 (17:57 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 5 Sep 2016 12:41:47 +0000 (13:41 +0100)
We are going to want to generate two tags.  The current code structure
is not really set up for this.  Also the knowledge of what tags are
being made needs to be used both in dopush and in the push responder.

So:
 * Introduce push_tagwants, which calculates which tags we are going
   to be making, including some details of them.
 * `View' indicates which tag this is.  For now there is only one,
   `dgit'.  But the tags are going to be in a defined order - or,
   at least, the `dgit' tag will come first.
 * Have push_parse_changelog no longer return the single tag name,
   and abolish the corresponding $i_tag varaiable.
 * push_mktag bcomes push_mktags and takes much of its instruction
   from @$tagwants.
 * push_mktags does more than just making tags - it also updates
   the dsc, and does some checks, so it needs to fish the relevant
   object id out of the dgit view tag.
 * $mktag in push_tagwants can now operate on a tagwant, and
   the tag-making part of push_mktags just iterates over the tagwants.
 * The filename plumbing in dopush is somewhat generalised: we
   collect the filenames out of push_mtags or responder_receive_files,
   and then substitute them into the tagwants.
 * The tag checking iterates over the tagwants.
 * The push spec computation iterates over the tagwants.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
dgit

diff --git a/dgit b/dgit
index 3137627..9127ff6 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -34,6 +34,7 @@ use POSIX;
 use IPC::Open2;
 use Digest::SHA;
 use Digest::MD5;
+use List::MoreUtils qw(pairwise);
 
 use Debian::Dgit;
 
@@ -1942,7 +1943,7 @@ sub push_parse_changelog ($) {
 
     my $dscfn = dscfn($cversion);
 
-    return ($clogp, $cversion, $tag, $dscfn);
+    return ($clogp, $cversion, $dscfn);
 }
 
 sub push_parse_dsc ($$$) {
@@ -1955,13 +1956,30 @@ sub push_parse_dsc ($$$) {
            " but debian/changelog is for $package $cversion";
 }
 
-sub push_mktag ($$$$$$$) {
-    my ($dgithead,$clogp,$dgittag,
-       $dscfn,
+sub push_tagwants ($$$) {
+    my ($cversion, $dgithead, $tfbase) = @_;
+    my @tagwants;
+    push @tagwants, {
+        TagFn => \&debiantag,
+       Objid => $dgithead,
+        TfSuffix => '',
+        View => 'dgit',
+    };
+    foreach my $tw (@tagwants) {
+       $tw->{Tag} = $tw->{TagFn}($cversion, access_basedistro);
+       $tw->{Tfn} = sub { $tfbase.$tw->{TfSuffix}.$_[0]; };
+    }
+    return @tagwants;
+}
+
+sub push_mktags ($$ $$ $) {
+    my ($clogp,$dscfn,
        $changesfile,$changesfilewhat,
-       $tfnbase) = @_;
+        $tagwants) = @_;
 
-    $dsc->{$ourdscfield[0]} = $dgithead;
+    die unless $tagwants->[0]{View} eq 'dgit';
+
+    $dsc->{$ourdscfield[0]} = $tagwants->[0]{Objid};
     $dsc->save("$dscfn.tmp") or die $!;
 
     my $changes = parsecontrol($changesfile,$changesfilewhat);
@@ -1981,7 +1999,10 @@ sub push_mktag ($$$$$$$) {
     my $declaredistro = access_basedistro();
 
     my $mktag = sub {
-       my ($tfn, $head, $tag) = @_;
+       my ($tw) = @_;
+       my $tfn = $tw->{Tfn};
+       my $head = $tw->{Objid};
+       my $tag = $tw->{Tag};
 
        open TO, '>', $tfn->('.tmp') or die $!;
        print TO <<END or die $!;
@@ -2023,8 +2044,7 @@ END
        return $tagobjfn;
     };
 
-    my @r;
-    push @r, $mktag->($tfnbase, $dgithead, $dgittag);
+    my @r = map { $mktag->($_); } @$tagwants;
     return @r;
 }
 
@@ -2056,7 +2076,7 @@ END
 
     responder_send_file('parsed-changelog', $clogpfn);
 
-    my ($clogp, $cversion, $tag, $dscfn) =
+    my ($clogp, $cversion, $dscfn) =
        push_parse_changelog("$clogpfn");
 
     my $dscpath = "$buildproductsdir/$dscfn";
@@ -2144,8 +2164,9 @@ END
        });
     }
 
-    my $tfn = sub { ".git/dgit/tag$_[0]"; };
-    my $tagobjfn;
+    my @tagwants = push_tagwants($cversion, $head,
+                                ".git/dgit/tag");
+    my @tagobjfns;
 
     supplementary_message(<<'END');
 Push failed, while signing the tag.
@@ -2153,23 +2174,29 @@ You can retry the push, after fixing the problem, if you like.
 END
     # If we manage to sign but fail to record it anywhere, it's fine.
     if ($we_are_responder) {
-       $tagobjfn = $tfn->('.signed.tmp');
-       responder_receive_files('signed-tag', $tagobjfn);
+       @tagobjfns = map { $_->{Tfn}('.signed-tmp') } @tagwants;
+       responder_receive_files('signed-tag', @tagobjfns);
     } else {
-       ($tagobjfn) =
-           push_mktag($head,$clogp,$tag,
-                      $dscpath,
-                      $changesfile,$changesfile,
-                      $tfn);
+       @tagobjfns = push_mktags($clogp,$dscpath,
+                             $changesfile,$changesfile,
+                             \@tagwants);
     }
     supplementary_message(<<'END');
 Push failed, *after* signing the tag.
 If you want to try again, you should use a new version number.
 END
 
-    my $tag_obj_hash = cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn;
-    runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash;
-    runcmd_ordryrun_local @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash;
+    pairwise { $a->{TagObjFn} = $b } @tagwants, @tagobjfns;
+
+    foreach my $tw (@tagwants) {
+       my $tag = $tw->{Tag};
+       my $tagobjfn = $tw->{TagObjFn};
+       my $tag_obj_hash =
+           cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn;
+       runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash;
+       runcmd_ordryrun_local
+           @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash;
+    }
 
     supplementary_message(<<'END');
 Push failed, while updating the remote git repository - see messages above.
@@ -2178,8 +2205,13 @@ END
     if (!check_for_git()) {
        create_remote_git_repo();
     }
-    runcmd_ordryrun @git, qw(push),access_giturl(),
-        $forceflag."HEAD:".rrref(), $forceflag."refs/tags/$tag";
+
+    my @pushrefs = $forceflag."HEAD:".rrref();
+    foreach my $tw (@tagwants) {
+       push @pushrefs, $forceflag."refs/tags/$tw->{Tag}";
+    }
+
+    runcmd_ordryrun @git, qw(push),access_giturl(), @pushrefs;
     runcmd_ordryrun @git, qw(update-ref -m), 'dgit push', lrref(), 'HEAD';
 
     supplementary_message(<<'END');
@@ -2542,13 +2574,13 @@ sub i_resp_want ($) {
     print RI "files-end\n" or die $!;
 }
 
-our ($i_clogp, $i_version, $i_tag, $i_dscfn, $i_changesfn);
+our ($i_clogp, $i_version, $i_dscfn, $i_changesfn);
 
 sub i_localname_parsed_changelog {
     return "remote-changelog.822";
 }
 sub i_file_parsed_changelog {
-    ($i_clogp, $i_version, $i_tag, $i_dscfn) =
+    ($i_clogp, $i_version, $i_dscfn) =
        push_parse_changelog "$i_tmp/remote-changelog.822";
     die if $i_dscfn =~ m#/|^\W#;
 }
@@ -2586,13 +2618,12 @@ sub i_want_signed_tag {
     $csuite = $&;
     push_parse_dsc $i_dscfn, 'remote dsc', $i_version;
 
-    my ($tagobjfn) =
-       push_mktag $head, $i_clogp, $i_tag,
-           $i_dscfn,
-           $i_changesfn, 'remote changes',
-           sub { "tag$_[0]"; };
+    my @tagwants = push_tagwants $i_version, $head, "tag";
 
-    return $tagobjfn;
+    return
+       push_mktags $i_clogp, $i_dscfn,
+           $i_changesfn, 'remote changes',
+           \@tagwants;
 }
 
 sub i_want_signed_dsc_changes {