summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-01-12 23:58:43 -0600
committerJesse Luehrs <doy@tozt.net>2011-01-12 23:58:43 -0600
commitf2dc99005ab12f416a17f16a76c6f8abd024e6fc (patch)
tree4797c3fa173044e10c8dfc86d6c608b7415d866d
parent83abcf9ed1aa392081942ace5bba28948f1ba79d (diff)
downloaddist-checkconflicts-f2dc99005ab12f416a17f16a76c6f8abd024e6fc.tar.gz
dist-checkconflicts-f2dc99005ab12f416a17f16a76c6f8abd024e6fc.zip
runtime conflict checks
-rw-r--r--lib/Dist/CheckConflicts.pm53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/Dist/CheckConflicts.pm b/lib/Dist/CheckConflicts.pm
index 0c2907f..b5e2a1c 100644
--- a/lib/Dist/CheckConflicts.pm
+++ b/lib/Dist/CheckConflicts.pm
@@ -117,6 +117,43 @@ sub import {
$CONFLICTS{$for} = \%conflicts;
$DISTS{$for} = $dist || $for;
+ # warn for already loaded things...
+ for my $conflict (keys %conflicts) {
+ (my $file = $conflict) =~ s{::}{/}g;
+ $file .= '.pm';
+ if (exists $INC{$file}) {
+ _check_version($for, $conflict, $conflicts{$conflict});
+ }
+ }
+
+ # and warn for subsequently loaded things...
+ unshift @INC, [
+ sub {
+ my ($sub, $file) = @_;
+
+ (my $mod = $file) =~ s{\.pm$}{};
+ $mod =~ s{/}{::}g;
+ return unless $mod =~ /[\w:]+/;
+
+ return unless exists $conflicts{$mod};
+
+ {
+ local @INC = grep {
+ !(ref($_) eq 'ARRAY' && @$_ > 1 && $_->[1] == \%CONFLICTS)
+ } @INC;
+
+ require $file;
+ }
+
+ _check_version($for, $mod, $conflicts{$mod});
+
+ my $i = 1;
+ return sub { $_ = $i-- }; # the previous require already handled it
+ },
+ \%CONFLICTS, # arbitrary but unique, see above
+ $for, # debugging
+ ];
+
goto $import;
}
@@ -133,6 +170,22 @@ sub _strip_opt {
return ( $val, @_ );
}
+sub _check_version {
+ my ($for, $mod, $conflict_ver) = @_;
+
+ my $version = do {
+ no strict 'refs';
+ ${ ${ $mod . '::' }{VERSION} };
+ };
+
+ if ($version le $conflict_ver) {
+ warn <<EOF;
+Conflict detected for $DISTS{$for}:
+ $mod is version $version, but must be greater than version $conflict_ver
+EOF
+ }
+}
+
=method conflicts
Returns the conflict specification (the C<-conflicts> parameter to