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