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