Commit | Line | Data |
---|---|---|
4a656c5e RGS |
1 | #!perl |
2 | # Generates info for Module::CoreList from this perl tree | |
e1018a69 DM |
3 | # run this from the root of a perl tree, using the perl built in that tree. |
4 | # | |
5 | # Data is on STDOUT. | |
6 | # | |
7 | # With an optional arg specifying the root of a CPAN mirror, outputs the | |
8 | # %upstream and %bug_tracker hashes too. | |
9 | ||
10 | use 5.010001; # needs Parse::CPAN::Meta | |
4a656c5e | 11 | |
4a656c5e RGS |
12 | use strict; |
13 | use warnings; | |
14 | use File::Find; | |
15 | use ExtUtils::MM_Unix; | |
fb237dfd NC |
16 | use lib "Porting"; |
17 | use Maintainers qw(%Modules files_to_modules); | |
18 | use File::Spec; | |
4a656c5e | 19 | |
e1018a69 | 20 | |
59189dd7 | 21 | my %lines; |
fb237dfd NC |
22 | my %module_to_file; |
23 | my %modlist; | |
e1018a69 DM |
24 | |
25 | die "usage: $0 [ cpan-mirror/ ]\n" unless @ARGV <= 1; | |
fb237dfd NC |
26 | my $cpan = shift; |
27 | ||
e1018a69 DM |
28 | if (! -f 'MANIFEST') { |
29 | die "Must be run from the root of a clean perl tree\n" | |
30 | } | |
31 | ||
fb237dfd NC |
32 | if ($cpan) { |
33 | my $modlistfile | |
34 | = File::Spec->catfile($cpan, 'modules', '02packages.details.txt'); | |
35 | open my $fh, '<', $modlistfile or die "Couldn't open $modlistfile: $!"; | |
36 | ||
37 | { | |
38 | local $/ = "\n\n"; | |
39 | die "Incompatible modlist format" | |
40 | unless <$fh> =~ /^Columns: +package name, version, path/m; | |
41 | } | |
42 | ||
43 | # Converting the file to a hash is about 5 times faster than a regexp flat | |
44 | # lookup. | |
45 | while (<$fh>) { | |
46 | next unless /^([A-Za-z_:0-9]+) +[-0-9.undefHASHVERSIONvsetwhenloadingbogus]+ +(\S+)/; | |
47 | $modlist{$1} = $2; | |
48 | } | |
49 | } | |
50 | ||
4a656c5e RGS |
51 | find(sub { |
52 | /(\.pm|_pm\.PL)$/ or return; | |
d51d469b | 53 | /PPPort\.pm$/ and return; |
4a656c5e | 54 | my $module = $File::Find::name; |
d51d469b RGS |
55 | $module =~ /\b(demo|t|private)\b/ and return; # demo or test modules |
56 | my $version = MM->parse_version($_); | |
57 | defined $version or $version = 'undef'; | |
4a656c5e RGS |
58 | $version =~ /\d/ and $version = "'$version'"; |
59 | # some heuristics to figure out the module name from the file name | |
4a626d91 RGS |
60 | $module =~ s{^(lib|(win32/|vms/|symbian/)?ext)/}{} |
61 | and $1 ne 'lib' | |
fb237dfd | 62 | and ( $module =~ s{\b(\w+)/\1\b}{$1}, |
dc5f10bb | 63 | $module =~ s{^B/O}{O}, |
da09dfe3 | 64 | $module =~ s{^Devel-PPPort}{Devel}, |
4a656c5e | 65 | $module =~ s{^Encode/encoding}{encoding}, |
da09dfe3 NC |
66 | $module =~ s{^IPC-SysV/}{IPC/}, |
67 | $module =~ s{^MIME-Base64/QuotedPrint}{MIME/QuotedPrint}, | |
dc5f10bb | 68 | $module =~ s{^(?:DynaLoader|Errno|Opcode)/}{}, |
4a656c5e RGS |
69 | ); |
70 | $module =~ s{/}{::}g; | |
da09dfe3 NC |
71 | $module =~ s{-}{::}g; |
72 | $module =~ s{^.*::lib::}{}; | |
4a656c5e | 73 | $module =~ s/(\.pm|_pm\.PL)$//; |
0fdd9e5c | 74 | $lines{$module} = $version; |
fb237dfd | 75 | $module_to_file{$module} = $File::Find::name; |
59189dd7 MB |
76 | }, 'lib', 'ext', 'vms/ext', 'symbian/ext'); |
77 | ||
0fdd9e5c | 78 | -e 'configpm' and $lines{Config} = 'undef'; |
cc8432b2 | 79 | |
59189dd7 MB |
80 | if (open my $ucdv, "<", "lib/unicore/version") { |
81 | chomp (my $ucd = <$ucdv>); | |
0fdd9e5c | 82 | $lines{Unicode} = "'$ucd'"; |
59189dd7 MB |
83 | close $ucdv; |
84 | } | |
fb237dfd NC |
85 | |
86 | sub display_hash { | |
87 | my ($hash) = @_; | |
0fdd9e5c | 88 | } |
fb237dfd NC |
89 | |
90 | print " $] => {\n"; | |
91 | printf "\t%-24s=> $lines{$_},\n", "'$_'" foreach sort keys %lines; | |
4a656c5e | 92 | print " },\n"; |
fb237dfd NC |
93 | |
94 | exit unless %modlist; | |
95 | ||
96 | # We have to go through this two stage lookup, given how Maintainers.pl keys its | |
97 | # data by "Module", which is really a dist. | |
98 | my $file_to_M = files_to_modules(values %module_to_file); | |
99 | ||
100 | my %module_to_upstream; | |
101 | my %module_to_dist; | |
102 | my %dist_to_meta_YAML; | |
103 | while (my ($module, $file) = each %module_to_file) { | |
104 | my $M = $file_to_M->{$file}; | |
105 | next unless $M; | |
106 | next if $Modules{$M}{MAINTAINER} eq 'p5p'; | |
107 | $module_to_upstream{$module} = $Modules{$M}{UPSTREAM}; | |
108 | next if defined $module_to_upstream{$module} && | |
109 | $module_to_upstream{$module} =~ /^(?:blead|first-come)$/; | |
110 | my $dist = $modlist{$module}; | |
111 | unless ($dist) { | |
112 | warn "Can't find a distribution for $module"; | |
113 | next; | |
114 | } | |
115 | $module_to_dist{$module} = $dist; | |
116 | ||
117 | next if exists $dist_to_meta_YAML{$dist}; | |
118 | ||
119 | $dist_to_meta_YAML{$dist} = undef; | |
120 | ||
121 | # Like it or lump it, this has to be Unix format. | |
122 | my $meta_YAML_path = "$cpan/authors/id/$dist"; | |
123 | $meta_YAML_path =~ s/(?:tar\.gz|zip)$/meta/ or die "$meta_YAML_path"; | |
124 | unless (-e $meta_YAML_path) { | |
125 | warn "$meta_YAML_path does not exist for $module"; | |
126 | # I tried code to open the tarballs with Archive::Tar to find and | |
127 | # extract META.yml, but only Text-Tabs+Wrap-2006.1117.tar.gz had one, | |
128 | # so it's not worth including. | |
129 | next; | |
130 | } | |
131 | require Parse::CPAN::Meta; | |
132 | $dist_to_meta_YAML{$dist} = Parse::CPAN::Meta::LoadFile($meta_YAML_path); | |
133 | } | |
134 | ||
135 | print "\n%upstream = (\n"; | |
136 | foreach my $module (sort keys %module_to_upstream) { | |
137 | my $upstream = defined $module_to_upstream{$module} | |
138 | ? "'$module_to_upstream{$module}'" : 'undef'; | |
139 | printf " %-24s=> $upstream,\n", "'$module'"; | |
140 | } | |
141 | print ");\n"; | |
142 | ||
143 | print "\n%bug_tracker = (\n"; | |
144 | foreach my $module (sort keys %module_to_upstream) { | |
145 | my $upstream = defined $module_to_upstream{$module}; | |
146 | next if defined $upstream | |
147 | and $upstream eq 'blead' || $upstream eq 'first-come'; | |
148 | ||
149 | my $bug_tracker; | |
150 | ||
151 | my $dist = $module_to_dist{$module}; | |
152 | $bug_tracker = $dist_to_meta_YAML{$dist}->{resources}{bugtracker} | |
153 | if $dist; | |
154 | ||
155 | $bug_tracker = defined $bug_tracker ? "'$bug_tracker'" : 'undef'; | |
156 | next if $bug_tracker eq "'http://rt.perl.org/perlbug/'"; | |
157 | printf " %-24s=> $bug_tracker,\n", "'$module'"; | |
158 | } | |
159 | print ");\n"; |