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