chiark / gitweb /
dgit: Enforce a syntax for nominal distros
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 88bd431ab37e277bcd273079a2f6fc42078e3030..de7b4de625ec4520ff13d552cee200172d76c3b3 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -142,7 +142,6 @@ our %opts_cfg_insertpos = map {
     scalar @{ $opts_opt_map{$_} }
 } keys %opts_opt_map;
 
-sub finalise_opts_opts();
 sub parseopts_late_defaults();
 
 our $keyid;
@@ -728,7 +727,10 @@ sub access_basedistro () {
 
 sub access_nomdistro () {
     my $base = access_basedistro();
-    return cfg("dgit-distro.$base.nominal-distro",'RETURN-UNDEF') // $base;
+    my $r = cfg("dgit-distro.$base.nominal-distro",'RETURN-UNDEF') // $base;
+    $r =~ m/^$distro_re$/ or badcfg
+ "bad syntax for (nominal) distro \`$r' (does not match /^$distro_re$/)";
+    return $r;
 }
 
 sub access_quirk () {
@@ -792,11 +794,11 @@ sub pushing () {
 Push failed, before we got started.
 You can retry the push, after fixing the problem, if you like.
 END
-    finalise_opts_opts();
+    parseopts_late_defaults();
 }
 
 sub notpushing () {
-    finalise_opts_opts();
+    parseopts_late_defaults();
 }
 
 sub supplementary_message ($) {
@@ -2701,6 +2703,18 @@ sub fetch_from_archive_record_2 ($) {
     }
 }
 
+sub parse_dsc_field ($$) {
+    my ($f, $what) = @_;
+    if (!defined $f) {
+       progress "$what: NO git hash";
+    } elsif ($f =~ m/^\w+/) {
+       $dsc_hash = $&;
+       progress "$what: specified git hash";
+    } else {
+       fail "$what: invalid Dgit info";
+    }
+}
+
 sub fetch_from_archive () {
     ensure_setup_existing_tree();
 
@@ -2712,17 +2726,12 @@ sub fetch_from_archive () {
     get_archive_dsc();
 
     if ($dsc) {
+       my $f;
        foreach my $field (@ourdscfield) {
-           $dsc_hash = $dsc->{$field};
-           last if defined $dsc_hash;
-       }
-       if (defined $dsc_hash) {
-           $dsc_hash =~ m/\w+/ or fail "invalid hash in .dsc \`$dsc_hash'";
-           $dsc_hash = $&;
-           progress "last upload to archive specified git hash";
-       } else {
-           progress "last upload to archive has NO git hash";
+           $f = $dsc->{$field};
+           last if defined $f;
        }
+       parse_dsc_field($f, 'last upload to archive');
     } else {
        progress "no version available from the archive";
     }
@@ -3724,7 +3733,11 @@ sub push_mktags ($$ $$ $) {
 
     die unless $tagwants->[0]{View} eq 'dgit';
 
-    $dsc->{$ourdscfield[0]} = $tagwants->[0]{Objid};
+    my $declaredistro = access_nomdistro();
+    my $reader_giturl = do { local $access_forpush=0; access_giturl(); };
+    $dsc->{$ourdscfield[0]} = join " ",
+       $tagwants->[0]{Objid}, $declaredistro, $tagwants->[0]{Tag},
+       $reader_giturl;
     $dsc->save("$dscfn.tmp") or die $!;
 
     my $changes = parsecontrol($changesfile,$changesfilewhat);
@@ -3741,7 +3754,6 @@ sub push_mktags ($$ $$ $) {
     # to control the "tagger" (b) we can do remote signing
     my $authline = clogp_authline $clogp;
     my $delibs = join(" ", "",@deliberatelies);
-    my $declaredistro = access_nomdistro();
 
     my $mktag = sub {
        my ($tw) = @_;
@@ -4132,7 +4144,6 @@ sub branchsuite () {
 }
 
 sub fetchpullargs () {
-    notpushing();
     if (!defined $package) {
        my $sourcep = parsecontrol('debian/control','debian/control');
        $package = getfield $sourcep, 'Source';
@@ -4148,6 +4159,7 @@ sub fetchpullargs () {
     } else {
        badusage "incorrect arguments to dgit fetch or dgit pull";
     }
+    notpushing();
 }
 
 sub cmd_fetch {
@@ -5889,31 +5901,31 @@ sub cmd_import_dsc {
 
     parse_dscdata();
 
-    my $dgit_commit = $dsc->{$ourdscfield[0]};
-    if (defined $dgit_commit
+    my $dgit_field = $dsc->{$ourdscfield[0]};
+    parse_dsc_field($dgit_field, "$ourdscfield[0] field in .dsc");
+
+    if (defined $dsc_hash
        && !forceing [qw(import-dsc-with-dgit-field)]) {
-       $dgit_commit =~ m/\w+/ or fail "invalid hash in .dsc";
-       $dgit_commit = $&;
        progress "dgit: import-dsc of .dsc with Dgit field, using git hash";
        my @cmd = (qw(sh -ec),
-                  "echo $dgit_commit | git cat-file --batch-check");
+                  "echo $dsc_hash | git cat-file --batch-check");
        my $objgot = cmdoutput @cmd;
        if ($objgot =~ m#^\w+ missing\b#) {
            fail <<END
-.dsc contains Dgit field referring to object $dgit_commit
+.dsc contains Dgit field referring to object $dsc_hash
 Your git tree does not have that object.  Try `git fetch' from a
 plausible server (browse.dgit.d.o? alioth?), and try the import-dsc again.
 END
        }
-       if ($oldhash && !is_fast_fwd $oldhash, $dgit_commit) {
+       if ($oldhash && !is_fast_fwd $oldhash, $dsc_hash) {
            if ($force > 0) {
                progress "Not fast forward, forced update.";
            } else {
-               fail "Not fast forward to $dgit_commit";
+               fail "Not fast forward to $dsc_hash";
            }
        }
        @cmd = (@git, qw(update-ref -m), "dgit import-dsc (Dgit): $info",
-               $dstbranch, $dgit_commit);
+               $dstbranch, $dsc_hash);
        runcmd @cmd;
        progress "dgit: import-dsc updated git ref $dstbranch";
        return 0;
@@ -6265,7 +6277,7 @@ END
 }
 
 
-sub finalise_opts_opts () {
+sub parseopts_late_defaults () {
     foreach my $k (keys %opts_opt_map) {
        my $om = $opts_opt_map{$k};
 
@@ -6293,32 +6305,6 @@ sub finalise_opts_opts () {
        }
     }
 
-    parseopts_late_defaults();
-}
-
-if ($ENV{$fakeeditorenv}) {
-    git_slurp_config();
-    quilt_fixup_editor();
-}
-
-parseopts();
-check_env_sanity();
-git_slurp_config();
-
-print STDERR "DRY RUN ONLY\n" if $dryrun_level > 1;
-print STDERR "DAMP RUN - WILL MAKE LOCAL (UNSIGNED) CHANGES\n"
-    if $dryrun_level == 1;
-if (!@ARGV) {
-    print STDERR $helpmsg or die $!;
-    exit 8;
-}
-my $cmd = shift @ARGV;
-$cmd =~ y/-/_/;
-
-my $pre_fn = ${*::}{"pre_$cmd"};
-$pre_fn->() if $pre_fn;
-
-sub parseopts_late_defaults () {
     if (!defined $rmchanges) {
        local $access_forpush;
        $rmchanges = access_cfg_bool(0, 'rm-old-changes');
@@ -6354,6 +6340,28 @@ sub parseopts_late_defaults () {
     }
 }
 
+if ($ENV{$fakeeditorenv}) {
+    git_slurp_config();
+    quilt_fixup_editor();
+}
+
+parseopts();
+check_env_sanity();
+git_slurp_config();
+
+print STDERR "DRY RUN ONLY\n" if $dryrun_level > 1;
+print STDERR "DAMP RUN - WILL MAKE LOCAL (UNSIGNED) CHANGES\n"
+    if $dryrun_level == 1;
+if (!@ARGV) {
+    print STDERR $helpmsg or die $!;
+    exit 8;
+}
+my $cmd = shift @ARGV;
+$cmd =~ y/-/_/;
+
+my $pre_fn = ${*::}{"pre_$cmd"};
+$pre_fn->() if $pre_fn;
+
 my $fn = ${*::}{"cmd_$cmd"};
 $fn or badusage "unknown operation $cmd";
 $fn->();