chiark / gitweb /
git-debrebase: merge: Comment about laundry of merge of unstitched
[dgit.git] / Debian / Dgit.pm
index 8f069f7575e64739be6d9a25237d2f0640f3dff6..34e40a3b0ab684327533e868de48e95f7d4d241e 100644 (file)
@@ -31,6 +31,7 @@ use Data::Dumper;
 use IPC::Open2;
 use File::Path;
 use File::Basename;
+use Dpkg::Control::Hash;
 
 BEGIN {
     use Exporter   ();
@@ -41,6 +42,9 @@ BEGIN {
     @EXPORT      = qw(setup_sigwarn forkcheck_setup forkcheck_mainprocess
                      dep14_version_mangle
                       debiantags debiantag_old debiantag_new
+                     debiantag_maintview
+                     upstreamversion
+                     stripepoch source_file_leafname is_orig_file_of_p_v
                      server_branch server_ref
                       stat_exists link_ltarget
                      hashfile
@@ -55,19 +59,21 @@ BEGIN {
                      git_reflog_action_msg  git_update_ref_cmd
                       $package_re $component_re $deliberately_re
                      $distro_re $versiontag_re $series_filename_re
+                     $orig_f_comp_re $orig_f_sig_re $orig_f_tail_re
                      $extra_orig_namepart_re
                      $git_null_obj
                       $branchprefix
                      $ffq_refprefix $gdrlast_refprefix
                       initdebug enabledebug enabledebuglevel
                       printdebug debugcmd
+                      $printdebug_when_debuglevel $debugcmd_when_debuglevel
                       $debugprefix *debuglevel *DEBUG
                       shellquote printcmd messagequote
                       $negate_harmful_gitattrs
                      changedir git_slurp_config_src
                      gdr_ffq_prev_branchinfo
                      parsecontrolfh parsecontrol parsechangelog
-                     getfield
+                     getfield parsechangelog_loop
                      playtree_setup);
     # implicitly uses $main::us
     %EXPORT_TAGS = ( policyflags => [qw(NOFFCHECK FRESHREPO NOCOMMITCHECK)],
@@ -89,9 +95,14 @@ our $versiontag_re = qr{[-+.\%_0-9a-zA-Z/]+};
 our $branchprefix = 'dgit';
 our $series_filename_re = qr{(?:^|\.)series(?!\n)$}s;
 our $extra_orig_namepart_re = qr{[-0-9a-z]+};
+our $orig_f_comp_re = qr{orig(?:-$extra_orig_namepart_re)?};
+our $orig_f_sig_re = '\\.(?:asc|gpg|pgp)';
+our $orig_f_tail_re = "$orig_f_comp_re\\.tar(?:\\.\\w+)?(?:$orig_f_sig_re)?";
 our $git_null_obj = '0' x 40;
 our $ffq_refprefix = 'ffq-prev';
 our $gdrlast_refprefix = 'debrebase-last';
+our $printdebug_when_debuglevel = 1;
+our $debugcmd_when_debuglevel = 1;
 
 # policy hook exit status bits
 # see dgit-repos-server head comment for documentation
@@ -148,7 +159,21 @@ sub enabledebuglevel ($) {
 }
     
 sub printdebug {
-    print DEBUG $debugprefix, @_ or die $! if $debuglevel>0;
+    # Prints a prefix, and @_, to DEBUG.  @_ should normally contain
+    # a trailing \n.
+
+    # With no (or only empty) arguments just prints the prefix and
+    # leaves the caller to do more with DEBUG.  The caller should make
+    # sure then to call printdebug with something ending in "\n" to
+    # get the prefix right in subsequent calls.
+
+    return unless $debuglevel >= $printdebug_when_debuglevel;
+    our $printdebug_noprefix;
+    print DEBUG $debugprefix unless $printdebug_noprefix;
+    pop @_ while @_ and !length $_[-1];
+    return unless @_;
+    print DEBUG @_ or die $!;
+    $printdebug_noprefix = $_[-1] !~ m{\n$};
 }
 
 sub messagequote ($) {
@@ -187,7 +212,8 @@ sub printcmd {
 
 sub debugcmd {
     my $extraprefix = shift @_;
-    printcmd(\*DEBUG,$debugprefix.$extraprefix,@_) if $debuglevel>0;
+    printcmd(\*DEBUG,$debugprefix.$extraprefix,@_)
+       if $debuglevel >= $debugcmd_when_debuglevel;
 }
 
 sub dep14_version_mangle ($) {
@@ -208,11 +234,40 @@ sub debiantag_new ($$) {
     return "archive/$distro/".dep14_version_mangle $v;
 }
 
+sub debiantag_maintview ($$) { 
+    my ($v,$distro) = @_;
+    return "$distro/".dep14_version_mangle $v;
+}
+
 sub debiantags ($$) {
     my ($version,$distro) = @_;
     map { $_->($version, $distro) } (\&debiantag_new, \&debiantag_old);
 }
 
+sub stripepoch ($) {
+    my ($vsn) = @_;
+    $vsn =~ s/^\d+\://;
+    return $vsn;
+}
+
+sub upstreamversion ($) {
+    my ($vsn) = @_;
+    $vsn =~ s/-[^-]+$//;
+    return $vsn;
+}
+
+sub source_file_leafname ($$$) {
+    my ($package,$vsn,$sfx) = @_;
+    return "${package}_".(stripepoch $vsn).$sfx
+}
+
+sub is_orig_file_of_p_v ($$$) {
+    my ($f, $package, $upstreamvsn) = @_;
+    my $base = source_file_leafname $package, $upstreamvsn, '';
+    return 0 unless $f =~ m/^\Q$base\E\.$orig_f_tail_re$/;
+    return 1;
+}
+
 sub server_branch ($) { return "$branchprefix/$_[0]"; }
 sub server_ref ($) { return "refs/".server_branch($_[0]); }
 
@@ -325,6 +380,7 @@ sub shell_cmd {
 
 sub cmdoutput_errok {
     confess Dumper(\@_)." ?" if grep { !defined } @_;
+    local $printdebug_when_debuglevel = $debugcmd_when_debuglevel;
     debugcmd "|",@_;
     open P, "-|", @_ or die "$_[0] $!";
     my $d;
@@ -377,6 +433,7 @@ sub git_cat_file ($;$) {
     # in scalar context, just the data
     # if $etype defined, dies unless type is $etype or in @$etype
     our ($gcf_pid, $gcf_i, $gcf_o);
+    local $printdebug_when_debuglevel = $debugcmd_when_debuglevel;
     my $chk = sub {
        my ($gtype, $data) = @_;
        if ($etype) {
@@ -609,6 +666,27 @@ sub getfield ($$) {
     fail "missing field $field in ".$dctrl->get_option('name');
 }
 
+sub parsechangelog_loop ($$$) {
+    my ($clogcmd, $descbase, $fn) = @_;
+    # @$clogcmd is qw(dpkg-parsechangelog ...some...options...)
+    # calls $fn->($thisstanza, $desc);
+    debugcmd "|",@$clogcmd;
+    open CLOGS, "-|", @$clogcmd or die $!;
+    for (;;) {
+       my $stanzatext = do { local $/=""; <CLOGS>; };
+       printdebug "clogp stanza ".Dumper($stanzatext) if $debuglevel>1;
+       last if !defined $stanzatext;
+
+       my $desc = "$descbase, entry no.$.";
+       open my $stanzafh, "<", \$stanzatext or die;
+       my $thisstanza = parsecontrolfh $stanzafh, $desc, 1;
+
+       $fn->($thisstanza, $desc);
+    }
+    die $! if CLOGS->error;
+    close CLOGS or $?==SIGPIPE or failedcmd @$clogcmd;
+}      
+
 # ========== playground handling ==========
 
 # terminology: