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