The following commit has been merged in the master branch:
commit 34123acf14ab34e5c59f9e400e485de8651b47c1
Author: Christoph Berg <[email protected]>
Date:   Fri Dec 31 19:11:22 2010 +0100

    debcheckout: new option --source to get orig.tgz
    
    --source: Some packages only place the debian directory in version control.
    debcheckout can retrieve the remaining parts of the source using apt-get 
source
    and move the files into the checkout.
    
    never: Only use the repository.
    
    auto (default): If the repository only contains the debian directory, 
retrieve
    the source package, unpack it, and also place the .orig.tar.gz file into the
    current directory. Else, do nothing.
    
    download-only: Always retrieve the .orig.tar.gz file, but do not unpack it.
    
    always: Always retrieve the .orig.tar.gz file, and if the repository only
    contains the debian directory, unpack it.

diff --git a/scripts/debcheckout.pl b/scripts/debcheckout.pl
index 939e5a2..c454718 100755
--- a/scripts/debcheckout.pl
+++ b/scripts/debcheckout.pl
@@ -119,6 +119,35 @@ Specify that the named file should be extracted from the 
repository and placed
 in the destination directory. May be used more than once to extract mutliple
 files.
 
+=item B<--source=never|auto|download-only|always>
+
+Some packages only place the debian directory in version control.
+B<debcheckout> can retrieve the remaining parts of the source using B<apt-get
+source> and move the files into the checkout.
+
+=over
+
+=item B<never>
+
+Only use the repository.
+
+=item B<auto> (default)
+
+If the repository only contains the debian directory, retrieve the source
+package, unpack it, and also place the .orig.tar.gz file into the current
+directory. Else, do nothing.
+
+=item B<download-only>
+
+Always retrieve the .orig.tar.gz file, but do not unpack it.
+
+=item B<always>
+
+Always retrieve the .orig.tar.gz file, and if the repository only contains the
+debian directory, unpack it.
+
+=back
+
 =back
 
 B<VCS-SPECIFIC OPTIONS>
@@ -271,12 +300,13 @@ sub recurs_mkdir {
 }
 
 # Find the repository URL (and type) for a given package name, parsing Vcs-*
-# fields.
+# fields.  Returns (version, type, url, origtgz_name) tuple.
 sub find_repo($$) {
     my ($pkg, $desired_ver) = @_;
-    my @repo = (0, "");
+    my @repo = ("", 0, "", "");
     my $found = 0;
     my $version = "";
+    my $origtgz_name = "";
     my $type = "";
     my $url = "";
     my @repos = ();
@@ -290,13 +320,16 @@ sub find_repo($$) {
            ($type, $url) = (lc($2), $3);
        } elsif ($line =~ /^Version:\s*(.*)$/i) {
            $version = $1;
+       } elsif ($line =~ /^ [a-f0-9]{32} \d+ (\S+)\.orig\.tar\.gz$/) {
+           $origtgz_name = $1;
        } elsif ($line =~ /^$/) {
-           push (@repos, [$version, $type, $url])
+           push (@repos, [$version, $type, $url, $origtgz_name])
                if ($version and $type and $url and
                    ($desired_ver eq "" or $desired_ver eq $version));
            $version = "";
            $type = "";
            $url = "";
+           $origtgz_name = "";
        }
     }
     close(APT);
@@ -304,7 +337,7 @@ sub find_repo($$) {
 
     if (@repos) {
        @repos = Devscripts::Versort::versort(@repos);
-       @repo = ($repos[0][1], $repos[0][2])
+       @repo = @{$repos[0]};
     }
     return @repo;
 }
@@ -746,6 +779,81 @@ sub checkout_files($$$$) {
     return 0;
 }
 
+# download source package, unpack it, and merge its contents into the checkout
+sub unpack_source($$$$) {
+    my ($pkg, $version, $origtgz_name, $unpack_source) = @_;
+
+    return 1 if ($unpack_source eq 'never');
+    return 1 if (defined $origtgz_name and $origtgz_name eq ''); # only really 
relevant with URL on command line
+
+    # is this a debian-dir-only repository?
+    unless (-d $pkg) {
+       print STDERR "debcheckout did not create the $pkg directory - this is 
probably a bug\n";
+       return 0;
+    }
+    my @repo_files = glob "$pkg/*";
+    my $debian_only = 0;
+    if (@repo_files == 1 and $repo_files[0] eq "$pkg/debian") {
+       $debian_only = 1;
+    }
+
+    return 1 if ($unpack_source eq 'auto' and not $debian_only);
+    if ($unpack_source ne 'download-only' and $debian_only) {
+       print "repository only contains the debian directory, using apt-get 
source\n";
+    }
+
+    use File::Temp;
+    my $tmpdir = File::Temp->newdir(DIR => ".");
+
+    # unpack
+    my $cmd = "cd $tmpdir && apt-get source ";
+    $cmd .= "--download-only " if ($unpack_source eq 'download-only' or not 
$debian_only);
+    $cmd .= $pkg;
+    $cmd .= "=$version" if ($version);
+    system($cmd);
+    if ($? >> 8) {
+       print STDERR "apt-get source failed\n";
+       return 0;
+    }
+
+    # put orig.tar.gz in place
+    my @origtgz = glob "$tmpdir/${pkg}_*.orig.tar.gz";
+    if (@origtgz) {
+       my $base = $origtgz[0];
+       $base =~ s!.*/!!;
+       rename $origtgz[0], $base or die "rename $origtgz[0] $base: $!";
+    }
+
+    return 1 if ($unpack_source eq 'download-only' or not $debian_only);
+
+    # figure out which directory was created
+    my @dirs = glob "$tmpdir/$pkg-*/";
+    unless (@dirs) {
+       print STDERR "apt-get source did not create any $tmpdir/$pkg-* 
directory\n";
+       return 0;
+    }
+    my $directory = $dirs[0];
+    chop $directory;
+
+    # move all files over, except the debian directory
+    opendir DIR, $directory or die "opendir $directory: $!";
+    foreach my $file (readdir DIR) {
+       if ($file eq 'debian') {
+           system ('rm', '-rf', "$directory/$file");
+       } elsif ($file eq '.' or $file eq '..') {
+           next;
+       } else {
+           rename "$directory/$file", "$pkg/$file" or
+               die "rename $directory/$file $pkg/$file: $!";
+       }
+    }
+    closedir DIR;
+    rmdir $directory or die "rmdir $directory: $!";
+
+    # $tmpdir is automatically removed
+    return 1;
+}
+
 # Print information about a repository and quit.
 sub print_repo($$) {
     my ($repo_type, $repo_url) = @_;
@@ -826,6 +934,7 @@ sub main() {
     my $destdir = "";    # destination directory
     my $pkg = "";                # package name
     my $version = "";       # package version
+    my $origtgz_name = undef; # orig.tar.gz name (or "" when none; undef means 
unknown)
     my $print_mode = 0;          # print only mode
     my $details_mode = 0;        # details only mode
     my $repo_type = "svn";  # default repo typo, overridden by '-t'
@@ -833,6 +942,7 @@ sub main() {
     my $user = "";       # login name (authenticated mode only)
     my $browse_url = "";    # online browsable repository URL
     my $git_track = "";     # list of remote GIT branches to --track
+    my $unpack_source = 'auto'; # retrieve and unpack orig.tar.gz
     GetOptions(
        "auth|a" => \$auth,
        "help|h" => sub { pod2usage({-exitval => 0, -verbose => 1}); },
@@ -842,6 +952,7 @@ sub main() {
        "user|u=s" => \$user,
        "file|f=s" => sub { push(@files, $_[1]); },
        "git-track=s" => \$git_track,
+       "source=s" => \$unpack_source,
        ) or pod2usage({-exitval => 3});
     pod2usage({-exitval => 3}) if ($#ARGV < 0 or $#ARGV > 1);
     pod2usage({-exitval => 3,
@@ -849,6 +960,10 @@ sub main() {
                   "-d and -p are mutually exclusive.\n", })
        if ($print_mode and $details_mode);
     my $dont_act = 1 if ($print_mode or $details_mode);
+    pod2usage({-exitval => 3,
+              -message =>
+                  "--orig argument must be one of never, auto, download-only, 
and always\n", })
+       unless ($unpack_source =~ /^(never|auto|download-only|always)$/);
 
     # -u|--user implies -a|--auth
     $auth = 1 if length $user;
@@ -856,12 +971,20 @@ sub main() {
     $destdir = $ARGV[1] if $#ARGV > 0;
     ($pkg, $version) = split(/=/, $ARGV[0]);
     $version ||= "";
+
     if (not is_package($pkg)) {  # repo-url passed on the command line
        $repo_url = $ARGV[0];
        $repo_type = guess_repo_type($repo_url, $repo_type);
        $pkg = ""; $version = "";
+       # guess package from url
+       if ($repo_url =~ m!([a-z0-9.+-]+)/trunk/?!) { # svn
+           $pkg = $1;
+       } elsif ($repo_url =~ /([a-z0-9.+-]+)(?:\.git)?$/) { # git, and 
catch-all
+           $pkg = $1;
+       }
+
     } else {  # package name passed on the command line
-       ($repo_type, $repo_url) = find_repo($pkg, $version);
+       ($version, $repo_type, $repo_url, $origtgz_name) = find_repo($pkg, 
$version);
        unless ($repo_type) {
            my $vermsg = "";
            $vermsg = ", version $version" if length $version;
@@ -970,8 +1093,21 @@ EOF
            }
        }
     }
+    die "post-checkout action failed\n"
+       if $rc != 0;
+
+    if ($unpack_source) {
+       unless ($pkg) {
+           print STDERR "could not determine package name for orig.tar.gz 
retrieval\n";
+           $rc ||= 1;
+           exit($rc);
+       }
+       unpack_source($pkg, $version, $origtgz_name, $unpack_source) or $rc = 1;
+    }
+
     exit($rc);
 }
 
 main();
 
+# vim:sw=4

-- 
Git repository for devscripts


-- 
To unsubscribe, send mail to [email protected].

Reply via email to