chiark / gitweb /
When source package contains things called .git (even files, and even in subdirectori...
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 8f4a71c2a3683087b020520dcc05fea6eb8a1fe5..687ebe14337ce29c8cab701e0b69393875f103f7 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -18,7 +18,9 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 use strict;
-$SIG{__WARN__} = sub { die $_[0]; };
+
+use Debian::Dgit;
+setup_sigwarn();
 
 use IO::Handle;
 use Data::Dumper;
@@ -444,12 +446,16 @@ our %defcfg = ('dgit.default.distro' => 'debian',
               'dgit.default.archive-query' => 'madison:',
               'dgit.default.sshpsql-dbname' => 'service=projectb',
               'dgit-distro.debian.archive-query' => 'ftpmasterapi:',
-              'dgit-distro.debian.git-host' => 'dgit-git.debian.net',
-              'dgit-distro.debian.git-user-force' => 'dgit',
-              'dgit-distro.debian.git-proto' => 'git+ssh://',
-              'dgit-distro.debian.git-path' => '/dgit/debian/repos',
-              'dgit-distro.debian.git-create' => 'true',
-              'dgit-distro.debian.git-check' => 'ssh-cmd',
+              'dgit-distro.debian.git-check' => 'url',
+              'dgit-distro.debian.git-check-suffix' => '/info/refs',
+              'dgit-distro.debian.new-private-pushers' => 't',
+              'dgit-distro.debian/push.git-url' => '',
+              'dgit-distro.debian/push.git-host' => 'push.dgit.debian.org',
+              'dgit-distro.debian/push.git-user-force' => 'dgit',
+              'dgit-distro.debian/push.git-proto' => 'git+ssh://',
+              'dgit-distro.debian/push.git-path' => '/dgit/debian/repos',
+              'dgit-distro.debian/push.git-create' => 'true',
+              'dgit-distro.debian/push.git-check' => 'ssh-cmd',
  'dgit-distro.debian.archive-query-url', 'https://api.ftp-master.debian.org/',
 # 'dgit-distro.debian.archive-query-tls-key',
 #    '/etc/ssl/certs/%HOST%.pem:/etc/dgit/%HOST%.pem',
@@ -460,13 +466,8 @@ our %defcfg = ('dgit.default.distro' => 'debian',
 # 'dgit-distro.debian.archive-query-tls-curl-args',
 #   '--ca-path=/etc/ssl/ca-debian',
 # ^ this is a workaround but works (only) on DSA-administered machines
-              'dgit-distro.debian.diverts.alioth' => '/alioth',
-              'dgit-distro.debian/push.diverts.alioth' => '/alioth',
-              'dgit-distro.debian/alioth.git-host' => 'git.debian.org',
-              'dgit-distro.debian/alioth.git-user-force' => '',
-              'dgit-distro.debian/alioth.git-proto' => 'git+ssh://',
-              'dgit-distro.debian/alioth.git-path' => '/git/dgit-repos/repos',
-              'dgit-distro.debian/alioth.git-create' => 'ssh-cmd',
+              'dgit-distro.debian.git-url' => 'https://git.dgit.debian.org',
+              'dgit-distro.debian.git-url-suffix' => '',
               '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*',
@@ -549,10 +550,45 @@ sub access_quirk () {
     return ('none',undef);
 }
 
-our $access_pushing = 0;
+our $access_forpush;
+
+sub parse_cfg_bool ($$$) {
+    my ($what,$def,$v) = @_;
+    $v //= $def;
+    return
+       $v =~ m/^[ty1]/ ? 1 :
+       $v =~ m/^[fn0]/ ? 0 :
+       badcfg "$what needs t (true, y, 1) or f (false, n, 0) not \`$v'";
+}      
+
+sub access_forpush_config () {
+    my $d = access_basedistro();
+
+    return 1 if
+       $new_package &&
+       parse_cfg_bool('new-private-pushers', 0,
+                      cfg("dgit-distro.$d.new-private-pushers",
+                          'RETURN-UNDEF'));
+
+    my $v = cfg("dgit-distro.$d.readonly", 'RETURN-UNDEF');
+    $v //= 'a';
+    return
+       $v =~ m/^[ty1]/ ? 0 : # force readonly,    forpush = 0
+       $v =~ m/^[fn0]/ ? 1 : # force nonreadonly, forpush = 1
+       $v =~ m/^[a]/  ? '' : # auto,              forpush = ''
+       badcfg "readonly needs t (true, y, 1) or f (false, n, 0) or a (auto)";
+}
+
+sub access_forpush () {
+    $access_forpush //= access_forpush_config();
+    return $access_forpush;
+}
 
 sub pushing () {
-    $access_pushing = 1;
+    die "$access_forpush ?" if ($access_forpush // 1) ne 1;
+    badcfg "pushing but distro is configured readonly"
+       if access_forpush_config() eq '0';
+    $access_forpush = 1;
 }
 
 sub access_distros () {
@@ -570,7 +606,7 @@ sub access_distros () {
     unshift @l, $instead_distro;
     @l = grep { defined } @l;
 
-    if ($access_pushing) {
+    if (access_forpush()) {
        @l = map { ("$_/push", $_) } @l;
     }
     @l;
@@ -647,7 +683,7 @@ sub access_giturl (;$) {
     my ($optional) = @_;
     my $url = access_cfg('git-url','RETURN-UNDEF');
     my $suffix;
-    if (!defined $url) {
+    if (!length $url) {
        my $proto = access_cfg('git-proto', 'RETURN-UNDEF');
        return undef unless defined $proto;
        $url =
@@ -1058,6 +1094,24 @@ sub check_for_git () {
        }
        failedcmd @cmd unless $r =~ m/^[01]$/;
        return $r+0;
+    } elsif ($how eq 'url') {
+       my $prefix = access_cfg('git-check-url','git-url');
+       my $suffix = access_cfg('git-check-suffix','git-suffix',
+                               'RETURN-UNDEF') // '.git';
+       my $url = "$prefix/$package$suffix";
+       my @cmd = (qw(curl -sS -I), $url);
+       my $result = cmdoutput @cmd;
+       $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;
+       }
     } elsif ($how eq 'true') {
        return 1;
     } elsif ($how eq 'false') {
@@ -1111,7 +1165,21 @@ sub mktree_in_ud_from_only_subdir () {
     $dirs[0] =~ m#^([^/]+)/\.$# or die;
     my $dir = $1;
     changedir $dir;
-    fail "source package contains .git directory" if stat_exists '.git';
+
+    my @gitscmd = qw(find -name .git -prune -print0);
+    debugcmd "|",@gitscmd;
+    open GITS, "-|", @gitscmd or failedcmd @gitscmd;
+    {
+       local $/="\0";
+       while (<GITS>) {
+           chomp or die;
+           print STDERR "$us: warning: removing from source package: ",
+               (messagequote $_), "\n";
+           rmtree $_;
+       }
+    }
+    $!=0; $?=0; close GITS or failedcmd @gitscmd;
+
     mktree_in_ud_here();
     my $format=get_source_format();
     if (madformat($format)) {
@@ -1800,12 +1868,6 @@ sub dopush ($) {
            failedcmd @diffcmd;
        }
     }
-#fetch from alioth
-#do fast forward check and maybe fake merge
-#    if (!is_fast_fwd(mainbranch
-#    runcmd @git, qw(fetch -p ), "$alioth_git/$package.git",
-#        map { lref($_).":".rref($_) }
-#        (uploadbranch());
     my $head = git_rev_parse('HEAD');
     if (!$changesfile) {
        my $multi = "$buildproductsdir/".
@@ -3027,6 +3089,7 @@ my $cmd = shift @ARGV;
 $cmd =~ y/-/_/;
 
 if (!defined $quilt_mode) {
+    local $access_forpush;
     $quilt_mode = cfg('dgit.force.quilt-mode', 'RETURN-UNDEF')
        // access_cfg('quilt-mode', 'RETURN-UNDEF')
        // 'linear';