Switch the main dev branch back to 'master'
[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");
864 local $^W = 0;
865 last SKIP;
866 }
867
868 1;
869}
870
3ca0dcf0 871sub die_unless_req_ok_for {
d1bd396f 872 if (my $err = shift->req_missing_for(shift) ) {
e3a7746c 873 die "Unable to continue due to missing requirements: $err\n";
31c31b8d 874 }
fb39747c 875}
876
3ca0dcf0 877
878
e3a7746c 879### Private functions
880
881# potentially shorten group desc
882sub __envvar_group_desc {
883 my @envs = @{$_[0]};
884
885 my (@res, $last_prefix);
886 while (my $ev = shift @envs) {
887 my ($pref, $sep, $suff) = split / ([\_\-]) (?= [^\_\-]+ \z )/x, $ev;
888
889 if ( defined $sep and ($last_prefix||'') eq $pref ) {
890 push @res, "...${sep}${suff}"
891 }
892 else {
893 push @res, $ev;
894 }
895
896 $last_prefix = $pref if $sep;
897 }
898
899 join '/', @res;
900}
901
9348feb8 902my $groupname_re = qr/ [a-z_] [0-9_a-z]* /x;
461e818a 903my $modname_re = qr/ [A-Z_a-z] [0-9A-Z_a-z]* (?:::[0-9A-Z_a-z]+)* /x;
904my $modver_re = qr/ [0-9]+ (?: \. [0-9]+ )? /x;
905
a3f8bd01 906# Expand includes from a random group in a specific order:
907# nonvariable groups first, then their includes, then the variable groups,
908# then their includes.
909# This allows reliably marking the rest of the mod reqs as variable (this is
910# also why variable includes are currently not allowed)
911sub __expand_includes {
912 my ($groups, $seen) = @_;
913
914 # !! DIFFERENT !! behavior and return depending on invocation mode
915 # (easier to recurse this way)
916 my $is_toplevel = $seen
917 ? 0
918 : !! ($seen = {})
919 ;
3ca0dcf0 920
a3f8bd01 921 my ($res_per_type, $missing_envvars);
d8799bab 922
a3f8bd01 923 # breadth-first evaluation, with non-variable includes on top
924 for my $g (@$groups) {
d8799bab 925
a3f8bd01 926 croak "Invalid requirement group name '$g': only ascii alphanumerics and _ are allowed"
461e818a 927 if $g !~ qr/ \A $groupname_re \z/x;
e163f484 928
a3f8bd01 929 my $r = $dbic_reqs->{$g}
930 or croak "Requirement group '$g' is not defined";
d8799bab 931
a3f8bd01 932 # always do this check *before* the $seen check
933 croak "Group '$g' with variable effective_modreqs can not be specified as an 'include'"
934 if ( $r->{env} and ! $is_toplevel );
d8799bab 935
a3f8bd01 936 next if $seen->{$g}++;
31c31b8d 937
a3f8bd01 938 my $req_type = 'static';
d8799bab 939
a3f8bd01 940 if ( my @e = @{$r->{env}||[]} ) {
e3a7746c 941
a3f8bd01 942 croak "Unexpected 'env' attribute under group '$g' (only allowed in test_* groups)"
943 unless $g =~ /^test_/;
e3a7746c 944
a3f8bd01 945 croak "Unexpected *odd* list in 'env' under group '$g'"
e3a7746c 946 if @e % 2;
947
e3a7746c 948 # deconstruct the whole thing
a3f8bd01 949 my (@group_envnames_list, $some_envs_required, $some_required_missing);
e3a7746c 950 while (@e) {
951 push @group_envnames_list, my $envname = shift @e;
952
953 # env required or not
954 next unless shift @e;
955
956 $some_envs_required ||= 1;
957
a3f8bd01 958 $some_required_missing ||= (
e3a7746c 959 ! defined $ENV{$envname}
960 or
961 ! length $ENV{$envname}
962 );
963 }
964
a3f8bd01 965 croak "None of the envvars in group '$g' declared as required, making the requirement moot"
e3a7746c 966 unless $some_envs_required;
967
a3f8bd01 968 if ($some_required_missing) {
969 push @{$missing_envvars->{$g}}, \@group_envnames_list;
970 $req_type = 'variable';
971 }
972 }
973
974 push @{$res_per_type->{"base_${req_type}"}}, $g;
975
976 if (my $i = $dbic_reqs->{$g}{include}) {
977 $i = [ $i ] unless ref $i eq 'ARRAY';
978
979 croak "Malformed 'include' for group '$g': must be another existing group name or arrayref of existing group names"
980 unless @$i;
981
982 push @{$res_per_type->{"incs_${req_type}"}}, @$i;
e3a7746c 983 }
a3f8bd01 984 }
985
986 my @ret = map {
987 @{ $res_per_type->{"base_${_}"} || [] },
988 ( $res_per_type->{"incs_${_}"} ? __expand_includes( $res_per_type->{"incs_${_}"}, $seen ) : () ),
989 } qw(static variable);
990
991 return ! $is_toplevel ? @ret : do {
992 my $rv = {};
993 $rv->{$_} = {
994 idx => 1 + keys %$rv,
995 missing_envvars => $missing_envvars->{$_},
996 } for @ret;
2baba3d9 997 $rv->{$_}{user_requested} = 1 for @$groups;
a3f8bd01 998 $rv;
999 };
1000}
1001
1002### Private OO API
1003our %req_unavailability_cache;
1004
1005# this method is just a lister and envvar/metadata checker - it does not try to load anything
1006sub _groups_to_reqs {
461e818a 1007 my ($self, $want) = @_;
a3f8bd01 1008
461e818a 1009 $want = [ $want || () ]
1010 unless ref $want eq 'ARRAY';
a3f8bd01 1011
1012 croak "@{[ (caller(1))[3] ]}() expects a requirement group name or arrayref of group names"
461e818a 1013 unless @$want;
e3a7746c 1014
a3f8bd01 1015 my $ret = {
1016 modreqs => {},
1017 modreqs_fully_documented => 1,
1018 };
e163f484 1019
461e818a 1020 my $groups;
1021 for my $piece (@$want) {
1022 if ($piece =~ qr/ \A $groupname_re \z /x) {
1023 push @$groups, $piece;
1024 }
1025 elsif ( my ($mod, $ver) = $piece =~ qr/ \A ($modname_re) \>\= ($modver_re) \z /x ) {
1026 croak "Ad hoc module specification lists '$mod' twice"
1027 if exists $ret->{modreqs}{$mod};
1028
1029 croak "Ad hoc module specification '${mod} >= $ver' (or greater) not listed in the test_adhoc optdep group" if (
1030 ! defined $dbic_reqs->{test_adhoc}{req}{$mod}
1031 or
1032 $dbic_reqs->{test_adhoc}{req}{$mod} < $ver
1033 );
1034
1035 $ret->{modreqs}{$mod} = $ver;
1036 $ret->{modreqs_fully_documented} = 0;
1037 }
1038 else {
1039 croak "Unsupported argument '$piece' supplied to @{[ (caller(1))[3] ]}()"
1040 }
1041 }
1042
a3f8bd01 1043 my $all_groups = __expand_includes($groups);
e163f484 1044
2baba3d9 1045 # pre-assemble list of augmentations, perform basic sanity checks
1046 # Note that below we *DO NOT* respect the source/target reationship, but
1047 # instead always default to augment the "later" group
1048 # This is done so that the "stable/variable" boundary keeps working as
1049 # expected
1050 my $augmentations;
1051 for my $requesting_group (keys %$all_groups) {
1052 if (my $ag = $dbic_reqs->{$requesting_group}{augment}) {
1053 for my $target_group (keys %$ag) {
1054
1055 croak "Group '$requesting_group' claims to augment a non-existent group '$target_group'"
1056 unless $dbic_reqs->{$target_group};
1057
1058 croak "Augmentation combined with variable effective_modreqs currently unsupported for group '$requesting_group'"
1059 if $dbic_reqs->{$requesting_group}{env};
1060
1061 croak "Augmentation of group '$target_group' with variable effective_modreqs unsupported (requested by '$requesting_group')"
1062 if $dbic_reqs->{$target_group}{env};
1063
1064 if (my @foreign = grep { $_ ne 'req' } keys %{$ag->{$target_group}} ) {
1065 croak "Only 'req' augmentations are currently supported (group '$requesting_group' attempts to alter '$foreign[0]' of group '$target_group'";
1066 }
1067
1068 $ret->{augments}{$target_group} = 1;
1069
1070 # no augmentation for stuff that hasn't been selected
1071 if ( $all_groups->{$target_group} and my $ar = $ag->{$target_group}{req} ) {
1072 push @{$augmentations->{
1073 ( $all_groups->{$requesting_group}{idx} < $all_groups->{$target_group}{idx} )
1074 ? $target_group
1075 : $requesting_group
1076 }}, $ar;
1077 }
1078 }
1079 }
1080 }
1081
a3f8bd01 1082 for my $group (sort { $all_groups->{$a}{idx} <=> $all_groups->{$b}{idx} } keys %$all_groups ) {
e163f484 1083
a3f8bd01 1084 my $group_reqs = $dbic_reqs->{$group}{req};
e163f484 1085
a3f8bd01 1086 # sanity-check
2baba3d9 1087 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
1088 for (keys %$req_bag) {
e163f484 1089
461e818a 1090 $_ =~ / \A $modname_re \z /x
2baba3d9 1091 or croak "Requirement '$_' in group '$group' is not a valid module name";
a3f8bd01 1092
2baba3d9 1093 # !!!DO NOT CHANGE!!!
1094 # remember - version.pm may not be available on the system
1095 croak "Requirement '$_' in group '$group' specifies an invalid version '$req_bag->{$_}' (only plain non-underscored floating point decimals are supported)"
461e818a 1096 if ( ($req_bag->{$_}||0) !~ qr/ \A $modver_re \z /x );
2baba3d9 1097 }
a3f8bd01 1098 }
e163f484 1099
a3f8bd01 1100 if (my $e = $all_groups->{$group}{missing_envvars}) {
1101 push @{$ret->{missing_envvars}}, @$e;
e163f484 1102 }
1103
31c31b8d 1104 # assemble into the final ret
e3a7746c 1105 for my $type (
1106 'modreqs',
a3f8bd01 1107 ( $ret->{missing_envvars} ? () : 'effective_modreqs' ),
e3a7746c 1108 ) {
2baba3d9 1109 for my $req_bag ($group_reqs, @{ $augmentations->{$group} || [] } ) {
e163f484 1110 for my $mod (keys %$req_bag) {
31c31b8d 1111
e163f484 1112 $ret->{$type}{$mod} = $req_bag->{$mod}||0 if (
31c31b8d 1113
e163f484 1114 ! exists $ret->{$type}{$mod}
1115 or
1116 # we sanitized the version to be numeric above - we can just -gt it
1117 ($req_bag->{$mod}||0) > $ret->{$type}{$mod}
fb39747c 1118
e163f484 1119 );
1120 }
e3a7746c 1121 }
fb39747c 1122 }
31c31b8d 1123
2baba3d9 1124 $ret->{modreqs_fully_documented} &&= !!$dbic_reqs->{$group}{pod}
1125 if $all_groups->{$group}{user_requested};
cb551b07 1126
1127 $ret->{release_testing_mandatory} ||= !!$dbic_reqs->{$group}{release_testing_mandatory};
31c31b8d 1128 }
1129
1130 return $ret;
1131}
1132
1133
250d9e55 1134# this method tries to find/load specified modreqs and returns a hashref of
31c31b8d 1135# module/loaderror pairs for anything that failed
1136sub _errorlist_for_modreqs {
1137 # args supposedly already went through _groups_to_reqs and are therefore sanitized
1138 # safe to eval at will
1139 my ($self, $reqs) = @_;
1140
1141 my $ret;
1142
1143 for my $m ( keys %$reqs ) {
1144 my $v = $reqs->{$m};
1145
1146 if (! exists $req_unavailability_cache{$m}{$v} ) {
1147 local $@;
1148 eval( "require $m;" . ( $v ? "$m->VERSION(q($v))" : '' ) );
1149 $req_unavailability_cache{$m}{$v} = $@;
fb39747c 1150 }
1151
31c31b8d 1152 $ret->{$m} = $req_unavailability_cache{$m}{$v}
1153 if $req_unavailability_cache{$m}{$v};
1154 }
1155
1156 $ret;
fb39747c 1157}
1158
250d9e55 1159# Unlike the above DO NOT try to load anything
1160# This is executed when some needed envvars are not available
1161# which in turn means a module load will never be reached anyway
1162# This is important because some modules (especially DBDs) can be
1163# *really* fickle when a require() is attempted, with pretty confusing
1164# side-effects (especially on windows)
1165sub _list_physically_missing_modules {
1166 my ($self, $modreqs) = @_;
1167
1168 # in case there is a coderef in @INC there is nothing we can definitively prove
1169 # so short circuit directly
1170 return '' if grep { length ref $_ } @INC;
1171
1172 my @definitely_missing;
1173 for my $mod (keys %$modreqs) {
1174 (my $fn = $mod . '.pm') =~ s|::|/|g;
1175
1176 push @definitely_missing, $mod unless grep
1177 # this should work on any combination of slashes
1178 { $_ and -d $_ and -f "$_/$fn" and -r "$_/$fn" }
1179 @INC
1180 ;
1181 }
1182
1183 join ' ', map
34f354c3 1184 { $modreqs->{$_} ? "$_~$modreqs->{$_}" : $_ }
250d9e55 1185 sort { lc($a) cmp lc($b) } @definitely_missing
1186 ;
1187}
1188
31c31b8d 1189
e3fc11e1 1190# This is to be called by the author only (automatically in Makefile.PL)
f6b26571 1191sub _gen_pod {
47589465 1192 my ($class, $distver, $pod_dir) = @_;
31fa1764 1193
47589465 1194 die "No POD root dir supplied" unless $pod_dir;
31fa1764 1195
ccebe1f1 1196 $distver ||=
31fa1764 1197 eval { require DBIx::Class; DBIx::Class->VERSION; }
1198 ||
ccebe1f1 1199 die
31fa1764 1200"\n\n---------------------------------------------------------------------\n" .
1201'Unable to load core DBIx::Class module to determine current version, '.
1202'possibly due to missing dependencies. Author-mode autodocumentation ' .
1203"halted\n\n" . $@ .
1204"\n\n---------------------------------------------------------------------\n"
31fa1764 1205 ;
1206
3d4c5a84 1207 # do not ask for a recent version, use 1.x API calls
47589465 1208 # this *may* execute on a smoker with old perl or whatnot
1209 require File::Path;
1210
1211 (my $modfn = __PACKAGE__ . '.pm') =~ s|::|/|g;
1212
1213 (my $podfn = "$pod_dir/$modfn") =~ s/\.pm$/\.pod/;
1214 (my $dir = $podfn) =~ s|/[^/]+$||;
1215
1216 File::Path::mkpath([$dir]);
1217
31c31b8d 1218 my $sqltver = $class->req_list_for('deploy')->{'SQL::Translator'}
e3fc11e1 1219 or die "Hrmm? No sqlt dep?";
7e3dc46f 1220
3ca0dcf0 1221
1222 my @chunks;
1223
1224#@@
1225#@@ HEADER
1226#@@
79b1bf0a 1227 push @chunks, <<"EOC";
af4ac504 1228#########################################################################
1229##################### A U T O G E N E R A T E D ########################
1230#########################################################################
1231#
1232# The contents of this POD file are auto-generated. Any changes you make
1233# will be lost. If you need to change the generated text edit _gen_pod()
1234# at the end of $modfn
1235#
79b1bf0a 1236
1237=head1 NAME
1238
1239$class - Optional module dependency specifications (for module authors)
af4ac504 1240EOC
3ca0dcf0 1241
1242
1243#@@
1244#@@ SYNOPSIS HEADING
1245#@@
79b1bf0a 1246 push @chunks, <<"EOC";
1247=head1 SYNOPSIS
1248
1249Somewhere in your build-file (e.g. L<ExtUtils::MakeMaker>'s F<Makefile.PL>):
7e3dc46f 1250
1251 ...
1252
79b1bf0a 1253 \$EUMM_ARGS{CONFIGURE_REQUIRES} = {
1254 \%{ \$EUMM_ARGS{CONFIGURE_REQUIRES} || {} },
1255 'DBIx::Class' => '$distver',
1256 };
7e3dc46f 1257
79b1bf0a 1258 ...
7e3dc46f 1259
2baba3d9 1260 my %DBIC_DEPLOY_AND_ORACLE_DEPS = %{ eval {
79b1bf0a 1261 require $class;
54a9a088 1262 $class->req_list_for([qw( deploy rdbms_oracle ic_dt )]);
79b1bf0a 1263 } || {} };
7e3dc46f 1264
79b1bf0a 1265 \$EUMM_ARGS{PREREQ_PM} = {
2baba3d9 1266 \%DBIC_DEPLOY_AND_ORACLE_DEPS,
79b1bf0a 1267 \%{ \$EUMM_ARGS{PREREQ_PM} || {} },
1268 };
7e3dc46f 1269
1270 ...
1271
79b1bf0a 1272 ExtUtils::MakeMaker::WriteMakefile(\%EUMM_ARGS);
1273
1274B<Note>: The C<eval> protection within the example is due to support for
1275requirements during L<the C<configure> build phase|CPAN::Meta::Spec/Phases>
1276not being available on a sufficient portion of production installations of
1277Perl. Robust support for such dependency requirements is available in the
1278L<CPAN> installer only since version C<1.94_56> first made available for
1279production with perl version C<5.12>. It is the belief of the current
1280maintainer that support for requirements during the C<configure> build phase
1281will not be sufficiently ubiquitous until the B<year 2020> at the earliest,
1282hence the extra care demonstrated above. It should also be noted that some
12833rd party installers (e.g. L<cpanminus|App::cpanminus>) do the right thing
1284with configure requirements independent from the versions of perl and CPAN
1285available.
1286EOC
3ca0dcf0 1287
1288
1289#@@
1290#@@ DESCRIPTION HEADING
1291#@@
79b1bf0a 1292 push @chunks, <<'EOC';
1293=head1 DESCRIPTION
1294
f6b26571 1295Some of the less-frequently used features of L<DBIx::Class> have external
1296module dependencies on their own. In order not to burden the average user
79b1bf0a 1297with modules they will never use, these optional dependencies are not included
f6b26571 1298in the base Makefile.PL. Instead an exception with a descriptive message is
79b1bf0a 1299thrown when a specific feature can't find one or several modules required for
1300its operation. This module is the central holding place for the current list
7e3dc46f 1301of such dependencies, for DBIx::Class core authors, and DBIx::Class extension
1302authors alike.
79b1bf0a 1303
1304Dependencies are organized in L<groups|/CURRENT REQUIREMENT GROUPS> where each
1305group can list one or more required modules, with an optional minimum version
e3a7746c 1306(or 0 for any version). In addition groups prefixed with C<test_> can specify
1307a set of environment variables, some (or all) of which are marked as required
1308for the group to be considered by L</req_list_for>
1309
1310Each group name (or a combination thereof) can be used in the
1311L<public methods|/METHODS> as described below.
79b1bf0a 1312EOC
3ca0dcf0 1313
1314
1315#@@
1316#@@ REQUIREMENT GROUPLIST HEADING
1317#@@
79b1bf0a 1318 push @chunks, '=head1 CURRENT REQUIREMENT GROUPS';
f6b26571 1319
2baba3d9 1320 my $standalone_info;
1321
31c31b8d 1322 for my $group (sort keys %$dbic_reqs) {
f6b26571 1323
2baba3d9 1324 my $info = $standalone_info->{$group} ||= $class->_groups_to_reqs($group);
f6b26571 1325
2baba3d9 1326 next unless (
1327 $info->{modreqs_fully_documented}
1328 and
1329 ( $info->{augments} or $info->{modreqs} )
1330 );
1331
1332 my $p = $dbic_reqs->{$group}{pod};
f6b26571 1333
1334 push @chunks, (
1335 "=head2 $p->{title}",
2baba3d9 1336 "=head3 $group",
1337 $p->{desc},
f6b26571 1338 '=over',
f6b26571 1339 );
2baba3d9 1340
1341 if ( keys %{ $info->{modreqs}||{} } ) {
1342 push @chunks, map
1343 { "=item * $_" . ($info->{modreqs}{$_} ? " >= $info->{modreqs}{$_}" : '') }
1344 ( sort keys %{ $info->{modreqs} } )
1345 ;
1346 }
1347 else {
1348 push @chunks, '=item * No standalone requirements',
1349 }
1350
1351 push @chunks, '=back';
1352
1353 for my $ag ( sort keys %{ $info->{augments} || {} } ) {
1354 my $ag_info = $standalone_info->{$ag} ||= $class->_groups_to_reqs($ag);
1355
1356 my $newreqs = $class->modreq_list_for([ $group, $ag ]);
1357 for (keys %$newreqs) {
1358 delete $newreqs->{$_} if (
1359 ( defined $info->{modreqs}{$_} and $info->{modreqs}{$_} == $newreqs->{$_} )
1360 or
1361 ( defined $ag_info->{modreqs}{$_} and $ag_info->{modreqs}{$_} == $newreqs->{$_} )
1362 );
1363 }
1364
1365 if (keys %$newreqs) {
1366 push @chunks, (
1367 "Combined with L</$ag> additionally requires:",
1368 '=over',
1369 ( map
1370 { "=item * $_" . ($newreqs->{$_} ? " >= $newreqs->{$_}" : '') }
1371 ( sort keys %$newreqs )
1372 ),
1373 '=back',
1374 );
1375 }
1376 }
f6b26571 1377 }
1378
3ca0dcf0 1379
1380#@@
1381#@@ API DOCUMENTATION HEADING
1382#@@
79b1bf0a 1383 push @chunks, <<'EOC';
1384
afb8fc52 1385=head1 IMPORT-LIKE ACTIONS
1386
1387Even though this module is not an L<Exporter>, it recognizes several C<actions>
1388supplied to its C<import> method.
1389
cb551b07 1390=head2 -skip_all_without
1391
1392=over
1393
1394=item Arguments: @group_names
1395
1396=back
1397
1398A convenience wrapper for use during testing:
1399EOC
1400
1401 push @chunks, " use $class -skip_all_without => qw(admin test_rdbms_mysql);";
1402
1403 push @chunks, 'Roughly equivalent to the following code:';
1404
1405 push @chunks, sprintf <<'EOS', ($class) x 2;
1406
1407 BEGIN {
1408 require %s;
1409 if ( my $missing = %s->req_missing_for(\@group_names_) ) {
1410 print "1..0 # SKIP requirements not satisfied: $missing\n";
1411 exit 0;
1412 }
1413 }
1414EOS
1415
1416 push @chunks, <<'EOC';
1417
1418It also takes into account the C<RELEASE_TESTING> environment variable and
1419behaves like L</-die_without> for any requirement groups marked as
1420C<release_testing_mandatory>.
1421
afb8fc52 1422=head2 -die_without
1423
1424=over
1425
1426=item Arguments: @group_names
1427
1428=back
1429
1430A convenience wrapper around L</die_unless_req_ok_for>:
1431EOC
1432
1433 push @chunks, " use $class -die_without => qw(deploy admin);";
1434
1435 push @chunks, <<'EOC';
1436
1437=head2 -list_missing
1438
1439=over
1440
1441=item Arguments: @group_names
1442
1443=back
1444
1445A convenience wrapper around L</modreq_missing_for>:
1446
1447 perl -Ilib -MDBIx::Class::Optional::Dependencies=-list_missing,deploy,admin | cpanm
1448
79b1bf0a 1449=head1 METHODS
1450
1451=head2 req_group_list
1452
1453=over
1454
1455=item Arguments: none
1456
1457=item Return Value: \%list_of_requirement_groups
1458
1459=back
1460
e3fc11e1 1461This method should be used by DBIx::Class packagers, to get a hashref of all
31c31b8d 1462dependencies B<keyed> by dependency group. Each key (group name), or a combination
1463thereof (as an arrayref) can be supplied to the methods below.
79b1bf0a 1464The B<values> of the returned hash are currently a set of options B<without a
1465well defined structure>. If you have use for any of the contents - contact the
1466maintainers, instead of treating this as public (left alone stable) API.
1467
1468=head2 req_list_for
1469
1470=over
1471
31c31b8d 1472=item Arguments: $group_name | \@group_names
79b1bf0a 1473
31c31b8d 1474=item Return Value: \%set_of_module_version_pairs
79b1bf0a 1475
1476=back
1477
f6b26571 1478This method should be used by DBIx::Class extension authors, to determine the
31c31b8d 1479version of modules a specific set of features requires for this version of
e3a7746c 1480DBIx::Class (regardless of their availability on the system).
1481See the L</SYNOPSIS> for a real-world example.
1482
1483When handling C<test_*> groups this method behaves B<differently> from
1484L</modreq_list_for> below (and is the only such inconsistency among the
1485C<req_*> methods). If a particular group declares as requirements some
1486C<environment variables> and these requirements are not satisfied (the envvars
1487are unset) - then the C<module requirements> of this group are not included in
1488the returned list.
1489
1490=head2 modreq_list_for
1491
1492=over
1493
1494=item Arguments: $group_name | \@group_names
1495
1496=item Return Value: \%set_of_module_version_pairs
1497
1498=back
1499
1500Same as L</req_list_for> but does not take into consideration any
1501C<environment variable requirements> - returns just the list of required
1502modules.
79b1bf0a 1503
1504=head2 req_ok_for
1505
1506=over
1507
31c31b8d 1508=item Arguments: $group_name | \@group_names
79b1bf0a 1509
1510=item Return Value: 1|0
1511
1512=back
1513
e3a7746c 1514Returns true or false depending on whether all modules/envvars required by
1515the group(s) are loadable/set on the system.
79b1bf0a 1516
1517=head2 req_missing_for
1518
1519=over
1520
31c31b8d 1521=item Arguments: $group_name | \@group_names
79b1bf0a 1522
1523=item Return Value: $error_message_string
1524
1525=back
1526
31c31b8d 1527Returns a single-line string suitable for inclusion in larger error messages.
e3a7746c 1528This method would normally be used by DBIx::Class core features, to indicate to
1529the user that they need to install specific modules and/or set specific
1530environment variables before being able to use a specific feature set.
f6b26571 1531
e3fc11e1 1532For example if some of the requirements for C<deploy> are not available,
1533the returned string could look like:
79b1bf0a 1534EOC
f6b26571 1535
34f354c3 1536 push @chunks, qq{ "SQL::Translator~$sqltver" (see $class documentation for details)};
f6b26571 1537
79b1bf0a 1538 push @chunks, <<'EOC';
f6b26571 1539The author is expected to prepend the necessary text to this message before
e3a7746c 1540returning the actual error seen by the user. See also L</modreq_missing_for>
1541
1542=head2 modreq_missing_for
f6b26571 1543
e3a7746c 1544=over
1545
1546=item Arguments: $group_name | \@group_names
1547
1548=item Return Value: $error_message_string
1549
1550=back
1551
1552Same as L</req_missing_for> except that the error string is guaranteed to be
1553either empty, or contain a set of module requirement specifications suitable
1554for piping to e.g. L<cpanminus|App::cpanminus>. The method explicitly does not
1555attempt to validate the state of required environment variables (if any).
1556
1557For instance if some of the requirements for C<deploy> are not available,
1558the returned string could look like:
1559EOC
1560
34f354c3 1561 push @chunks, qq{ "SQL::Translator~$sqltver"};
e3a7746c 1562
1563 push @chunks, <<'EOC';
afb8fc52 1564
1565See also L</-list_missing>.
1566
461e818a 1567=head2 skip_without
1568
1569=over
1570
1571=item Arguments: $group_name | \@group_names
1572
1573=back
1574
1575A convenience wrapper around L<skip|Test::More/SKIP>. It does not take neither
1576a reason (it is generated by L</req_missing_for>) nor an amount of skipped tests
1577(it is always C<1>, thus mandating unconditional use of
1578L<done_testing|Test::More/done_testing>). Most useful in combination with ad hoc
1579requirement specifications:
1580EOC
1581
1582 push @chunks, <<EOC;
1583 SKIP: {
1584 $class->skip_without([ deploy YAML>=0.90 ]);
1585
1586 ...
1587 }
1588EOC
1589
1590 push @chunks, <<'EOC';
1591
79b1bf0a 1592=head2 die_unless_req_ok_for
1593
1594=over
1595
31c31b8d 1596=item Arguments: $group_name | \@group_names
79b1bf0a 1597
1598=back
1599
31c31b8d 1600Checks if L</req_ok_for> passes for the supplied group(s), and
344f1f52 1601in case of failure throws an exception including the information
afb8fc52 1602from L</req_missing_for>. See also L</-die_without>.
79b1bf0a 1603
5ffa39c7 1604=head2 modreq_errorlist_for
79b1bf0a 1605
1606=over
1607
31c31b8d 1608=item Arguments: $group_name | \@group_names
79b1bf0a 1609
31c31b8d 1610=item Return Value: \%set_of_loaderrors_per_module
79b1bf0a 1611
1612=back
1613
4a0eed52 1614Returns a hashref containing the actual errors that occurred while attempting
31c31b8d 1615to load each module in the requirement group(s).
5ffa39c7 1616
1617=head2 req_errorlist_for
1618
1619Deprecated method name, equivalent (via proxy) to L</modreq_errorlist_for>.
1620
79b1bf0a 1621EOC
3ca0dcf0 1622
1623#@@
1624#@@ FOOTER
1625#@@
79b1bf0a 1626 push @chunks, <<'EOC';
1627=head1 FURTHER QUESTIONS?
1628
1629Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1630
1631=head1 COPYRIGHT AND LICENSE
1632
a2bd3796 1633This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1634by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1635redistribute it and/or modify it under the same terms as the
1636L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
79b1bf0a 1637EOC
3ca0dcf0 1638
3f5e367a 1639 eval {
1640 open (my $fh, '>', $podfn) or die;
1641 print $fh join ("\n\n", @chunks) or die;
1642 print $fh "\n" or die;
1643 close ($fh) or die;
1644 } or croak( "Unable to write $podfn: " . ( $! || $@ || 'unknown error') );
f6b26571 1645}
1646
8057ed01 16471;