Now that I have your attention, to put an end to this discussion I have coded a small perl script which is able to download or (human-legibly) list the sources and patches in a spec file, even if they contain macros, well even if they're conditionalized beyond all recognition. It does this by using RPM for the parsing of the macros etc. and so should be able to cope with most spec files. Options (which unfortunately aren't listed by the script): -l|--list: only list expanded sources/patches -D|--dummy: don't retrieve stuff, just do as if (for testing) -d|--define: to define macros just like with RPM (use as often as you want to) -v|--verbose: increase verbosity level, useful with --dummy It accepts as arguments: - the spec file - optionally what to list/retrieve: "sources", "patches", "all", "source0", "patch5", you get the idea. Good night, Nils -- Nils Philippsen / Red Hat / nphilipp@xxxxxxxxxx "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -- B. Franklin, 1759 PGP fingerprint: C4A8 9474 5C4C ADE3 2B8F 656D 47D8 9B65 6951 3011
#!/usr/bin/perl -w use strict; use File::Temp; use Getopt::Long; Getopt::Long::Configure ('no_ignore_case'); my $dir = File::Temp::tempdir ( CLEANUP => 1 ); my ($fh, $filename) = File::Temp::tempfile ( DIR => $dir ); my @rpm_sections = qw/description prep build install clean pre preun post postun triggerin triggerun triggerpostun files changelog/; my %rpm_sections; foreach (@rpm_sections) { $rpm_sections{$_} = 1; } my @protocols = qw/ftp http https/; my $protocols_re = '(?:' . join ('|', @protocols) . ')'; my @defines; my %sources; my %patches; my $specfile; my $verbose = 0; my $dummy = 0; sub eval_sources_patches { print $fh "Summary: foo Name: foo Version: foo Release: foo License: FOO! Group: Foo \%description \%prep echo BEGIN "; foreach (@defines) { print $fh "\%define $_\n"; } print $fh "cat << EOF_$filename\n"; while (<>) { my $line = $_; if ($line =~ m/^\s*%(\w+)/) { my $word = lc $1; if (defined ($rpm_sections{$word})) { last; } } print $fh $line; } print $fh "EOF_$filename"; close $fh; open PIPE, "rpmbuild -bp $filename 2>/dev/null |" or die; while (<PIPE>) { chomp (); if (m/^\s*(source|patch)(\d*)\s*:\s*(.*\S)\s*$/i) { my $what = \%sources; if ($1 eq 'patch') { $what = \%patches; } my $index = 0; if ($2 ne '') { $index = $2; } $what->{$index} = $3; } } close PIPE; } sub expand { my $foo = $_[0]; my @retval; foreach ($foo) { m/^sources$/i && do { foreach (sort (keys %sources)) { $retval[$#retval + 1] = "source$_"; } }; m/^patches$/i && do { foreach (sort (keys %patches)) { $retval[$#retval + 1] = "patch$_"; } }; m/^all$/i && do { @retval = (expand ('sources'), expand ('patches')); }; } return @retval; } sub list_sources_patches { foreach (@_) { m/^source(\d+)$/i && print "Source$1: " . $sources{$1} . "\n"; m/^patch(\d+)$/i && print "Patch$1: " . $patches{$1} . "\n"; m/^(sources|patches|all)$/i && list_sources_patches (expand ($1)); } } sub retrievable { my $url = $_[0]; return eval "\$url =~ m,^$protocols_re://,;"; } sub retrieve { my $url = $_[0]; if (retrievable ($url)) { print "Getting $url\n" if ($verbose); print "--> wget $url\n" if ($verbose > 1); system ("wget $url") unless ($dummy); } else { print STDERR "Couldn't fetch $url: missing URL\n" if ($verbose); } } sub retrieve_sources_patches { foreach (@_) { m/^source(\d+)$/i && retrieve ($sources{$1}); m/^patch(\d+)$/i && retrieve ($patches{$1}); m/^(sources|patches|all)$/i && retrieve_sources_patches (expand ($1)); } } # main my $command = 'retrieve'; GetOptions ('d|define=s' => \@defines, 'l|list' => sub { $command = 'list'; }, 'v|verbose' => sub { $verbose++; }, 'D|dummy' => sub { $dummy = 1; }); $specfile = $ARGV[0]; my @what = @ARGV[1..$#ARGV]; if ($#what < 0) { @what = ('all'); } eval_sources_patches (); foreach ($command) { m/list/ && list_sources_patches (@what); m/retrieve/ && retrieve_sources_patches (@what); }
Attachment:
signature.asc
Description: This is a digitally signed message part