- Only load Class::C3 and friends if necessary ($] < 5.010)
- Greatly reduced loading of non-essential modules to aid startup
time (mainly benefiting CGI users)
+ - Make sure all namespaces are clean of rogue imports
0.08127 2011-01-19 16:40 (UTC)
* New Features / Changes
my $runtime_requires = {
'Carp::Clan' => '6.0',
'Class::Accessor::Grouped' => '0.10002',
- 'Class::C3::Componentised' => '1.0008',
+ 'Class::C3::Componentised' => '1.0009',
'Class::Inspector' => '1.24',
'Config::Any' => '0.20',
'Context::Preserve' => '0.01',
package # hide from PAUSE
DBIx::Class::Admin::Descriptive;
-use DBIx::Class::Admin::Usage;
use base 'Getopt::Long::Descriptive';
+require DBIx::Class::Admin::Usage;
sub usage_class { 'DBIx::Class::Admin::Usage'; }
1;
use warnings;
use base 'Class::C3::Componentised';
-use Carp::Clan qw/^DBIx::Class|^Class::C3::Componentised/;
use mro 'c3';
+use Carp::Clan qw/^DBIx::Class|^Class::C3::Componentised/;
+use namespace::clean;
+
+
my $warned;
# this warns of subtle bugs introduced by UTF8Columns hacky handling of store_column
__PACKAGE__->load_components(qw/ResultSetProxy/);
-{
- no warnings 'once';
- *dbi_commit = \&txn_commit;
- *dbi_rollback = \&txn_rollback;
-}
-
sub storage { shift->schema_instance(@_)->storage; }
+sub dbi_commit { shift->txn_commit(@_) }
+sub dbi_rollback { shift->txn_rollback(@_) }
=head1 NAME
use strict;
use warnings;
-use Scalar::Util qw/blessed/;
use base qw/DBIx::Class::Row/;
use File::Path;
use File::Copy;
use Path::Class;
-
use Carp::Clan qw/^DBIx::Class/;
+use namespace::clean;
+
carp 'InflateColumn::File has entered a deprecation cycle. This component '
.'has a number of architectural deficiencies that can quickly drive '
.'your filesystem and database out of sync and is not recommended '
.'DBIC_IC_FILE_NOWARN to a true value to disable this warning.'
unless $ENV{DBIC_IC_FILE_NOWARN};
+
+
__PACKAGE__->load_components(qw/InflateColumn/);
sub register_column {
use warnings;
use strict;
-use Carp;
+use Carp ();
# NO EXTERNAL NON-5.8.1 CORE DEPENDENCIES EVER (e.g. C::A::G)
# This module is to be loaded by Makefile.PM on a pristine system
sub req_list_for {
my ($class, $group) = @_;
- croak "req_list_for() expects a requirement group name"
+ Carp::croak "req_list_for() expects a requirement group name"
unless $group;
my $deps = $reqs->{$group}{req}
- or croak "Requirement group '$group' does not exist";
+ or Carp::croak "Requirement group '$group' does not exist";
return { %$deps };
}
sub req_ok_for {
my ($class, $group) = @_;
- croak "req_ok_for() expects a requirement group name"
+ Carp::croak "req_ok_for() expects a requirement group name"
unless $group;
return $class->_check_deps($group)->{status};
sub req_missing_for {
my ($class, $group) = @_;
- croak "req_missing_for() expects a requirement group name"
+ Carp::croak "req_missing_for() expects a requirement group name"
unless $group;
return $class->_check_deps($group)->{missing};
sub req_errorlist_for {
my ($class, $group) = @_;
- croak "req_errorlist_for() expects a requirement group name"
+ Carp::croak "req_errorlist_for() expects a requirement group name"
unless $group;
return $class->_check_deps($group)->{errorlist};
'You may distribute this code under the same terms as Perl itself',
);
- open (my $fh, '>', $podfn) or croak "Unable to write to $podfn: $!";
+ open (my $fh, '>', $podfn) or Carp::croak "Unable to write to $podfn: $!";
print $fh join ("\n\n", @chunks);
close ($fh);
}
use strict;
use warnings;
use Carp::Clan qw/^DBIx::Class|^Try::Tiny/;
+use namespace::clean;
our %_pod_inherit_config =
(
# not importing first() as it will clash with our own method
use List::Util ();
-use namespace::clean;
-
-
BEGIN {
# De-duplication in _merge_attr() is disabled, but left in for reference
# (the merger is used for other things that ought not to be de-duped)
*__HM_DEDUP = sub () { 0 };
}
+use namespace::clean;
+
use overload
'0+' => "count",
'bool' => "_bool",
use base 'DBIx::Class';
-use Carp::Clan qw/^DBIx::Class/;
use DBIx::Class::Exception;
+use Carp::Clan qw/^DBIx::Class/;
+use namespace::clean;
# not importing first() as it will clash with our own method
use List::Util ();
use DBIx::Class::Exception;
use Scalar::Util 'blessed';
use Try::Tiny;
-use namespace::clean;
###
### Internal method
: sub () { 0 };
}
+use namespace::clean;
+
=head1 NAME
DBIx::Class::Row - Basic row methods
}
};
}
+
+ # Current SQLA pollutes its namespace - clean for the time being
+ namespace::clean->clean_subroutines(qw/SQL::Abstract carp croak confess/);
}
# the "oh noes offset/top without limit" constant
DBIx::Class::SQLMaker::MSSQL;
use base qw( DBIx::Class::SQLMaker );
-use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/;
#
# MSSQL does not support ... OVER() ... RNO limits
use base qw( DBIx::Class::SQLMaker );
use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/;
+use namespace::clean;
#
# MySQL does not understand the standard INSERT INTO $table DEFAULT VALUES
use base qw( DBIx::Class::SQLMaker );
use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/;
+use namespace::clean;
BEGIN {
- use Carp::Clan qw/^DBIx::Class/;
use DBIx::Class::Optional::Dependencies;
croak('The following extra modules are required for Oracle-based Storages ' . DBIx::Class::Optional::Dependencies->req_missing_for ('id_shortener') )
unless DBIx::Class::Optional::Dependencies->req_ok_for ('id_shortener');
use base qw( DBIx::Class::SQLMaker::Oracle );
use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/;
+use namespace::clean;
sub select {
my ($self, $table, $fields, $where, $rs_attrs, @rest) = @_;
DBIx::Class::SQLMaker::SQLite;
use base qw( DBIx::Class::SQLMaker );
-use Carp::Clan qw/^DBIx::Class|^SQL::Abstract/;
#
# SQLite does not understand SELECT ... FOR UPDATE
use Storable;
use Carp::Clan qw/^DBIx::Class/;
+use namespace::clean;
carp 'The Serialize::Storable component is now *DEPRECATED*. It has not '
.'been providing any useful functionality for quite a while, and in fact '
use warnings;
use Carp::Clan qw/^DBIx::Class/;
+use namespace::clean;
carp 'Setting of storage_type is redundant as connections through DBD::Sybase'
.' are now properly recognized and reblessed into the appropriate subclass'
DBIx::Class::Storage::DBI::MSSQL
/;
use mro 'c3';
+
use Carp::Clan qw/^DBIx::Class/;
+use namespace::clean;
__PACKAGE__->datetime_parser_type(
'DBIx::Class::Storage::DBI::Sybase::Microsoft_SQL_Server::DateTime::Format'
use base qw/DBIx::Class/;
use IO::File;
+use namespace::clean;
__PACKAGE__->mk_group_accessors(simple => qw/callback _debugfh silence/);
use Try::Tiny;
use Scalar::Util qw/weaken blessed/;
use DBIx::Class::Exception;
-use namespace::clean;
# temporary until we fix the $@ issue in core
# we also need a real appendable, stackable exception object
}
}
+use namespace::clean;
+
my ($guards_count, $compat_handler, $foreign_handler);
sub new {
--- /dev/null
+use strict;
+use warnings;
+
+use Test::More;
+
+use File::Find;
+use File::Spec;
+use B qw/svref_2object/;
+
+# makes sure we can load at least something
+use DBIx::Class;
+
+my @modules = grep {
+ my $mod = $_;
+
+ # trap deprecation warnings and whatnot
+ local $SIG{__WARN__} = sub {};
+
+ # not all modules are loadable at all times
+ eval "require $mod" ? $mod : do {
+ SKIP: { skip "Failed require of $mod: $@", 1 }A
+ ();
+ };
+
+
+} find_modules();
+
+# have an exception table for old and/or weird code we are not sure
+# we *want* to clean in the first place
+my $skip_idx = { map { $_ => 1 } (
+ (grep { /^DBIx::Class::CDBICompat/ } @modules), # too crufty to touch
+ 'SQL::Translator::Producer::DBIx::Class::File', # ditto
+
+ # not sure how to handle type libraries
+ 'DBIx::Class::Storage::DBI::Replicated::Types',
+ 'DBIx::Class::Admin::Types',
+
+ # G::L::D is unclean, but we never inherit from it
+ 'DBIx::Class::Admin::Descriptive',
+ 'DBIx::Class::Admin::Usage',
+) };
+
+my $has_cmop = eval { require Class::MOP };
+
+# can't use Class::Inspector for the mundane parts as it does not
+# distinguish imports from anything else, what a crock of...
+# Class::MOP is not always available either - hence just do it ourselves
+
+my $seen; #inheritance means we will see the same method multiple times
+
+for my $mod (@modules) {
+ SKIP: {
+ skip "$mod exempt from namespace checks",1 if $skip_idx->{$mod};
+
+ my %all_method_like = do {
+ no strict 'refs';
+ map {
+ my $m = $_;
+ map
+ { *{"${m}::$_"}{CODE} ? ( $_ => *{"${m}::$_"}{CODE} ) : () }
+ keys %{"${m}::"}
+ } (reverse @{mro::get_linear_isa($mod)});
+ };
+
+ my %parents = map { $_ => 1 } @{mro::get_linear_isa($mod)};
+
+ my %roles;
+ if ($has_cmop and my $mc = Class::MOP::class_of($mod)) {
+ if ($mc->can('calculate_all_roles_with_inheritance')) {
+ $roles{$_->name} = 1 for ($mc->calculate_all_roles_with_inheritance);
+ }
+ }
+
+ for my $name (keys %all_method_like) {
+
+ # overload is a funky thing - it is neither cleaned, and its imports are named funny
+ next if $name =~ /^\(/;
+
+ my $gv = svref_2object($all_method_like{$name})->GV;
+ my $origin = $gv->STASH->NAME;
+
+ next if $seen->{"${origin}:${name}"}++;
+
+ TODO: {
+ local $TODO = 'CAG does not clean its BEGIN constants' if $name =~ /^__CAG_/;
+ is ($gv->NAME, $name, "Properly named $name method at $origin");
+ }
+
+ if ($origin eq $mod) {
+ pass ("$name is a native $mod method");
+ }
+ elsif ($roles{$origin}) {
+ pass ("${mod}::${name} came from consumption of role $origin");
+ }
+ elsif ($parents{$origin}) {
+ pass ("${mod}::${name} came from proper parent-class $origin");
+ }
+ else {
+ my $via;
+ for (reverse @{mro::get_linear_isa($mod)} ) {
+ if ( ($_->can($name)||'') eq $all_method_like{$name} ) {
+ $via = $_;
+ last;
+ }
+ }
+ fail ("${mod}::${name} appears to have entered inheritance chain by import into "
+ . ($via || 'UNKNOWN')
+ );
+ }
+ }
+ }
+}
+
+sub find_modules {
+ my @modules;
+
+ find({
+ wanted => sub {
+ -f $_ or return;
+ s/\.pm$// or return;
+ s/^ (?: lib | blib . (?:lib|arch) ) . //x;
+ push @modules, join ('::', File::Spec->splitdir($_));
+ },
+ no_chdir => 1,
+ }, (-e 'blib' ? 'blib' : 'lib') );
+
+ return sort @modules;
+}
+
+
+done_testing;