Codebase list libcpandb-perl / fe87850
[svn-upgrade] Integrating new upstream version, libcpandb-perl (0.13) Ansgar Burchardt 14 years ago
30 changed file(s) with 1207 addition(s) and 342 deletion(s). Raw diff Collapse all Expand all
00 Changes for Perl extension CPANDB
11
2 0.12
2 0.13 Mon 19 Apr 2010
3 - Updated ORLite::POD-generated documentation.
4 - Added documentation on additional methods
5
6 0.12 Mon 26 Oct 2009
37 - Added documentation for cpangraph (in POD)
48
59 0.11 Thu 1 Oct 2009
2424 script/cpangraph
2525 t/01_compile.t
2626 t/02_release.t
27 t/97_meta.t
28 t/98_pod.t
29 t/99_pmv.t
27 xt/meta.t
28 xt/pmv.t
29 xt/pod.t
00 ---
11 abstract: 'An ORLite-based ORM Database API'
22 author:
3 - 'Adam Kennedy.'
3 - '- 2010 Adam Kennedy.'
44 build_requires:
55 ExtUtils::MakeMaker: 6.42
66 LWP::Online: 1.07
88 configure_requires:
99 ExtUtils::MakeMaker: 6.42
1010 distribution_type: module
11 generated_by: 'Module::Install version 0.91'
11 generated_by: 'Module::Install version 0.95'
1212 license: perl
1313 meta-spec:
1414 url: http://module-build.sourceforge.net/META-spec-v1.4.html
1919 directory:
2020 - inc
2121 - t
22 - xt
2223 requires:
2324 DateTime: 0.50
2425 Getopt::Long: 2.33
3233 ChangeLog: http://fisheye2.atlassian.com/changelog/cpan/trunk/CPANDB
3334 license: http://dev.perl.org/licenses/
3435 repository: http://svn.ali.as/cpan/trunk/CPANDB
35 version: 0.12
36 version: 0.13
00 NAME
11 CPANDB - An ORLite-based ORM Database API
22
3 SYNOPSIS
4 TO BE COMPLETED
5
63 DESCRIPTION
7 TO BE COMPLETED
4 CPANDB is an module for accessing CPAN metadata merged from many
5 different CPAN websites into a single simple object model.
86
97 METHODS
108 dsn
4846
4947 The "dbh" method returns a DBI::db object, or throws an exception on
5048 error.
49
50 begin
51 CPANDB->begin;
52
53 The "begin" method indicates the start of a transaction.
54
55 In the same way that ORLite allows only a single connection, likewise it
56 allows only a single application-wide transaction.
57
58 No indication is given as to whether you are currently in a transaction
59 or not, all code should be written neutrally so that it works either way
60 or doesn't need to care.
61
62 Returns true or throws an exception on error.
63
64 rollback
65 The "rollback" method rolls back the current transaction. If called
66 outside of a current transaction, it is accepted and treated as a null
67 operation.
68
69 Once the rollback has been completed, the database connection falls back
70 into auto-commit state. If you wish to immediately start another
71 transaction, you will need to issue a separate ->begin call.
72
73 If a transaction exists at END-time as the process exits, it will be
74 automatically rolled back.
75
76 Returns true or throws an exception on error.
77
78 do
79 CPANDB->do(
80 'insert into table ( foo, bar ) values ( ?, ? )', {},
81 \$foo_value,
82 \$bar_value,
83 );
84
85 The "do" method is a direct wrapper around the equivalent DBI method,
86 but applied to the appropriate locally-provided connection or
87 transaction.
88
89 It takes the same parameters and has the same return values and error
90 behaviour.
5191
5292 selectall_arrayref
5393 The "selectall_arrayref" method is a direct wrapper around the
116156 The "pragma" method provides a convenient method for fetching a pragma
117157 for a datase. See the SQLite documentation for more details.
118158
159 distribution
160 my $dist = CPANDB->distribution('Config-Tiny');
161
162 The "distribution" method is a convenient shortcut for direct access to
163 the CPANDB::Distribution object for a single named distribution.
164
165 graph
166 my $everything = CPANDB->graph;
167
168 Originally created as a proof of concept for Graph integration, the
169 "graph" method creates a single giant Graph::Directed object
170 representing the dependency structure of the entire CPAN at a
171 distribution-to-distribution level.
172
173 The graphing features of CPANDB are considered optional. To use this
174 method you will need to install Graph::Directed yourself, and set up a
175 dependency in any code that uses Graph features.
176
119177 SUPPORT
120 CPANDB is based on ORLite 1.23.
178 CPANDB is based on ORLite $ORLite::VERSION.
121179
122 Documentation created by ORLite::Pod 0.06.
180 Documentation created by ORLite::Pod $ORLite::Pod::VERSION.
123181
124182 For general support please see the support section of the main project
125183 documentation.
126184
127185 COPYRIGHT
128 Copyright 2009 Adam Kennedy.
186 Copyright 2009 - 2010 Adam Kennedy.
129187
130188 This program is free software; you can redistribute it and/or modify it
131189 under the same terms as Perl itself.
33 use strict 'vars';
44 use vars qw{$VERSION};
55 BEGIN {
6 $VERSION = '0.91';
6 $VERSION = '0.95';
77 }
88
99 # Suspend handler for "redefined" warnings
88
99 use vars qw{$VERSION @ISA $ISCORE};
1010 BEGIN {
11 $VERSION = '0.91';
11 $VERSION = '0.95';
1212 @ISA = 'Module::Install::Base';
1313 $ISCORE = 1;
1414 }
33 use strict;
44 use vars qw{$VERSION $ISCORE};
55 BEGIN {
6 $VERSION = '0.91';
6 $VERSION = '0.95';
77 $ISCORE = 1;
88 *inc::Module::Install::DSL::VERSION = *VERSION;
99 @inc::Module::Install::DSL::ISA = __PACKAGE__;
3838 }
3939
4040 # Convert the basic syntax to code
41 my $code = "package main;\n\n"
41 my $code = "INIT {\n"
42 . "package main;\n\n"
4243 . dsl2code($dsl)
43 . "\n\nWriteAll();\n";
44 . "\n\nWriteAll();\n"
45 . "}\n";
4446
4547 # Execute the script
4648 eval $code;
47 print STDERR "Failed to execute the generated code" if $@;
49 print STDERR "Failed to execute the generated code...\n$@" if $@;
4850
4951 exit(0);
5052 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '0.91';
8 $VERSION = '0.95';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
66
77 use vars qw{$VERSION @ISA $ISCORE};
88 BEGIN {
9 $VERSION = '0.91';
9 $VERSION = '0.95';
1010 @ISA = 'Module::Install::Base';
1111 $ISCORE = 1;
1212 }
2424 die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
2525 }
2626
27 # In automated testing, always use defaults
28 if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
27 # In automated testing or non-interactive session, always use defaults
28 if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) {
2929 local $ENV{PERL_MM_USE_DEFAULT} = 1;
3030 goto &ExtUtils::MakeMaker::prompt;
3131 } else {
3333 }
3434 }
3535
36 # Store a cleaned up version of the MakeMaker version,
37 # since we need to behave differently in a variety of
38 # ways based on the MM version.
39 my $makemaker = eval $ExtUtils::MakeMaker::VERSION;
40
41 # If we are passed a param, do a "newer than" comparison.
42 # Otherwise, just return the MakeMaker version.
43 sub makemaker {
44 ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0
45 }
46
47 # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified
48 # as we only need to know here whether the attribute is an array
49 # or a hash or something else (which may or may not be appendable).
50 my %makemaker_argtype = (
51 C => 'ARRAY',
52 CONFIG => 'ARRAY',
53 # CONFIGURE => 'CODE', # ignore
54 DIR => 'ARRAY',
55 DL_FUNCS => 'HASH',
56 DL_VARS => 'ARRAY',
57 EXCLUDE_EXT => 'ARRAY',
58 EXE_FILES => 'ARRAY',
59 FUNCLIST => 'ARRAY',
60 H => 'ARRAY',
61 IMPORTS => 'HASH',
62 INCLUDE_EXT => 'ARRAY',
63 LIBS => 'ARRAY', # ignore ''
64 MAN1PODS => 'HASH',
65 MAN3PODS => 'HASH',
66 META_ADD => 'HASH',
67 META_MERGE => 'HASH',
68 PL_FILES => 'HASH',
69 PM => 'HASH',
70 PMLIBDIRS => 'ARRAY',
71 PMLIBPARENTDIRS => 'ARRAY',
72 PREREQ_PM => 'HASH',
73 CONFIGURE_REQUIRES => 'HASH',
74 SKIP => 'ARRAY',
75 TYPEMAPS => 'ARRAY',
76 XS => 'HASH',
77 # VERSION => ['version',''], # ignore
78 # _KEEP_AFTER_FLUSH => '',
79
80 clean => 'HASH',
81 depend => 'HASH',
82 dist => 'HASH',
83 dynamic_lib=> 'HASH',
84 linkext => 'HASH',
85 macro => 'HASH',
86 postamble => 'HASH',
87 realclean => 'HASH',
88 test => 'HASH',
89 tool_autosplit => 'HASH',
90
91 # special cases where you can use makemaker_append
92 CCFLAGS => 'APPENDABLE',
93 DEFINE => 'APPENDABLE',
94 INC => 'APPENDABLE',
95 LDDLFLAGS => 'APPENDABLE',
96 LDFROM => 'APPENDABLE',
97 );
98
3699 sub makemaker_args {
37 my $self = shift;
100 my ($self, %new_args) = @_;
38101 my $args = ( $self->{makemaker_args} ||= {} );
39 %$args = ( %$args, @_ );
102 foreach my $key (keys %new_args) {
103 if ($makemaker_argtype{$key} eq 'ARRAY') {
104 $args->{$key} = [] unless defined $args->{$key};
105 unless (ref $args->{$key} eq 'ARRAY') {
106 $args->{$key} = [$args->{$key}]
107 }
108 push @{$args->{$key}},
109 ref $new_args{$key} eq 'ARRAY'
110 ? @{$new_args{$key}}
111 : $new_args{$key};
112 }
113 elsif ($makemaker_argtype{$key} eq 'HASH') {
114 $args->{$key} = {} unless defined $args->{$key};
115 foreach my $skey (keys %{ $new_args{$key} }) {
116 $args->{$key}{$skey} = $new_args{$key}{$skey};
117 }
118 }
119 elsif ($makemaker_argtype{$key} eq 'APPENDABLE') {
120 $self->makemaker_append($key => $new_args{$key});
121 }
122 else {
123 if (defined $args->{$key}) {
124 warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n};
125 }
126 $args->{$key} = $new_args{$key};
127 }
128 }
40129 return $args;
41130 }
42131
43132 # For mm args that take multiple space-seperated args,
44133 # append an argument to the current list.
45134 sub makemaker_append {
46 my $self = sShift;
135 my $self = shift;
47136 my $name = shift;
48137 my $args = $self->makemaker_args;
49 $args->{name} = defined $args->{$name}
50 ? join( ' ', $args->{name}, @_ )
138 $args->{$name} = defined $args->{$name}
139 ? join( ' ', $args->{$name}, @_ )
51140 : join( ' ', @_ );
52141 }
53142
106195 %test_dir = ();
107196 require File::Find;
108197 File::Find::find( \&_wanted_t, $dir );
198 if ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
199 File::Find::find( \&_wanted_t, 'xt' );
200 }
109201 $self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir );
110202 }
111203
129221 # an underscore, even though its own version may contain one!
130222 # Hence the funny regexp to get rid of it. See RT #35800
131223 # for details.
132 $self->build_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
133 $self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
224 my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/;
225 $self->build_requires( 'ExtUtils::MakeMaker' => $v );
226 $self->configure_requires( 'ExtUtils::MakeMaker' => $v );
134227 } else {
135228 # Allow legacy-compatibility with 5.005 by depending on the
136229 # most recent EU:MM that supported 5.005.
137 $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 );
230 $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 );
138231 $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 );
139232 }
140233
142235 my $args = $self->makemaker_args;
143236 $args->{DISTNAME} = $self->name;
144237 $args->{NAME} = $self->module_name || $self->name;
145 $args->{VERSION} = $self->version;
146238 $args->{NAME} =~ s/-/::/g;
239 $args->{VERSION} = $self->version or die <<'EOT';
240 ERROR: Can't determine distribution version. Please specify it
241 explicitly via 'version' in Makefile.PL, or set a valid $VERSION
242 in a module, and provide its file path via 'version_from' (or
243 'all_from' if you prefer) in Makefile.PL.
244 EOT
245
246 $DB::single = 1;
147247 if ( $self->tests ) {
148 $args->{test} = { TESTS => $self->tests };
248 my @tests = split ' ', $self->tests;
249 my %seen;
250 $args->{test} = {
251 TESTS => (join ' ', grep {!$seen{$_}++} @tests),
252 };
253 } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
254 $args->{test} = {
255 TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ),
256 };
149257 }
150258 if ( $] >= 5.005 ) {
151259 $args->{ABSTRACT} = $self->abstract;
152 $args->{AUTHOR} = $self->author;
153 }
154 if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
155 $args->{NO_META} = 1;
156 }
157 if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
260 $args->{AUTHOR} = join ', ', @{$self->author || []};
261 }
262 if ( $self->makemaker(6.10) ) {
263 $args->{NO_META} = 1;
264 #$args->{NO_MYMETA} = 1;
265 }
266 if ( $self->makemaker(6.17) and $self->sign ) {
158267 $args->{SIGN} = 1;
159268 }
160269 unless ( $self->is_admin ) {
161270 delete $args->{SIGN};
162271 }
163
164 # Merge both kinds of requires into prereq_pm
272 if ( $self->makemaker(6.31) and $self->license ) {
273 $args->{LICENSE} = $self->license;
274 }
275
165276 my $prereq = ($args->{PREREQ_PM} ||= {});
166277 %$prereq = ( %$prereq,
167 map { @$_ }
278 map { @$_ } # flatten [module => version]
168279 map { @$_ }
169280 grep $_,
170 ($self->configure_requires, $self->build_requires, $self->requires)
281 ($self->requires)
171282 );
172283
173284 # Remove any reference to perl, PREREQ_PM doesn't support it
174285 delete $args->{PREREQ_PM}->{perl};
175286
176 # merge both kinds of requires into prereq_pm
287 # Merge both kinds of requires into BUILD_REQUIRES
288 my $build_prereq = ($args->{BUILD_REQUIRES} ||= {});
289 %$build_prereq = ( %$build_prereq,
290 map { @$_ } # flatten [module => version]
291 map { @$_ }
292 grep $_,
293 ($self->configure_requires, $self->build_requires)
294 );
295
296 # Remove any reference to perl, BUILD_REQUIRES doesn't support it
297 delete $args->{BUILD_REQUIRES}->{perl};
298
299 # Delete bundled dists from prereq_pm
177300 my $subdirs = ($args->{DIR} ||= []);
178301 if ($self->bundles) {
179302 foreach my $bundle (@{ $self->bundles }) {
180303 my ($file, $dir) = @$bundle;
181304 push @$subdirs, $dir if -d $dir;
182 delete $prereq->{$file};
183 }
305 delete $build_prereq->{$file}; #Delete from build prereqs only
306 }
307 }
308
309 unless ( $self->makemaker('6.55_03') ) {
310 %$prereq = (%$prereq,%$build_prereq);
311 delete $args->{BUILD_REQUIRES};
184312 }
185313
186314 if ( my $perl_version = $self->perl_version ) {
187315 eval "use $perl_version; 1"
188316 or die "ERROR: perl: Version $] is installed, "
189317 . "but we need version >= $perl_version";
190 }
191
192 $args->{INSTALLDIRS} = $self->installdirs;
193
194 my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
318
319 if ( $self->makemaker(6.48) ) {
320 $args->{MIN_PERL_VERSION} = $perl_version;
321 }
322 }
323
324 if ($self->installdirs) {
325 warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS};
326 $args->{INSTALLDIRS} = $self->installdirs;
327 }
328
329 my %args = map {
330 ( $_ => $args->{$_} ) } grep {defined($args->{$_} )
331 } keys %$args;
195332
196333 my $user_preop = delete $args{dist}->{PREOP};
197 if (my $preop = $self->admin->preop($user_preop)) {
334 if ( my $preop = $self->admin->preop($user_preop) ) {
198335 foreach my $key ( keys %$preop ) {
199336 $args{dist}->{$key} = $preop->{$key};
200337 }
264401
265402 __END__
266403
267 #line 394
404 #line 531
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '0.91';
8 $VERSION = '0.95';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
1818 name
1919 module_name
2020 abstract
21 author
2221 version
2322 distribution_type
2423 tests
4241
4342 my @array_keys = qw{
4443 keywords
44 author
4545 };
46
47 *authors = \&author;
4648
4749 sub Meta { shift }
4850 sub Meta_BooleanKeys { @boolean_keys }
229231 die("The path '$file' does not exist, or is not a file");
230232 }
231233
234 $self->{values}{all_from} = $file;
235
232236 # Some methods pull from POD instead of code.
233237 # If there is a matching .pod, use that instead
234238 my $pod = $file;
239243 $self->name_from($file) unless $self->name;
240244 $self->version_from($file) unless $self->version;
241245 $self->perl_version_from($file) unless $self->perl_version;
242 $self->author_from($pod) unless $self->author;
246 $self->author_from($pod) unless @{$self->author || []};
243247 $self->license_from($pod) unless $self->license;
244248 $self->abstract_from($pod) unless $self->abstract;
245249
384388 }
385389 }
386390
387 sub perl_version_from {
388 my $self = shift;
391 sub _extract_perl_version {
389392 if (
390 Module::Install::_read($_[0]) =~ m/
391 ^
393 $_[0] =~ m/
394 ^\s*
392395 (?:use|require) \s*
393396 v?
394397 ([\d_\.]+)
397400 ) {
398401 my $perl_version = $1;
399402 $perl_version =~ s{_}{}g;
403 return $perl_version;
404 } else {
405 return;
406 }
407 }
408
409 sub perl_version_from {
410 my $self = shift;
411 my $perl_version=_extract_perl_version(Module::Install::_read($_[0]));
412 if ($perl_version) {
400413 $self->perl_version($perl_version);
401414 } else {
402415 warn "Cannot determine perl version info from $_[0]\n";
416429 ([^\n]*)
417430 /ixms) {
418431 my $author = $1 || $2;
419 $author =~ s{E<lt>}{<}g;
420 $author =~ s{E<gt>}{>}g;
432
433 # XXX: ugly but should work anyway...
434 if (eval "require Pod::Escapes; 1") {
435 # Pod::Escapes has a mapping table.
436 # It's in core of perl >= 5.9.3, and should be installed
437 # as one of the Pod::Simple's prereqs, which is a prereq
438 # of Pod::Text 3.x (see also below).
439 $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
440 {
441 defined $2
442 ? chr($2)
443 : defined $Pod::Escapes::Name2character_number{$1}
444 ? chr($Pod::Escapes::Name2character_number{$1})
445 : do {
446 warn "Unknown escape: E<$1>";
447 "E<$1>";
448 };
449 }gex;
450 }
451 elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) {
452 # Pod::Text < 3.0 has yet another mapping table,
453 # though the table name of 2.x and 1.x are different.
454 # (1.x is in core of Perl < 5.6, 2.x is in core of
455 # Perl < 5.9.3)
456 my $mapping = ($Pod::Text::VERSION < 2)
457 ? \%Pod::Text::HTML_Escapes
458 : \%Pod::Text::ESCAPES;
459 $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
460 {
461 defined $2
462 ? chr($2)
463 : defined $mapping->{$1}
464 ? $mapping->{$1}
465 : do {
466 warn "Unknown escape: E<$1>";
467 "E<$1>";
468 };
469 }gex;
470 }
471 else {
472 $author =~ s{E<lt>}{<}g;
473 $author =~ s{E<gt>}{>}g;
474 }
421475 $self->author($author);
422476 } else {
423477 warn "Cannot determine author info from $_[0]\n";
424478 }
425479 }
426480
481 sub _extract_license {
482 my $pod = shift;
483 my $matched;
484 return __extract_license(
485 ($matched) = $pod =~ m/
486 (=head \d \s+ (?:licen[cs]e|licensing)\b.*?)
487 (=head \d.*|=cut.*|)\z
488 /ixms
489 ) || __extract_license(
490 ($matched) = $pod =~ m/
491 (=head \d \s+ (?:copyrights?|legal)\b.*?)
492 (=head \d.*|=cut.*|)\z
493 /ixms
494 );
495 }
496
497 sub __extract_license {
498 my $license_text = shift or return;
499 my @phrases = (
500 'under the same (?:terms|license) as (?:perl|the perl programming language)' => 'perl', 1,
501 'under the terms of (?:perl|the perl programming language) itself' => 'perl', 1,
502 'Artistic and GPL' => 'perl', 1,
503 'GNU general public license' => 'gpl', 1,
504 'GNU public license' => 'gpl', 1,
505 'GNU lesser general public license' => 'lgpl', 1,
506 'GNU lesser public license' => 'lgpl', 1,
507 'GNU library general public license' => 'lgpl', 1,
508 'GNU library public license' => 'lgpl', 1,
509 'BSD license' => 'bsd', 1,
510 'Artistic license' => 'artistic', 1,
511 'GPL' => 'gpl', 1,
512 'LGPL' => 'lgpl', 1,
513 'BSD' => 'bsd', 1,
514 'Artistic' => 'artistic', 1,
515 'MIT' => 'mit', 1,
516 'proprietary' => 'proprietary', 0,
517 );
518 while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
519 $pattern =~ s#\s+#\\s+#gs;
520 if ( $license_text =~ /\b$pattern\b/i ) {
521 return $license;
522 }
523 }
524 }
525
427526 sub license_from {
428527 my $self = shift;
429 if (
430 Module::Install::_read($_[0]) =~ m/
431 (
432 =head \d \s+
433 (?:licen[cs]e|licensing|copyright|legal)\b
434 .*?
435 )
436 (=head\\d.*|=cut.*|)
437 \z
438 /ixms ) {
439 my $license_text = $1;
440 my @phrases = (
441 'under the same (?:terms|license) as (?:perl|the perl programming language) itself' => 'perl', 1,
442 'GNU general public license' => 'gpl', 1,
443 'GNU public license' => 'gpl', 1,
444 'GNU lesser general public license' => 'lgpl', 1,
445 'GNU lesser public license' => 'lgpl', 1,
446 'GNU library general public license' => 'lgpl', 1,
447 'GNU library public license' => 'lgpl', 1,
448 'BSD license' => 'bsd', 1,
449 'Artistic license' => 'artistic', 1,
450 'GPL' => 'gpl', 1,
451 'LGPL' => 'lgpl', 1,
452 'BSD' => 'bsd', 1,
453 'Artistic' => 'artistic', 1,
454 'MIT' => 'mit', 1,
455 'proprietary' => 'proprietary', 0,
456 );
457 while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
458 $pattern =~ s{\s+}{\\s+}g;
459 if ( $license_text =~ /\b$pattern\b/i ) {
460 $self->license($license);
461 return 1;
462 }
463 }
464 }
465
466 warn "Cannot determine license info from $_[0]\n";
467 return 'unknown';
528 if (my $license=_extract_license(Module::Install::_read($_[0]))) {
529 $self->license($license);
530 } else {
531 warn "Cannot determine license info from $_[0]\n";
532 return 'unknown';
533 }
468534 }
469535
470536 sub _extract_bugtracker {
471 my @links = $_[0] =~ m#L<(\Qhttp://rt.cpan.org/\E[^>]+)>#g;
537 my @links = $_[0] =~ m#L<(
538 \Qhttp://rt.cpan.org/\E[^>]+|
539 \Qhttp://github.com/\E[\w_]+/[\w_]+/issues|
540 \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list
541 )>#gx;
472542 my %links;
473543 @links{@links}=();
474544 @links=keys %links;
484554 return 0;
485555 }
486556 if ( @links > 1 ) {
487 warn "Found more than on rt.cpan.org link in $_[0]\n";
557 warn "Found more than one bugtracker link in $_[0]\n";
488558 return 0;
489559 }
490560
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '0.91';
8 $VERSION = '0.95';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '0.91';
8 $VERSION = '0.95';
99 @ISA = 'Module::Install::Base';
1010 $ISCORE = 1;
1111 }
55
66 use vars qw{$VERSION @ISA $ISCORE};
77 BEGIN {
8 $VERSION = '0.91';;
8 $VERSION = '0.95';;
99 @ISA = qw{Module::Install::Base};
1010 $ISCORE = 1;
1111 }
2525
2626 $self->check_nmake if $args{check_nmake};
2727 unless ( $self->makemaker_args->{PL_FILES} ) {
28 $self->makemaker_args( PL_FILES => {} );
28 # XXX: This still may be a bit over-defensive...
29 unless ($self->makemaker(6.25)) {
30 $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL';
31 }
2932 }
3033
3134 # Until ExtUtils::MakeMaker support MYMETA.yml, make sure
1818
1919 use 5.005;
2020 use strict 'vars';
21 use Cwd ();
22 use File::Find ();
23 use File::Path ();
24 use FindBin;
2125
2226 use vars qw{$VERSION $MAIN};
2327 BEGIN {
2731 # This is not enforced yet, but will be some time in the next few
2832 # releases once we can make sure it won't clash with custom
2933 # Module::Install extensions.
30 $VERSION = '0.91';
34 $VERSION = '0.95';
3135
3236 # Storage for the pseudo-singleton
3337 $MAIN = undef;
3741
3842 }
3943
40
41
42
43
44 # Whether or not inc::Module::Install is actually loaded, the
45 # $INC{inc/Module/Install.pm} is what will still get set as long as
46 # the caller loaded module this in the documented manner.
47 # If not set, the caller may NOT have loaded the bundled version, and thus
48 # they may not have a MI version that works with the Makefile.PL. This would
49 # result in false errors or unexpected behaviour. And we don't want that.
50 my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
51 unless ( $INC{$file} ) { die <<"END_DIE" }
44 sub import {
45 my $class = shift;
46 my $self = $class->new(@_);
47 my $who = $self->_caller;
48
49 #-------------------------------------------------------------
50 # all of the following checks should be included in import(),
51 # to allow "eval 'require Module::Install; 1' to test
52 # installation of Module::Install. (RT #51267)
53 #-------------------------------------------------------------
54
55 # Whether or not inc::Module::Install is actually loaded, the
56 # $INC{inc/Module/Install.pm} is what will still get set as long as
57 # the caller loaded module this in the documented manner.
58 # If not set, the caller may NOT have loaded the bundled version, and thus
59 # they may not have a MI version that works with the Makefile.PL. This would
60 # result in false errors or unexpected behaviour. And we don't want that.
61 my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
62 unless ( $INC{$file} ) { die <<"END_DIE" }
5263
5364 Please invoke ${\__PACKAGE__} with:
5465
6071
6172 END_DIE
6273
63
64
65
66
67 # If the script that is loading Module::Install is from the future,
68 # then make will detect this and cause it to re-run over and over
69 # again. This is bad. Rather than taking action to touch it (which
70 # is unreliable on some platforms and requires write permissions)
71 # for now we should catch this and refuse to run.
72 if ( -f $0 ) {
73 my $s = (stat($0))[9];
74
75 # If the modification time is only slightly in the future,
76 # sleep briefly to remove the problem.
77 my $a = $s - time;
78 if ( $a > 0 and $a < 5 ) { sleep 5 }
79
80 # Too far in the future, throw an error.
81 my $t = time;
82 if ( $s > $t ) { die <<"END_DIE" }
74 # This reportedly fixes a rare Win32 UTC file time issue, but
75 # as this is a non-cross-platform XS module not in the core,
76 # we shouldn't really depend on it. See RT #24194 for detail.
77 # (Also, this module only supports Perl 5.6 and above).
78 eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006;
79
80 # If the script that is loading Module::Install is from the future,
81 # then make will detect this and cause it to re-run over and over
82 # again. This is bad. Rather than taking action to touch it (which
83 # is unreliable on some platforms and requires write permissions)
84 # for now we should catch this and refuse to run.
85 if ( -f $0 ) {
86 my $s = (stat($0))[9];
87
88 # If the modification time is only slightly in the future,
89 # sleep briefly to remove the problem.
90 my $a = $s - time;
91 if ( $a > 0 and $a < 5 ) { sleep 5 }
92
93 # Too far in the future, throw an error.
94 my $t = time;
95 if ( $s > $t ) { die <<"END_DIE" }
8396
8497 Your installer $0 has a modification time in the future ($s > $t).
8598
88101 Please correct this, then run $0 again.
89102
90103 END_DIE
91 }
92
93
94
95
96
97 # Build.PL was formerly supported, but no longer is due to excessive
98 # difficulty in implementing every single feature twice.
99 if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
104 }
105
106
107 # Build.PL was formerly supported, but no longer is due to excessive
108 # difficulty in implementing every single feature twice.
109 if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
100110
101111 Module::Install no longer supports Build.PL.
102112
106116
107117 END_DIE
108118
109
110
111
112
113 # To save some more typing in Module::Install installers, every...
114 # use inc::Module::Install
115 # ...also acts as an implicit use strict.
116 $^H |= strict::bits(qw(refs subs vars));
117
118
119
120
121
122 use Cwd ();
123 use File::Find ();
124 use File::Path ();
125 use FindBin;
119 #-------------------------------------------------------------
120
121 # To save some more typing in Module::Install installers, every...
122 # use inc::Module::Install
123 # ...also acts as an implicit use strict.
124 $^H |= strict::bits(qw(refs subs vars));
125
126 #-------------------------------------------------------------
127
128 unless ( -f $self->{file} ) {
129 require "$self->{path}/$self->{dispatch}.pm";
130 File::Path::mkpath("$self->{prefix}/$self->{author}");
131 $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
132 $self->{admin}->init;
133 @_ = ($class, _self => $self);
134 goto &{"$self->{name}::import"};
135 }
136
137 *{"${who}::AUTOLOAD"} = $self->autoload;
138 $self->preload;
139
140 # Unregister loader and worker packages so subdirs can use them again
141 delete $INC{"$self->{file}"};
142 delete $INC{"$self->{path}.pm"};
143
144 # Save to the singleton
145 $MAIN = $self;
146
147 return 1;
148 }
126149
127150 sub autoload {
128151 my $self = shift;
151174 };
152175 }
153176
154 sub import {
155 my $class = shift;
156 my $self = $class->new(@_);
157 my $who = $self->_caller;
158
159 unless ( -f $self->{file} ) {
160 require "$self->{path}/$self->{dispatch}.pm";
161 File::Path::mkpath("$self->{prefix}/$self->{author}");
162 $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
163 $self->{admin}->init;
164 @_ = ($class, _self => $self);
165 goto &{"$self->{name}::import"};
166 }
167
168 *{"${who}::AUTOLOAD"} = $self->autoload;
169 $self->preload;
170
171 # Unregister loader and worker packages so subdirs can use them again
172 delete $INC{"$self->{file}"};
173 delete $INC{"$self->{path}.pm"};
174
175 # Save to the singleton
176 $MAIN = $self;
177
178 return 1;
179 }
180
181177 sub preload {
182178 my $self = shift;
183179 unless ( $self->{extensions} ) {
347343 return $call;
348344 }
349345
346 # Done in evals to avoid confusing Perl::MinimumVersion
347 eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
350348 sub _read {
351349 local *FH;
352 if ( $] >= 5.006 ) {
353 open( FH, '<', $_[0] ) or die "open($_[0]): $!";
354 } else {
355 open( FH, "< $_[0]" ) or die "open($_[0]): $!";
356 }
350 open( FH, '<', $_[0] ) or die "open($_[0]): $!";
357351 my $string = do { local $/; <FH> };
358352 close FH or die "close($_[0]): $!";
359353 return $string;
360354 }
355 END_NEW
356 sub _read {
357 local *FH;
358 open( FH, "< $_[0]" ) or die "open($_[0]): $!";
359 my $string = do { local $/; <FH> };
360 close FH or die "close($_[0]): $!";
361 return $string;
362 }
363 END_OLD
361364
362365 sub _readperl {
363366 my $string = Module::Install::_read($_[0]);
378381 return $string;
379382 }
380383
384 # Done in evals to avoid confusing Perl::MinimumVersion
385 eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
381386 sub _write {
382387 local *FH;
383 if ( $] >= 5.006 ) {
384 open( FH, '>', $_[0] ) or die "open($_[0]): $!";
385 } else {
386 open( FH, "> $_[0]" ) or die "open($_[0]): $!";
387 }
388 open( FH, '>', $_[0] ) or die "open($_[0]): $!";
388389 foreach ( 1 .. $#_ ) {
389390 print FH $_[$_] or die "print($_[0]): $!";
390391 }
391392 close FH or die "close($_[0]): $!";
392393 }
394 END_NEW
395 sub _write {
396 local *FH;
397 open( FH, "> $_[0]" ) or die "open($_[0]): $!";
398 foreach ( 1 .. $#_ ) {
399 print FH $_[$_] or die "print($_[0]): $!";
400 }
401 close FH or die "close($_[0]): $!";
402 }
403 END_OLD
393404
394405 # _version is for processing module versions (eg, 1.03_05) not
395406 # Perl versions (eg, 5.8.1).
426437
427438 1;
428439
429 # Copyright 2008 - 2009 Adam Kennedy.
440 # Copyright 2008 - 2010 Adam Kennedy.
1010 TO BE COMPLETED
1111
1212 =head1 METHODS
13
14 =head2 base
15
16 my $namespace = CPANDB::Author->base; # Returns 'CPANDB'
17
18 Normally you will only need to work directly with a table class,
19 and only with one ORLite package.
20
21 However, if for some reason you need to work with multiple ORLite packages
22 at the same time without hardcoding the root namespace all the time, you
23 can determine the root namespace from an object or table class with the
24 C<base> method.
25
26 =head2 table
27
28 print CPANDB::Author->table; # Returns 'author'
29
30 While you should not need the name of table for any simple operations,
31 from time to time you may need it programatically. If you do need it,
32 you can use the C<table> method to get the table name.
33
34 =head2 load
35
36 my $object = CPANDB::Author->load( $author );
37
38 If your table has single column primary key, a C<load> method will be
39 generated in the class. If there is no primary key, the method is not
40 created.
41
42 The C<load> method provides a shortcut mechanism for fetching a single
43 object based on the value of the primary key. However it should only
44 be used for cases where your code trusts the record to already exists.
45
46 It returns a C<CPANDB::Author> object, or throws an exception if the
47 object does not exist.
1348
1449 =head2 select
1550
3570 context.
3671
3772 Throws an exception on error, typically directly from the L<DBI> layer.
73
74 =head2 iterate
75
76 CPANDB::Author->iterate( sub {
77 print $_->author . "\n";
78 } );
79
80 The C<iterate> method enables the processing of large tables one record at
81 a time without loading having to them all into memory in advance.
82
83 This plays well to the strength of SQLite, allowing it to do the work of
84 loading arbitrarily large stream of records from disk while retaining the
85 full power of Perl when processing the records.
86
87 The last argument to C<iterate> must be a subroutine reference that will be
88 called for each element in the list, with the object provided in the topic
89 variable C<$_>.
90
91 This makes the C<iterate> code fragment above functionally equivalent to the
92 following, except with an O(1) memory cost instead of O(n).
93
94 foreach ( CPANDB::Author->select ) {
95 print $_->author . "\n";
96 }
97
98 You can filter the list via SQL in the same way you can with C<select>.
99 CPANDB::Author->iterate(
100 'order by ?', 'author',
101 sub {
102 print $_->author . "\n";
103 }
104 );
105
106 You can also use it in raw form from the root namespace for better control.
107 Using this form also allows for the use of arbitrarily complex queries,
108 including joins. Instead of being objects, rows are provided as C<ARRAY>
109 references when used in this form.
110 CPANDB->iterate(
111 'select name from author order by author',
112 sub {
113 print $_->[0] . "\n";
114 }
115 );
38116
39117 =head2 count
40118
64142 =head2 author
65143
66144 if ( $object->author ) {
67 print "Object has been inserted\n";
145 print "Object has been inserted\\n";
68146 } else {
69 print "Object has not been inserted\n";
147 print "Object has not been inserted\\n";
70148 }
71149
72150 Returns true, or throws an exception on error.
93171
94172 =head1 COPYRIGHT
95173
96 Copyright 2009 Adam Kennedy.
174 Copyright 2009 - 2010 Adam Kennedy.
97175
98176 This program is free software; you can redistribute
99177 it and/or modify it under the same terms as Perl itself.
1010 TO BE COMPLETED
1111
1212 =head1 METHODS
13
14 =head2 base
15
16 my $namespace = CPANDB::Dependency->base; # Returns 'CPANDB'
17
18 Normally you will only need to work directly with a table class,
19 and only with one ORLite package.
20
21 However, if for some reason you need to work with multiple ORLite packages
22 at the same time without hardcoding the root namespace all the time, you
23 can determine the root namespace from an object or table class with the
24 C<base> method.
25
26 =head2 table
27
28 print CPANDB::Dependency->table; # Returns 'dependency'
29
30 While you should not need the name of table for any simple operations,
31 from time to time you may need it programatically. If you do need it,
32 you can use the C<table> method to get the table name.
33
34 =head2 load
35
36 my $object = CPANDB::Dependency->load( $distribution );
37
38 If your table has single column primary key, a C<load> method will be
39 generated in the class. If there is no primary key, the method is not
40 created.
41
42 The C<load> method provides a shortcut mechanism for fetching a single
43 object based on the value of the primary key. However it should only
44 be used for cases where your code trusts the record to already exists.
45
46 It returns a C<CPANDB::Dependency> object, or throws an exception if the
47 object does not exist.
1348
1449 =head2 select
1550
3671
3772 Throws an exception on error, typically directly from the L<DBI> layer.
3873
74 =head2 iterate
75
76 CPANDB::Dependency->iterate( sub {
77 print $_->distribution . "\n";
78 } );
79
80 The C<iterate> method enables the processing of large tables one record at
81 a time without loading having to them all into memory in advance.
82
83 This plays well to the strength of SQLite, allowing it to do the work of
84 loading arbitrarily large stream of records from disk while retaining the
85 full power of Perl when processing the records.
86
87 The last argument to C<iterate> must be a subroutine reference that will be
88 called for each element in the list, with the object provided in the topic
89 variable C<$_>.
90
91 This makes the C<iterate> code fragment above functionally equivalent to the
92 following, except with an O(1) memory cost instead of O(n).
93
94 foreach ( CPANDB::Dependency->select ) {
95 print $_->distribution . "\n";
96 }
97
98 You can filter the list via SQL in the same way you can with C<select>.
99 CPANDB::Dependency->iterate(
100 'order by ?', 'distribution',
101 sub {
102 print $_->distribution . "\n";
103 }
104 );
105
106 You can also use it in raw form from the root namespace for better control.
107 Using this form also allows for the use of arbitrarily complex queries,
108 including joins. Instead of being objects, rows are provided as C<ARRAY>
109 references when used in this form.
110 CPANDB->iterate(
111 'select name from dependency order by distribution',
112 sub {
113 print $_->[0] . "\n";
114 }
115 );
116
39117 =head2 count
40118
41119 # How many objects are in the table
64142 =head2 distribution
65143
66144 if ( $object->distribution ) {
67 print "Object has been inserted\n";
145 print "Object has been inserted\\n";
68146 } else {
69 print "Object has not been inserted\n";
147 print "Object has not been inserted\\n";
70148 }
71149
72150 Returns true, or throws an exception on error.
73
74151
75152 REMAINING ACCESSORS TO BE COMPLETED
76153
93170 FOREIGN KEY (
94171 distribution
95172 )
96 REFERENCES distribition (
173 REFERENCES distribution (
97174 distribution
98175 )
99176 ,
114191
115192 =head1 COPYRIGHT
116193
117 Copyright 2009 Adam Kennedy.
194 Copyright 2009 - 2010 Adam Kennedy.
118195
119196 This program is free software; you can redistribute
120197 it and/or modify it under the same terms as Perl itself.
55 use DateTime ();
66 use ORLite::Statistics;
77
8 our $VERSION = '0.11';
8 our $VERSION = '0.13';
99
1010 my $today = DateTime->today( time_zone => 'UTC' );
1111
3636 $_[0]->age->in_units('months');
3737 }
3838
39 sub quadrant {
39 sub quartile {
4040 my $self = shift;
4141
4242 # Get the boundary dates
43 my @quadrant = ref($self)->_quadrant;
44
45 # Find which quadrant we are in
43 my @quartile = ref($self)->_quartile;
44
45 # Find which quartile we are in
4646 my $uploaded = $self->uploaded;
47 if ( $uploaded gt $quadrant[0] ) {
47 if ( $uploaded gt $quartile[0] ) {
4848 return 1;
49 } elsif ( $uploaded gt $quadrant[1] ) {
49 } elsif ( $uploaded gt $quartile[1] ) {
5050 return 2;
51 } elsif ( $uploaded gt $quadrant[2] ) {
51 } elsif ( $uploaded gt $quartile[2] ) {
5252 return 3;
5353 } else {
5454 return 4;
5757
5858 my @QUADRANT = ();
5959
60 sub _quadrant {
60 sub _quartile {
6161 return @QUADRANT if @QUADRANT;
6262
6363 # Start with the total number of distributions
6666 my $mod = $rows % 4;
6767 my $range = ($rows - $mod) / 4;
6868
69 # Find the last row in each quadrant
69 # Find the last row in each quartile
7070 foreach ( 1 .. 4 ) {
7171 my $offset = ($range * $_) + $mod - 1;
7272
8080 # Find the upload date for the resulting row
8181 my @object = $class->select("order by uploaded desc limit 1 offset $offset");
8282 unless ( @object == 1 ) {
83 die("Failed to find edge of quadrant $_");
83 die("Failed to find edge of quartile $_");
8484 }
8585
8686 push @QUADRANT, $object[0]->uploaded;
11
22 CPANDB::Distribution - CPANDB class for the distribution table
33
4 =head1 SYNOPSIS
5
6 TO BE COMPLETED
7
84 =head1 DESCRIPTION
95
10 TO BE COMPLETED
6 B<CPANDB::Distribution> provides an object representation of a distribution
7 in the CPAN. Because many CPAN websites are oriented around distributions,
8 this class serves as one of the primary integration points for the various
9 different CPAN databases providing information on popularity and testing data.
10
11 Distributions are also the primary plane on which graph-aware algorithms are
12 run, and on which metrics are calculated.
1113
1214 =head1 METHODS
15
16 =head2 base
17
18 my $namespace = CPANDB::Distribution->base; # Returns 'CPANDB'
19
20 Normally you will only need to work directly with a table class,
21 and only with one ORLite package.
22
23 However, if for some reason you need to work with multiple ORLite packages
24 at the same time without hardcoding the root namespace all the time, you
25 can determine the root namespace from an object or table class with the
26 C<base> method.
27
28 =head2 table
29
30 print CPANDB::Distribution->table; # Returns 'distribution'
31
32 While you should not need the name of table for any simple operations,
33 from time to time you may need it programatically. If you do need it,
34 you can use the C<table> method to get the table name.
35
36 =head2 load
37
38 my $object = CPANDB::Distribution->load( $distribution );
39
40 If your table has single column primary key, a C<load> method will be
41 generated in the class. If there is no primary key, the method is not
42 created.
43
44 The C<load> method provides a shortcut mechanism for fetching a single
45 object based on the value of the primary key. However it should only
46 be used for cases where your code trusts the record to already exists.
47
48 It returns a C<CPANDB::Distribution> object, or throws an exception if the
49 object does not exist.
1350
1451 =head2 select
1552
3673
3774 Throws an exception on error, typically directly from the L<DBI> layer.
3875
76 =head2 iterate
77
78 CPANDB::Distribution->iterate( sub {
79 print $_->distribution . "\n";
80 } );
81
82 The C<iterate> method enables the processing of large tables one record at
83 a time without loading having to them all into memory in advance.
84
85 This plays well to the strength of SQLite, allowing it to do the work of
86 loading arbitrarily large stream of records from disk while retaining the
87 full power of Perl when processing the records.
88
89 The last argument to C<iterate> must be a subroutine reference that will be
90 called for each element in the list, with the object provided in the topic
91 variable C<$_>.
92
93 This makes the C<iterate> code fragment above functionally equivalent to the
94 following, except with an O(1) memory cost instead of O(n).
95
96 foreach ( CPANDB::Distribution->select ) {
97 print $_->distribution . "\n";
98 }
99
100 You can filter the list via SQL in the same way you can with C<select>.
101 CPANDB::Distribution->iterate(
102 'order by ?', 'distribution',
103 sub {
104 print $_->distribution . "\n";
105 }
106 );
107
108 You can also use it in raw form from the root namespace for better control.
109 Using this form also allows for the use of arbitrarily complex queries,
110 including joins. Instead of being objects, rows are provided as C<ARRAY>
111 references when used in this form.
112 CPANDB->iterate(
113 'select name from distribution order by distribution',
114 sub {
115 print $_->[0] . "\n";
116 }
117 );
118
39119 =head2 count
40120
41121 # How many objects are in the table
59139
60140 Throws an exception on error, typically directly from the L<DBI> layer.
61141
142 =head2 uploaded_datetime
143
144 For situations in which date math will be done, the C<uploaded_datetime>
145 method can be used to access the date of the most decent release as a
146 L<DateTime> object.
147
148 Returns a L<DateTime> object with date attributes, without a time set,
149 and set at the UTC timezone in the 'C' locale.
150
151 =head2 age
152
153 The B<age> method finds the age of a distribution in L<DateTime> terms,
154 and where high age is considered a negative property. It is calculated as
155 the time between the current day and the date of the last release of the
156 distribution.
157
158 Returns a L<DateTime::Duration> object, with maximum resolution at the 'day'
159 level.
160
161 =head2 age_months
162
163 When expressing the age of a module in the CPAN, the most normal unit to use
164 is the month. Releasing more than once a month is considered high pace for a
165 CPAN distribution, while releasing every few months or even once per several
166 months is fairly reasonable for mature modules.
167
168 For situations when a single numeric value is desired to represent a
169 distribution's age, the C<age_months> thus provides a direct calculation of
170 this value.
171
172 Returns the age in months as an integer, with a value of zero if the module
173 has been released within the last month.
174
175 =head2 quartile
176
177 The C<quartile> method determines which statstical age quartile the
178 distribution falls into, between 1 and 4.
179
180 Quartile 1 represents "new" or "current" modules, which have seen
181 a release in at least the last year.
182
183 Distributions in the first quadrant are usually going to work and be up to
184 date, as the author is likely to be present (for new modules) or maintains
185 the module to a reasonable level of diligence (for older modules).
186
187 Quartile 2 represents "mature" or "stale" modules, which have seen a release
188 in the last several years, but not recently.
189
190 Smaller distributions with high CPAN Testers PASS rates and low or no bug counts
191 are often simply "mature" as they are essentially "finished" and don't need to
192 be extended. These will often see a new release only every 2 or 3 years to fix
193 trivial issues or match changes in some underlying dependency which has changed.
194
195 Larger distributions with non-perfect CPAN Tester PASS rates (or those with high
196 bug counts) can be considered to be "stale". However, their authors are still
197 likely to be around. Contacting the author may result in new releases due to the
198 your attention, or the author might be interested in handing off the module for
199 maintenance.
200
201 Quartile 3 represents "old" or "rotten" modules, which have not seen a release
202 in the last several years.
203
204 Modules with high number of other modules depending on them in this range may
205 simply be "old" and suffering from benign neglect due to the author moving on to
206 other careers, languages, or projects and not annointing a replacement
207
208 They aren't actively broken, but nobody remains to maintain them and they may
209 have crufty and hard to learn codebases. Due to entrenched workarounds for any
210 bugs they have, they can also be risky to change.
211
212 Modules without downstream dependencies in this zone are often "rotten", broken
213 due to changes in the modules around them and abandoned by anything that used
214 to depend on them.
215
216 It can also be common to find modules in this range labelled as "DEPRECATED" in
217 the abstract.
218
219 Quartile 4 represents the garbage dump of the CPAN. These modules tend to
220 largely be abandoned modules, ideas that failed dramatically, Acme:: joke
221 modules that have never needed updated releases, or modules who have been
222 replaced wholesale by updated core techniques or dramatically superior
223 replacements.
224
225 The oldest of these modules date from the age of Perl 4 and the earliest Perl 5.
226
227 =head2 dependency_graph
228
229 This method generates a L<Graph::Directed> object linking the distribution to
230 all the other distributions that are needed by it to work, recursively.
231
232 =head2 dependants_graph
233
234 This method generates a L<Graph::Directed> object linking the distribution to
235 all the other distributions that use the distribution, recursively.
236
237 =head2 dependency_easy
238
239 This method generates a L<Graph::Easy> object linking the distribution to
240 all the other distributions that are needed by it to work, recursively.
241
242 =head2 dependants_easy
243
244 This method generates a L<Graph::Easy> object linking the distribution to
245 all the other distributions that use the distribution, recursively.
246
247 =head2 dependency_graphviz
248
249 This method generates a L<Graphviz> object linking the distribution to
250 all the other distributions that are needed by it to work, recursively.
251
252 =head2 dependants_graphviz
253
254 This method generates a L<Graphviz> object linking the distribution to
255 all the other distributions that use the distribution, recursively.
256
257 =head2 dependency_xgmml
258
259 This method generates a L<Graph::XGMML> object linking the distribution to
260 all the other distributions that are needed by it to work, recursively.
261
262 =head2 dependants_xgmml
263
264 This method generates a L<Graph::XGMML> object linking the distribution to
265 all the other distributions that use the distribution, recursively.
266
62267 =head1 ACCESSORS
63268
64269 =head2 distribution
65270
66271 if ( $object->distribution ) {
67 print "Object has been inserted\n";
272 print "Object has been inserted\\n";
68273 } else {
69 print "Object has not been inserted\n";
274 print "Object has not been inserted\\n";
70275 }
71276
72277 Returns true, or throws an exception on error.
73
74278
75279 REMAINING ACCESSORS TO BE COMPLETED
76280
112316
113317 =head1 COPYRIGHT
114318
115 Copyright 2009 Adam Kennedy.
319 Copyright 2009 - 2010 Adam Kennedy.
116320
117321 This program is free software; you can redistribute
118322 it and/or modify it under the same terms as Perl itself.
1010 TO BE COMPLETED
1111
1212 =head1 METHODS
13
14 =head2 base
15
16 my $namespace = CPANDB::Module->base; # Returns 'CPANDB'
17
18 Normally you will only need to work directly with a table class,
19 and only with one ORLite package.
20
21 However, if for some reason you need to work with multiple ORLite packages
22 at the same time without hardcoding the root namespace all the time, you
23 can determine the root namespace from an object or table class with the
24 C<base> method.
25
26 =head2 table
27
28 print CPANDB::Module->table; # Returns 'module'
29
30 While you should not need the name of table for any simple operations,
31 from time to time you may need it programatically. If you do need it,
32 you can use the C<table> method to get the table name.
33
34 =head2 load
35
36 my $object = CPANDB::Module->load( $module );
37
38 If your table has single column primary key, a C<load> method will be
39 generated in the class. If there is no primary key, the method is not
40 created.
41
42 The C<load> method provides a shortcut mechanism for fetching a single
43 object based on the value of the primary key. However it should only
44 be used for cases where your code trusts the record to already exists.
45
46 It returns a C<CPANDB::Module> object, or throws an exception if the
47 object does not exist.
1348
1449 =head2 select
1550
3570 context.
3671
3772 Throws an exception on error, typically directly from the L<DBI> layer.
73
74 =head2 iterate
75
76 CPANDB::Module->iterate( sub {
77 print $_->module . "\n";
78 } );
79
80 The C<iterate> method enables the processing of large tables one record at
81 a time without loading having to them all into memory in advance.
82
83 This plays well to the strength of SQLite, allowing it to do the work of
84 loading arbitrarily large stream of records from disk while retaining the
85 full power of Perl when processing the records.
86
87 The last argument to C<iterate> must be a subroutine reference that will be
88 called for each element in the list, with the object provided in the topic
89 variable C<$_>.
90
91 This makes the C<iterate> code fragment above functionally equivalent to the
92 following, except with an O(1) memory cost instead of O(n).
93
94 foreach ( CPANDB::Module->select ) {
95 print $_->module . "\n";
96 }
97
98 You can filter the list via SQL in the same way you can with C<select>.
99 CPANDB::Module->iterate(
100 'order by ?', 'module',
101 sub {
102 print $_->module . "\n";
103 }
104 );
105
106 You can also use it in raw form from the root namespace for better control.
107 Using this form also allows for the use of arbitrarily complex queries,
108 including joins. Instead of being objects, rows are provided as C<ARRAY>
109 references when used in this form.
110 CPANDB->iterate(
111 'select name from module order by module',
112 sub {
113 print $_->[0] . "\n";
114 }
115 );
38116
39117 =head2 count
40118
64142 =head2 module
65143
66144 if ( $object->module ) {
67 print "Object has been inserted\n";
145 print "Object has been inserted\\n";
68146 } else {
69 print "Object has not been inserted\n";
147 print "Object has not been inserted\\n";
70148 }
71149
72150 Returns true, or throws an exception on error.
100178
101179 =head1 COPYRIGHT
102180
103 Copyright 2009 Adam Kennedy.
181 Copyright 2009 - 2010 Adam Kennedy.
104182
105183 This program is free software; you can redistribute
106184 it and/or modify it under the same terms as Perl itself.
1010 TO BE COMPLETED
1111
1212 =head1 METHODS
13
14 =head2 base
15
16 my $namespace = CPANDB::Requires->base; # Returns 'CPANDB'
17
18 Normally you will only need to work directly with a table class,
19 and only with one ORLite package.
20
21 However, if for some reason you need to work with multiple ORLite packages
22 at the same time without hardcoding the root namespace all the time, you
23 can determine the root namespace from an object or table class with the
24 C<base> method.
25
26 =head2 table
27
28 print CPANDB::Requires->table; # Returns 'requires'
29
30 While you should not need the name of table for any simple operations,
31 from time to time you may need it programatically. If you do need it,
32 you can use the C<table> method to get the table name.
33
34 =head2 load
35
36 my $object = CPANDB::Requires->load( $distribution );
37
38 If your table has single column primary key, a C<load> method will be
39 generated in the class. If there is no primary key, the method is not
40 created.
41
42 The C<load> method provides a shortcut mechanism for fetching a single
43 object based on the value of the primary key. However it should only
44 be used for cases where your code trusts the record to already exists.
45
46 It returns a C<CPANDB::Requires> object, or throws an exception if the
47 object does not exist.
1348
1449 =head2 select
1550
3671
3772 Throws an exception on error, typically directly from the L<DBI> layer.
3873
74 =head2 iterate
75
76 CPANDB::Requires->iterate( sub {
77 print $_->distribution . "\n";
78 } );
79
80 The C<iterate> method enables the processing of large tables one record at
81 a time without loading having to them all into memory in advance.
82
83 This plays well to the strength of SQLite, allowing it to do the work of
84 loading arbitrarily large stream of records from disk while retaining the
85 full power of Perl when processing the records.
86
87 The last argument to C<iterate> must be a subroutine reference that will be
88 called for each element in the list, with the object provided in the topic
89 variable C<$_>.
90
91 This makes the C<iterate> code fragment above functionally equivalent to the
92 following, except with an O(1) memory cost instead of O(n).
93
94 foreach ( CPANDB::Requires->select ) {
95 print $_->distribution . "\n";
96 }
97
98 You can filter the list via SQL in the same way you can with C<select>.
99 CPANDB::Requires->iterate(
100 'order by ?', 'distribution',
101 sub {
102 print $_->distribution . "\n";
103 }
104 );
105
106 You can also use it in raw form from the root namespace for better control.
107 Using this form also allows for the use of arbitrarily complex queries,
108 including joins. Instead of being objects, rows are provided as C<ARRAY>
109 references when used in this form.
110 CPANDB->iterate(
111 'select name from requires order by distribution',
112 sub {
113 print $_->[0] . "\n";
114 }
115 );
116
39117 =head2 count
40118
41119 # How many objects are in the table
64142 =head2 distribution
65143
66144 if ( $object->distribution ) {
67 print "Object has been inserted\n";
145 print "Object has been inserted\\n";
68146 } else {
69 print "Object has not been inserted\n";
147 print "Object has not been inserted\\n";
70148 }
71149
72150 Returns true, or throws an exception on error.
114192
115193 =head1 COPYRIGHT
116194
117 Copyright 2009 Adam Kennedy.
195 Copyright 2009 - 2010 Adam Kennedy.
118196
119197 This program is free software; you can redistribute
120198 it and/or modify it under the same terms as Perl itself.
77 use ORLite::Mirror ();
88 use CPANDB::Distribution ();
99
10 our $VERSION = '0.12';
10 our $VERSION = '0.13';
1111
1212 sub import {
1313 my $class = shift;
1616 # Pass through any params from above
1717 $params->{url} ||= 'http://svn.ali.as/db/cpandb.bz2';
1818 $params->{maxage} ||= 24 * 60 * 60; # One day
19
20 # Always turn on string eval debugging if Perl is new enough
21 if ( $^V > 5.008008 ) {
22 $^P = $^P | 0x800;
23 }
1924
2025 # Prevent double-initialisation
2126 $class->can('orlite') or
11
22 CPANDB - An ORLite-based ORM Database API
33
4 =head1 SYNOPSIS
5
6 TO BE COMPLETED
7
84 =head1 DESCRIPTION
95
10 TO BE COMPLETED
6 B<CPANDB> is an module for accessing CPAN metadata merged from many different
7 CPAN websites into a single simple object model.
118
129 =head1 METHODS
1310
5552 The C<dbh> method returns a L<DBI::db> object, or throws an exception on
5653 error.
5754
55 =head2 begin
56
57 CPANDB->begin;
58
59 The C<begin> method indicates the start of a transaction.
60
61 In the same way that ORLite allows only a single connection, likewise
62 it allows only a single application-wide transaction.
63
64 No indication is given as to whether you are currently in a transaction
65 or not, all code should be written neutrally so that it works either way
66 or doesn't need to care.
67
68 Returns true or throws an exception on error.
69
70 =head2 rollback
71
72 The C<rollback> method rolls back the current transaction. If called outside
73 of a current transaction, it is accepted and treated as a null operation.
74
75 Once the rollback has been completed, the database connection falls back
76 into auto-commit state. If you wish to immediately start another
77 transaction, you will need to issue a separate -E<gt>begin call.
78
79 If a transaction exists at END-time as the process exits, it will be
80 automatically rolled back.
81
82 Returns true or throws an exception on error.
83
84 =head2 do
85
86 CPANDB->do(
87 'insert into table ( foo, bar ) values ( ?, ? )', {},
88 \$foo_value,
89 \$bar_value,
90 );
91
92 The C<do> method is a direct wrapper around the equivalent L<DBI> method,
93 but applied to the appropriate locally-provided connection or transaction.
94
95 It takes the same parameters and has the same return values and error
96 behaviour.
97
5898 =head2 selectall_arrayref
5999
60100 The C<selectall_arrayref> method is a direct wrapper around the equivalent
130170 The C<pragma> method provides a convenient method for fetching a pragma
131171 for a datase. See the SQLite documentation for more details.
132172
173 =head2 distribution
174
175 my $dist = CPANDB->distribution('Config-Tiny');
176
177 The C<distribution> method is a convenient shortcut for direct access to
178 the L<CPANDB::Distribution> object for a single named distribution.
179
180 =head2 graph
181
182 my $everything = CPANDB->graph;
183
184 Originally created as a proof of concept for L<Graph> integration, the C<graph>
185 method creates a single giant L<Graph::Directed> object representing the
186 dependency structure of the entire CPAN at a distribution-to-distribution level.
187
188 The graphing features of L<CPANDB> are considered optional. To use this method
189 you will need to install L<Graph::Directed> yourself, and set up a dependency
190 in any code that uses L<Graph> features.
191
133192 =head1 SUPPORT
134193
135 CPANDB is based on L<ORLite> 1.23.
136
137 Documentation created by L<ORLite::Pod> 0.06.
194 CPANDB is based on L<ORLite> $ORLite::VERSION.
195
196 Documentation created by L<ORLite::Pod> $ORLite::Pod::VERSION.
138197
139198 For general support please see the support section of the main
140199 project documentation.
141200
142201 =head1 COPYRIGHT
143202
144 Copyright 2009 Adam Kennedy.
203 Copyright 2009 - 2010 Adam Kennedy.
145204
146205 This program is free software; you can redistribute
147206 it and/or modify it under the same terms as Perl itself.
1414 Version 0.12
1515
1616 =cut
17 our $VERSION = '0.12';
17 our $VERSION = '0.13';
1818
1919 use CPANDB ();
2020
109109 is( scalar(@latest), 10, 'Found the 10 latest results' );
110110 foreach ( @latest ) {
111111 isa_ok( $_, 'CPANDB::Distribution' );
112 is( $_->quadrant, 1, $_->distribution . ' is in quadrant 1' );
112 is( $_->quartile, 1, $_->distribution . ' is in quartile 1' );
113113 }
114114 }
115115
+0
-27
t/97_meta.t less more
0 #!/usr/bin/perl
1
2 # Test that our META.yml file matches the current specification.
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my $MODULE = 'Test::CPAN::Meta 0.12';
11
12 # Don't run tests for installs
13 use Test::More;
14 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
15 plan( skip_all => "Author tests not required for installation" );
16 }
17
18 # Load the testing module
19 eval "use $MODULE";
20 if ( $@ ) {
21 $ENV{RELEASE_TESTING}
22 ? die( "Failed to load required release-testing module $MODULE" )
23 : plan( skip_all => "$MODULE not available for testing" );
24 }
25
26 meta_yaml_ok();
+0
-32
t/98_pod.t less more
0 #!/usr/bin/perl
1
2 # Test that the syntax of our POD documentation is valid
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my @MODULES = (
11 'Pod::Simple 3.07',
12 'Test::Pod 1.26',
13 );
14
15 # Don't run tests for installs
16 use Test::More;
17 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
18 plan( skip_all => "Author tests not required for installation" );
19 }
20
21 # Load the testing modules
22 foreach my $MODULE ( @MODULES ) {
23 eval "use $MODULE";
24 if ( $@ ) {
25 $ENV{RELEASE_TESTING}
26 ? die( "Failed to load required release-testing module $MODULE" )
27 : plan( skip_all => "$MODULE not available for testing" );
28 }
29 }
30
31 all_pod_files_ok();
+0
-32
t/99_pmv.t less more
0 #!/usr/bin/perl
1
2 # Test that our declared minimum Perl version matches our syntax
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my @MODULES = (
11 'Perl::MinimumVersion 1.20',
12 'Test::MinimumVersion 0.008',
13 );
14
15 # Don't run tests for installs
16 use Test::More;
17 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
18 plan( skip_all => "Author tests not required for installation" );
19 }
20
21 # Load the testing modules
22 foreach my $MODULE ( @MODULES ) {
23 eval "use $MODULE";
24 if ( $@ ) {
25 $ENV{RELEASE_TESTING}
26 ? die( "Failed to load required release-testing module $MODULE" )
27 : plan( skip_all => "$MODULE not available for testing" );
28 }
29 }
30
31 all_minimum_version_from_metayml_ok();
0 #!/usr/bin/perl
1
2 # Test that our META.yml file matches the current specification.
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my $MODULE = 'Test::CPAN::Meta 0.12';
11
12 # Don't run tests for installs
13 use Test::More;
14 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
15 plan( skip_all => "Author tests not required for installation" );
16 }
17
18 # Load the testing module
19 eval "use $MODULE";
20 if ( $@ ) {
21 $ENV{RELEASE_TESTING}
22 ? die( "Failed to load required release-testing module $MODULE" )
23 : plan( skip_all => "$MODULE not available for testing" );
24 }
25
26 meta_yaml_ok();
0 #!/usr/bin/perl
1
2 # Test that our declared minimum Perl version matches our syntax
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my @MODULES = (
11 'Perl::MinimumVersion 1.20',
12 'Test::MinimumVersion 0.008',
13 );
14
15 # Don't run tests for installs
16 use Test::More;
17 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
18 plan( skip_all => "Author tests not required for installation" );
19 }
20
21 # Load the testing modules
22 foreach my $MODULE ( @MODULES ) {
23 eval "use $MODULE";
24 if ( $@ ) {
25 $ENV{RELEASE_TESTING}
26 ? die( "Failed to load required release-testing module $MODULE" )
27 : plan( skip_all => "$MODULE not available for testing" );
28 }
29 }
30
31 all_minimum_version_from_metayml_ok();
0 #!/usr/bin/perl
1
2 # Test that the syntax of our POD documentation is valid
3
4 use strict;
5 BEGIN {
6 $| = 1;
7 $^W = 1;
8 }
9
10 my @MODULES = (
11 'Pod::Simple 3.07',
12 'Test::Pod 1.26',
13 );
14
15 # Don't run tests for installs
16 use Test::More;
17 unless ( $ENV{AUTOMATED_TESTING} or $ENV{RELEASE_TESTING} ) {
18 plan( skip_all => "Author tests not required for installation" );
19 }
20
21 # Load the testing modules
22 foreach my $MODULE ( @MODULES ) {
23 eval "use $MODULE";
24 if ( $@ ) {
25 $ENV{RELEASE_TESTING}
26 ? die( "Failed to load required release-testing module $MODULE" )
27 : plan( skip_all => "$MODULE not available for testing" );
28 }
29 }
30
31 all_pod_files_ok();