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