chiark / gitweb /
Use curl to download things rather than dget; do our own processing of the files
[dgit.git] / dgit
diff --git a/dgit b/dgit
index f9e6d1bc7d9443c3c866e45d3cdf81f000a6e9d9..461e5e658305f3bfcfe2f507117931f05aabedbc 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -57,6 +57,7 @@ our $suite_re = '[-+.0-9a-z]+';
 
 our (@git) = qw(git);
 our (@dget) = qw(dget);
+our (@curl) = qw(curl -f);
 our (@dput) = qw(dput);
 our (@debsign) = qw(debsign);
 our (@gpg) = qw(gpg);
@@ -69,7 +70,8 @@ our (@dpkggenchanges) = qw(dpkg-genchanges);
 our (@mergechanges) = qw(mergechanges -f);
 our (@changesopts) = ('');
 
-our %opts_opt_map = ('dget' => \@dget,
+our %opts_opt_map = ('dget' => \@dget, # accept for compatibility
+                    'curl' => \@curl,
                     'dput' => \@dput,
                     'debsign' => \@debsign,
                      'gpg' => \@gpg,
@@ -465,12 +467,14 @@ our %defcfg = ('dgit.default.distro' => 'debian',
               'dgit-distro.debian.git-path' => '/git/dgit-repos/repos',
               'dgit-distro.debian.git-check' => 'ssh-cmd',
               'dgit-distro.debian.git-create' => 'ssh-cmd',
-              'dgit-distro.debian.sshpsql-host' => 'coccia.debian.org',
+              'dgit-distro.debian.sshpsql-host' => 'mirror.ftp-master.debian.org',
               'dgit-distro.debian.sshpsql-dbname' => 'service=projectb',
               'dgit-distro.debian.upload-host' => 'ftp-master', # for dput
               'dgit-distro.debian.mirror' => 'http://ftp.debian.org/debian/',
  'dgit-distro.debian.backports-quirk' => '(squeeze)-backports*',
  'dgit-distro.debian-backports.mirror' => 'http://backports.debian.org/debian-backports/',
+              'dgit-distro.ubuntu.git-check' => 'false',
+ 'dgit-distro.ubuntu.mirror' => 'http://archive.ubuntu.com/ubuntu',
               'dgit-distro.test-dummy.ssh' => "$td/ssh",
               'dgit-distro.test-dummy.username' => "alice",
               'dgit-distro.test-dummy.git-check' => "ssh-cmd",
@@ -505,8 +509,14 @@ sub cfg {
 }
 
 sub access_basedistro () {
-    return cfg("dgit-suite.$isuite.distro",
-              "dgit.default.distro");
+    if (defined $idistro) {
+       return cfg("dgit-distro.basedistro.distro",
+                  "dgit-suite.$isuite.distro",
+                  'RETURN-UNDEF') // $idistro;
+    } else {   
+       return cfg("dgit-suite.$isuite.distro",
+                  "dgit.default.distro");
+    }
 }
 
 sub access_quirk () {
@@ -859,6 +869,8 @@ sub check_for_git () {
        return $r+0;
     } elsif ($how eq 'true') {
        return 1;
+    } elsif ($how eq 'false') {
+       return 0;
     } else {
        badcfg "unknown git-check \`$how'";
     }
@@ -962,20 +974,33 @@ sub clogp_authline ($) {
 sub generate_commit_from_dsc () {
     prep_ud();
     changedir $ud;
-    my @files;
-    foreach my $f (dsc_files()) {
+
+    foreach my $fi (dsc_files_info()) {
+       my $f = $fi->{Filename};
        die "$f ?" if $f =~ m#/|^\.|\.dsc$|\.tmp$#;
-       push @files, $f;
+
        link "../../../$f", $f
            or $!==&ENOENT
            or die "$f $!";
+
+       complete_file_from_dsc('.', $fi);
+
+       if (is_orig_file($f)) {
+           link $f, "../../../../$f"
+               or $!==&EEXIST
+               or die "$f $!";
+       }
     }
-    runcmd @dget, qw(--), $dscurl;
-    foreach my $f (grep { is_orig_file($_) } @files) {
-       link $f, "../../../../$f"
-           or $!==&EEXIST
-           or die "$f $!";
-    }
+
+    my $dscfn = "$package.dsc";
+
+    open D, ">", $dscfn or die "$dscfn: $!";
+    print D $dscdata or die "$dscfn: $!";
+    close D or die "$dscfn: $!";
+    my @cmd = qw(dpkg-source);
+    push @cmd, qw(-x --), $dscfn;
+    runcmd @cmd;
+
     my ($tree,$dir) = mktree_in_ud_from_only_subdir();
     runcmd qw(sh -ec), 'dpkg-parsechangelog >../changelog.tmp';
     my $clogp = parsecontrol('../changelog.tmp',"commit's changelog");
@@ -1036,30 +1061,47 @@ END
     return $outputhash;
 }
 
+sub complete_file_from_dsc ($$) {
+    our ($dstdir, $fi) = @_;
+    # Ensures that we have, in $dir, the file $fi, with the correct
+    # contents.  (Downloading it from alongside $dscurl if necessary.)
+
+    my $f = $fi->{Filename};
+    my $tf = "$dstdir/$f";
+    my $downloaded = 0;
+
+    if (stat $tf) {
+       progress "using existing $f";
+    } else {
+       die "$tf $!" unless $!==&ENOENT;
+
+       my $furl = $dscurl;
+       $furl =~ s{/[^/]+$}{};
+       $furl .= "/$f";
+       die "$f ?" unless $f =~ m/^${package}_/;
+       die "$f ?" if $f =~ m#/#;
+       runcmd_ordryrun_local @curl,qw(-o),$tf,'--',"$furl";
+       next if !act_local();
+       $downloaded = 1;
+    }
+
+    open F, "<", "$tf" or die "$tf: $!";
+    $fi->{Digester}->reset();
+    $fi->{Digester}->addfile(*F);
+    F->error and die $!;
+    my $got = $fi->{Digester}->hexdigest();
+    $got eq $fi->{Hash} or
+       fail "file $f has hash $got but .dsc".
+           " demands hash $fi->{Hash} ".
+           ($downloaded ? "(got wrong file from archive!)"
+            : "(perhaps you should delete this file?)");
+}
+
 sub ensure_we_have_orig () {
     foreach my $fi (dsc_files_info()) {
        my $f = $fi->{Filename};
        next unless is_orig_file($f);
-       if (open F, "<", "../$f") {
-           $fi->{Digester}->reset();
-           $fi->{Digester}->addfile(*F);
-           F->error and die $!;
-           my $got = $fi->{Digester}->hexdigest();
-           $got eq $fi->{Hash} or
-               fail "existing file $f has hash $got but .dsc".
-                   " demands hash $fi->{Hash}".
-                   " (perhaps you should delete this file?)";
-           progress "using existing $f";
-           next;
-       } else {
-           die "$f $!" unless $!==&ENOENT;
-       }
-       my $origurl = $dscurl;
-       $origurl =~ s{/[^/]+$}{};
-       $origurl .= "/$f";
-       die "$f ?" unless $f =~ m/^${package}_/;
-       die "$f ?" if $f =~ m#/#;
-       runcmd_ordryrun_local shell_cmd 'cd ..', @dget,'--',$origurl;
+       complete_file_from_dsc('..', $fi);
     }
 }
 
@@ -1363,6 +1405,8 @@ sub dopush () {
     printdebug "actually entering push\n";
     prep_ud();
 
+    access_giturl(); # check that success is vaguely likely
+
     my $clogpfn = ".git/dgit/changelog.822.tmp";
     runcmd shell_cmd "exec >$clogpfn", qw(dpkg-parsechangelog);
 
@@ -1503,6 +1547,12 @@ sub cmd_clone {
     }
     $dstdir ||= "$package";
 
+    if (stat $dstdir) {
+       fail "$dstdir already exists";
+    } elsif ($! != &ENOENT) {
+       die "$dstdir: $!";
+    }
+
     my $cwd_remove;
     if ($rmonerror && !$dryrun_level) {
        $cwd_remove= getcwd();
@@ -2146,8 +2196,6 @@ if ($ENV{$fakeeditorenv}) {
     quilt_fixup_editor();
 }
 
-delete $ENV{'DGET_UNPACK'};
-
 parseopts();
 print STDERR "DRY RUN ONLY\n" if $dryrun_level > 1;
 print STDERR "DAMP RUN - WILL MAKE LOCAL (UNSIGNED) CHANGES\n"