chiark / gitweb /
wip changes for remote push - no intentional functional change, break out push_parse_...
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 25 Sep 2013 23:58:20 +0000 (00:58 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 25 Sep 2013 23:58:20 +0000 (00:58 +0100)
TODO
dgit

diff --git a/TODO b/TODO
index 7ee9998..5a52c0c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,2 +1,14 @@
 --gpg= etc. @gpg should be in manual
 should pass @gpg to debsign
+
+approach for remote signing
+  - initiator acts as oracle for responder
+  - one of each operation
+  - debsign: copy up changes and dsc, run debsign on initiator, copy down
+  - git tag: generate tag contents on initiator
+
+protocol:
+  - responder sends parsed changelog
+  - responder sends changelog
+  - responder sends dsc
+  - responder sends head commit hash
diff --git a/dgit b/dgit
index e8b6c30..5cdf21e 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -900,28 +900,104 @@ sub madformat ($) {
     return 1;
 }
 
-sub dopush () {
-    print DEBUG "actually entering push\n";
-    my $clogp = parsechangelog();
+sub push_parse_changelog ($) {
+    my ($clogpfn) = @_;
+
+    my $clogp = Dpkg::Control::Hash->new();
+    $clogp->load($clogpfn);
+
     $package = getfield $clogp, 'Source';
     my $cversion = getfield $clogp, 'Version';
+    my $tag = debiantag($cversion);
+    runcmd @git, qw(check-ref-format), $tag;
+
     my $dscfn = dscfn($cversion);
-    stat "../$dscfn" or
-       fail "looked for .dsc $dscfn, but $!;".
-           " maybe you forgot to build";
-    $dsc = parsecontrol("../$dscfn","$dscfn");
-    my $dscpackage = getfield $dsc, 'Source';
-    my $format = getfield $dsc, 'Format';
+
+    return ($clogp, $cversion, $tag, $dscfn);
+}
+
+sub push_parse_dsc ($$) {
+    my ($dscfn,$dscfnwhat, $cversion) = @_;
+    $dsc = parsecontrol($dscfn,$dscfnwhat);
     my $dversion = getfield $dsc, 'Version';
+    my $dscpackage = getfield $dsc, 'Source';
     ($dscpackage eq $package && $dversion eq $cversion) or
        fail "$dsc is for $dscpackage $dversion".
            " but debian/changelog is for $package $cversion";
+}
+
+sub push_mktag ($$$$$$$$) {
+    my ($head,$clogp,$tag,
+       $dsc,$dscfn,
+       $changesfile,$changesfilewhat,
+       $tfn) = @_;
+
+    $dsc->{$ourdscfield[0]} = $head;
+    $dsc->save("$dscfn.tmp") or die $!;
+
+    my $changes = parsecontrol($changesfile,$changesfilewhat);
+    foreach my $field (qw(Source Distribution Version)) {
+       $changes->{$field} eq $clogp->{$field} or
+           fail "changes field $field \`$changes->{$field}'".
+               " does not match changelog \`$clogp->{$field}'";
+    }
+
+    # We make the git tag by hand because (a) that makes it easier
+    # to control the "tagger" (b) we can do remote signing
+    my $authline = clogp_authline $clogp;
+    open TO, '>', $tfn->('.tmp') or die $!;
+    print TO <<END or die $!;
+object $head
+type commit
+tag $tag
+tagger $authline
+
+$package release $cversion for $csuite [dgit]
+END
+    close TO or die $!;
+
+    my $tagobjfn = $tfn->('.tmp');
+    if ($sign) {
+       if (!defined $keyid) {
+           $keyid = access_cfg('keyid','RETURN-UNDEF');
+       }
+       unlink $tfn->('.tmp.asc') or $!==&ENOENT or die $!;
+       my @sign_cmd = (@gpg, qw(--detach-sign --armor));
+       push @sign_cmd, qw(-u),$keyid if defined $keyid;
+       push @sign_cmd, $tfn->('.tmp');
+       runcmd_ordryrun @sign_cmd;
+       if (!$dryrun) {
+           $tagobjfn = $tfn->('.signed.tmp');
+           runcmd shell_cmd "exec >$tagobjfn", qw(cat --),
+               $tfn->('.tmp'), $tfn->('.tmp.asc');
+       }
+    }
+
+    return ($tagobjfn);
+}
+
+sub dopush () {
+    print DEBUG "actually entering push\n";
+    prep_ud();
+
+    runcmd shell_cmd "exec >.git/dgit/changelog.822.tmp",
+        qw(dpkg-parsechangelog);
+
+    my ($clogp, $cversion, $tag, $dscfn) =
+       push_parse_changelog(".git/dgit/changelog.822.tmp");
+
+    stat "../$dscfn" or
+       fail "looked for .dsc $dscfn, but $!;".
+           " maybe you forgot to build";
+
+    push_parse_dsc("../$dscfn", $dscfn, $cversion);
+
+    my $format = getfield $dsc, 'Format';
     print DEBUG "format $format\n";
     if (madformat($format)) {
        commit_quilty_patch();
     }
     check_not_dirty();
-    prep_ud();
     chdir $ud or die $!;
     print "checking that $dscfn corresponds to HEAD\n";
     runcmd qw(dpkg-source -x --), "../../../../$dscfn";
@@ -945,8 +1021,6 @@ sub dopush () {
 #        map { lref($_).":".rref($_) }
 #        (uploadbranch());
     my $head = rev_parse('HEAD');
-    $dsc->{$ourdscfield[0]} = $head;
-    $dsc->save("../$dscfn.tmp") or die $!;
     if (!$changesfile) {
        my $multi = "../${package}_".(stripepoch $cversion)."_multi.changes";
        if (stat "$multi") {
@@ -962,46 +1036,13 @@ sub dopush () {
            ($changesfile) = @cs;
        }
     }
-    my $changes = parsecontrol($changesfile,$changesfile);
-    foreach my $field (qw(Source Distribution Version)) {
-       $changes->{$field} eq $clogp->{$field} or
-           fail "changes field $field \`$changes->{$field}'".
-               " does not match changelog \`$clogp->{$field}'";
-    }
-    my $tag = debiantag($dversion);
-    runcmd @git, qw(check-ref-format), $tag;
 
-    # We make the git tag by hand because (a) that makes it easier
-    # to control the "tagger" (b) we can do remote signing
-    my $authline = clogp_authline $clogp;
-    my $tfn = sub { ".git/dgit/tag$_[0]"; };
-    open TO, '>', $tfn->('.tmp') or die $!;
-    print TO <<END or die $!;
-object $head
-type commit
-tag $tag
-tagger $authline
+    my ($tagobjfn) =
+       push_mktag($head,$clogp,$tag,
+                  $dsc,"../$dscfn",
+                  $changesfile,$changesfile,
+                  sub { ".git/dgit/tag$_[0]"; });
 
-$package release $dversion for $csuite [dgit]
-END
-    close TO or die $!;
-
-    my $tagobjfn = $tfn->('.tmp');
-    if ($sign) {
-       if (!defined $keyid) {
-           $keyid = access_cfg('keyid','RETURN-UNDEF');
-       }
-       unlink $tfn->('.tmp.asc') or $!==&ENOENT or die $!;
-       my @sign_cmd = (@gpg, qw(--detach-sign --armor));
-       push @sign_cmd, qw(-u),$keyid if defined $keyid;
-       push @sign_cmd, $tfn->('.tmp');
-       runcmd_ordryrun @sign_cmd;
-       if (!$dryrun) {
-           $tagobjfn = $tfn->('.signed.tmp');
-           runcmd shell_cmd "exec >$tagobjfn", qw(cat --),
-               $tfn->('.tmp'), $tfn->('.tmp.asc');
-       }
-    }
     my $tag_obj_hash = cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn;
     runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash;
     runcmd_ordryrun @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash;
@@ -1028,7 +1069,7 @@ END
     my $host = access_cfg('upload-host','RETURN-UNDEF');
     my @hostarg = defined($host) ? ($host,) : ();
     runcmd_ordryrun @dput, @hostarg, $changesfile;
-    printdone "pushed and uploaded $dversion";
+    printdone "pushed and uploaded $cversion";
 }
 
 sub cmd_clone {