7 ## Patch the provides list in the perl package PKGBUILD. Scan the appropriate
8 ## directories under the perl source tree for directories containing dists
9 ## similar to CPAN dists. Search the files in the distributions for VERSION
10 ## strings, which are perl expressions. Filters these version strings through
11 ## the perl interpreter, then transform the dist. names and versions into
12 ## package names and versions. Finally, we cut out the "provides" array from the
13 ## PKGBUILD and replace it with the newer version.
16 ## patchprov [path to perl source tree] [path to PKGBUILD]
19 ## The path code is not platform independent and will only work in POSIX.
22 ## 06/10/14 JD Rewrite from scratch for perl 5.20.0 and ArchLinux.
25 ## Justin "juster" Davis <jrcd83@gmail.com>
33 print STDERR
"patchprov: error: @_\n";
37 ## Extract the dist. name from its containing directory.
45 ## Create a path like $path/lib/Foo/Bar.pm for Foo::Bar.
48 my($path, $modname) = @_;
49 $modname =~ s{::}{/}g;
50 return "$path/lib/$modname.pm";
53 ## Create a path to a file in the containing directory, named after
54 ## the last segment of the module name, with suffix attached.
57 my($path, $modname, $suffix) = @_;
58 $modname =~ s{^.*::}{};
59 return "$path/$modname$suffix";
62 ## Find a source file contained in the directory that we can scrape the
63 ## perl versions string from.
66 'Scalar-List-Utils' => 'List::Util',
67 'IO-Compress' => 'IO::Compress::Gzip',
72 my $distname = path_dist
($path);
74 if(exists $distmods{$distname}){
75 $modname = $distmods{$distname};
81 lib_modpath
($path, $modname),
82 dumb_modpath
($path, $modname, '.pm'),
83 dumb_modpath
($path, $modname, '_pm.PL'),
84 dumb_modpath
($path, '__'.$modname.'__', '.pm'),
85 "$path/VERSION", # for podlators
87 for my $src (@srcpaths){
88 return $src if(-f
$src);
93 ## Scrape the version string for the module file or Makefile.PL.
97 open my $fh, '<', $srcpath or die "open: $!";
98 while(my $ln = <$fh>){
99 if($ln =~ s/^.*VERSION *=>? *//){
105 err
("failed to find VERSION in $srcpath");
108 ## Scrape the version string from the module source file.
112 return scrape_verln
($srcpath);
115 ## Scrape the version string from the Makefile.PL. (for libnet)
119 my $verln = scrape_verln
($srcpath);
124 ## Scrape the version string from a file inside the dist dir.
128 my $srcpath = dist_srcpath
($distpath);
129 my $mkplpath = "$distpath/Makefile.PL";
130 if(defined $srcpath){
131 return scrape_modver
($srcpath);
132 }elsif(-f
$mkplpath){
133 return scrape_mkplver
($mkplpath);
135 err
("failed to scrape version from $distpath");
139 ## Search the base path for the dist dirs and extract their respective
144 opendir my $dh, $basepath or die "opendir: $!";
145 my @dirs = grep { -d
$_ } map { "$basepath/$_" } grep { !/^[.]/ } readdir $dh;
149 for my $dpath (@dirs){
150 push @distvers, [ path_dist
($dpath), distpath_ver
($dpath) ];
155 ## Maps an aref of dist name/perl version strings (perl expressions) to
156 ## a package name and version string suitable for a PKGBUILD.
159 my($dist, $ver) = @
$_;
160 $dist =~ tr/A-Z/a-z/;
162 return "perl-$dist=$ver";
165 ## Searches the perl source dir provided for a list of packages which
166 ## correspond to the core distributions bundled within in.
170 my @dirs = ("$perlpath/cpan", "$perlpath/dist");
174 err
("$d is not a valid directory");
176 push @provs, map pkgspec
, find_distvers
($d);
181 ## Formats the provided lines into a neatly formatted bash array. The first arg
182 ## is the name of the bash variable to assign it to.
187 ## Sort entries and surround with quotes.
188 my @lns = sort map { qq{'$_'} } @_;
189 $lns[0] = "$vname=($lns[0]";
191 ## Indent lines for OCD geeks.
193 my $ind = length($vname) + 2;
194 splice @lns, 1, @lns-1,
195 map { (' ' x
$ind) . $_ } @lns[1 .. $#lns];
199 return map { "$_\n" } @lns;
202 ## Patch the PKGBUILD at the given path with a new provides array, overwriting
207 open my $fh, '<', $pbpath or die "open: $!";
212 for($i = 0; $i < @lines; $i++){
213 last if($lines[$i] =~ /^provides=/);
216 err
("failed to find provides array in PKGBUILD");
218 for($j = $i; $j < @lines; $j++){
219 last if($lines[$j] =~ /[)]/);
222 err
("failed to find end of provides array");
225 splice @lines, $i, $j-$i+1,
226 basharray
('provides', grep { !/win32|next/ } @_);
228 ## Avoid corrupting the existing PKGBUILD in case of a crash, etc.
230 err
("pbpath.$$ temporary file already exists, please remove it.");
232 open $fh, '>', "$pbpath.$$" or die "open: $!";
234 close $fh or die "close: $!";
235 rename "$pbpath.$$", "$pbpath" or die "rename: $!";
240 ## Program entrypoint.
244 print STDERR
"usage: $0 [perl source path] [PKGBUILD path]\n";
247 my($perlpath, $pbpath) = @_;
249 err
("$pbpath is not a valid file.");
250 }elsif(!-d
$perlpath){
251 err
("$perlpath is not a valid directory.");
253 patchpb
($pbpath, perlcorepkgs
($perlpath));