This is Paul's ActiveState Repo. ppm rep add "Paul's Repo" https://voltar.org/active/5.8/ I have a Makefile that builds the packlist.xml: https://voltar.org/active/5.8/Makefile -=-------------=-----------------=-------------------------------- -= These scripts are for building your own repos: #!/bin/bash # NOTE: this is the ppdp or ppd push pgram I use to publish my active packages. set -e [ ! -f Makefile ] && perl Makefile.PL if [ -f notest ]; then nmake else nmake test fi nmake ppd perl -MActivePerl::DocTools -e 'UpdateHTML_blib(installdirs => "site")' if [ ! -f META.yml ]; then make metafile cp */META.yml . fi x=`grep ^name: META.yml | head -n 1 | sed s/name:[\ ]*//` mv $x.ppd $x.ppd_pre sed "s/CODEBASE HREF=\"\"/CODEBASE HREF=\"$x.tar.gz\"/" $x.ppd_pre > $x.ppd tar -cvvf $x.tar blib/ gzip --best $x.tar chmod 644 $x.tar.gz $x.ppd ssh webhost.tld rm -f dirname/$x.old scp -p $x.{tar.gz,ppd} webhost.tld:dirname #!/usr/bin/perl # NOTE: This fixes the brain-dead ActiveState dependency problems. # # What's brain-dead? They use the dist-name of modules instead of the module # name and they do it very poorly. Example: build a Test-Harness ppd and it # requires File::Spec. Try to install Test-Harness and PPM tries to pull in # File::Spec 0.82 (with a warning) without the ability to realize it really # wants PathTools. QED. (This program is a partial fix.) our $CPAN_MIRROR = 'http://www.perl.com/CPAN/bug'; # select a mirror please use strict; use Compress::Zlib; use WWW::Mechanize; use Term::GentooFunctions qw(:all); use Module::CoreList; use Data::Dump qw(dump); my $pauls_skiplist = {Config=>1}; # modules that aren't distributed (but come with perl, like Config.pm) my $pauls_corelist = # corelist modules that shouldn't be upgraded to separate dist versions {constant=>1, IO=>1}; my ($mod_db, $pro_db, $f_db); &fetch; &parse; &scan; &smarten; &write; # write {{{ sub write { for my $dist_name (grep {exists $f_db->{$_}{a}} keys %$f_db) { my @e = @{ $f_db->{$dist_name}{e} }; $e[1] =~ s/\.ppd$/.fix/ or die "couldn't rename output file"; $e[0] =~ s/]+>/MYDEPS/g; $e[0] =~ s/MYDEPS.*MYDEPS/MYDEPS/s; $e[0] =~ s/^\s+MYDEPS/MYDEPS/m; my $deps = ""; my %did = (); for (@{ $f_db->{$dist_name}{a}{d} }) { next if exists $did{$_->[0]}; $deps .= " [0]\" VERSION=\"$_->[1]\"\/>\n"; $did{$_->[0]} = undef; } chomp $deps; $e[0] =~ s/MYDEPS/$deps/; ebegin "writing $e[1]"; open my $out, ">$e[1]" or die "coudln't open output file: $!"; print $out $e[0]; close $out; eend 1; } } # }}} # smarten {{{ sub smarten { for my $dist_name (keys %$f_db) { my @deps = @{ $f_db->{$dist_name}{d} }; my @ndep = @deps; my $altered = 0; my $overall_result = 1; for my $dep (@deps) { my $mname = $dep->[0]; $mname =~ s/-/::/g; my $difn = $mod_db->{$mname}{d}; if( $pauls_skiplist->{$mname} ) { einfo "$dist_name depends on $dep->[0] ($mname), which is on Paul's special skiplist."; @ndep = grep {$_ != $dep} @ndep; $altered = 1; next; } my $adep = $dep; if( $difn ne "perl" and $difn ne $dep->[0] ) { einfo "$dist_name depends on $dep->[0], which doesn't equal $difn, renaming"; edie "difn='' on $dist_name, $dep->[0]" unless $difn; $adep = [$difn, $dep->[1]]; @ndep = map {$_ == $dep ? $adep : $_} @ndep; $altered = 1; } if( my $core = Module::CoreList->first_release($mname) ) { if( $difn eq "perl" ) { einfo "$dist_name depends on $dep->[0] ($mname), which is CORE in perl $core and is only shipped there. Removing."; @ndep = grep {$_ != $adep} @ndep; $altered = 1; } if( $pauls_corelist->{$difn} ) { einfo "$dist_name depends on $dep->[0] ($mname), which is CORE and is shipped elsewhere, but is ruled by Paul's Core List."; @ndep = grep {$_ != $adep} @ndep; $altered = 1; } } } if( $altered ) { einfo "tagging $dist_name with renamed and removed dependencies"; $f_db->{$dist_name}{a} = { d => \@ndep, }; } } } # }}} # fetch {{{ sub fetch { my $mech; if( not -f "02packages.details.txt.gz" or (stat _)[9]<(time-86400) ) { ebegin "fetching 02packages.details.txt.gz"; $mech ||= new WWW::Mechanize; $mech->get($CPAN_MIRROR . "modules/02packages.details.txt.gz", ":content_file" => "02packages.details.txt.gz"); eend (my $s = -s "02packages.details.txt.gz"); edie "not enough file" unless $s; } } # }}} # parse {{{ sub parse { my $gz = Compress::Zlib::gzopen("02packages.details.txt.gz", "rb") or die "couldn't open 02packages.details.txt.gz file: $!"; my $line; my $status_line_count = undef; my $my_line_count = 0; my %mod_db; my %pro_db; $mod_db = \%mod_db; $pro_db = \%pro_db; ebegin "parsing modules.txt.gz"; while( my $bytes = $gz->gzreadline($line) ) { chomp $line; if( my ($package, $version, $author_plus_dir, $dist_fname) = $line =~ m/^(\S+)\s+(\S+)\s+(\w\/\w{2}\/[\w\-]+)\/(\S+)/ ) { $version = undef if $version =~ m/undef/; my $dist; if( $dist_fname =~ m/^(.+?)-v?[\d\.]+(?:[a-z]|E\d+)?\.(?:tar\.gz|tgz|zip|pm\.gz)$/) { $dist = $1; } else { # seriously not worth mentioning when this doesn't work... wow # edie "ERROR PARSING package=\"$package\" dist_fname=\"$dist_fname\" (line $.)"; # zcat modules.txt.gz | grep -v tar.gz$ | grep -v tgz$ | grep -v zip$ | grep -v pm.gz } $mod_db{$package} = { v=>$version, p=>$author_plus_dir, f=>$dist_fname, d=>$dist, }; if( (my @s = split m/\//, $dist) == 2 ) { # NOTE: not worth mentioning, ... surprisingly common # ewarn "$dist_fname seems to have a subdir, adding {s} and shortening {d}"; $mod_db{$package}{s} = $s[0]; $mod_db{$package}{d} = $s[1]; } $my_line_count ++; } elsif ( $line =~ m/[A-Z][\w\-]+:\s*\S/ and not $line =~ m/::/ ) { # prolly a status line $status_line_count = $1 if $line =~ /^Line-Count:\s+(\d+)/; } elsif ( $line =~ m/^\s*$/ ) { # yawn } else { edie "ERROR PARSING LINE $.: $line"; } } ewarn "my_line_count: $my_line_count; status_line_count: $status_line_count" if $my_line_count != $status_line_count; eend( $my_line_count == $status_line_count ); ebegin "building dist db"; for my $mod (keys %mod_db) { if( my $dis = $mod_db{$mod}{d} ) { $pro_db{$dis} = [] unless exists $pro_db{$dis}; push @{$pro_db{$dis}}, $mod; } } eend 1; } # }}} # scan {{{ sub scan { local $/ = undef; my %f_db; $f_db = \%f_db; ebegin "parsing ppd files"; for my $file (glob "*.ppd") { open my $fh, $file or die "error opening $file: $!"; my $entire_file = <$fh>; close $fh; my ($dist_name) = $entire_file =~ m/SOFTPKG NAME="([^"]+)"/; my @dep; # depenedencies while( $entire_file =~ m/DEPENDENCY NAME="([^"]+)" VERSION="([^"]+)"/g ) { push @dep, [$1, $2]; } my @dis_pro = @{$pro_db->{$dist_name}} if exists $pro_db->{$dist_name}; ewarn "couldn't find that $dist_name provides anything..." unless @dis_pro; $f_db{$dist_name} = { p=>\@dis_pro, d=>\@dep, e=>[$entire_file, $file], }; } eend (keys %f_db); } # }}}