1 package DBIx::Class::Schema::Loader::Optional::Dependencies;
3 ### This may look crazy, but it in fact tangibly ( by 50(!)% ) shortens
4 # the skip-test time when everything requested is unavailable
6 if ( $ENV{RELEASE_TESTING} ) {
7 require warnings and warnings->import;
8 require strict and strict->import;
18 # NO EXTERNAL NON-5.8.1 CORE DEPENDENCIES EVER (e.g. C::A::G)
19 # This module is to be loaded by Makefile.PM on a pristine system
21 # POD is generated automatically by calling _gen_pod from the
22 # Makefile.PL in $AUTHOR mode
29 'MooseX::NonMoose' => '0.25',
30 'namespace::autoclean' => '0.09',
31 'MooseX::MarkAsMethods' => '0.13',
35 desc => 'Modules required for the use_moose option',
44 title => 'dbicdump config file',
45 desc => 'Modules required for using a config file with dbicdump',
49 test_dbicdump_config => {
50 include => 'dbicdump_config',
52 'Config::General' => '0',
55 title => 'dbicdump config file testing',
56 desc => 'Modules required for using testing using a config file with dbicdump',
60 _rdbms_generic_odbc => {
66 _rdbms_generic_ado => {
72 # must list any dep used by adhoc testing
73 # this prevents the "skips due to forgotten deps" issue
81 'Math::BigInt' => '1.80',
82 'Math::Base36' => '0.07',
88 'Test::Pod' => '1.14',
89 'Pod::Simple' => '3.22',
92 title => 'POD testing',
93 desc => 'Modules required for testing POD in this distribution',
95 release_testing_mandatory => 1,
100 'Test::Pod::Coverage' => '1.08',
101 'Pod::Coverage' => '0.20',
103 release_testing_mandatory => 1,
108 'Test::EOL' => '1.0',
109 'Test::NoTabs' => '0.9',
111 release_testing_mandatory => 1,
116 'Test::Strict' => '0.20',
118 release_testing_mandatory => 1,
123 SCHEMA_LOADER_TESTS_BACKCOMPAT => 1,
127 # this is just for completeness as SQLite
128 # is a core dep of DBIC for testing
134 title => 'SQLite support',
135 desc => 'Modules required to connect to SQLite',
143 # when changing this list make sure to adjust xt/optional_deps.t
147 title => 'PostgreSQL support',
148 desc => 'Modules required to connect to PostgreSQL',
152 _rdbms_mssql_common => {
155 rdbms_mssql_odbc => {
156 include => [qw( _rdbms_generic_odbc _rdbms_mssql_common )],
158 title => 'MSSQL support via DBD::ODBC',
159 desc => 'Modules required to connect to MSSQL via DBD::ODBC',
163 rdbms_mssql_sybase => {
164 include => '_rdbms_mssql_common',
169 title => 'MSSQL support via DBD::Sybase',
170 desc => 'Modules required to connect to MSSQL via DBD::Sybase',
175 include => [qw( _rdbms_generic_ado _rdbms_mssql_common )],
177 title => 'MSSQL support via DBD::ADO (Windows only)',
178 desc => 'Modules required to connect to MSSQL via DBD::ADO. This particular DBD is available on Windows only',
182 _rdbms_msaccess_common => {
185 rdbms_msaccess_odbc => {
186 include => [qw( _rdbms_generic_odbc _rdbms_msaccess_common )],
188 title => 'MS Access support via DBD::ODBC',
189 desc => 'Modules required to connect to MS Access via DBD::ODBC',
193 rdbms_msaccess_ado => {
194 include => [qw( _rdbms_generic_ado _rdbms_msaccess_common )],
196 title => 'MS Access support via DBD::ADO (Windows only)',
197 desc => 'Modules required to connect to MS Access via DBD::ADO. This particular DBD is available on Windows only',
206 title => 'MySQL support',
207 desc => 'Modules required to connect to MySQL',
212 include => 'id_shortener',
217 title => 'Oracle support',
218 desc => 'Modules required to connect to Oracle',
229 title => 'Sybase ASE support',
230 desc => 'Modules required to connect to Sybase ASE',
239 title => 'DB2 support',
240 desc => 'Modules required to connect to DB2',
246 'DBD::Informix' => 0,
249 title => 'Informix support',
250 desc => 'Modules required to connect to Informix',
254 _rdbms_sqlanywhere_common => {
257 rdbms_sqlanywhere => {
258 include => '_rdbms_sqlanywhere_common',
260 'DBD::SQLAnywhere' => 0,
263 title => 'SQLAnywhere support',
264 desc => 'Modules required to connect to SQLAnywhere',
268 rdbms_sqlanywhere_odbc => {
269 include => [qw( _rdbms_generic_odbc _rdbms_sqlanywhere_common )],
271 title => 'SQLAnywhere support via DBD::ODBC',
272 desc => 'Modules required to connect to SQLAnywhere via DBD::ODBC',
276 _rdbms_firebird_common => {
280 include => '_rdbms_firebird_common',
282 'DBD::Firebird' => 0,
285 title => 'Firebird support',
286 desc => 'Modules required to connect to Firebird',
290 rdbms_firebird_interbase => {
291 include => '_rdbms_firebird_common',
293 'DBD::InterBase' => 0,
296 title => 'Firebird support via DBD::InterBase',
297 desc => 'Modules required to connect to Firebird via DBD::InterBase',
301 rdbms_firebird_odbc => {
302 include => [qw( _rdbms_generic_odbc _rdbms_firebird_common )],
304 title => 'Firebird support via DBD::ODBC',
305 desc => 'Modules required to connect to Firebird via DBD::ODBC',
309 test_rdbms_sqlite => {
310 include => 'rdbms_sqlite',
313 ### IMPORTANT - do not raise this dependency
314 ### even though many bugfixes are present in newer versions, the general DBIC
315 ### rule is to bend over backwards for available DBDs (given upgrading them is
316 ### often *not* easy or even possible)
318 'DBD::SQLite' => '1.29',
323 include => 'rdbms_pg',
325 DBICTEST_PG_DSN => 1,
326 DBICTEST_PG_USER => 0,
327 DBICTEST_PG_PASS => 0,
330 # the order does matter because the rdbms support group might require
331 # a different version that the test group
333 # when changing this list make sure to adjust xt/optional_deps.t
334 'DBD::Pg' => '2.009002', # specific version to test bytea
338 test_rdbms_mssql_odbc => {
339 include => 'rdbms_mssql_odbc',
341 DBICTEST_MSSQL_ODBC_DSN => 1,
342 DBICTEST_MSSQL_ODBC_USER => 0,
343 DBICTEST_MSSQL_ODBC_PASS => 0,
347 test_rdbms_mssql_ado => {
348 include => 'rdbms_mssql_ado',
350 DBICTEST_MSSQL_ADO_DSN => 1,
351 DBICTEST_MSSQL_ADO_USER => 0,
352 DBICTEST_MSSQL_ADO_PASS => 0,
356 test_rdbms_mssql_sybase => {
357 include => 'rdbms_mssql_sybase',
359 DBICTEST_MSSQL_DSN => 1,
360 DBICTEST_MSSQL_USER => 0,
361 DBICTEST_MSSQL_PASS => 0,
365 test_rdbms_msaccess_odbc => {
366 include => 'rdbms_msaccess_odbc',
368 DBICTEST_MSACCESS_ODBC_DSN => 1,
369 DBICTEST_MSACCESS_ODBC_USER => 0,
370 DBICTEST_MSACCESS_ODBC_PASS => 0,
377 test_rdbms_msaccess_ado => {
378 include => 'rdbms_msaccess_ado',
380 DBICTEST_MSACCESS_ADO_DSN => 1,
381 DBICTEST_MSACCESS_ADO_USER => 0,
382 DBICTEST_MSACCESS_ADO_PASS => 0,
389 test_rdbms_mysql => {
390 include => 'rdbms_mysql',
392 DBICTEST_MYSQL_DSN => 1,
393 DBICTEST_MYSQL_USER => 0,
394 DBICTEST_MYSQL_PASS => 0,
398 test_rdbms_oracle => {
399 include => 'rdbms_oracle',
401 DBICTEST_ORA_DSN => 1,
402 DBICTEST_ORA_USER => 0,
403 DBICTEST_ORA_PASS => 0,
406 'DBD::Oracle' => '1.24',
411 include => 'rdbms_ase',
413 DBICTEST_SYBASE_DSN => 1,
414 DBICTEST_SYBASE_USER => 0,
415 DBICTEST_SYBASE_PASS => 0,
420 include => 'rdbms_db2',
422 DBICTEST_DB2_DSN => 1,
423 DBICTEST_DB2_USER => 0,
424 DBICTEST_DB2_PASS => 0,
428 test_rdbms_informix => {
429 include => 'rdbms_informix',
431 DBICTEST_INFORMIX_DSN => 1,
432 DBICTEST_INFORMIX_USER => 0,
433 DBICTEST_INFORMIX_PASS => 0,
437 test_rdbms_sqlanywhere => {
438 include => 'rdbms_sqlanywhere',
440 DBICTEST_SQLANYWHERE_DSN => 1,
441 DBICTEST_SQLANYWHERE_USER => 0,
442 DBICTEST_SQLANYWHERE_PASS => 0,
446 test_rdbms_sqlanywhere_odbc => {
447 include => 'rdbms_sqlanywhere_odbc',
449 DBICTEST_SQLANYWHERE_ODBC_DSN => 1,
450 DBICTEST_SQLANYWHERE_ODBC_USER => 0,
451 DBICTEST_SQLANYWHERE_ODBC_PASS => 0,
455 test_rdbms_firebird => {
456 include => 'rdbms_firebird',
458 DBICTEST_FIREBIRD_DSN => 1,
459 DBICTEST_FIREBIRD_USER => 0,
460 DBICTEST_FIREBIRD_PASS => 0,
464 test_rdbms_firebird_interbase => {
465 include => 'rdbms_firebird_interbase',
467 DBICTEST_FIREBIRD_INTERBASE_DSN => 1,
468 DBICTEST_FIREBIRD_INTERBASE_USER => 0,
469 DBICTEST_FIREBIRD_INTERBASE_PASS => 0,
473 test_rdbms_firebird_odbc => {
474 include => 'rdbms_firebird_odbc',
476 DBICTEST_FIREBIRD_ODBC_DSN => 1,
477 DBICTEST_FIREBIRD_ODBC_USER => 0,
478 DBICTEST_FIREBIRD_ODBC_PASS => 0,
495 if ($action eq '-die_without') {
499 eval { $class->die_unless_req_ok_for(\@_); 1 }
502 die "\n$err\n" if $err;
504 elsif ($action eq '-list_missing') {
505 print $class->modreq_missing_for(\@_);
509 elsif ($action eq '-skip_all_without') {
511 # sanity check - make sure ->current_test is 0 and no plan has been declared
515 Test::Builder->new->current_test
517 Test::Builder->new->has_plan
519 } and croak("Unable to invoke -skip_all_without after testing has started");
521 if ( my $missing = $class->req_missing_for(\@_) ) {
523 die ("\nMandatory requirements not satisfied during release-testing: $missing\n\n")
524 if $ENV{RELEASE_TESTING} and $class->_groups_to_reqs(\@_)->{release_testing_mandatory};
526 print "1..0 # SKIP requirements not satisfied: $missing\n";
530 elsif ($action =~ /^-/) {
531 croak "Unknown import-time action '$action'";
534 croak "$class is not an exporter, unable to import '$action'";
542 croak( __PACKAGE__ . " does not implement unimport" );
545 # OO for (mistakenly considered) ease of extensibility, not due to any need to
546 # carry state of any sort. This API is currently used outside, so leave as-is.
547 # FIXME - make sure to not propagate this further if module is extracted as a
548 # standalone library - keep the stupidity to a DBIC-secific shim!
551 shift->_groups_to_reqs(shift)->{effective_modreqs};
554 sub modreq_list_for {
555 shift->_groups_to_reqs(shift)->{modreqs};
560 { $_ => $_[0]->_groups_to_reqs($_) }
561 grep { $_ !~ /^_/ } keys %$dbic_reqs
565 sub req_errorlist_for { shift->modreq_errorlist_for(shift) } # deprecated
566 sub modreq_errorlist_for {
567 my ($self, $groups) = @_;
568 $self->_errorlist_for_modreqs( $self->_groups_to_reqs($groups)->{modreqs} );
572 shift->req_missing_for(shift) ? 0 : 1;
575 sub req_missing_for {
576 my ($self, $groups) = @_;
578 my $reqs = $self->_groups_to_reqs($groups);
580 my $mods_missing = $reqs->{missing_envvars}
581 ? $self->_list_physically_missing_modules( $reqs->{modreqs} )
582 : $self->modreq_missing_for($groups)
588 ! $reqs->{missing_envvars}
591 my @res = $mods_missing || ();
593 push @res, 'the following group(s) of environment variables: ' . join ' and ', sort map
594 { __envvar_group_desc($_) }
595 @{$reqs->{missing_envvars}}
596 if $reqs->{missing_envvars};
599 ( join ' as well as ', @res )
601 ( $reqs->{modreqs_fully_documented} ? " (see @{[ ref $self || $self ]} documentation for details)" : '' ),
605 sub modreq_missing_for {
606 my ($self, $groups) = @_;
608 my $reqs = $self->_groups_to_reqs($groups);
609 my $modreq_errors = $self->_errorlist_for_modreqs($reqs->{modreqs})
613 { $reqs->{modreqs}{$_} ? "$_~$reqs->{modreqs}{$_}" : $_ }
614 sort { lc($a) cmp lc($b) } keys %$modreq_errors
620 my ($self, $groups) = @_;
622 $tb ||= do { local $@; eval { Test::Builder->new } }
623 or croak "Calling skip_without() before loading Test::Builder makes no sense";
625 if ( my $err = $self->req_missing_for($groups) ) {
626 my ($fn, $ln) = (caller(0))[1,2];
627 $tb->skip("block in $fn around line $ln requires $err");
635 sub die_unless_req_ok_for {
636 if (my $err = shift->req_missing_for(shift) ) {
637 die "Unable to continue due to missing requirements: $err\n";
643 ### Private functions
645 # potentially shorten group desc
646 sub __envvar_group_desc {
649 my (@res, $last_prefix);
650 while (my $ev = shift @envs) {
651 my ($pref, $sep, $suff) = split / ([\_\-]) (?= [^\_\-]+ \z )/x, $ev;
653 if ( defined $sep and ($last_prefix||'') eq $pref ) {
654 push @res, "...${sep}${suff}"
660 $last_prefix = $pref if $sep;
666 my $groupname_re = qr/ [a-z_] [0-9_a-z]* /x;
667 my $modname_re = qr/ [A-Z_a-z] [0-9A-Z_a-z]* (?:::[0-9A-Z_a-z]+)* /x;
668 my $modver_re = qr/ [0-9]+ (?: \. [0-9]+ )? /x;
670 # Expand includes from a random group in a specific order:
671 # nonvariable groups first, then their includes, then the variable groups,
672 # then their includes.
673 # This allows reliably marking the rest of the mod reqs as variable (this is
674 # also why variable includes are currently not allowed)
675 sub __expand_includes {
676 my ($groups, $seen) = @_;
678 # !! DIFFERENT !! behavior and return depending on invocation mode
679 # (easier to recurse this way)
680 my $is_toplevel = $seen
685 my ($res_per_type, $missing_envvars);
687 # breadth-first evaluation, with non-variable includes on top
688 for my $g (@$groups) {
690 croak "Invalid requirement group name '$g': only ascii alphanumerics and _ are allowed"
691 if $g !~ qr/ \A $groupname_re \z/x;
693 my $r = $dbic_reqs->{$g}
694 or croak "Requirement group '$g' is not defined";
696 # always do this check *before* the $seen check
697 croak "Group '$g' with variable effective_modreqs can not be specified as an 'include'"
698 if ( $r->{env} and ! $is_toplevel );
700 next if $seen->{$g}++;
702 my $req_type = 'static';
704 if ( my @e = @{$r->{env}||[]} ) {
706 croak "Unexpected 'env' attribute under group '$g' (only allowed in test_* groups)"
707 unless $g =~ /^test_/;
709 croak "Unexpected *odd* list in 'env' under group '$g'"
712 # deconstruct the whole thing
713 my (@group_envnames_list, $some_envs_required, $some_required_missing);
715 push @group_envnames_list, my $envname = shift @e;
717 # env required or not
718 next unless shift @e;
720 $some_envs_required ||= 1;
722 $some_required_missing ||= (
723 ! defined $ENV{$envname}
725 ! length $ENV{$envname}
729 croak "None of the envvars in group '$g' declared as required, making the requirement moot"
730 unless $some_envs_required;
732 if ($some_required_missing) {
733 push @{$missing_envvars->{$g}}, \@group_envnames_list;
734 $req_type = 'variable';
738 push @{$res_per_type->{"base_${req_type}"}}, $g;
740 if (my $i = $dbic_reqs->{$g}{include}) {
741 $i = [ $i ] unless ref $i eq 'ARRAY';
743 croak "Malformed 'include' for group '$g': must be another existing group name or arrayref of existing group names"
746 push @{$res_per_type->{"incs_${req_type}"}}, @$i;
751 @{ $res_per_type->{"base_${_}"} || [] },
752 ( $res_per_type->{"incs_${_}"} ? __expand_includes( $res_per_type->{"incs_${_}"}, $seen ) : () ),
753 } qw(static variable);
755 return ! $is_toplevel ? @ret : do {
758 idx => 1 + keys %$rv,
759 missing_envvars => $missing_envvars->{$_},
761 $rv->{$_}{user_requested} = 1 for @$groups;
767 our %req_unavailability_cache;
769 # this method is just a lister and envvar/metadata checker - it does not try to load anything
770 sub _groups_to_reqs {
771 my ($self, $want) = @_;
773 $want = [ $want || () ]
774 unless ref $want eq 'ARRAY';
776 croak "@{[ (caller(1))[3] ]}() expects a requirement group name or arrayref of group names"
781 modreqs_fully_documented => 1,
785 for my $piece (@$want) {
786 if ($piece =~ qr/ \A $groupname_re \z /x) {
787 push @$groups, $piece;
789 elsif ( my ($mod, $ver) = $piece =~ qr/ \A ($modname_re) \>\= ($modver_re) \z /x ) {
790 croak "Ad hoc module specification lists '$mod' twice"
791 if exists $ret->{modreqs}{$mod};
793 croak "Ad hoc module specification '${mod} >= $ver' (or greater) not listed in the test_adhoc optdep group" if (
794 ! defined $dbic_reqs->{test_adhoc}{req}{$mod}
796 $dbic_reqs->{test_adhoc}{req}{$mod} < $ver
799 $ret->{modreqs}{$mod} = $ver;
800 $ret->{modreqs_fully_documented} = 0;
803 croak "Unsupported argument '$piece' supplied to @{[ (caller(1))[3] ]}()"
807 my $all_groups = __expand_includes($groups);
809 # pre-assemble list of augmentations, perform basic sanity checks
810 # Note that below we *DO NOT* respect the source/target reationship, but
811 # instead always default to augment the "later" group
812 # This is done so that the "stable/variable" boundary keeps working as
815 for my $requesting_group (keys %$all_groups) {
816 if (my $ag = $dbic_reqs->{$requesting_group}{augment}) {
817 for my $target_group (keys %$ag) {
819 croak "Group '$requesting_group' claims to augment a non-existent group '$target_group'"
820 unless $dbic_reqs->{$target_group};
822 croak "Augmentation combined with variable effective_modreqs currently unsupported for group '$requesting_group'"
823 if $dbic_reqs->{$requesting_group}{env};
825 croak "Augmentation of group '$target_group' with variable effective_modreqs unsupported (requested by '$requesting_group')"
826 if $dbic_reqs->{$target_group}{env};
828 if (my @foreign = grep { $_ ne 'req' } keys %{$ag->{$target_group}} ) {
829 croak "Only 'req' augmentations are currently supported (group '$requesting_group' attempts to alter '$foreign[0]' of group '$target_group'";
832 $ret->{augments}{$target_group} = 1;
834 # no augmentation for stuff that hasn't been selected
835 if ( $all_groups->{$target_group} and my $ar = $ag->{$target_group}{req} ) {
836 push @{$augmentations->{
837 ( $all_groups->{$requesting_group}{idx} < $all_groups->{$target_group}{idx} )
846 for my $group (sort { $all_groups->{$a}{idx} <=> $all_groups->{$b}{idx} } keys %$all_groups ) {
848 my $group_reqs = $dbic_reqs->{$group}{req};
851 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
852 for (keys %$req_bag) {
854 $_ =~ / \A $modname_re \z /x
855 or croak "Requirement '$_' in group '$group' is not a valid module name";
857 # !!!DO NOT CHANGE!!!
858 # remember - version.pm may not be available on the system
859 croak "Requirement '$_' in group '$group' specifies an invalid version '$req_bag->{$_}' (only plain non-underscored floating point decimals are supported)"
860 if ( ($req_bag->{$_}||0) !~ qr/ \A $modver_re \z /x );
864 if (my $e = $all_groups->{$group}{missing_envvars}) {
865 push @{$ret->{missing_envvars}}, @$e;
868 # assemble into the final ret
871 ( $ret->{missing_envvars} ? () : 'effective_modreqs' ),
873 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
874 for my $mod (keys %$req_bag) {
876 $ret->{$type}{$mod} = $req_bag->{$mod}||0 if (
878 ! exists $ret->{$type}{$mod}
880 # we sanitized the version to be numeric above - we can just -gt it
881 ($req_bag->{$mod}||0) > $ret->{$type}{$mod}
888 $ret->{modreqs_fully_documented} &&= !!$dbic_reqs->{$group}{pod}
889 if $all_groups->{$group}{user_requested};
891 $ret->{release_testing_mandatory} ||= !!$dbic_reqs->{$group}{release_testing_mandatory};
898 # this method tries to find/load specified modreqs and returns a hashref of
899 # module/loaderror pairs for anything that failed
900 sub _errorlist_for_modreqs {
901 # args supposedly already went through _groups_to_reqs and are therefore sanitized
902 # safe to eval at will
903 my ($self, $reqs) = @_;
907 for my $m ( keys %$reqs ) {
910 if (! exists $req_unavailability_cache{$m}{$v} ) {
912 eval( "require $m;" . ( $v ? "$m->VERSION(q($v))" : '' ) );
913 $req_unavailability_cache{$m}{$v} = $@;
916 $ret->{$m} = $req_unavailability_cache{$m}{$v}
917 if $req_unavailability_cache{$m}{$v};
923 # Unlike the above DO NOT try to load anything
924 # This is executed when some needed envvars are not available
925 # which in turn means a module load will never be reached anyway
926 # This is important because some modules (especially DBDs) can be
927 # *really* fickle when a require() is attempted, with pretty confusing
928 # side-effects (especially on windows)
929 sub _list_physically_missing_modules {
930 my ($self, $modreqs) = @_;
932 # in case there is a coderef in @INC there is nothing we can definitively prove
933 # so short circuit directly
934 return '' if grep { length ref $_ } @INC;
936 my @definitely_missing;
937 for my $mod (keys %$modreqs) {
938 (my $fn = $mod . '.pm') =~ s|::|/|g;
940 push @definitely_missing, $mod unless grep
941 # this should work on any combination of slashes
942 { $_ and -d $_ and -f "$_/$fn" and -r "$_/$fn" }
948 { $modreqs->{$_} ? "$_~$modreqs->{$_}" : $_ }
949 sort { lc($a) cmp lc($b) } @definitely_missing
954 # This is to be called by the author only (automatically in Makefile.PL)
956 my ($class, $distver, $pod_dir) = @_;
958 die "No POD root dir supplied" unless $pod_dir;
962 require DBIx::Class::Schema::Loader;
963 DBIx::Class::Schema::Loader->VERSION;
966 "\n\n---------------------------------------------------------------------\n" .
967 'Unable to load core DBIx::Class::Schema::Loader module to determine current version, '.
968 'possibly due to missing dependencies. Author-mode autodocumentation ' .
970 "\n\n---------------------------------------------------------------------\n"
973 # do not ask for a recent version, use 1.x API calls
974 # this *may* execute on a smoker with old perl or whatnot
977 (my $modfn = __PACKAGE__ . '.pm') =~ s|::|/|g;
979 (my $podfn = "$pod_dir/$modfn") =~ s/\.pm$/\.pod/;
980 (my $dir = $podfn) =~ s|/[^/]+$||;
982 File::Path::mkpath([$dir]);
984 my $moosever = $class->req_list_for('use_moose')->{'Moose'}
985 or die "Hrmm? No Moose dep?";
993 push @chunks, <<"EOC";
994 #########################################################################
995 ##################### A U T O G E N E R A T E D ########################
996 #########################################################################
998 # The contents of this POD file are auto-generated. Any changes you make
999 # will be lost. If you need to change the generated text edit _gen_pod()
1000 # at the end of $modfn
1005 $class - Optional module dependency specifications (for module authors)
1010 #@@ SYNOPSIS HEADING
1012 push @chunks, <<"EOC";
1015 Somewhere in your build-file (e.g. L<ExtUtils::MakeMaker>'s F<Makefile.PL>):
1019 \$EUMM_ARGS{CONFIGURE_REQUIRES} = {
1020 \%{ \$EUMM_ARGS{CONFIGURE_REQUIRES} || {} },
1021 'DBIx::Class::Schema::Loader' => '$distver',
1026 my %DBIC_CONFIG_AND_ORACLE_DEPS = %{ eval {
1028 $class->req_list_for([qw( dbicdump_config rdbms_oracle )]);
1031 \$EUMM_ARGS{PREREQ_PM} = {
1032 \%DBIC_CONFIG_AND_ORACLE_DEPS,
1033 \%{ \$EUMM_ARGS{PREREQ_PM} || {} },
1038 ExtUtils::MakeMaker::WriteMakefile(\%EUMM_ARGS);
1040 B<Note>: The C<eval> protection within the example is due to support for
1041 requirements during L<the C<configure> build phase|CPAN::Meta::Spec/Phases>
1042 not being available on a sufficient portion of production installations of
1043 Perl. Robust support for such dependency requirements is available in the
1044 L<CPAN> installer only since version C<1.94_56> first made available for
1045 production with perl version C<5.12>. It is the belief of the current
1046 maintainer that support for requirements during the C<configure> build phase
1047 will not be sufficiently ubiquitous until the B<year 2020> at the earliest,
1048 hence the extra care demonstrated above. It should also be noted that some
1049 3rd party installers (e.g. L<cpanminus|App::cpanminus>) do the right thing
1050 with configure requirements independent from the versions of perl and CPAN
1056 #@@ DESCRIPTION HEADING
1058 push @chunks, <<'EOC';
1061 Some of the less-frequently used features of L<DBIx::Class::Schema::Loader> have external
1062 module dependencies on their own. In order not to burden the average user
1063 with modules they will never use, these optional dependencies are not included
1064 in the base Makefile.PL. Instead an exception with a descriptive message is
1065 thrown when a specific feature can't find one or several modules required for
1066 its operation. This module is the central holding place for the current list
1067 of such dependencies, for DBIx::Class::Schema::Loader core authors, and DBIx::Class::Schema::Loader extension
1070 Dependencies are organized in L<groups|/CURRENT REQUIREMENT GROUPS> where each
1071 group can list one or more required modules, with an optional minimum version
1072 (or 0 for any version). In addition groups prefixed with C<test_> can specify
1073 a set of environment variables, some (or all) of which are marked as required
1074 for the group to be considered by L</req_list_for>
1076 Each group name (or a combination thereof) can be used in the
1077 L<public methods|/METHODS> as described below.
1082 #@@ REQUIREMENT GROUPLIST HEADING
1084 push @chunks, '=head1 CURRENT REQUIREMENT GROUPS';
1086 my $standalone_info;
1088 for my $group (sort keys %$dbic_reqs) {
1090 my $info = $standalone_info->{$group} ||= $class->_groups_to_reqs($group);
1093 $info->{modreqs_fully_documented}
1095 ( $info->{augments} or $info->{modreqs} )
1098 my $p = $dbic_reqs->{$group}{pod};
1101 "=head2 $p->{title}",
1107 if ( keys %{ $info->{modreqs}||{} } ) {
1109 { "=item * $_" . ($info->{modreqs}{$_} ? " >= $info->{modreqs}{$_}" : '') }
1110 ( sort keys %{ $info->{modreqs} } )
1114 push @chunks, '=item * No standalone requirements',
1117 push @chunks, '=back';
1119 for my $ag ( sort keys %{ $info->{augments} || {} } ) {
1120 my $ag_info = $standalone_info->{$ag} ||= $class->_groups_to_reqs($ag);
1122 my $newreqs = $class->modreq_list_for([ $group, $ag ]);
1123 for (keys %$newreqs) {
1124 delete $newreqs->{$_} if (
1125 ( defined $info->{modreqs}{$_} and $info->{modreqs}{$_} == $newreqs->{$_} )
1127 ( defined $ag_info->{modreqs}{$_} and $ag_info->{modreqs}{$_} == $newreqs->{$_} )
1131 if (keys %$newreqs) {
1133 "Combined with L</$ag> additionally requires:",
1136 { "=item * $_" . ($newreqs->{$_} ? " >= $newreqs->{$_}" : '') }
1137 ( sort keys %$newreqs )
1147 #@@ API DOCUMENTATION HEADING
1149 push @chunks, <<'EOC';
1151 =head1 IMPORT-LIKE ACTIONS
1153 Even though this module is not an L<Exporter>, it recognizes several C<actions>
1154 supplied to its C<import> method.
1156 =head2 -skip_all_without
1160 =item Arguments: @group_names
1164 A convenience wrapper for use during testing:
1167 push @chunks, " use $class -skip_all_without => qw(admin test_rdbms_mysql);";
1169 push @chunks, 'Roughly equivalent to the following code:';
1171 push @chunks, sprintf <<'EOS', ($class) x 2;
1175 if ( my $missing = %s->req_missing_for(\@group_names_) ) {
1176 print "1..0 # SKIP requirements not satisfied: $missing\n";
1182 push @chunks, <<'EOC';
1184 It also takes into account the C<RELEASE_TESTING> environment variable and
1185 behaves like L</-die_without> for any requirement groups marked as
1186 C<release_testing_mandatory>.
1192 =item Arguments: @group_names
1196 A convenience wrapper around L</die_unless_req_ok_for>:
1199 push @chunks, " use $class -die_without => qw(deploy admin);";
1201 push @chunks, <<'EOC';
1203 =head2 -list_missing
1207 =item Arguments: @group_names
1211 A convenience wrapper around L</modreq_missing_for>:
1213 perl -Ilib -MDBIx::Class::Schema::Loader::Optional::Dependencies=-list_missing,dbicdump_config,rdbms_oracle | cpanm
1217 =head2 req_group_list
1221 =item Arguments: none
1223 =item Return Value: \%list_of_requirement_groups
1227 This method should be used by DBIx::Class::Schema::Loader packagers, to get a hashref of all
1228 dependencies B<keyed> by dependency group. Each key (group name), or a combination
1229 thereof (as an arrayref) can be supplied to the methods below.
1230 The B<values> of the returned hash are currently a set of options B<without a
1231 well defined structure>. If you have use for any of the contents - contact the
1232 maintainers, instead of treating this as public (left alone stable) API.
1238 =item Arguments: $group_name | \@group_names
1240 =item Return Value: \%set_of_module_version_pairs
1244 This method should be used by DBIx::Class::Schema::Loader extension authors, to determine the
1245 version of modules a specific set of features requires for this version of
1246 DBIx::Class::Schema::Loader (regardless of their availability on the system).
1247 See the L</SYNOPSIS> for a real-world example.
1249 When handling C<test_*> groups this method behaves B<differently> from
1250 L</modreq_list_for> below (and is the only such inconsistency among the
1251 C<req_*> methods). If a particular group declares as requirements some
1252 C<environment variables> and these requirements are not satisfied (the envvars
1253 are unset) - then the C<module requirements> of this group are not included in
1256 =head2 modreq_list_for
1260 =item Arguments: $group_name | \@group_names
1262 =item Return Value: \%set_of_module_version_pairs
1266 Same as L</req_list_for> but does not take into consideration any
1267 C<environment variable requirements> - returns just the list of required
1274 =item Arguments: $group_name | \@group_names
1276 =item Return Value: 1|0
1280 Returns true or false depending on whether all modules/envvars required by
1281 the group(s) are loadable/set on the system.
1283 =head2 req_missing_for
1287 =item Arguments: $group_name | \@group_names
1289 =item Return Value: $error_message_string
1293 Returns a single-line string suitable for inclusion in larger error messages.
1294 This method would normally be used by DBIx::Class::Schema::Loader core features, to indicate to
1295 the user that they need to install specific modules and/or set specific
1296 environment variables before being able to use a specific feature set.
1298 For example if some of the requirements for C<deploy> are not available,
1299 the returned string could look like:
1302 push @chunks, qq{ "Moose~$moosever" (see $class documentation for details)};
1304 push @chunks, <<'EOC';
1305 The author is expected to prepend the necessary text to this message before
1306 returning the actual error seen by the user. See also L</modreq_missing_for>
1308 =head2 modreq_missing_for
1312 =item Arguments: $group_name | \@group_names
1314 =item Return Value: $error_message_string
1318 Same as L</req_missing_for> except that the error string is guaranteed to be
1319 either empty, or contain a set of module requirement specifications suitable
1320 for piping to e.g. L<cpanminus|App::cpanminus>. The method explicitly does not
1321 attempt to validate the state of required environment variables (if any).
1323 For instance if some of the requirements for C<deploy> are not available,
1324 the returned string could look like:
1327 push @chunks, qq{ "Moose~$moosever"};
1329 push @chunks, <<'EOC';
1331 See also L</-list_missing>.
1337 =item Arguments: $group_name | \@group_names
1341 A convenience wrapper around L<skip|Test::More/SKIP>. It does not take neither
1342 a reason (it is generated by L</req_missing_for>) nor an amount of skipped tests
1343 (it is always C<1>, thus mandating unconditional use of
1344 L<done_testing|Test::More/done_testing>). Most useful in combination with ad hoc
1345 requirement specifications:
1348 push @chunks, <<EOC;
1350 $class->skip_without([ deploy YAML>=0.90 ]);
1356 push @chunks, <<'EOC';
1358 =head2 die_unless_req_ok_for
1362 =item Arguments: $group_name | \@group_names
1366 Checks if L</req_ok_for> passes for the supplied group(s), and
1367 in case of failure throws an exception including the information
1368 from L</req_missing_for>. See also L</-die_without>.
1370 =head2 modreq_errorlist_for
1374 =item Arguments: $group_name | \@group_names
1376 =item Return Value: \%set_of_loaderrors_per_module
1380 Returns a hashref containing the actual errors that occurred while attempting
1381 to load each module in the requirement group(s).
1383 =head2 req_errorlist_for
1385 Deprecated method name, equivalent (via proxy) to L</modreq_errorlist_for>.
1392 push @chunks, <<'EOC';
1393 =head1 FURTHER QUESTIONS?
1395 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1397 =head1 COPYRIGHT AND LICENSE
1399 This module is free software L<copyright|DBIx::Class::Schema::Loader/COPYRIGHT AND LICENSE>
1400 by the L<DBIx::Class::Schema::Loader (DBICSL) authors|DBIx::Class::Schema::Loader/AUTHORS>.
1401 You can redistribute it and/or modify it under the same terms as the
1402 L<DBIx::Class::Schema::Loader library|DBIx::Class::Schema::Loader/COPYRIGHT AND LICENSE>.
1406 open (my $fh, '>', $podfn) or die;
1407 print $fh join ("\n\n", @chunks) or die;
1408 print $fh "\n" or die;
1410 } or croak( "Unable to write $podfn: " . ( $! || $@ || 'unknown error') );