Browse files

Look for "require Module; Module->VERSION(min);"

Solves RT#72062
  • Loading branch information...
1 parent 0d1f559 commit 9b52fcff71094c311801e41bc8d078458caf6922 @madsen madsen committed Oct 31, 2011
Showing with 103 additions and 1 deletion.
  1. +2 −0 Changes
  2. +62 −1 lib/Perl/PrereqScanner/Scanner/Perl5.pm
  3. +39 −0 t/autoprereq.t
View
2 Changes
@@ -1,6 +1,8 @@
Revision history for Perl-PrereqScanner
{{$NEXT}}
+ - fix rt#72062 - look for "require Module; Module->VERSION(min);"
+ (Christopher J. Madsen)
1.007 2011-08-31 09:22:12 Europe/Paris
- new option --combine for scan_prereqs script (randy stauner)
View
63 lib/Perl/PrereqScanner/Scanner/Perl5.pm
@@ -18,6 +18,23 @@ This scanner will look for the following indicators:
=end :list
+Since Perl does not allow you to supply a version requirement with a
+C<require> statement, the scanner will check the statement after the
+C<require Module> to see if it is C<< Module->VERSION( minimum_version ); >>.
+
+In order to provide a minimum version, that method call must meet the
+following requirements:
+
+=begin :list
+
+* it must be the very next statement after C<require Module>. Nothing can separate them but whitespace and comments (and one semicolon).
+
+* C<Module> must be a bareword, and match the C<require> exactly.
+
+* C<minimum_version> must be a literal number, v-string, or single-quoted string. Double quotes are not allowed.
+
+=end :list
+
=cut
sub scan_for_prereqs {
@@ -53,8 +70,52 @@ sub scan_for_prereqs {
my $version = $node->module_version ? $node->module_version->content : 0;
# rt#55851: 'require $foo;' shouldn't add any prereq
- $req->add_minimum($node->module, $version) if $node->module;
+ next unless $node->module;
+
+ # See if the next statement after require is Module->VERSION(min):
+ $version = $self->_check_required_version($node) || 0
+ if not $version and $node->type eq 'require';
+
+ $req->add_minimum($node->module, $version);
}
}
+# For "require Module", see if the next statement is Module->VERSION(min):
+sub _check_required_version {
+ my ($self, $node) = @_;
+
+ my $next = $node->snext_sibling;
+
+ return unless $next and $next->class eq 'PPI::Statement';
+
+ my ($invocant, $op, $method, $list, $too_much) = $next->schildren;
+
+ return unless defined $list # need enough children
+ and $op->class eq 'PPI::Token::Operator'
+ and $op->content eq '->'
+ and $method->content eq 'VERSION'
+ and (not defined $too_much # but not too many children
+ or $too_much->content eq ';')
+ and $invocant->content eq $node->module
+ and $list->class eq 'PPI::Structure::List'
+ and $list->braces eq '()'
+ and $list->schildren == 1;
+
+ my $exp = $list->schild(0);
+
+ return unless $exp->class eq 'PPI::Statement::Expression'
+ and $exp->schildren == 1;
+
+ my $arg = $exp->schild(0);
+
+ if ($arg->isa('PPI::Token::Number')) {
+ return $arg->content;
+ } elsif ($arg->isa('PPI::Token::Quote') and $arg->can('literal')) {
+ return $arg->literal;
+ }
+
+ return; # No minimum version found
+} # end _check_required_version
+
+
1;
View
39 t/autoprereq.t
@@ -70,6 +70,45 @@ prereq_is(
{ 'Import::IgnoreAPI' => 0 },
);
+prereq_is('require Require; Require->VERSION(0.50);', { Require => '0.50' });
+
+prereq_is('require Require; Require->VERSION(+0.50);', { Require => 0 });
+
+prereq_is('require Require; foo(); Require->VERSION(1.00);', { Require => 0 });
+
+prereq_is(
+ 'require Require; Require->VERSION(v1.0.50);',
+ { Require => 'v1.0.50' }
+);
+
+prereq_is(
+ q{require Require; Require->VERSION('v1.0.50');},
+ { Require => 'v1.0.50' }
+);
+
+prereq_is(
+ 'require Require; Require->VERSION(q[1.00]);',
+ { Require => '1.00' }
+);
+
+prereq_is(
+ 'require Require; Require::Other->VERSION(1.00);',
+ { Require => 0 }
+);
+
+prereq_is(
+ <<'END REQUIRE WITH COMMENT',
+require Require::This; # this comment shouldn't matter
+Require::This->VERSION(0.450);
+END REQUIRE WITH COMMENT
+ { 'Require::This' => '0.450' }, 'require with comment'
+);
+
+prereq_is(
+ 'require Require; Require->VERSION(0.450) if some_condition; ',
+ { 'Require' => 0 }
+);
+
# Moose features
prereq_is(

0 comments on commit 9b52fcf

Please sign in to comment.