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