chiark / gitweb /
dgit: update-vcs-git: Do not crash if url is unchanged
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 696978b2ee7abb53f26fa198652666b1e18c2e4d..d57b64351e1883f78772e9ae075be814f0bee8c4 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -30,7 +30,7 @@ setup_sigwarn();
 
 use IO::Handle;
 use Data::Dumper;
-use LWP::UserAgent;
+use WWW::Curl::Easy;
 use Dpkg::Control::Hash;
 use File::Path;
 use File::Spec;
@@ -639,20 +639,6 @@ sub progress {
 
 our $ua;
 
-sub url_get {
-    if (!$ua) {
-       $ua = LWP::UserAgent->new();
-       $ua->env_proxy;
-    }
-    my $what = $_[$#_];
-    progress "downloading $what...";
-    my $r = $ua->get(@_) or confess "$!";
-    return undef if $r->code == 404;
-    $r->is_success or fail f_ "failed to fetch %s: %s",
-       $what, $r->status_line;
-    return $r->decoded_content(charset => 'none');
-}
-
 our ($dscdata,$dscurl,$dsc,$dsc_checked,$skew_warning_vsn);
 
 sub act_local () { return $dryrun_level <= 1; }
@@ -1192,12 +1178,11 @@ sub cfg_apply_map ($$$) {
     $$varref = $_;
 }
 
-#---------- `ftpmasterapi' archive query method (nascent) ----------
-
-sub archive_api_query_curl ($) {
-    my ($url) = @_;
-
-    use WWW::Curl::Easy;
+sub url_fetch ($;@) {
+    my ($url, %xopts) = @_;
+    # Ok404 => 1   means give undef for 404
+    # AccessBase => 'archive-query' (eg)
+    # CurlOpts => { key => value }
 
     my $curl  = WWW::Curl::Easy->new;
     my $setopt = sub {
@@ -1206,38 +1191,52 @@ sub archive_api_query_curl ($) {
        confess "$k $v ".$curl->strerror($x)." ?" if $x;
     };
 
-    my $response_body;
+    my $response_body = '';
     $setopt->(CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS|CURLPROTO_HTTP);
     $setopt->(CURLOPT_URL,             $url);
+    $setopt->(CURLOPT_NOSIGNAL,        1);
     $setopt->(CURLOPT_WRITEDATA,       \$response_body);
 
-    if ($url =~ m#^https://([-.0-9a-z]+)/#) {
-       foreach my $k (qw(archive-query-tls-key
-                         archive-query-tls-curl-ca-args)) {
+    my $xcurlopts = $xopts{CurlOpts} // { };
+    keys %$xcurlopts;
+    while (my ($k,$v) = each %$xcurlopts) { $setopt->($k,$v); }
+
+    if ($xopts{AccessBase} && $url =~ m#^https://([-.0-9a-z]+)/#) {
+       foreach my $k ("$xopts{AccessBase}-tls-key",
+                      "$xopts{AccessBase}-tls-curl-ca-args") {
            fail "config option $k is obsolete and no longer supported"
                if defined access_cfg($k, 'RETURN-UNDEF');
        }
     }
 
-    printdebug "archive api query: fetching $url...\n";
+    printdebug "query: fetching $url...\n";
+
+    local $SIG{PIPE} = 'IGNORE';
 
     my $x = $curl->perform();
     fail f_ "fetch of %s failed (%s): %s",
        $url, $curl->strerror($x), $curl->errbuf
        if $x;
 
-    return $curl->getinfo(CURLINFO_HTTP_CODE), $response_body;
+    my $code = $curl->getinfo(CURLINFO_HTTP_CODE);
+    if ($code eq '404' && $xopts{Ok404}) { return undef; }
+    
+    fail f_ "fetch of %s gave HTTP code %s", $url, $code
+       unless $url =~ m#^file://# or $code =~ m/^2/;
+
+    confess unless defined $response_body;
+    return $response_body;
 }
 
+#---------- `ftpmasterapi' archive query method (nascent) ----------
+
 sub api_query_raw ($;$) {
     my ($subpath, $ok404) = @_;
     my $url = access_cfg('archive-query-url');
     $url .= $subpath;
-    my ($code,$json)  = archive_api_query_curl($url);
-    return undef if $code eq '404' && $ok404;
-    fail f_ "fetch of %s gave HTTP code %s", $url, $code
-       unless $url =~ m#^file://# or $code =~ m/^2/;
-    return $json;
+    return url_fetch $url,
+       Ok404 => $ok404,
+       AccessBase => 'archive-query';
 }
 
 sub api_query ($$;$) {
@@ -1737,7 +1736,7 @@ sub get_archive_dsc () {
     foreach my $vinfo (@vsns) {
        my ($vsn,$vsn_dscurl,$digester,$digest) = @$vinfo;
        $dscurl = $vsn_dscurl;
-       $dscdata = url_get($dscurl);
+       $dscdata = url_fetch($dscurl);
        if (!$dscdata) {
            $skew_warning_vsn = $vsn if !defined $skew_warning_vsn;
            next;
@@ -1791,22 +1790,13 @@ sub check_for_git () {
        my $suffix = access_cfg('git-check-suffix','git-suffix',
                                'RETURN-UNDEF') // '.git';
        my $url = "$prefix/$package$suffix";
-       my @cmd = (@curl, qw(-sS -I), $url);
-       my $result = cmdoutput @cmd;
-       $result =~ s/^\S+ 200 .*\n\r?\n//;
-       # curl -sS -I with https_proxy prints
-       # HTTP/1.0 200 Connection established
-       $result =~ m/^\S+ (404|200) /s or
-           fail +(__ "unexpected results from git check query - ").
-               Dumper($prefix, $result);
-       my $code = $1;
-       if ($code eq '404') {
-           return 0;
-       } elsif ($code eq '200') {
-           return 1;
-       } else {
-           die;
-       }
+       my $result = url_fetch $url,
+           CurlOpts => { CURLOPT_NOBODY() => 1 },
+           Ok404 => 1,
+           AccessBase => 'git-check';
+       $result = defined $result;
+       printdebug "dgit-repos check_for_git => $result.\n";
+       return $result;
     } elsif ($how eq 'true') {
        return 1;
     } elsif ($how eq 'false') {
@@ -3858,6 +3848,15 @@ END
     printdone f_ "ready for work in %s", $dstdir;
 }
 
+sub vcs_git_url_of_ctrl ($) {
+    my ($ctrl) = @_;
+    my $vcsgiturl = $ctrl->{'Vcs-Git'};
+    if (length $vcsgiturl) {
+       $vcsgiturl =~ s/\s+-b\s+\S+//g;
+    }
+    return $vcsgiturl;
+}
+
 sub clone ($) {
     # in multisuite, returns twice!
     # once in parent after first suite fetched,
@@ -3896,9 +3895,8 @@ sub clone ($) {
        progress __ "starting new git history";
     }
     fetch_from_archive() or no_such_package;
-    my $vcsgiturl = $dsc->{'Vcs-Git'};
+    my $vcsgiturl = vcs_git_url_of_ctrl $dsc;
     if (length $vcsgiturl) {
-       $vcsgiturl =~ s/\s+-b\s+\S+//g;
        runcmd @git, qw(remote add vcs-git), $vcsgiturl;
     }
     clone_finish($dstdir);
@@ -4034,6 +4032,7 @@ sub get_source_format () {
     }
     $_ = <F>;
     F->error and confess "$!";
+    close F;
     chomp;
     return ($_, \%options);
 }
@@ -4986,7 +4985,7 @@ sub cmd_update_vcs_git () {
        print STDERR f_ "changing vcs-git url to: %s\n", $url;
        @cmd = (@git, qw(remote set-url vcs-git), $url);
     }
-    runcmd_ordryrun_local @cmd;
+    runcmd_ordryrun_local @cmd if @cmd;
     if ($dofetch) {
        print f_ "fetching (%s)\n", "@ARGV";
        runcmd_ordryrun_local @git, qw(fetch vcs-git), @ARGV;