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