Port ::Replicated from Moose to Moo
Dagfinn Ilmari Mannsåker [Thu, 19 Mar 2015 15:09:26 +0000 (16:09 +0100)]
14 files changed:
lib/DBIx/Class/Optional/Dependencies.pm
lib/DBIx/Class/Storage/DBI/Replicated.pm
lib/DBIx/Class/Storage/DBI/Replicated/Balancer.pm
lib/DBIx/Class/Storage/DBI/Replicated/Balancer/First.pm
lib/DBIx/Class/Storage/DBI/Replicated/Balancer/Random.pm
lib/DBIx/Class/Storage/DBI/Replicated/Pool.pm
lib/DBIx/Class/Storage/DBI/Replicated/Replicant.pm
lib/DBIx/Class/Storage/DBI/Replicated/Types.pm [deleted file]
lib/DBIx/Class/Storage/DBI/Replicated/WithDSN.pm
lib/DBIx/Class/_Types.pm
maint/travis-ci_scripts/30_before_script.bash
maint/travis-ci_scripts/50_after_success.bash
t/storage/replicated.t
xt/extra/internals/namespaces_cleaned.t

index 87254da..b121793 100644 (file)
@@ -21,14 +21,6 @@ sub croak {
 # POD is generated automatically by calling _gen_pod from the
 # Makefile.PL in $AUTHOR mode
 
-# *DELIBERATELY* not making a group for these - they must disappear
-# forever as optdeps in the first place
-my $moose_basic = {
-  'Moose'                         => '0.98',
-  'MooseX::Types'                 => '0.21',
-  'MooseX::Types::LoadableClass'  => '0.011',
-};
-
 my $dbic_reqs = {
 
   # NOTE: the rationale for 2 JSON::Any versions is that
@@ -84,7 +76,9 @@ my $dbic_reqs = {
   },
 
   replicated => {
-    req => $moose_basic,
+    req => {
+      'Class::Load' => '0.20',
+    },
     pod => {
       title => 'Storage::Replicated',
       desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
@@ -93,9 +87,6 @@ my $dbic_reqs = {
 
   test_replicated => {
     include => 'replicated',
-    req => {
-      'Test::Moose' => '0',
-    },
   },
 
   admin => {
index 92a0e17..84623b7 100644 (file)
@@ -1,28 +1,19 @@
 package DBIx::Class::Storage::DBI::Replicated;
 
-use warnings;
-use strict;
-
-BEGIN {
-  require DBIx::Class::Optional::Dependencies;
-  if ( my $missing = DBIx::Class::Optional::Dependencies->req_missing_for('replicated') ) {
-    die "The following modules are required for Replicated storage support: $missing\n";
-  }
-}
-
-use Moose;
+use Moo;
 use DBIx::Class::Storage::DBI;
 use DBIx::Class::Storage::DBI::Replicated::Pool;
 use DBIx::Class::Storage::DBI::Replicated::Balancer;
-use DBIx::Class::Storage::DBI::Replicated::Types qw/BalancerClassNamePart DBICSchema DBICStorageDBI/;
-use MooseX::Types::Moose qw/ClassName HashRef Object/;
-use Scalar::Util 'reftype';
+use DBIx::Class::_Types qw/BalancerClassNamePart LoadableClass HashRef Object DBICSchema DBICStorageDBI/;
+use Scalar::Util qw(reftype blessed);
+use Sub::Name qw(subname);
 use Hash::Merge;
 use List::Util qw/min max reduce/;
 use Context::Preserve 'preserve_context';
+use Class::Inspector;
 use Try::Tiny;
 
-use namespace::clean -except => 'meta';
+use namespace::clean;
 
 =head1 NAME
 
@@ -139,7 +130,7 @@ to: L<DBIx::Class::Storage::DBI::Replicated::Pool>.
 
 has 'pool_type' => (
   is=>'rw',
-  isa=>ClassName,
+  isa=>LoadableClass,
   default=>'DBIx::Class::Storage::DBI::Replicated::Pool',
   handles=>{
     'create_pool' => 'new',
@@ -170,8 +161,7 @@ choose how to spread the query load across each replicant in the pool.
 
 has 'balancer_type' => (
   is=>'rw',
-  isa=>BalancerClassNamePart,
-  coerce=>1,
+  isa=>BalancerClassNamePart(coerce=>1),
   required=>1,
   default=> 'DBIx::Class::Storage::DBI::Replicated::Balancer::First',
   handles=>{
@@ -190,7 +180,6 @@ has 'balancer_args' => (
   is=>'rw',
   isa=>HashRef,
   lazy=>1,
-  required=>1,
   default=>sub { {} },
 );
 
@@ -203,8 +192,10 @@ container class for one or more replicated databases.
 
 has 'pool' => (
   is=>'ro',
-  isa=>'DBIx::Class::Storage::DBI::Replicated::Pool',
-  lazy_build=>1,
+  isa=>Object, # 'DBIx::Class::Storage::DBI::Replicated::Pool',
+  lazy=>1,
+  builder=>1,
+  clearer=>1,
   handles=>[qw/
     connect_replicants
     replicants
@@ -221,8 +212,9 @@ is a class that takes a pool (L<DBIx::Class::Storage::DBI::Replicated::Pool>)
 
 has 'balancer' => (
   is=>'rw',
-  isa=>'DBIx::Class::Storage::DBI::Replicated::Balancer',
-  lazy_build=>1,
+  isa=>Object, # 'DBIx::Class::Storage::DBI::Replicated::Balancer',
+  lazy=>1,
+  builder=>1,
   handles=>[qw/auto_validate_every/],
 );
 
@@ -239,7 +231,8 @@ pool of databases that is allowed to handle write traffic.
 has 'master' => (
   is=> 'ro',
   isa=>DBICStorageDBI,
-  lazy_build=>1,
+  lazy=>1,
+  builder=>1,
 );
 
 =head1 ATTRIBUTES IMPLEMENTING THE DBIx::Storage::DBI INTERFACE
@@ -322,7 +315,7 @@ my $method_dispatch = {
     _execute
     _do_query
     _dbh_execute
-  /, Class::MOP::Class->initialize('DBIx::Class::Storage::DBIHacks')->get_method_list ],
+  /, @{Class::Inspector->functions('DBIx::Class::Storage::DBIHacks')} ],
   reader => [qw/
     select
     select_single
@@ -367,10 +360,9 @@ my $method_dispatch = {
     _bind_sth_params
   /,(
     # the capability framework
-    # not sure if CMOP->initialize does evil things to DBIC::S::DBI, fix if a problem
     grep
       { $_ =~ /^ _ (?: use | supports | determine_supports ) _ /x and $_ ne '_use_multicolumn_in' }
-      ( Class::MOP::Class->initialize('DBIx::Class::Storage::DBI')->get_all_method_names )
+      @{Class::Inspector->functions('DBIx::Class::Storage::DBI')}
   )],
 };
 
@@ -401,10 +393,11 @@ if (DBIx::Class::_ENV_::DBICTEST) {
 }
 
 for my $method (@{$method_dispatch->{unimplemented}}) {
-  __PACKAGE__->meta->add_method($method, sub {
+  no strict 'refs';
+  *{$method} = subname $method => sub {
     my $self = shift;
     $self->throw_exception("$method() must not be called on ".(blessed $self).' objects');
-  });
+  };
 }
 
 =head2 read_handler
@@ -416,7 +409,8 @@ Defines an object that implements the read side of L<DBIx::Class::Storage::DBI>.
 has 'read_handler' => (
   is=>'rw',
   isa=>Object,
-  lazy_build=>1,
+  lazy=>1,
+  builder=>1,
   handles=>$method_dispatch->{reader},
 );
 
@@ -432,7 +426,8 @@ run on a replicant.
 has 'write_handler' => (
   is=>'ro',
   isa=>Object,
-  lazy_build=>1,
+  lazy=>1,
+  builder=>1,
   handles=>$method_dispatch->{writer},
 );
 
@@ -499,9 +494,8 @@ around connect_info => sub {
     # Make sure master is blessed into the correct class and apply role to it.
     my $master = $self->master;
     $master->_determine_driver;
-    Moose::Meta::Class->initialize(ref $master);
 
-    DBIx::Class::Storage::DBI::Replicated::WithDSN->meta->apply($master);
+    Moo::Role->apply_roles_to_object($master, 'DBIx::Class::Storage::DBI::Replicated::WithDSN');
 
     # link pool back to master
     $self->pool->master($master);
@@ -1132,6 +1126,4 @@ L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
 
 =cut
 
-__PACKAGE__->meta->make_immutable;
-
 1;
index 26e3580..27b2aff 100644 (file)
@@ -1,11 +1,13 @@
 package DBIx::Class::Storage::DBI::Replicated::Balancer;
 
-use Moose::Role;
+use Moo::Role;
 requires 'next_storage';
-use MooseX::Types::Moose qw/Int/;
+
+use DBIx::Class::_Types qw(PositiveInteger DBICStorageDBI DBICStorageDBIReplicatedPool);
 use DBIx::Class::Storage::DBI::Replicated::Pool;
-use DBIx::Class::Storage::DBI::Replicated::Types qw/DBICStorageDBI/;
-use namespace::clean -except => 'meta';
+use Scalar::Util qw(blessed);
+
+use namespace::clean;
 
 =head1 NAME
 
@@ -36,7 +38,7 @@ will end up validating every query.
 
 has 'auto_validate_every' => (
   is=>'rw',
-  isa=>Int,
+  isa=>PositiveInteger,
   predicate=>'has_auto_validate_every',
 );
 
@@ -63,7 +65,7 @@ balance.
 
 has 'pool' => (
   is=>'ro',
-  isa=>'DBIx::Class::Storage::DBI::Replicated::Pool',
+  isa=>DBICStorageDBIReplicatedPool,
   required=>1,
 );
 
@@ -83,7 +85,8 @@ via its balancer object.
 has 'current_replicant' => (
   is=> 'rw',
   isa=>DBICStorageDBI,
-  lazy_build=>1,
+  lazy=>1,
+  builder=>1,
   handles=>[qw/
     select
     select_single
index c7a160e..0474959 100644 (file)
@@ -1,8 +1,8 @@
 package DBIx::Class::Storage::DBI::Replicated::Balancer::First;
 
-use Moose;
+use Moo;
 with 'DBIx::Class::Storage::DBI::Replicated::Balancer';
-use namespace::clean -except => 'meta';
+use namespace::clean;
 
 =head1 NAME
 
@@ -52,6 +52,4 @@ L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
 
 =cut
 
-__PACKAGE__->meta->make_immutable;
-
 1;
index 6b430f4..46fade3 100644 (file)
@@ -1,9 +1,10 @@
 package DBIx::Class::Storage::DBI::Replicated::Balancer::Random;
 
-use Moose;
+use Moo;
 with 'DBIx::Class::Storage::DBI::Replicated::Balancer';
-use DBIx::Class::Storage::DBI::Replicated::Types 'Weight';
-use namespace::clean -except => 'meta';
+use DBIx::Class::_Types qw(PositiveNumber);
+
+use namespace::clean;
 
 =head1 NAME
 
@@ -43,7 +44,7 @@ any single replicant, if for example you have a very powerful master.
 
 =cut
 
-has master_read_weight => (is => 'rw', isa => Weight, default => sub { 0 });
+has master_read_weight => (is => 'rw', isa => PositiveNumber, default => sub { 0 });
 
 =head1 METHODS
 
@@ -91,6 +92,4 @@ L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
 
 =cut
 
-__PACKAGE__->meta->make_immutable;
-
 1;
index 9980b4d..f8a1c66 100644 (file)
@@ -1,15 +1,14 @@
 package DBIx::Class::Storage::DBI::Replicated::Pool;
 
-use Moose;
+use Moo;
 use DBIx::Class::Storage::DBI::Replicated::Replicant;
 use List::Util 'sum';
 use Scalar::Util 'reftype';
 use DBI ();
-use MooseX::Types::Moose qw/Num Int ClassName HashRef/;
-use DBIx::Class::Storage::DBI::Replicated::Types 'DBICStorageDBI';
+use DBIx::Class::_Types qw(HashRef Number Integer LoadableClass DBICStorageDBI);
 use Try::Tiny;
 
-use namespace::clean -except => 'meta';
+use namespace::clean;
 
 =head1 NAME
 
@@ -43,10 +42,9 @@ return a number of seconds that the replicating database is lagging.
 
 has 'maximum_lag' => (
   is=>'rw',
-  isa=>Num,
-  required=>1,
+  isa=>Number,
   lazy=>1,
-  default=>0,
+  default=>sub { 0 },
 );
 
 =head2 last_validated
@@ -59,11 +57,11 @@ built-in.
 
 has 'last_validated' => (
   is=>'rw',
-  isa=>Int,
+  isa=>Integer,
   reader=>'last_validated',
   writer=>'_last_validated',
   lazy=>1,
-  default=>0,
+  default=>sub { 0 },
 );
 
 =head2 replicant_type ($classname)
@@ -76,7 +74,7 @@ just leave this alone.
 
 has 'replicant_type' => (
   is=>'ro',
-  isa=>ClassName,
+  isa=>LoadableClass,
   required=>1,
   default=>'DBIx::Class::Storage::DBI',
   handles=>{
@@ -125,34 +123,28 @@ Removes the replicant under $key from the pool
 
 has 'replicants' => (
   is=>'rw',
-  traits => ['Hash'],
-  isa=>HashRef['Object'],
+  isa=>HashRef,
   default=>sub {{}},
-  handles  => {
-    'set_replicant' => 'set',
-    'get_replicant' => 'get',
-    'has_replicants' => 'is_empty',
-    'num_replicants' => 'count',
-    'delete_replicant' => 'delete',
-    'all_replicant_storages' => 'values',
-  },
 );
 
-around has_replicants => sub {
-    my ($orig, $self) = @_;
-    return !$self->$orig;
-};
+sub set_replicant { $_[0]->replicants->{$_[1]} = $_[2] }
+sub get_replicant { $_[0]->replicants->{$_[1]} }
+sub has_replicants { !!keys %{$_[0]->replicants} }
+sub num_replicants { 0+keys %{$_[0]->replicants} }
+sub delete_replicant { delete $_[0]->replicants->{$_[1]} }
+sub all_replicant_storages { values %{$_[0]->replicants} }
 
 has next_unknown_replicant_id => (
   is => 'rw',
-  traits => ['Counter'],
-  isa => Int,
+  isa => Integer,
   default => 1,
-  handles => {
-    'inc_unknown_replicant_id' => 'inc',
-  },
 );
 
+sub inc_unknown_replicant_id {
+  my ($self) = @_;
+  $self->next_unknown_replicant_id($self->next_unknown_replicant_id + 1);
+}
+
 =head2 master
 
 Reference to the master Storage.
@@ -252,9 +244,7 @@ sub connect_replicant {
     $replicant->_determine_driver
   });
 
-  Moose::Meta::Class->initialize(ref $replicant);
-
-  DBIx::Class::Storage::DBI::Replicated::Replicant->meta->apply($replicant);
+  Moo::Role->apply_roles_to_object($replicant, 'DBIx::Class::Storage::DBI::Replicated::Replicant');
 
   # link back to master
   $replicant->master($self->master);
@@ -423,6 +413,4 @@ L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
 
 =cut
 
-__PACKAGE__->meta->make_immutable;
-
 1;
index 7c6084b..c84c880 100644 (file)
@@ -1,12 +1,11 @@
 package DBIx::Class::Storage::DBI::Replicated::Replicant;
 
-use Moose::Role;
+use Moo::Role;
 requires qw/_query_start/;
 with 'DBIx::Class::Storage::DBI::Replicated::WithDSN';
-use MooseX::Types::Moose qw/Bool Str/;
-use DBIx::Class::Storage::DBI::Replicated::Types 'DBICStorageDBI';
+use DBIx::Class::_Types qw(Bool Str DBICStorageDBI);
 
-use namespace::clean -except => 'meta';
+use namespace::clean;
 
 =head1 NAME
 
diff --git a/lib/DBIx/Class/Storage/DBI/Replicated/Types.pm b/lib/DBIx/Class/Storage/DBI/Replicated/Types.pm
deleted file mode 100644 (file)
index 0782a6e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package # hide from PAUSE
-  DBIx::Class::Storage::DBI::Replicated::Types;
-
-# DBIx::Class::Storage::DBI::Replicated::Types - Types used internally by
-# L<DBIx::Class::Storage::DBI::Replicated>
-
-# Workaround for https://rt.cpan.org/Public/Bug/Display.html?id=83336
-use warnings;
-use strict;
-
-use MooseX::Types
-  -declare => [qw/BalancerClassNamePart Weight DBICSchema DBICStorageDBI/];
-use MooseX::Types::Moose qw/ClassName Str Num/;
-use MooseX::Types::LoadableClass qw/LoadableClass/;
-
-class_type 'DBIx::Class::Storage::DBI';
-class_type 'DBIx::Class::Schema';
-
-subtype DBICSchema, as 'DBIx::Class::Schema';
-subtype DBICStorageDBI, as 'DBIx::Class::Storage::DBI';
-
-subtype BalancerClassNamePart,
-  as LoadableClass;
-
-coerce BalancerClassNamePart,
-  from Str,
-  via {
-    my $type = $_;
-    $type =~ s/\A::/DBIx::Class::Storage::DBI::Replicated::Balancer::/;
-    $type;
-  };
-
-subtype Weight,
-  as Num,
-  where { $_ >= 0 },
-  message { 'weight must be a decimal greater than 0' };
-
-1;
index 46b1430..b5735ff 100644 (file)
@@ -1,11 +1,12 @@
 package DBIx::Class::Storage::DBI::Replicated::WithDSN;
 
-use Moose::Role;
+use Moo::Role;
 use Scalar::Util 'reftype';
 requires qw/_query_start/;
 
 use Try::Tiny;
-use namespace::clean -except => 'meta';
+
+use namespace::clean;
 
 =head1 NAME
 
index e13228f..79b8517 100644 (file)
@@ -168,5 +168,14 @@ sub DoesDBICStorageReplicatedBalancer {
     unless(Object(@_) && $_[0]->does('DBIx::Class::Storage::DBI::Replicated::Balancer') );
 }
 
+sub BalancerClassNamePart {
+  LoadableClass(@_);
+}
+
+sub coerce_BalancerClassNamePart {
+  (my $name = $_[0] || '') =~ s/\A::/DBIx::Class::Storage::DBI::Replicated::Balancer::/;
+  $name;
+}
+
 1;
 
index 513e3d3..5d57ac6 100755 (executable)
@@ -93,7 +93,7 @@ else
   parallel_installdeps_notest Test::Warn B::Hooks::EndOfScope Test::Differences HTTP::Status
   parallel_installdeps_notest Test::Pod::Coverage Test::EOL Devel::GlobalDestruction Sub::Name MRO::Compat Class::XSAccessor URI::Escape HTML::Entities
   parallel_installdeps_notest YAML LWP Class::Trigger DateTime::Format::Builder Class::Accessor::Grouped Package::Variant
-  parallel_installdeps_notest SQL::Abstract Moose Module::Install@1.15 JSON SQL::Translator File::Which Class::DBI::Plugin
+  parallel_installdeps_notest SQL::Abstract Module::Install@1.15 JSON SQL::Translator File::Which Class::DBI::Plugin
 
   # the official version is very much outdated and does not compile on 5.14+
   # use this rather updated source tree (needs to go to PAUSE):
index 69feec2..4e412a6 100755 (executable)
@@ -12,8 +12,6 @@ export HARNESS_OPTIONS="j$VCPU_USE"
 
 if [[ "$DEVREL_DEPS" == "true" ]] && perl -M5.008003 -e1 &>/dev/null ; then
   # FIXME - these really need to be installed *with* testing under "allowed failures"
-  # Change when Moose goes away
-  parallel_installdeps_notest Moose
   parallel_installdeps_notest $(perl -Ilib -MDBIx::Class::Optional::Dependencies=-list_missing,dist_dir)
 
   run_or_err "Attempt to build a dist" "rm -rf inc/ && perl Makefile.PL --skip-author-deps && make dist"
@@ -39,10 +37,8 @@ if [[ -n "$tarball_assembled" ]] ; then
 
 
   # undo some of the pollution (if any) affecting the plain install deps
-  # FIXME - this will go away once we move off Moose, and a new SQLT
-  # with much less recommends ships
+  # FIXME - this will go away once a new SQLT with much less recommends ships
   export DBICTEST_SQLT_DEPLOY=""
-  export DBICTEST_VIA_REPLICATED=""
 
 
   # make sure we are retrying with newest CPAN possible
index 82c809d..3f14eca 100644 (file)
@@ -4,26 +4,15 @@ use strict;
 use warnings;
 
 use Test::More;
-use DBIx::Class::_Util 'modver_gt_or_eq_and_lt';
 use lib qw(t/lib);
 use DBICTest;
-
-BEGIN {
-  plan skip_all => "A trial version of Moose detected known to break replication - skipping test known to fail" if (
-    DBICTest::RunMode->is_smoker
-      and
-    modver_gt_or_eq_and_lt( 'Moose', '1.99', '1.9903' )
-  )
-}
-
-use Test::Moose;
 use Test::Exception;
 use List::Util 'first';
 use Scalar::Util 'reftype';
+use Class::Inspector;
 use File::Spec;
-use Moose();
-use MooseX::Types();
-note "Using Moose version $Moose::VERSION and MooseX::Types version $MooseX::Types::VERSION";
+use Moo::Role ();
+use IO::Handle;
 
 my $var_dir = quotemeta ( File::Spec->catdir(qw/t var/) );
 
@@ -32,9 +21,7 @@ use DBIx::Class::Storage::DBI::Replicated;
 {
     package DBIx::Class::Storage::DBI::Replicated;
 
-    use Moose;
-
-    __PACKAGE__->meta->make_mutable;
+    use Moo;
 
     around connect_info => sub {
       my ($next, $self, $info) = @_;
@@ -42,12 +29,14 @@ use DBIx::Class::Storage::DBI::Replicated;
       $self->$next($info);
     };
 
-    __PACKAGE__->meta->make_immutable;
-
-    no Moose;
 }
 
-
+sub does_ok ($$;$) {
+  my ($thing, $role, $desc) = @_;
+  $desc ||= "The object does $role";
+  local $Test::Builder::Level = $Test::Builder::Level + 1;
+  ok Moo::Role::does_role($thing, $role), $desc;
+}
 
 =head1 HOW TO USE
 
@@ -270,11 +259,9 @@ for my $method (qw/by_connect_info by_storage_type/) {
 
 ### check that all Storage::DBI methods are handled by ::Replicated
 {
-  my @storage_dbi_methods = Class::MOP::Class
-    ->initialize('DBIx::Class::Storage::DBI')->get_all_method_names;
+  my @storage_dbi_methods = @{Class::Inspector->methods('DBIx::Class::Storage::DBI')};
 
-  my @replicated_methods  = DBIx::Class::Storage::DBI::Replicated->meta
-    ->get_all_method_names;
+  my @replicated_methods  = @{Class::Inspector->methods('DBIx::Class::Storage::DBI::Replicated')};
 
 # remove constants and OTHER_CRAP
   @storage_dbi_methods = grep !/^[A-Z_]+\z/, @storage_dbi_methods;
@@ -283,8 +270,7 @@ for my $method (qw/by_connect_info by_storage_type/) {
   @storage_dbi_methods = grep !/_accessor\z/, @storage_dbi_methods;
 
 # remove DBIx::Class (the root parent, with CAG and stuff) methods
-  my @root_methods = Class::MOP::Class->initialize('DBIx::Class')
-    ->get_all_method_names;
+  my @root_methods = @{Class::Inspector->methods('DBIx::Class')};
   my %count;
   $count{$_}++ for (@storage_dbi_methods, @root_methods);
 
@@ -318,9 +304,6 @@ for my $method (qw/by_connect_info by_storage_type/) {
   }
 }
 
-ok $replicated->schema->storage->meta
-    => 'has a meta object';
-
 isa_ok $replicated->schema->storage->master
     => 'DBIx::Class::Storage::DBI';
 
index 565216f..ae65b96 100644 (file)
@@ -68,9 +68,6 @@ 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',
-
   # G::L::D is unclean, but we never inherit from it
   'DBIx::Class::Admin::Descriptive',
   'DBIx::Class::Admin::Usage',