Fix forgotten 'unless' tripped by 05a5ca4b (introduced in c863e102)
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Optional / Dependencies.pm
CommitLineData
8057ed01 1package DBIx::Class::Optional::Dependencies;
2
cb551b07 3### This may look crazy, but it in fact tangibly ( by 50(!)% ) shortens
4# the skip-test time when everything requested is unavailable
bd510251 5BEGIN {
6 if ( $ENV{RELEASE_TESTING} ) {
7 require warnings and warnings->import;
8 require strict and strict->import;
9 }
10}
cb551b07 11
12sub croak {
13 require Carp;
14 Carp::croak(@_);
15};
16###
fb39747c 17
18# NO EXTERNAL NON-5.8.1 CORE DEPENDENCIES EVER (e.g. C::A::G)
8057ed01 19# This module is to be loaded by Makefile.PM on a pristine system
20
f6b26571 21# POD is generated automatically by calling _gen_pod from the
22# Makefile.PL in $AUTHOR mode
23
60256113 24# *DELIBERATELY* not making a group for these - they must disappear
25# forever as optdeps in the first place
2b48ebff 26my $moose_basic = {
68de9438 27 'Moose' => '0.98',
28 'MooseX::Types' => '0.21',
d401ab6b 29 'MooseX::Types::LoadableClass' => '0.011',
68de9438 30};
31
31c31b8d 32my $dbic_reqs = {
60256113 33
34 # NOTE: the rationale for 2 JSON::Any versions is that
35 # we need the newer only to work around JSON::XS, which
36 # itself is an optional dep
37 _json_any => {
38 req => {
39 'JSON::Any' => '1.23',
40 },
41 },
42
43 _json_xs_compatible_json_any => {
44 req => {
45 'JSON::Any' => '1.31',
46 },
47 },
48
7d2772a4 49 # a common placeholder for engines with IC::DT support based off DT::F::S
2baba3d9 50 _icdt_strptime_based => {
51 augment => {
52 icdt => {
53 req => {
54 'DateTime::Format::Strptime' => '1.2',
55 },
56 },
57 }
58 },
7d2772a4 59
60256113 60 _rdbms_generic_odbc => {
61 req => {
62 'DBD::ODBC' => 0,
63 }
64 },
65
66 _rdbms_generic_ado => {
67 req => {
68 'DBD::ADO' => 0,
69 }
70 },
71
461e818a 72 # must list any dep used by adhoc testing
73 # this prevents the "skips due to forgotten deps" issue
74 test_adhoc => {
75 req => {
83eef562 76 'Class::DBI::Plugin::DeepAbstractSearch' => '0',
77 'Class::DBI' => '3.000005',
461e818a 78 'Date::Simple' => '3.03',
79 'YAML' => '0',
80 'Class::Unload' => '0.07',
83eef562 81 'Time::Piece' => '0',
82 'Time::Piece::MySQL' => '0',
461e818a 83 },
84 },
85
8057ed01 86 replicated => {
e163f484 87 req => $moose_basic,
f6b26571 88 pod => {
89 title => 'Storage::Replicated',
90 desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
91 },
8057ed01 92 },
93
68de9438 94 test_replicated => {
e163f484 95 include => 'replicated',
68de9438 96 req => {
e163f484 97 'Test::Moose' => '0',
68de9438 98 },
99 },
100
8057ed01 101 admin => {
60256113 102 include => '_json_any',
2b48ebff 103 req => {
e163f484 104 %$moose_basic,
e163f484 105 'MooseX::Types::Path::Class' => '0.05',
106 'MooseX::Types::JSON' => '0.02',
ebcd0e4f 107 },
108 pod => {
109 title => 'DBIx::Class::Admin',
110 desc => 'Modules required for the DBIx::Class administrative library',
111 },
112 },
113
a4a02f15 114 admin_script => {
e163f484 115 include => 'admin',
ebcd0e4f 116 req => {
e163f484 117 'Getopt::Long::Descriptive' => '0.081',
118 'Text::CSV' => '1.16',
2b48ebff 119 },
e144415f 120 pod => {
121 title => 'dbicadmin',
122 desc => 'Modules required for the CLI DBIx::Class interface dbicadmin',
123 },
8057ed01 124 },
125
126 deploy => {
f6b26571 127 req => {
08ac7648 128 'SQL::Translator' => '0.11018',
f6b26571 129 },
130 pod => {
131 title => 'Storage::DBI::deploy()',
5529838f 132 desc => 'Modules required for L<DBIx::Class::Storage::DBI/deployment_statements> and L<DBIx::Class::Schema/deploy>',
f6b26571 133 },
8057ed01 134 },
135
2baba3d9 136 icdt => {
137 req => {
138 'DateTime' => '0.55',
0d1e5280 139 'DateTime::TimeZone::OlsonDB' => 0,
2baba3d9 140 },
141 pod => {
142 title => 'InflateColumn::DateTime support',
143 desc =>
144 'Modules required for L<DBIx::Class::InflateColumn::DateTime>. '
145 . 'Note that this group does not require much on its own, but '
146 . 'instead is augmented by various RDBMS-specific groups. See the '
147 . 'documentation of each C<rbms_*> group for details',
148 },
149 },
150
c7d50a7d 151 id_shortener => {
e163f484 152 req => {
153 'Math::BigInt' => '1.80',
154 'Math::Base36' => '0.07',
155 },
c7d50a7d 156 },
157
83eef562 158 cdbicompat => {
159 req => {
160 'Class::Data::Inheritable' => '0',
161 'Class::Trigger' => '0',
162 'DBIx::ContextualFetch' => '0',
163 'Clone' => '0.32',
164 },
165 pod => {
166 title => 'DBIx::Class::CDBICompat support',
167 desc => 'Modules required for L<DBIx::Class::CDBICompat>'
168 },
169 },
170
a109c954 171 test_pod => {
f6b26571 172 req => {
cbb19edf 173 'Test::Pod' => '1.42',
a109c954 174 },
cb551b07 175 release_testing_mandatory => 1,
a109c954 176 },
177
178 test_podcoverage => {
179 req => {
f6b26571 180 'Test::Pod::Coverage' => '1.08',
181 'Pod::Coverage' => '0.20',
a109c954 182 },
cb551b07 183 release_testing_mandatory => 1,
a109c954 184 },
185
ffce4b65 186 test_whitespace => {
a109c954 187 req => {
8273e845 188 'Test::EOL' => '1.0',
ffce4b65 189 'Test::NoTabs' => '0.9',
f6b26571 190 },
cb551b07 191 release_testing_mandatory => 1,
8057ed01 192 },
193
4a233f30 194 test_strictures => {
195 req => {
b2c1212f 196 'Test::Strict' => '0.20',
4a233f30 197 },
cb551b07 198 release_testing_mandatory => 1,
4a233f30 199 },
200
2a2a7b23 201 test_prettydebug => {
60256113 202 include => '_json_any',
2a2a7b23 203 },
204
99503754 205 test_admin_script => {
60256113 206 include => [qw( admin_script _json_xs_compatible_json_any )],
99503754 207 req => {
99503754 208 'JSON' => 0,
be855469 209 'JSON::PP' => 0,
210 'Cpanel::JSON::XS' => 0,
99503754 211 'JSON::XS' => 0,
212 $^O eq 'MSWin32'
213 # for t/admin/10script.t
214 ? ('Win32::ShellQuote' => 0)
215 # DWIW does not compile (./configure even) on win32
216 : ('JSON::DWIW' => 0 )
217 ,
218 }
219 },
220
556c4fe6 221 test_leaks_heavy => {
f6b26571 222 req => {
556c4fe6 223 'Class::MethodCache' => '0.02',
224 'PadWalker' => '1.06',
a109c954 225 },
226 },
f6b26571 227
8057ed01 228
be68095d 229 # this is just for completeness as SQLite
230 # is a core dep of DBIC for testing
231 rdbms_sqlite => {
232 req => {
e163f484 233 'DBD::SQLite' => 0,
be68095d 234 },
235 pod => {
236 title => 'SQLite support',
237 desc => 'Modules required to connect to SQLite',
238 },
2baba3d9 239 augment => {
240 icdt => {
241 req => {
242 'DateTime::Format::SQLite' => '0',
243 },
244 },
245 },
246 },
247
248 # centralize the specification, as we have ICDT tests which can
249 # test the full behavior of RDBMS-specific ICDT on top of bare SQLite
250 # not _-prefixed so that it will show up under req_group_list
251 icdt_pg => {
252 augment => {
253 icdt => {
254 req => {
255 'DateTime::Format::Pg' => '0.16004',
256 },
257 },
258 },
be68095d 259 },
260
261 rdbms_pg => {
2baba3d9 262 include => 'icdt_pg',
be68095d 263 req => {
a4fc1239 264 # when changing this list make sure to adjust xt/optional_deps.t
e163f484 265 'DBD::Pg' => 0,
be68095d 266 },
267 pod => {
268 title => 'PostgreSQL support',
269 desc => 'Modules required to connect to PostgreSQL',
270 },
271 },
272
7d2772a4 273 _rdbms_mssql_common => {
274 include => '_icdt_strptime_based',
275 },
276
be68095d 277 rdbms_mssql_odbc => {
7d2772a4 278 include => [qw( _rdbms_generic_odbc _rdbms_mssql_common )],
be68095d 279 pod => {
280 title => 'MSSQL support via DBD::ODBC',
281 desc => 'Modules required to connect to MSSQL via DBD::ODBC',
282 },
283 },
284
285 rdbms_mssql_sybase => {
7d2772a4 286 include => '_rdbms_mssql_common',
be68095d 287 req => {
e163f484 288 'DBD::Sybase' => 0,
be68095d 289 },
290 pod => {
291 title => 'MSSQL support via DBD::Sybase',
56dca25f 292 desc => 'Modules required to connect to MSSQL via DBD::Sybase',
293 },
294 },
295
296 rdbms_mssql_ado => {
7d2772a4 297 include => [qw( _rdbms_generic_ado _rdbms_mssql_common )],
56dca25f 298 pod => {
299 title => 'MSSQL support via DBD::ADO (Windows only)',
300 desc => 'Modules required to connect to MSSQL via DBD::ADO. This particular DBD is available on Windows only',
be68095d 301 },
302 },
303
7d2772a4 304 _rdbms_msaccess_common => {
305 include => '_icdt_strptime_based',
306 },
307
726c8f65 308 rdbms_msaccess_odbc => {
7d2772a4 309 include => [qw( _rdbms_generic_odbc _rdbms_msaccess_common )],
726c8f65 310 pod => {
311 title => 'MS Access support via DBD::ODBC',
312 desc => 'Modules required to connect to MS Access via DBD::ODBC',
313 },
314 },
315
316 rdbms_msaccess_ado => {
7d2772a4 317 include => [qw( _rdbms_generic_ado _rdbms_msaccess_common )],
726c8f65 318 pod => {
319 title => 'MS Access support via DBD::ADO (Windows only)',
320 desc => 'Modules required to connect to MS Access via DBD::ADO. This particular DBD is available on Windows only',
321 },
322 },
323
2baba3d9 324 # centralize the specification, as we have ICDT tests which can
325 # test the full behavior of RDBMS-specific ICDT on top of bare SQLite
326 # not _-prefixed so that it will show up under req_group_list
327 icdt_mysql => {
328 augment => {
329 icdt => {
330 req => {
331 'DateTime::Format::MySQL' => '0',
332 },
333 },
334 },
335 },
336
be68095d 337 rdbms_mysql => {
2baba3d9 338 include => 'icdt_mysql',
be68095d 339 req => {
e163f484 340 'DBD::mysql' => 0,
be68095d 341 },
342 pod => {
343 title => 'MySQL support',
344 desc => 'Modules required to connect to MySQL',
345 },
346 },
347
348 rdbms_oracle => {
e163f484 349 include => 'id_shortener',
be68095d 350 req => {
e163f484 351 'DBD::Oracle' => 0,
be68095d 352 },
353 pod => {
354 title => 'Oracle support',
355 desc => 'Modules required to connect to Oracle',
356 },
2baba3d9 357 augment => {
358 icdt => {
359 req => {
360 'DateTime::Format::Oracle' => '0',
361 },
362 },
363 },
be68095d 364 },
365
366 rdbms_ase => {
7d2772a4 367 include => '_icdt_strptime_based',
be68095d 368 req => {
e163f484 369 'DBD::Sybase' => 0,
be68095d 370 },
371 pod => {
372 title => 'Sybase ASE support',
373 desc => 'Modules required to connect to Sybase ASE',
374 },
375 },
376
7d2772a4 377 _rdbms_db2_common => {
2baba3d9 378 augment => {
379 icdt => {
380 req => {
381 'DateTime::Format::DB2' => '0',
382 },
383 },
384 },
7d2772a4 385 },
386
be68095d 387 rdbms_db2 => {
7d2772a4 388 include => '_rdbms_db2_common',
be68095d 389 req => {
e163f484 390 'DBD::DB2' => 0,
be68095d 391 },
392 pod => {
393 title => 'DB2 support',
394 desc => 'Modules required to connect to DB2',
395 },
396 },
397
199fbc45 398 rdbms_db2_400 => {
7d2772a4 399 include => [qw( _rdbms_generic_odbc _rdbms_db2_common )],
199fbc45 400 pod => {
401 title => 'DB2 on AS/400 support',
402 desc => 'Modules required to connect to DB2 on AS/400',
403 },
404 },
405
406 rdbms_informix => {
7d2772a4 407 include => '_icdt_strptime_based',
199fbc45 408 req => {
e163f484 409 'DBD::Informix' => 0,
199fbc45 410 },
411 pod => {
412 title => 'Informix support',
413 desc => 'Modules required to connect to Informix',
414 },
8273e845 415 },
199fbc45 416
7d2772a4 417 _rdbms_sqlanywhere_common => {
418 inclide => '_icdt_strptime_based',
419 },
420
199fbc45 421 rdbms_sqlanywhere => {
7d2772a4 422 include => '_rdbms_sqlanywhere_common',
199fbc45 423 req => {
e163f484 424 'DBD::SQLAnywhere' => 0,
199fbc45 425 },
426 pod => {
427 title => 'SQLAnywhere support',
428 desc => 'Modules required to connect to SQLAnywhere',
429 },
8273e845 430 },
199fbc45 431
432 rdbms_sqlanywhere_odbc => {
7d2772a4 433 include => [qw( _rdbms_generic_odbc _rdbms_sqlanywhere_common )],
199fbc45 434 pod => {
435 title => 'SQLAnywhere support via DBD::ODBC',
436 desc => 'Modules required to connect to SQLAnywhere via DBD::ODBC',
437 },
8273e845 438 },
199fbc45 439
7d2772a4 440 _rdbms_firebird_common => {
441 include => '_icdt_strptime_based',
442 },
443
199fbc45 444 rdbms_firebird => {
7d2772a4 445 include => '_rdbms_firebird_common',
199fbc45 446 req => {
e163f484 447 'DBD::Firebird' => 0,
199fbc45 448 },
449 pod => {
450 title => 'Firebird support',
451 desc => 'Modules required to connect to Firebird',
452 },
8273e845 453 },
199fbc45 454
455 rdbms_firebird_interbase => {
7d2772a4 456 include => '_rdbms_firebird_common',
199fbc45 457 req => {
e163f484 458 'DBD::InterBase' => 0,
199fbc45 459 },
460 pod => {
461 title => 'Firebird support via DBD::InterBase',
462 desc => 'Modules required to connect to Firebird via DBD::InterBase',
463 },
8273e845 464 },
199fbc45 465
466 rdbms_firebird_odbc => {
7d2772a4 467 include => [qw( _rdbms_generic_odbc _rdbms_firebird_common )],
199fbc45 468 pod => {
469 title => 'Firebird support via DBD::ODBC',
470 desc => 'Modules required to connect to Firebird via DBD::ODBC',
471 },
8273e845 472 },
199fbc45 473
7975645b 474 test_rdbms_sqlite => {
475 include => 'rdbms_sqlite',
476 req => {
477 ###
478 ### IMPORTANT - do not raise this dependency
479 ### even though many bugfixes are present in newer versions, the general DBIC
480 ### rule is to bend over backwards for available DBDs (given upgrading them is
481 ### often *not* easy or even possible)
482 ###
483 'DBD::SQLite' => '1.29',
484 },
485 },
486
68de9438 487 test_rdbms_pg => {
e163f484 488 include => 'rdbms_pg',
e3a7746c 489 env => [
490 DBICTEST_PG_DSN => 1,
491 DBICTEST_PG_USER => 0,
492 DBICTEST_PG_PASS => 0,
493 ],
f6b26571 494 req => {
e3a7746c 495 # the order does matter because the rdbms support group might require
496 # a different version that the test group
497 #
498 # when changing this list make sure to adjust xt/optional_deps.t
e3a7746c 499 'DBD::Pg' => '2.009002', # specific version to test bytea
f6b26571 500 },
8057ed01 501 },
502
afae8507 503 test_rdbms_mssql_odbc => {
e163f484 504 include => 'rdbms_mssql_odbc',
e3a7746c 505 env => [
506 DBICTEST_MSSQL_ODBC_DSN => 1,
507 DBICTEST_MSSQL_ODBC_USER => 0,
508 DBICTEST_MSSQL_ODBC_PASS => 0,
509 ],
afae8507 510 },
511
56dca25f 512 test_rdbms_mssql_ado => {
e163f484 513 include => 'rdbms_mssql_ado',
e3a7746c 514 env => [
515 DBICTEST_MSSQL_ADO_DSN => 1,
516 DBICTEST_MSSQL_ADO_USER => 0,
517 DBICTEST_MSSQL_ADO_PASS => 0,
518 ],
56dca25f 519 },
520
afae8507 521 test_rdbms_mssql_sybase => {
e163f484 522 include => 'rdbms_mssql_sybase',
e3a7746c 523 env => [
524 DBICTEST_MSSQL_DSN => 1,
525 DBICTEST_MSSQL_USER => 0,
526 DBICTEST_MSSQL_PASS => 0,
527 ],
afae8507 528 },
529
726c8f65 530 test_rdbms_msaccess_odbc => {
4b9c54b5 531 include => 'rdbms_msaccess_odbc',
e3a7746c 532 env => [
533 DBICTEST_MSACCESS_ODBC_DSN => 1,
534 DBICTEST_MSACCESS_ODBC_USER => 0,
535 DBICTEST_MSACCESS_ODBC_PASS => 0,
536 ],
726c8f65 537 req => {
e3a7746c 538 'Data::GUID' => '0',
726c8f65 539 },
540 },
541
542 test_rdbms_msaccess_ado => {
4b9c54b5 543 include => 'rdbms_msaccess_ado',
e3a7746c 544 env => [
545 DBICTEST_MSACCESS_ADO_DSN => 1,
546 DBICTEST_MSACCESS_ADO_USER => 0,
547 DBICTEST_MSACCESS_ADO_PASS => 0,
548 ],
726c8f65 549 req => {
e3a7746c 550 'Data::GUID' => 0,
726c8f65 551 },
552 },
553
68de9438 554 test_rdbms_mysql => {
e163f484 555 include => 'rdbms_mysql',
e3a7746c 556 env => [
557 DBICTEST_MYSQL_DSN => 1,
558 DBICTEST_MYSQL_USER => 0,
559 DBICTEST_MYSQL_PASS => 0,
560 ],
8057ed01 561 },
562
68de9438 563 test_rdbms_oracle => {
e163f484 564 include => 'rdbms_oracle',
e3a7746c 565 env => [
566 DBICTEST_ORA_DSN => 1,
567 DBICTEST_ORA_USER => 0,
568 DBICTEST_ORA_PASS => 0,
569 ],
f6b26571 570 req => {
e3a7746c 571 'DBD::Oracle' => '1.24',
f6b26571 572 },
8057ed01 573 },
574
68de9438 575 test_rdbms_ase => {
e163f484 576 include => 'rdbms_ase',
e3a7746c 577 env => [
578 DBICTEST_SYBASE_DSN => 1,
579 DBICTEST_SYBASE_USER => 0,
580 DBICTEST_SYBASE_PASS => 0,
581 ],
8057ed01 582 },
583
68de9438 584 test_rdbms_db2 => {
e163f484 585 include => 'rdbms_db2',
e3a7746c 586 env => [
587 DBICTEST_DB2_DSN => 1,
588 DBICTEST_DB2_USER => 0,
589 DBICTEST_DB2_PASS => 0,
590 ],
f58a165c 591 },
592
199fbc45 593 test_rdbms_db2_400 => {
e163f484 594 include => 'rdbms_db2_400',
e3a7746c 595 env => [
596 DBICTEST_DB2_400_DSN => 1,
597 DBICTEST_DB2_400_USER => 0,
598 DBICTEST_DB2_400_PASS => 0,
599 ],
199fbc45 600 },
601
602 test_rdbms_informix => {
e163f484 603 include => 'rdbms_informix',
e3a7746c 604 env => [
605 DBICTEST_INFORMIX_DSN => 1,
606 DBICTEST_INFORMIX_USER => 0,
607 DBICTEST_INFORMIX_PASS => 0,
608 ],
199fbc45 609 },
610
611 test_rdbms_sqlanywhere => {
e163f484 612 include => 'rdbms_sqlanywhere',
e3a7746c 613 env => [
614 DBICTEST_SQLANYWHERE_DSN => 1,
615 DBICTEST_SQLANYWHERE_USER => 0,
616 DBICTEST_SQLANYWHERE_PASS => 0,
617 ],
199fbc45 618 },
619
620 test_rdbms_sqlanywhere_odbc => {
e163f484 621 include => 'rdbms_sqlanywhere_odbc',
e3a7746c 622 env => [
623 DBICTEST_SQLANYWHERE_ODBC_DSN => 1,
624 DBICTEST_SQLANYWHERE_ODBC_USER => 0,
625 DBICTEST_SQLANYWHERE_ODBC_PASS => 0,
626 ],
199fbc45 627 },
628
629 test_rdbms_firebird => {
e163f484 630 include => 'rdbms_firebird',
e3a7746c 631 env => [
632 DBICTEST_FIREBIRD_DSN => 1,
633 DBICTEST_FIREBIRD_USER => 0,
634 DBICTEST_FIREBIRD_PASS => 0,
635 ],
199fbc45 636 },
637
638 test_rdbms_firebird_interbase => {
e163f484 639 include => 'rdbms_firebird_interbase',
e3a7746c 640 env => [
641 DBICTEST_FIREBIRD_INTERBASE_DSN => 1,
642 DBICTEST_FIREBIRD_INTERBASE_USER => 0,
643 DBICTEST_FIREBIRD_INTERBASE_PASS => 0,
644 ],
199fbc45 645 },
646
e02b39b4 647 test_rdbms_firebird_odbc => {
e163f484 648 include => 'rdbms_firebird_odbc',
e3a7746c 649 env => [
650 DBICTEST_FIREBIRD_ODBC_DSN => 1,
651 DBICTEST_FIREBIRD_ODBC_USER => 0,
652 DBICTEST_FIREBIRD_ODBC_PASS => 0,
653 ],
e02b39b4 654 },
655
42168332 656 test_memcached => {
e3a7746c 657 env => [
658 DBICTEST_MEMCACHED => 1,
659 ],
42168332 660 req => {
e3a7746c 661 'Cache::Memcached' => 0,
42168332 662 },
663 },
664
344f1f52 665 dist_dir => {
60256113 666 # we need to run the dbicadmin so we can self-generate its POD
667 # also we do not want surprises in case JSON::XS is in the path
668 # so make sure we get an always-working JSON::Any
bf44bdb9 669 include => [qw(
670 admin_script
671 _json_xs_compatible_json_any
672 id_shortener
673 deploy
674 test_pod
675 test_podcoverage
676 test_whitespace
677 test_strictures
678 )],
344f1f52 679 req => {
b81d8515 680 'ExtUtils::MakeMaker' => '6.64',
bf44bdb9 681 'Module::Install' => '1.06',
06fc872a 682 'Pod::Inherit' => '0.91',
683 },
344f1f52 684 },
685
686 dist_upload => {
687 req => {
688 'CPAN::Uploader' => '0.103001',
689 },
690 },
8057ed01 691};
692
f6b26571 693
3ca0dcf0 694
695### Public API
696
afb8fc52 697sub import {
698 my $class = shift;
699
700 if (@_) {
701
702 my $action = shift;
703
704 if ($action eq '-die_without') {
705 my $err;
706 {
707 local $@;
708 eval { $class->die_unless_req_ok_for(\@_); 1 }
709 or $err = $@;
710 }
711 die "\n$err\n" if $err;
712 }
713 elsif ($action eq '-list_missing') {
714 print $class->modreq_missing_for(\@_);
715 print "\n";
716 exit 0;
717 }
cb551b07 718 elsif ($action eq '-skip_all_without') {
719
720 # sanity check - make sure ->current_test is 0 and no plan has been declared
721 do {
722 local $@;
723 defined eval {
724 Test::Builder->new->current_test
725 or
726 Test::Builder->new->has_plan
727 };
728 } and croak("Unable to invoke -skip_all_without after testing has started");
729
730 if ( my $missing = $class->req_missing_for(\@_) ) {
731
732 die ("\nMandatory requirements not satisfied during release-testing: $missing\n\n")
733 if $ENV{RELEASE_TESTING} and $class->_groups_to_reqs(\@_)->{release_testing_mandatory};
734
735 print "1..0 # SKIP requirements not satisfied: $missing\n";
736 exit 0;
737 }
738 }
afb8fc52 739 elsif ($action =~ /^-/) {
740 croak "Unknown import-time action '$action'";
741 }
742 else {
743 croak "$class is not an exporter, unable to import '$action'";
744 }
745 }
746
747 1;
748}
749
750sub unimport {
751 croak( __PACKAGE__ . " does not implement unimport" );
752}
753
3ca0dcf0 754# OO for (mistakenly considered) ease of extensibility, not due to any need to
755# carry state of any sort. This API is currently used outside, so leave as-is.
756# FIXME - make sure to not propagate this further if module is extracted as a
757# standalone library - keep the stupidity to a DBIC-secific shim!
758#
fb39747c 759sub req_list_for {
d1bd396f 760 shift->_groups_to_reqs(shift)->{effective_modreqs};
e3a7746c 761}
762
763sub modreq_list_for {
d1bd396f 764 shift->_groups_to_reqs(shift)->{modreqs};
fb39747c 765}
766
3ca0dcf0 767sub req_group_list {
31c31b8d 768 +{ map
769 { $_ => $_[0]->_groups_to_reqs($_) }
60256113 770 grep { $_ !~ /^_/ } keys %$dbic_reqs
31c31b8d 771 }
3ca0dcf0 772}
fb39747c 773
d1bd396f 774sub req_errorlist_for { shift->modreq_errorlist_for(shift) } # deprecated
5ffa39c7 775sub modreq_errorlist_for {
d1bd396f 776 my ($self, $groups) = @_;
777 $self->_errorlist_for_modreqs( $self->_groups_to_reqs($groups)->{modreqs} );
344f1f52 778}
779
fb39747c 780sub req_ok_for {
d1bd396f 781 shift->req_missing_for(shift) ? 0 : 1;
e3a7746c 782}
783
784sub req_missing_for {
d1bd396f 785 my ($self, $groups) = @_;
e3a7746c 786
d1bd396f 787 my $reqs = $self->_groups_to_reqs($groups);
250d9e55 788
789 my $mods_missing = $reqs->{missing_envvars}
790 ? $self->_list_physically_missing_modules( $reqs->{modreqs} )
791 : $self->modreq_missing_for($groups)
792 ;
e3a7746c 793
794 return '' if
795 ! $mods_missing
796 and
797 ! $reqs->{missing_envvars}
31c31b8d 798 ;
e3a7746c 799
800 my @res = $mods_missing || ();
801
d1f653cf 802 push @res, 'the following group(s) of environment variables: ' . join ' and ', sort map
e3a7746c 803 { __envvar_group_desc($_) }
804 @{$reqs->{missing_envvars}}
805 if $reqs->{missing_envvars};
806
807 return (
808 ( join ' as well as ', @res )
809 .
810 ( $reqs->{modreqs_fully_documented} ? " (see @{[ ref $self || $self ]} documentation for details)" : '' ),
811 );
fb39747c 812}
813
e3a7746c 814sub modreq_missing_for {
d1bd396f 815 my ($self, $groups) = @_;
fb39747c 816
d1bd396f 817 my $reqs = $self->_groups_to_reqs($groups);
e3a7746c 818 my $modreq_errors = $self->_errorlist_for_modreqs($reqs->{modreqs})
819 or return '';
fb39747c 820
e3a7746c 821 join ' ', map
34f354c3 822 { $reqs->{modreqs}{$_} ? "$_~$reqs->{modreqs}{$_}" : $_ }
e3a7746c 823 sort { lc($a) cmp lc($b) } keys %$modreq_errors
31c31b8d 824 ;
fb39747c 825}
826
461e818a 827my $tb;
828sub skip_without {
829 my ($self, $groups) = @_;
830
831 $tb ||= do { local $@; eval { Test::Builder->new } }
832 or croak "Calling skip_without() before loading Test::Builder makes no sense";
833
834 if ( my $err = $self->req_missing_for($groups) ) {
835 my ($fn, $ln) = (caller(0))[1,2];
836 $tb->skip("block in $fn around line $ln requires $err");
837 local $^W = 0;
838 last SKIP;
839 }
840
841 1;
842}
843
3ca0dcf0 844sub die_unless_req_ok_for {
d1bd396f 845 if (my $err = shift->req_missing_for(shift) ) {
e3a7746c 846 die "Unable to continue due to missing requirements: $err\n";
31c31b8d 847 }
fb39747c 848}
849
3ca0dcf0 850
851
e3a7746c 852### Private functions
853
854# potentially shorten group desc
855sub __envvar_group_desc {
856 my @envs = @{$_[0]};
857
858 my (@res, $last_prefix);
859 while (my $ev = shift @envs) {
860 my ($pref, $sep, $suff) = split / ([\_\-]) (?= [^\_\-]+ \z )/x, $ev;
861
862 if ( defined $sep and ($last_prefix||'') eq $pref ) {
863 push @res, "...${sep}${suff}"
864 }
865 else {
866 push @res, $ev;
867 }
868
869 $last_prefix = $pref if $sep;
870 }
871
872 join '/', @res;
873}
874
461e818a 875my $groupname_re = qr/ [A-Z_a-z][0-9A-Z_a-z]* /x;
876my $modname_re = qr/ [A-Z_a-z] [0-9A-Z_a-z]* (?:::[0-9A-Z_a-z]+)* /x;
877my $modver_re = qr/ [0-9]+ (?: \. [0-9]+ )? /x;
878
a3f8bd01 879# Expand includes from a random group in a specific order:
880# nonvariable groups first, then their includes, then the variable groups,
881# then their includes.
882# This allows reliably marking the rest of the mod reqs as variable (this is
883# also why variable includes are currently not allowed)
884sub __expand_includes {
885 my ($groups, $seen) = @_;
886
887 # !! DIFFERENT !! behavior and return depending on invocation mode
888 # (easier to recurse this way)
889 my $is_toplevel = $seen
890 ? 0
891 : !! ($seen = {})
892 ;
3ca0dcf0 893
a3f8bd01 894 my ($res_per_type, $missing_envvars);
d8799bab 895
a3f8bd01 896 # breadth-first evaluation, with non-variable includes on top
897 for my $g (@$groups) {
d8799bab 898
a3f8bd01 899 croak "Invalid requirement group name '$g': only ascii alphanumerics and _ are allowed"
461e818a 900 if $g !~ qr/ \A $groupname_re \z/x;
e163f484 901
a3f8bd01 902 my $r = $dbic_reqs->{$g}
903 or croak "Requirement group '$g' is not defined";
d8799bab 904
a3f8bd01 905 # always do this check *before* the $seen check
906 croak "Group '$g' with variable effective_modreqs can not be specified as an 'include'"
907 if ( $r->{env} and ! $is_toplevel );
d8799bab 908
a3f8bd01 909 next if $seen->{$g}++;
31c31b8d 910
a3f8bd01 911 my $req_type = 'static';
d8799bab 912
a3f8bd01 913 if ( my @e = @{$r->{env}||[]} ) {
e3a7746c 914
a3f8bd01 915 croak "Unexpected 'env' attribute under group '$g' (only allowed in test_* groups)"
916 unless $g =~ /^test_/;
e3a7746c 917
a3f8bd01 918 croak "Unexpected *odd* list in 'env' under group '$g'"
e3a7746c 919 if @e % 2;
920
e3a7746c 921 # deconstruct the whole thing
a3f8bd01 922 my (@group_envnames_list, $some_envs_required, $some_required_missing);
e3a7746c 923 while (@e) {
924 push @group_envnames_list, my $envname = shift @e;
925
926 # env required or not
927 next unless shift @e;
928
929 $some_envs_required ||= 1;
930
a3f8bd01 931 $some_required_missing ||= (
e3a7746c 932 ! defined $ENV{$envname}
933 or
934 ! length $ENV{$envname}
935 );
936 }
937
a3f8bd01 938 croak "None of the envvars in group '$g' declared as required, making the requirement moot"
e3a7746c 939 unless $some_envs_required;
940
a3f8bd01 941 if ($some_required_missing) {
942 push @{$missing_envvars->{$g}}, \@group_envnames_list;
943 $req_type = 'variable';
944 }
945 }
946
947 push @{$res_per_type->{"base_${req_type}"}}, $g;
948
949 if (my $i = $dbic_reqs->{$g}{include}) {
950 $i = [ $i ] unless ref $i eq 'ARRAY';
951
952 croak "Malformed 'include' for group '$g': must be another existing group name or arrayref of existing group names"
953 unless @$i;
954
955 push @{$res_per_type->{"incs_${req_type}"}}, @$i;
e3a7746c 956 }
a3f8bd01 957 }
958
959 my @ret = map {
960 @{ $res_per_type->{"base_${_}"} || [] },
961 ( $res_per_type->{"incs_${_}"} ? __expand_includes( $res_per_type->{"incs_${_}"}, $seen ) : () ),
962 } qw(static variable);
963
964 return ! $is_toplevel ? @ret : do {
965 my $rv = {};
966 $rv->{$_} = {
967 idx => 1 + keys %$rv,
968 missing_envvars => $missing_envvars->{$_},
969 } for @ret;
2baba3d9 970 $rv->{$_}{user_requested} = 1 for @$groups;
a3f8bd01 971 $rv;
972 };
973}
974
975### Private OO API
976our %req_unavailability_cache;
977
978# this method is just a lister and envvar/metadata checker - it does not try to load anything
979sub _groups_to_reqs {
461e818a 980 my ($self, $want) = @_;
a3f8bd01 981
461e818a 982 $want = [ $want || () ]
983 unless ref $want eq 'ARRAY';
a3f8bd01 984
985 croak "@{[ (caller(1))[3] ]}() expects a requirement group name or arrayref of group names"
461e818a 986 unless @$want;
e3a7746c 987
a3f8bd01 988 my $ret = {
989 modreqs => {},
990 modreqs_fully_documented => 1,
991 };
e163f484 992
461e818a 993 my $groups;
994 for my $piece (@$want) {
995 if ($piece =~ qr/ \A $groupname_re \z /x) {
996 push @$groups, $piece;
997 }
998 elsif ( my ($mod, $ver) = $piece =~ qr/ \A ($modname_re) \>\= ($modver_re) \z /x ) {
999 croak "Ad hoc module specification lists '$mod' twice"
1000 if exists $ret->{modreqs}{$mod};
1001
1002 croak "Ad hoc module specification '${mod} >= $ver' (or greater) not listed in the test_adhoc optdep group" if (
1003 ! defined $dbic_reqs->{test_adhoc}{req}{$mod}
1004 or
1005 $dbic_reqs->{test_adhoc}{req}{$mod} < $ver
1006 );
1007
1008 $ret->{modreqs}{$mod} = $ver;
1009 $ret->{modreqs_fully_documented} = 0;
1010 }
1011 else {
1012 croak "Unsupported argument '$piece' supplied to @{[ (caller(1))[3] ]}()"
1013 }
1014 }
1015
a3f8bd01 1016 my $all_groups = __expand_includes($groups);
e163f484 1017
2baba3d9 1018 # pre-assemble list of augmentations, perform basic sanity checks
1019 # Note that below we *DO NOT* respect the source/target reationship, but
1020 # instead always default to augment the "later" group
1021 # This is done so that the "stable/variable" boundary keeps working as
1022 # expected
1023 my $augmentations;
1024 for my $requesting_group (keys %$all_groups) {
1025 if (my $ag = $dbic_reqs->{$requesting_group}{augment}) {
1026 for my $target_group (keys %$ag) {
1027
1028 croak "Group '$requesting_group' claims to augment a non-existent group '$target_group'"
1029 unless $dbic_reqs->{$target_group};
1030
1031 croak "Augmentation combined with variable effective_modreqs currently unsupported for group '$requesting_group'"
1032 if $dbic_reqs->{$requesting_group}{env};
1033
1034 croak "Augmentation of group '$target_group' with variable effective_modreqs unsupported (requested by '$requesting_group')"
1035 if $dbic_reqs->{$target_group}{env};
1036
1037 if (my @foreign = grep { $_ ne 'req' } keys %{$ag->{$target_group}} ) {
1038 croak "Only 'req' augmentations are currently supported (group '$requesting_group' attempts to alter '$foreign[0]' of group '$target_group'";
1039 }
1040
1041 $ret->{augments}{$target_group} = 1;
1042
1043 # no augmentation for stuff that hasn't been selected
1044 if ( $all_groups->{$target_group} and my $ar = $ag->{$target_group}{req} ) {
1045 push @{$augmentations->{
1046 ( $all_groups->{$requesting_group}{idx} < $all_groups->{$target_group}{idx} )
1047 ? $target_group
1048 : $requesting_group
1049 }}, $ar;
1050 }
1051 }
1052 }
1053 }
1054
a3f8bd01 1055 for my $group (sort { $all_groups->{$a}{idx} <=> $all_groups->{$b}{idx} } keys %$all_groups ) {
e163f484 1056
a3f8bd01 1057 my $group_reqs = $dbic_reqs->{$group}{req};
e163f484 1058
a3f8bd01 1059 # sanity-check
2baba3d9 1060 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
1061 for (keys %$req_bag) {
e163f484 1062
461e818a 1063 $_ =~ / \A $modname_re \z /x
2baba3d9 1064 or croak "Requirement '$_' in group '$group' is not a valid module name";
a3f8bd01 1065
2baba3d9 1066 # !!!DO NOT CHANGE!!!
1067 # remember - version.pm may not be available on the system
1068 croak "Requirement '$_' in group '$group' specifies an invalid version '$req_bag->{$_}' (only plain non-underscored floating point decimals are supported)"
461e818a 1069 if ( ($req_bag->{$_}||0) !~ qr/ \A $modver_re \z /x );
2baba3d9 1070 }
a3f8bd01 1071 }
e163f484 1072
a3f8bd01 1073 if (my $e = $all_groups->{$group}{missing_envvars}) {
1074 push @{$ret->{missing_envvars}}, @$e;
e163f484 1075 }
1076
31c31b8d 1077 # assemble into the final ret
e3a7746c 1078 for my $type (
1079 'modreqs',
a3f8bd01 1080 ( $ret->{missing_envvars} ? () : 'effective_modreqs' ),
e3a7746c 1081 ) {
2baba3d9 1082 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
e163f484 1083 for my $mod (keys %$req_bag) {
31c31b8d 1084
e163f484 1085 $ret->{$type}{$mod} = $req_bag->{$mod}||0 if (
31c31b8d 1086
e163f484 1087 ! exists $ret->{$type}{$mod}
1088 or
1089 # we sanitized the version to be numeric above - we can just -gt it
1090 ($req_bag->{$mod}||0) > $ret->{$type}{$mod}
fb39747c 1091
e163f484 1092 );
1093 }
e3a7746c 1094 }
fb39747c 1095 }
31c31b8d 1096
2baba3d9 1097 $ret->{modreqs_fully_documented} &&= !!$dbic_reqs->{$group}{pod}
1098 if $all_groups->{$group}{user_requested};
cb551b07 1099
1100 $ret->{release_testing_mandatory} ||= !!$dbic_reqs->{$group}{release_testing_mandatory};
31c31b8d 1101 }
1102
1103 return $ret;
1104}
1105
1106
250d9e55 1107# this method tries to find/load specified modreqs and returns a hashref of
31c31b8d 1108# module/loaderror pairs for anything that failed
1109sub _errorlist_for_modreqs {
1110 # args supposedly already went through _groups_to_reqs and are therefore sanitized
1111 # safe to eval at will
1112 my ($self, $reqs) = @_;
1113
1114 my $ret;
1115
1116 for my $m ( keys %$reqs ) {
1117 my $v = $reqs->{$m};
1118
1119 if (! exists $req_unavailability_cache{$m}{$v} ) {
1120 local $@;
1121 eval( "require $m;" . ( $v ? "$m->VERSION(q($v))" : '' ) );
1122 $req_unavailability_cache{$m}{$v} = $@;
fb39747c 1123 }
1124
31c31b8d 1125 $ret->{$m} = $req_unavailability_cache{$m}{$v}
1126 if $req_unavailability_cache{$m}{$v};
1127 }
1128
1129 $ret;
fb39747c 1130}
1131
250d9e55 1132# Unlike the above DO NOT try to load anything
1133# This is executed when some needed envvars are not available
1134# which in turn means a module load will never be reached anyway
1135# This is important because some modules (especially DBDs) can be
1136# *really* fickle when a require() is attempted, with pretty confusing
1137# side-effects (especially on windows)
1138sub _list_physically_missing_modules {
1139 my ($self, $modreqs) = @_;
1140
1141 # in case there is a coderef in @INC there is nothing we can definitively prove
1142 # so short circuit directly
1143 return '' if grep { length ref $_ } @INC;
1144
1145 my @definitely_missing;
1146 for my $mod (keys %$modreqs) {
1147 (my $fn = $mod . '.pm') =~ s|::|/|g;
1148
1149 push @definitely_missing, $mod unless grep
1150 # this should work on any combination of slashes
1151 { $_ and -d $_ and -f "$_/$fn" and -r "$_/$fn" }
1152 @INC
1153 ;
1154 }
1155
1156 join ' ', map
34f354c3 1157 { $modreqs->{$_} ? "$_~$modreqs->{$_}" : $_ }
250d9e55 1158 sort { lc($a) cmp lc($b) } @definitely_missing
1159 ;
1160}
1161
31c31b8d 1162
e3fc11e1 1163# This is to be called by the author only (automatically in Makefile.PL)
f6b26571 1164sub _gen_pod {
47589465 1165 my ($class, $distver, $pod_dir) = @_;
31fa1764 1166
47589465 1167 die "No POD root dir supplied" unless $pod_dir;
31fa1764 1168
ccebe1f1 1169 $distver ||=
31fa1764 1170 eval { require DBIx::Class; DBIx::Class->VERSION; }
1171 ||
ccebe1f1 1172 die
31fa1764 1173"\n\n---------------------------------------------------------------------\n" .
1174'Unable to load core DBIx::Class module to determine current version, '.
1175'possibly due to missing dependencies. Author-mode autodocumentation ' .
1176"halted\n\n" . $@ .
1177"\n\n---------------------------------------------------------------------\n"
31fa1764 1178 ;
1179
3d4c5a84 1180 # do not ask for a recent version, use 1.x API calls
47589465 1181 # this *may* execute on a smoker with old perl or whatnot
1182 require File::Path;
1183
1184 (my $modfn = __PACKAGE__ . '.pm') =~ s|::|/|g;
1185
1186 (my $podfn = "$pod_dir/$modfn") =~ s/\.pm$/\.pod/;
1187 (my $dir = $podfn) =~ s|/[^/]+$||;
1188
1189 File::Path::mkpath([$dir]);
1190
31c31b8d 1191 my $sqltver = $class->req_list_for('deploy')->{'SQL::Translator'}
e3fc11e1 1192 or die "Hrmm? No sqlt dep?";
7e3dc46f 1193
3ca0dcf0 1194
1195 my @chunks;
1196
1197#@@
1198#@@ HEADER
1199#@@
79b1bf0a 1200 push @chunks, <<"EOC";
af4ac504 1201#########################################################################
1202##################### A U T O G E N E R A T E D ########################
1203#########################################################################
1204#
1205# The contents of this POD file are auto-generated. Any changes you make
1206# will be lost. If you need to change the generated text edit _gen_pod()
1207# at the end of $modfn
1208#
79b1bf0a 1209
1210=head1 NAME
1211
1212$class - Optional module dependency specifications (for module authors)
af4ac504 1213EOC
3ca0dcf0 1214
1215
1216#@@
1217#@@ SYNOPSIS HEADING
1218#@@
79b1bf0a 1219 push @chunks, <<"EOC";
1220=head1 SYNOPSIS
1221
1222Somewhere in your build-file (e.g. L<ExtUtils::MakeMaker>'s F<Makefile.PL>):
7e3dc46f 1223
1224 ...
1225
79b1bf0a 1226 \$EUMM_ARGS{CONFIGURE_REQUIRES} = {
1227 \%{ \$EUMM_ARGS{CONFIGURE_REQUIRES} || {} },
1228 'DBIx::Class' => '$distver',
1229 };
7e3dc46f 1230
79b1bf0a 1231 ...
7e3dc46f 1232
2baba3d9 1233 my %DBIC_DEPLOY_AND_ORACLE_DEPS = %{ eval {
79b1bf0a 1234 require $class;
2baba3d9 1235 $class->req_list_for([qw( deploy rdbms_oracle icdt )]);
79b1bf0a 1236 } || {} };
7e3dc46f 1237
79b1bf0a 1238 \$EUMM_ARGS{PREREQ_PM} = {
2baba3d9 1239 \%DBIC_DEPLOY_AND_ORACLE_DEPS,
79b1bf0a 1240 \%{ \$EUMM_ARGS{PREREQ_PM} || {} },
1241 };
7e3dc46f 1242
1243 ...
1244
79b1bf0a 1245 ExtUtils::MakeMaker::WriteMakefile(\%EUMM_ARGS);
1246
1247B<Note>: The C<eval> protection within the example is due to support for
1248requirements during L<the C<configure> build phase|CPAN::Meta::Spec/Phases>
1249not being available on a sufficient portion of production installations of
1250Perl. Robust support for such dependency requirements is available in the
1251L<CPAN> installer only since version C<1.94_56> first made available for
1252production with perl version C<5.12>. It is the belief of the current
1253maintainer that support for requirements during the C<configure> build phase
1254will not be sufficiently ubiquitous until the B<year 2020> at the earliest,
1255hence the extra care demonstrated above. It should also be noted that some
12563rd party installers (e.g. L<cpanminus|App::cpanminus>) do the right thing
1257with configure requirements independent from the versions of perl and CPAN
1258available.
1259EOC
3ca0dcf0 1260
1261
1262#@@
1263#@@ DESCRIPTION HEADING
1264#@@
79b1bf0a 1265 push @chunks, <<'EOC';
1266=head1 DESCRIPTION
1267
f6b26571 1268Some of the less-frequently used features of L<DBIx::Class> have external
1269module dependencies on their own. In order not to burden the average user
79b1bf0a 1270with modules they will never use, these optional dependencies are not included
f6b26571 1271in the base Makefile.PL. Instead an exception with a descriptive message is
79b1bf0a 1272thrown when a specific feature can't find one or several modules required for
1273its operation. This module is the central holding place for the current list
7e3dc46f 1274of such dependencies, for DBIx::Class core authors, and DBIx::Class extension
1275authors alike.
79b1bf0a 1276
1277Dependencies are organized in L<groups|/CURRENT REQUIREMENT GROUPS> where each
1278group can list one or more required modules, with an optional minimum version
e3a7746c 1279(or 0 for any version). In addition groups prefixed with C<test_> can specify
1280a set of environment variables, some (or all) of which are marked as required
1281for the group to be considered by L</req_list_for>
1282
1283Each group name (or a combination thereof) can be used in the
1284L<public methods|/METHODS> as described below.
79b1bf0a 1285EOC
3ca0dcf0 1286
1287
1288#@@
1289#@@ REQUIREMENT GROUPLIST HEADING
1290#@@
79b1bf0a 1291 push @chunks, '=head1 CURRENT REQUIREMENT GROUPS';
f6b26571 1292
2baba3d9 1293 my $standalone_info;
1294
31c31b8d 1295 for my $group (sort keys %$dbic_reqs) {
f6b26571 1296
2baba3d9 1297 my $info = $standalone_info->{$group} ||= $class->_groups_to_reqs($group);
f6b26571 1298
2baba3d9 1299 next unless (
1300 $info->{modreqs_fully_documented}
1301 and
1302 ( $info->{augments} or $info->{modreqs} )
1303 );
1304
1305 my $p = $dbic_reqs->{$group}{pod};
f6b26571 1306
1307 push @chunks, (
1308 "=head2 $p->{title}",
2baba3d9 1309 "=head3 $group",
1310 $p->{desc},
f6b26571 1311 '=over',
f6b26571 1312 );
2baba3d9 1313
1314 if ( keys %{ $info->{modreqs}||{} } ) {
1315 push @chunks, map
1316 { "=item * $_" . ($info->{modreqs}{$_} ? " >= $info->{modreqs}{$_}" : '') }
1317 ( sort keys %{ $info->{modreqs} } )
1318 ;
1319 }
1320 else {
1321 push @chunks, '=item * No standalone requirements',
1322 }
1323
1324 push @chunks, '=back';
1325
1326 for my $ag ( sort keys %{ $info->{augments} || {} } ) {
1327 my $ag_info = $standalone_info->{$ag} ||= $class->_groups_to_reqs($ag);
1328
1329 my $newreqs = $class->modreq_list_for([ $group, $ag ]);
1330 for (keys %$newreqs) {
1331 delete $newreqs->{$_} if (
1332 ( defined $info->{modreqs}{$_} and $info->{modreqs}{$_} == $newreqs->{$_} )
1333 or
1334 ( defined $ag_info->{modreqs}{$_} and $ag_info->{modreqs}{$_} == $newreqs->{$_} )
1335 );
1336 }
1337
1338 if (keys %$newreqs) {
1339 push @chunks, (
1340 "Combined with L</$ag> additionally requires:",
1341 '=over',
1342 ( map
1343 { "=item * $_" . ($newreqs->{$_} ? " >= $newreqs->{$_}" : '') }
1344 ( sort keys %$newreqs )
1345 ),
1346 '=back',
1347 );
1348 }
1349 }
f6b26571 1350 }
1351
3ca0dcf0 1352
1353#@@
1354#@@ API DOCUMENTATION HEADING
1355#@@
79b1bf0a 1356 push @chunks, <<'EOC';
1357
afb8fc52 1358=head1 IMPORT-LIKE ACTIONS
1359
1360Even though this module is not an L<Exporter>, it recognizes several C<actions>
1361supplied to its C<import> method.
1362
cb551b07 1363=head2 -skip_all_without
1364
1365=over
1366
1367=item Arguments: @group_names
1368
1369=back
1370
1371A convenience wrapper for use during testing:
1372EOC
1373
1374 push @chunks, " use $class -skip_all_without => qw(admin test_rdbms_mysql);";
1375
1376 push @chunks, 'Roughly equivalent to the following code:';
1377
1378 push @chunks, sprintf <<'EOS', ($class) x 2;
1379
1380 BEGIN {
1381 require %s;
1382 if ( my $missing = %s->req_missing_for(\@group_names_) ) {
1383 print "1..0 # SKIP requirements not satisfied: $missing\n";
1384 exit 0;
1385 }
1386 }
1387EOS
1388
1389 push @chunks, <<'EOC';
1390
1391It also takes into account the C<RELEASE_TESTING> environment variable and
1392behaves like L</-die_without> for any requirement groups marked as
1393C<release_testing_mandatory>.
1394
afb8fc52 1395=head2 -die_without
1396
1397=over
1398
1399=item Arguments: @group_names
1400
1401=back
1402
1403A convenience wrapper around L</die_unless_req_ok_for>:
1404EOC
1405
1406 push @chunks, " use $class -die_without => qw(deploy admin);";
1407
1408 push @chunks, <<'EOC';
1409
1410=head2 -list_missing
1411
1412=over
1413
1414=item Arguments: @group_names
1415
1416=back
1417
1418A convenience wrapper around L</modreq_missing_for>:
1419
1420 perl -Ilib -MDBIx::Class::Optional::Dependencies=-list_missing,deploy,admin | cpanm
1421
79b1bf0a 1422=head1 METHODS
1423
1424=head2 req_group_list
1425
1426=over
1427
1428=item Arguments: none
1429
1430=item Return Value: \%list_of_requirement_groups
1431
1432=back
1433
e3fc11e1 1434This method should be used by DBIx::Class packagers, to get a hashref of all
31c31b8d 1435dependencies B<keyed> by dependency group. Each key (group name), or a combination
1436thereof (as an arrayref) can be supplied to the methods below.
79b1bf0a 1437The B<values> of the returned hash are currently a set of options B<without a
1438well defined structure>. If you have use for any of the contents - contact the
1439maintainers, instead of treating this as public (left alone stable) API.
1440
1441=head2 req_list_for
1442
1443=over
1444
31c31b8d 1445=item Arguments: $group_name | \@group_names
79b1bf0a 1446
31c31b8d 1447=item Return Value: \%set_of_module_version_pairs
79b1bf0a 1448
1449=back
1450
f6b26571 1451This method should be used by DBIx::Class extension authors, to determine the
31c31b8d 1452version of modules a specific set of features requires for this version of
e3a7746c 1453DBIx::Class (regardless of their availability on the system).
1454See the L</SYNOPSIS> for a real-world example.
1455
1456When handling C<test_*> groups this method behaves B<differently> from
1457L</modreq_list_for> below (and is the only such inconsistency among the
1458C<req_*> methods). If a particular group declares as requirements some
1459C<environment variables> and these requirements are not satisfied (the envvars
1460are unset) - then the C<module requirements> of this group are not included in
1461the returned list.
1462
1463=head2 modreq_list_for
1464
1465=over
1466
1467=item Arguments: $group_name | \@group_names
1468
1469=item Return Value: \%set_of_module_version_pairs
1470
1471=back
1472
1473Same as L</req_list_for> but does not take into consideration any
1474C<environment variable requirements> - returns just the list of required
1475modules.
79b1bf0a 1476
1477=head2 req_ok_for
1478
1479=over
1480
31c31b8d 1481=item Arguments: $group_name | \@group_names
79b1bf0a 1482
1483=item Return Value: 1|0
1484
1485=back
1486
e3a7746c 1487Returns true or false depending on whether all modules/envvars required by
1488the group(s) are loadable/set on the system.
79b1bf0a 1489
1490=head2 req_missing_for
1491
1492=over
1493
31c31b8d 1494=item Arguments: $group_name | \@group_names
79b1bf0a 1495
1496=item Return Value: $error_message_string
1497
1498=back
1499
31c31b8d 1500Returns a single-line string suitable for inclusion in larger error messages.
e3a7746c 1501This method would normally be used by DBIx::Class core features, to indicate to
1502the user that they need to install specific modules and/or set specific
1503environment variables before being able to use a specific feature set.
f6b26571 1504
e3fc11e1 1505For example if some of the requirements for C<deploy> are not available,
1506the returned string could look like:
79b1bf0a 1507EOC
f6b26571 1508
34f354c3 1509 push @chunks, qq{ "SQL::Translator~$sqltver" (see $class documentation for details)};
f6b26571 1510
79b1bf0a 1511 push @chunks, <<'EOC';
f6b26571 1512The author is expected to prepend the necessary text to this message before
e3a7746c 1513returning the actual error seen by the user. See also L</modreq_missing_for>
1514
1515=head2 modreq_missing_for
f6b26571 1516
e3a7746c 1517=over
1518
1519=item Arguments: $group_name | \@group_names
1520
1521=item Return Value: $error_message_string
1522
1523=back
1524
1525Same as L</req_missing_for> except that the error string is guaranteed to be
1526either empty, or contain a set of module requirement specifications suitable
1527for piping to e.g. L<cpanminus|App::cpanminus>. The method explicitly does not
1528attempt to validate the state of required environment variables (if any).
1529
1530For instance if some of the requirements for C<deploy> are not available,
1531the returned string could look like:
1532EOC
1533
34f354c3 1534 push @chunks, qq{ "SQL::Translator~$sqltver"};
e3a7746c 1535
1536 push @chunks, <<'EOC';
afb8fc52 1537
1538See also L</-list_missing>.
1539
461e818a 1540=head2 skip_without
1541
1542=over
1543
1544=item Arguments: $group_name | \@group_names
1545
1546=back
1547
1548A convenience wrapper around L<skip|Test::More/SKIP>. It does not take neither
1549a reason (it is generated by L</req_missing_for>) nor an amount of skipped tests
1550(it is always C<1>, thus mandating unconditional use of
1551L<done_testing|Test::More/done_testing>). Most useful in combination with ad hoc
1552requirement specifications:
1553EOC
1554
1555 push @chunks, <<EOC;
1556 SKIP: {
1557 $class->skip_without([ deploy YAML>=0.90 ]);
1558
1559 ...
1560 }
1561EOC
1562
1563 push @chunks, <<'EOC';
1564
79b1bf0a 1565=head2 die_unless_req_ok_for
1566
1567=over
1568
31c31b8d 1569=item Arguments: $group_name | \@group_names
79b1bf0a 1570
1571=back
1572
31c31b8d 1573Checks if L</req_ok_for> passes for the supplied group(s), and
344f1f52 1574in case of failure throws an exception including the information
afb8fc52 1575from L</req_missing_for>. See also L</-die_without>.
79b1bf0a 1576
5ffa39c7 1577=head2 modreq_errorlist_for
79b1bf0a 1578
1579=over
1580
31c31b8d 1581=item Arguments: $group_name | \@group_names
79b1bf0a 1582
31c31b8d 1583=item Return Value: \%set_of_loaderrors_per_module
79b1bf0a 1584
1585=back
1586
4a0eed52 1587Returns a hashref containing the actual errors that occurred while attempting
31c31b8d 1588to load each module in the requirement group(s).
5ffa39c7 1589
1590=head2 req_errorlist_for
1591
1592Deprecated method name, equivalent (via proxy) to L</modreq_errorlist_for>.
1593
79b1bf0a 1594EOC
3ca0dcf0 1595
1596#@@
1597#@@ FOOTER
1598#@@
79b1bf0a 1599 push @chunks, <<'EOC';
1600=head1 FURTHER QUESTIONS?
1601
1602Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1603
1604=head1 COPYRIGHT AND LICENSE
1605
a2bd3796 1606This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1607by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1608redistribute it and/or modify it under the same terms as the
1609L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
79b1bf0a 1610EOC
3ca0dcf0 1611
3f5e367a 1612 eval {
1613 open (my $fh, '>', $podfn) or die;
1614 print $fh join ("\n\n", @chunks) or die;
1615 print $fh "\n" or die;
1616 close ($fh) or die;
1617 } or croak( "Unable to write $podfn: " . ( $! || $@ || 'unknown error') );
f6b26571 1618}
1619
8057ed01 16201;