1 |
commit: a0cc3228fccccb38c3c5f08c418fdd53dc567818 |
2 |
Author: Kent Fredric <kentfredric <AT> gmail <DOT> com> |
3 |
AuthorDate: Thu Oct 27 19:24:00 2011 +0000 |
4 |
Commit: Kent Fredric <kentfredric <AT> gmail <DOT> com> |
5 |
CommitDate: Mon Oct 31 02:45:47 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/perl-overlay.git;a=commit;h=a0cc3228 |
7 |
|
8 |
Finally looking like a little progress is being made on generating dependencies |
9 |
|
10 |
--- |
11 |
scripts/gen_ebuild.pl | 178 +++++++++++++++++++++++++++++++++++++++++++++- |
12 |
scripts/lib/metacpan.pm | 67 +++++++++++++++++- |
13 |
2 files changed, 240 insertions(+), 5 deletions(-) |
14 |
|
15 |
diff --git a/scripts/gen_ebuild.pl b/scripts/gen_ebuild.pl |
16 |
index 0d0fa06..1623bb8 100755 |
17 |
--- a/scripts/gen_ebuild.pl |
18 |
+++ b/scripts/gen_ebuild.pl |
19 |
@@ -10,6 +10,9 @@ use FindBin; |
20 |
use lib "$FindBin::Bin/lib"; |
21 |
use env::gentoo::perl_experimental; |
22 |
use metacpan qw( mcpan ); |
23 |
+use utf8; |
24 |
+use Gentoo::PerlMod::Version qw( gentooize_version ); |
25 |
+use Text::Wrap; |
26 |
|
27 |
my $flags; |
28 |
my $singleflags; |
29 |
@@ -36,12 +39,179 @@ if ( $flags->{help} or $singleflags->{h} ) { print help(); exit 0; } |
30 |
# emits Moose/Moose-2.30.100_rc.ebuild |
31 |
my ($release) = shift(@ARGV); |
32 |
|
33 |
-my $result = [ map { $_->{as_string} } metacpan->find_dist_simple( $release , {notrim=>1}) ]; |
34 |
+*STDOUT->binmode(':utf8'); |
35 |
+*STDERR->binmode(':utf8'); |
36 |
+ |
37 |
+my %phases; |
38 |
+my %modules; |
39 |
+my %providers; |
40 |
+ |
41 |
+my $dep_phases = get_dep_phases( $release ); |
42 |
+%phases = %{ $dep_phases->{phases} }; |
43 |
+%modules = %{ $dep_phases->{modules} }; |
44 |
|
45 |
use Data::Dump qw( pp ); |
46 |
-use JSON qw( to_json ); |
47 |
-say to_json($result , { pretty => 1 } ); |
48 |
-1; |
49 |
+use JSON qw( to_json encode_json ); |
50 |
+ |
51 |
+sub provider_map { |
52 |
+ my ( $module ) = shift; |
53 |
+ my @providers = metacpan->find_dist_simple( $module ); |
54 |
+ my %moduleprov; |
55 |
+ |
56 |
+ for my $provider ( @providers ) { |
57 |
+ |
58 |
+ next if $provider->{status} eq 'backpan'; |
59 |
+ next if $provider->{maturity} eq 'developer'; |
60 |
+# pp $provider; |
61 |
+ |
62 |
+ my $dist = $provider->{distribution}; |
63 |
+ my $distv = $provider->{version} // 'undef'; |
64 |
+ $moduleprov{$dist} //= []; |
65 |
+ my @provided_matching_mods; |
66 |
+ for my $mod ( @{ $provider->{'_source.module' } } ) { |
67 |
+ next unless $mod->{name} eq $module; |
68 |
+ my $modv = $mod->{version} // 'undef'; |
69 |
+ my $dv = $distv; |
70 |
+ if( $distv ne $modv ) { |
71 |
+ $dv = $distv . " => " . '"' . $modv . '"'; |
72 |
+ } |
73 |
+ push @provided_matching_mods, $dv |
74 |
+ if $mod->{name} eq $module; |
75 |
+ } |
76 |
+ push @{ $moduleprov{$dist} }, @provided_matching_mods; |
77 |
+ } |
78 |
+ return \%moduleprov; |
79 |
+} |
80 |
+for my $module ( keys %modules ) { |
81 |
+ for my $declaration ( @{ $modules{$module} } ) { |
82 |
+ |
83 |
+ my $depstring = $module; |
84 |
+ if ( $declaration->[1] ne '0.0.0' ) { |
85 |
+ $depstring .= " " . $declaration->[0] . " ( " . $declaration->[1] . " ) " ; |
86 |
+ } |
87 |
+ |
88 |
+ my $want_string = "$release -> " . $declaration->[2] . " " . $declaration->[3] . " " . $depstring; |
89 |
+ |
90 |
+ |
91 |
+ my %moduleprov = %{ provider_map( $module ) }; |
92 |
+ |
93 |
+ my $pc = scalar keys %moduleprov; |
94 |
+ |
95 |
+ my $multi = ( $pc > 1 ); |
96 |
+ my $any = ( $pc > 0 ); |
97 |
+ |
98 |
+ *STDERR->printf("\e[1;93m%s\e[0m\n", $want_string ); |
99 |
+ |
100 |
+ |
101 |
+ |
102 |
+ if ( not $any ) { |
103 |
+ *STDERR->printf("%sWARNING: NO PROVIDER FOUND FOR \"%s\"%s\n", "\e[1;91m", $module, "\e[0m" ); |
104 |
+ next; |
105 |
+ } |
106 |
+ if( $multi ){ |
107 |
+ *STDERR->printf("%sWARNING: MULTIPLE PROVIDERS FOUND FOR \"%s\"%s\n", "\e[1;91m", $module, "\e[0m" ); |
108 |
+ } |
109 |
+ |
110 |
+ for my $prov ( keys %moduleprov ) { |
111 |
+ my $prefix = $depstring . ' in ' . $prov; |
112 |
+ my $lines = xwrap( join q[, ], @{$moduleprov{ $prov } } ); |
113 |
+ my ( @slines ) = split /$/m , $lines; |
114 |
+ $_ =~ s/[\r\n]*//m for @slines; |
115 |
+ *STDERR->printf(" %s%s -> %s%s\n", "\e[1;92m", $depstring, "\e[0m\e[92m" ,$prov); |
116 |
+ for ( @slines ) { |
117 |
+ *STDERR->print(" \e[1;91m*") if $multi; |
118 |
+ *STDERR->print(" \e[1;92m*") if not $multi; |
119 |
+ |
120 |
+ *STDERR->printf(" %s%s -> %s%s\n", "\e[1;94m", $prov , "\e[0m\e[94m", $_ ); |
121 |
+ } |
122 |
+ } |
123 |
+ if ( $multi ){ |
124 |
+ *STDERR->print(" \e[1;91m-\n\n"); |
125 |
+ } else { |
126 |
+ *STDERR->print(" \e[1;92m-\n\n"); |
127 |
+ } |
128 |
+ |
129 |
+# my ( $prov ) = ( keys %moduleprov ); |
130 |
+# my $prefix = $want_string.q{/}.$prov; |
131 |
+ # |
132 |
+# *STDERR->printf("%s -> %s [ \n%s\n] \n", $want_string, $prov, clines("\e[39m", "\e[96m$prefix\e[0m", xwrap( join q[, ], @{$moduleprov{$prov}} ) )); |
133 |
+# } else { |
134 |
+# *STDERR->printf("\n%s -> \e[31mMULTIPLE CHOICE: [\e[0m\n", $module); |
135 |
+# for my $prov ( keys %moduleprov ) { |
136 |
+# my $prefix = "\e[94m$want_string/$prov\e[0m"; |
137 |
+# *STDERR->printf(" %s -> \e[31m%s \e[0m[\n%s\n]\n", $want_string, $prov, clines("\e[32m",$prefix, xwrap(join q[, ], @{$moduleprov{$prov}})) ); |
138 |
+# } |
139 |
+# *STDERR->print("\e[31m]\e[0m\n"); |
140 |
+ |
141 |
+# } |
142 |
+# *STDERR->printf("%s -> %s\n", $module, $providers{$module}->[0]->{as_string} ); |
143 |
+ #push @{ $modules{$module}->[0] }, $providers{$module}->[0]->{as_string}; |
144 |
+}} |
145 |
+ |
146 |
+use Data::Dump qw( pp ); |
147 |
+use JSON qw( to_json encode_json ); |
148 |
+#say pp( \%modules,);# { pretty => 1 } ); |
149 |
+exit 1; |
150 |
+ |
151 |
+sub xwrap { |
152 |
+ local $Text::Wrap::break = qr/,/; |
153 |
+ local $Text::Wrap::overflow = 'huge'; |
154 |
+ local $Text::Wrap::columns = 128; |
155 |
+ $Text::Wrap::overflow = 'huge'; |
156 |
+ my $pre = " "; |
157 |
+ my $lines = wrap( $pre , $pre, @_ ); |
158 |
+ return $lines; |
159 |
+} |
160 |
+sub clines { |
161 |
+ my ( $c, $prefix , $lines ) = @_ ; |
162 |
+ $lines =~ s/^/$prefix>>$c/mg; |
163 |
+ $lines =~ s/$/\e[0m/mg; |
164 |
+ return $lines; |
165 |
+} |
166 |
+ |
167 |
+sub get_dep_phases { |
168 |
+ my ( $release ) = shift; |
169 |
+ my %phases; |
170 |
+ my %modules; |
171 |
+ my ( $result, ) = get_deps($release); |
172 |
+ for my $dep ( @{ $result->{dependency} } ) { |
173 |
+ my $phase = $dep->{phase}; |
174 |
+ my $module = $dep->{module}; |
175 |
+ my $required = ( $dep->{relationship} eq 'requires' ); |
176 |
+ |
177 |
+ next unless $required; |
178 |
+ next if $phase eq 'develop'; |
179 |
+ |
180 |
+ $phases{$phase} //= []; |
181 |
+ $modules{$module} //= []; |
182 |
+ |
183 |
+ my $v = gentooize_version( $dep->{version}, { lax => 1 } ); |
184 |
+ |
185 |
+ push @{ $phases{$phase} }, [ $dep->{module} , $dep->{version} , $v, $dep->{relationship} ]; |
186 |
+ push @{ $modules{$module} }, [ $dep->{version}, $v, $dep->{phase} , $dep->{relationship} ]; |
187 |
+ } |
188 |
+ return { phases => \%phases, modules => \%modules }; |
189 |
+} |
190 |
+ |
191 |
+sub to_curl { |
192 |
+ my ( $target, $query ) = @_; |
193 |
+ |
194 |
+ my $query_json = to_json( $query, { pretty => 1 } ); |
195 |
+ print 'curl -XPOST api.metacpan.org/v0/' . $target . '/_search -d \''; |
196 |
+ print $query_json; |
197 |
+ print qq{'\n}; |
198 |
+ |
199 |
+} |
200 |
+ |
201 |
+sub get_deps { |
202 |
+ my ($release) = shift; |
203 |
+ |
204 |
+ my ( $author, $distrelease ); |
205 |
+ |
206 |
+ $release =~ qr{^([^/]+)/(.*$)}; |
207 |
+ ( $author, $distrelease ) = ( "$1", "$2" ); |
208 |
+ return metacpan->find_release( $author, $distrelease ); |
209 |
+} |
210 |
|
211 |
sub pkg_for_module { |
212 |
my ($module) = shift; |
213 |
|
214 |
diff --git a/scripts/lib/metacpan.pm b/scripts/lib/metacpan.pm |
215 |
index cb02681..58ce0f2 100644 |
216 |
--- a/scripts/lib/metacpan.pm |
217 |
+++ b/scripts/lib/metacpan.pm |
218 |
@@ -33,6 +33,25 @@ sub mcpan { |
219 |
} |
220 |
} |
221 |
|
222 |
+# |
223 |
+# ->find_dist_all( $module::name , \%opts ) # returns an array of results. |
224 |
+# |
225 |
+# $opts{notrim} = 1 to skip the postprocessing filter that eliminates false matches. |
226 |
+# |
227 |
+# $opts{mangle} = sub { |
228 |
+# my $query = shift; |
229 |
+# # You can optionally do this to modify the query before it is performed. |
230 |
+# }; |
231 |
+# |
232 |
+# Array items are each a subset of a 'file' entry which contains information |
233 |
+# about the distribution that file was in. |
234 |
+# |
235 |
+# each 'file' entry will have at least one 'file.module' entry that conforms to |
236 |
+# |
237 |
+# module.name == $module::name && module.authorized == true && module.indexed == true |
238 |
+# |
239 |
+# Essentially returning exactly what CPAN does. |
240 |
+# |
241 |
sub find_dist_all { |
242 |
my ( $class, $module, $opts ) = @_; |
243 |
|
244 |
@@ -82,7 +101,19 @@ sub find_dist_all { |
245 |
|
246 |
|
247 |
} |
248 |
-use Data::Dump qw( pp ); |
249 |
+ |
250 |
+# ->find_dist_simple( $module::name , \%opts ) # returns an array of results. |
251 |
+# |
252 |
+# A convenience wrapper around find_dist_all |
253 |
+# |
254 |
+# Adds 3 records not already in metacpan to the result for conveninece. |
255 |
+# |
256 |
+# $record{mod_path} = "AUTHOR/Release-Name-1.2.3-TRIAL/lib/path/to/module.pm" |
257 |
+# $record{mod} = [ "path::to::module" , "1.9.9" ] |
258 |
+# |
259 |
+# $record{as_string} = "path::to::module 1.9.9 in AUTHOR/Release-Name-1.2.3-TRIAL/lib/path/to/module.pm" |
260 |
+# |
261 |
+# |
262 |
sub find_dist_simple { |
263 |
my ( $class, $module, $opts ) = @_; |
264 |
return map { |
265 |
@@ -110,5 +141,39 @@ sub _skip_result { |
266 |
return 1; |
267 |
} |
268 |
|
269 |
+# |
270 |
+# ->find_release( 'DOY' , 'Moose-2.0301-TRIAL' ) |
271 |
+# |
272 |
+# Returns the content of a /release/ entry matching that criteria. |
273 |
+# |
274 |
+# Will return an array just in case there's more than one, but its not likely. |
275 |
+# |
276 |
+sub find_release { |
277 |
+ my ( $class, $author, $distrelease , $opts ) = @_ ; |
278 |
+ my @terms = ( |
279 |
+ { term => { author => $author } }, |
280 |
+ { term => { name => $distrelease } }, |
281 |
+ ); |
282 |
+ my $filter = { filter => { and => [ |
283 |
+ @terms |
284 |
+ ]}}; |
285 |
+ my $q = { |
286 |
+ explain => 1, |
287 |
+ query => { constant_score => $filter }, |
288 |
+ }; |
289 |
+ my @query = ( |
290 |
+ release => $q |
291 |
+ ); |
292 |
+ |
293 |
+ if ( $opts->{mangle} ) { |
294 |
+ $opts->{mangle}->( $q, ); |
295 |
+ } |
296 |
+ |
297 |
+ my $results = mcpan->post(@query); |
298 |
+ |
299 |
+ return map { $_->{_source} } @{ $results->{hits}->{hits} }; |
300 |
+ |
301 |
+} |
302 |
+ |
303 |
1; |