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