chiark / gitweb /
Split tags: Preparation: Reorganise tagwants and mktags
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 7306d7d1214abfa0fa8216c21387fd962e164260..9127ff694d4f9a87aa55ae67d4a369832638f210 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;
 
@@ -1138,6 +1139,15 @@ sub access_cfg_tagformats () {
     split /\,/, access_cfg('dgit-tag-format');
 }
 
+sub need_tagformat ($$) {
+    my ($fmt, $why) = @_;
+    fail "need to use tag format $fmt ($why) but also need".
+       " to use tag format $tagformat_want->[0] ($tagformat_want->[1])".
+       " - no way to proceed"
+       if $tagformat_want && $tagformat_want->[0] ne $fmt;
+    $tagformat_want = [$fmt, $why, $tagformat_want->[2] // 0];
+}
+
 sub select_tagformat () {
     # sets $tagformatfn
     return if $tagformatfn && !$tagformat_want;
@@ -1933,7 +1943,7 @@ sub push_parse_changelog ($) {
 
     my $dscfn = dscfn($cversion);
 
-    return ($clogp, $cversion, $tag, $dscfn);
+    return ($clogp, $cversion, $dscfn);
 }
 
 sub push_parse_dsc ($$$) {
@@ -1946,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);
@@ -1972,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 $!;
@@ -2014,8 +2044,7 @@ END
        return $tagobjfn;
     };
 
-    my @r;
-    push @r, $mktag->($tfnbase, $dgithead, $dgittag);
+    my @r = map { $mktag->($_); } @$tagwants;
     return @r;
 }
 
@@ -2047,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";
@@ -2135,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.
@@ -2144,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.
@@ -2169,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');
@@ -2398,11 +2439,7 @@ sub cmd_remote_push_responder { cmd_remote_push_build_host(); }
 
 sub rpush_handle_protovsn_bothends () {
     if ($protovsn < 4) {
-       fail "rpush negotiated protocol version $protovsn".
-           " which supports old tag format only".
-           " but trying to use new format (".$tagformat_want->[1].")"
-           if $tagformat_want && $tagformat_want->[0] ne 'old';
-       $tagformat_want = ['old', "rpush negotiated protocol $protovsn", 0];
+       need_tagformat 'old', "rpush negotiated protocol $protovsn";
     }
     select_tagformat();
 }
@@ -2537,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#;
 }
@@ -2581,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 {