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