chiark / gitweb /
dgit-repos-server: parsetag_general: New argument $need_distro
[dgit.git] / infra / dgit-repos-server
index 54a63f926116b87673baa22d7b821795cca4cf97..ee4d5c52db3d2c4fa0f35ae5a5294d602d6e6585 100755 (executable)
@@ -303,13 +303,6 @@ sub reject ($) {
     die "\ndgit-repos-server: reject: $why\n\n";
 }
 
-sub runcmd {
-    debugcmd '+',@_;
-    $!=0; $?=0;
-    my $r = system @_;
-    die (shellquote @_)." $? $!" if $r;
-}
-
 sub policyhook {
     my ($policyallowbits, @polargs) = @_;
     # => ($exitstatuspolicybitmap);
@@ -546,15 +539,12 @@ sub readupdates () {
     STDIN->error and die $!;
 
     reject "push is missing tag ref update" unless %tags;
-    my @newtags = grep { m#^archive/# } keys %tags;
-    my @omtags = grep { !m#^archive/# } keys %tags;
-    reject "pushing too many similar tags" if @newtags>1 || @omtags>1;
-    if (@newtags) {
-       ($tagname) = @newtags;
-       ($maint_tagname) = @omtags;
-    } else {
-       ($tagname) = @omtags or die;
-    }
+    my @dtags = grep { m#^archive/# } keys %tags;
+    reject "need exactly one archive/* tag" if @dtags!=1;
+    my @mtags = grep { !m#^archive/# } keys %tags;
+    reject "pushing too many non-dgit tags" if @mtags>1;
+    ($tagname) = @dtags;
+    ($maint_tagname) = @mtags;
     $tagval = $tags{$tagname};
     $maint_tagval = $tags{$maint_tagname // ''};
 
@@ -562,7 +552,8 @@ sub readupdates () {
     printdebug " updates ok.\n";
 }
 
-sub parsetag () {
+sub parsetag_general ($$;$) {
+    my ($mainfn, $dgititemfn, $need_distro) = @_;
     printdebug " parsetag...\n";
     open PT, ">dgit-tmp/plaintext" or die $!;
     open DS, ">dgit-tmp/plaintext.asc" or die $!;
@@ -579,12 +570,8 @@ sub parsetag () {
        }
     }
     $!=0; $_=<T>; defined or die $!;
-    m/^($package_re) release (\S+) for \S+ \((\S+)\) \[dgit\]$/ or
-       reject "tag message not in expected format";
 
-    die unless $1 eq $package;
-    $version = $2;
-    die "$3 != $suite " unless $3 eq $suite;
+    $mainfn->();
 
     my $copyl = $_;
     for (;;) {
@@ -594,13 +581,10 @@ sub parsetag () {
        if (m/^\[dgit ([^"].*)\]$/) { # [dgit "something"] is for future
            $_ = $1." ";
            while (length) {
-               if (s/^distro\=(\S+) //) {
+               if ($dgititemfn->()) {
+               } elsif (s/^distro\=(\S+) //) {
                    die "$1 != $distro" unless $1 eq $distro;
-               } elsif (s/^(--deliberately-$deliberately_re) //) {
-                   push @deliberatelies, $1;
-               } elsif (s/^previously:(\S+)=(\w+) //) {
-                   die "previously $1 twice" if defined $previously{$1};
-                   $previously{$1} = $2;
+                   $need_distro = 0;
                } elsif (s/^[-+.=0-9a-z]\S* //) {
                } else {
                    die "unknown dgit info in tag ($_)";
@@ -610,6 +594,8 @@ sub parsetag () {
        }
        last if m/^-----BEGIN PGP/;
     }
+    reject "need distro info in tag" if $need_distro;
+
     $_ = $copyl;
     for (;;) {
        print DS or die $!;
@@ -622,6 +608,26 @@ sub parsetag () {
     printdebug " parsetag ok.\n";
 }
 
+sub parsetag () {
+    parsetag_general sub {
+       m/^($package_re) release (\S+) for \S+ \((\S+)\) \[dgit\]$/ or
+           reject "tag message not in expected format";
+       die unless $1 eq $package;
+       $version = $2;
+       die "$3 != $suite " unless $3 eq $suite;
+    }, sub {
+       if (s/^(--deliberately-$deliberately_re) //) {
+           push @deliberatelies, $1;
+       } elsif (s/^previously:(\S+)=(\w+) //) {
+           die "previously $1 twice" if defined $previously{$1};
+           $previously{$1} = $2;
+       } else {
+           return 0;
+       }
+       return 1;
+    };
+}
+
 sub checksig_keyring ($) {
     my ($keyringfile) = @_;
     # returns primary-keyid if signed by a key in this keyring
@@ -857,20 +863,23 @@ sub tagh1 ($) {
     return $vals->[0];
 }
 
-sub checks () {
+sub basic_tag_checks() {
     printdebug "checks\n";
 
     tagh1('type') eq 'commit' or reject "tag refers to wrong kind of object";
     tagh1('object') eq $commit or reject "tag refers to wrong commit";
     tagh1('tag') eq $tagname or reject "tag name in tag is wrong";
+}
+
+sub checks () {
+    basic_tag_checks();
 
     my @expecttagnames = debiantags($version, $distro);
     printdebug "expected tag @expecttagnames\n";
     grep { $tagname eq $_ } @expecttagnames or die;
 
     foreach my $othertag (grep { $_ ne $tagname } @expecttagnames) {
-       reject "tag $othertag (pushed with differing dgit version)".
-           " already exists -".
+       reject "tag $othertag already exists -".
            " not replacing previously-pushed version"
            if git_get_ref "refs/tags/".$othertag;
     }
@@ -902,8 +911,8 @@ sub checks () {
 
     # defend against commits generated by #849041
     if (!($policy & NOCOMMITCHECK)) {
-       my @checks = qw(%ae %at
-                       %ce %ct);
+       my @checks = qw(%at
+                       %ct);
        my @chk = qw(git log -z);
        push @chk, '--pretty=tformat:%H%n'.
            (join "", map { $_, '%n' } @checks);
@@ -943,6 +952,17 @@ sub onwardpush () {
     my @cmdbase = (qw(git send-pack), $destrepo);
     push @cmdbase, qw(--force) if $policy & NOFFCHECK;
 
+    if ($ENV{GIT_QUARANTINE_PATH}) {
+       my $recv_wrapper = "$ENV{GIT_QUARANTINE_PATH}/dgit-recv-wrapper";
+       mkscript $recv_wrapper, <<'END';
+#!/bin/sh
+set -e
+unset GIT_QUARANTINE_PATH
+exec git receive-pack "$@"
+END
+       push @cmdbase, "--receive-pack=$recv_wrapper";
+    }
+
     my @cmd = @cmdbase;
     push @cmd, "$commit:refs/dgit/$suite",
               "$tagval:refs/tags/$tagname";
@@ -1151,7 +1171,7 @@ sub parseargsdispatch () {
 
     $ENV{"DGIT_DRS_\U$_"} = ${ $main::{$_} } foreach @hookenvs;
 
-    die unless @ARGV==1;
+    die unless @ARGV>=1;
 
     my $mode = shift @ARGV;
     die unless $mode =~ m/^--(\w+)$/;