Emit Optional::Dependencies error messages in a way simplifying c/p for cpanm
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Optional / Dependencies.pm
CommitLineData
8057ed01 1package DBIx::Class::Optional::Dependencies;
2
3use warnings;
4use strict;
5
3f5e367a 6use Carp;
fb39747c 7
8# NO EXTERNAL NON-5.8.1 CORE DEPENDENCIES EVER (e.g. C::A::G)
8057ed01 9# This module is to be loaded by Makefile.PM on a pristine system
10
f6b26571 11# POD is generated automatically by calling _gen_pod from the
12# Makefile.PL in $AUTHOR mode
13
3ade80ee 14# NOTE: the rationale for 2 JSON::Any versions is that
15# we need the newer only to work around JSON::XS, which
16# itself is an optional dep
17my $min_json_any = {
be855469 18 'JSON::Any' => '1.23',
2a2a7b23 19};
3ade80ee 20my $test_and_dist_json_any = {
21 'JSON::Any' => '1.31',
22};
2a2a7b23 23
2b48ebff 24my $moose_basic = {
68de9438 25 'Moose' => '0.98',
26 'MooseX::Types' => '0.21',
d401ab6b 27 'MooseX::Types::LoadableClass' => '0.011',
68de9438 28};
29
30my $replicated = {
31 %$moose_basic,
2b48ebff 32};
33
ebcd0e4f 34my $admin_basic = {
35 %$moose_basic,
3ade80ee 36 %$min_json_any,
68de9438 37 'MooseX::Types::Path::Class' => '0.05',
38 'MooseX::Types::JSON' => '0.02',
68de9438 39};
40
a0361822 41my $admin_script = {
42 %$moose_basic,
43 %$admin_basic,
44 'Getopt::Long::Descriptive' => '0.081',
45 'Text::CSV' => '1.16',
46};
47
68de9438 48my $datetime_basic = {
49 'DateTime' => '0.55',
50 'DateTime::Format::Strptime' => '1.2',
ebcd0e4f 51};
52
c7d50a7d 53my $id_shortener = {
b09652f7 54 'Digest::MD5' => '0',
26022fb5 55 'Math::BigInt' => '1.80',
c7d50a7d 56 'Math::Base36' => '0.07',
57};
58
be68095d 59my $rdbms_sqlite = {
60 'DBD::SQLite' => '0',
61};
62my $rdbms_pg = {
63 'DBD::Pg' => '0',
64};
65my $rdbms_mssql_odbc = {
66 'DBD::ODBC' => '0',
67};
68my $rdbms_mssql_sybase = {
69 'DBD::Sybase' => '0',
70};
56dca25f 71my $rdbms_mssql_ado = {
72 'DBD::ADO' => '0',
73};
726c8f65 74my $rdbms_msaccess_odbc = {
75 'DBD::ODBC' => '0',
76};
77my $rdbms_msaccess_ado = {
78 'DBD::ADO' => '0',
79};
be68095d 80my $rdbms_mysql = {
81 'DBD::mysql' => '0',
82};
83my $rdbms_oracle = {
84 'DBD::Oracle' => '0',
85 %$id_shortener,
86};
87my $rdbms_ase = {
88 'DBD::Sybase' => '0',
89};
90my $rdbms_db2 = {
91 'DBD::DB2' => '0',
92};
199fbc45 93my $rdbms_db2_400 = {
94 'DBD::ODBC' => '0',
95};
96my $rdbms_informix = {
97 'DBD::Informix' => '0',
98};
99my $rdbms_sqlanywhere = {
100 'DBD::SQLAnywhere' => '0',
101};
102my $rdbms_sqlanywhere_odbc = {
103 'DBD::ODBC' => '0',
104};
105my $rdbms_firebird = {
106 'DBD::Firebird' => '0',
107};
108my $rdbms_firebird_interbase = {
109 'DBD::InterBase' => '0',
110};
e02b39b4 111my $rdbms_firebird_odbc = {
112 'DBD::ODBC' => '0',
113};
be68095d 114
8057ed01 115my $reqs = {
8057ed01 116 replicated => {
68de9438 117 req => $replicated,
f6b26571 118 pod => {
119 title => 'Storage::Replicated',
120 desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
121 },
8057ed01 122 },
123
68de9438 124 test_replicated => {
125 req => {
126 %$replicated,
127 'Test::Moose' => '0',
128 },
129 },
130
131
8057ed01 132 admin => {
2b48ebff 133 req => {
ebcd0e4f 134 %$admin_basic,
135 },
136 pod => {
137 title => 'DBIx::Class::Admin',
138 desc => 'Modules required for the DBIx::Class administrative library',
139 },
140 },
141
a4a02f15 142 admin_script => {
ebcd0e4f 143 req => {
a0361822 144 %$admin_script,
2b48ebff 145 },
e144415f 146 pod => {
147 title => 'dbicadmin',
148 desc => 'Modules required for the CLI DBIx::Class interface dbicadmin',
149 },
8057ed01 150 },
151
152 deploy => {
f6b26571 153 req => {
08ac7648 154 'SQL::Translator' => '0.11018',
f6b26571 155 },
156 pod => {
157 title => 'Storage::DBI::deploy()',
5529838f 158 desc => 'Modules required for L<DBIx::Class::Storage::DBI/deployment_statements> and L<DBIx::Class::Schema/deploy>',
f6b26571 159 },
8057ed01 160 },
161
c7d50a7d 162 id_shortener => {
163 req => $id_shortener,
164 },
165
0d374214 166 test_component_accessor => {
167 req => {
168 'Class::Unload' => '0.07',
169 },
170 },
171
a109c954 172 test_pod => {
f6b26571 173 req => {
cbb19edf 174 'Test::Pod' => '1.42',
a109c954 175 },
176 },
177
178 test_podcoverage => {
179 req => {
f6b26571 180 'Test::Pod::Coverage' => '1.08',
181 'Pod::Coverage' => '0.20',
a109c954 182 },
183 },
184
ffce4b65 185 test_whitespace => {
a109c954 186 req => {
8273e845 187 'Test::EOL' => '1.0',
ffce4b65 188 'Test::NoTabs' => '0.9',
f6b26571 189 },
8057ed01 190 },
191
4a233f30 192 test_strictures => {
193 req => {
b2c1212f 194 'Test::Strict' => '0.20',
4a233f30 195 },
196 },
197
2a2a7b23 198 test_prettydebug => {
3ade80ee 199 req => $min_json_any,
2a2a7b23 200 },
201
99503754 202 test_admin_script => {
203 req => {
204 %$admin_script,
3ade80ee 205 %$test_and_dist_json_any,
99503754 206 'JSON' => 0,
be855469 207 'JSON::PP' => 0,
208 'Cpanel::JSON::XS' => 0,
99503754 209 'JSON::XS' => 0,
210 $^O eq 'MSWin32'
211 # for t/admin/10script.t
212 ? ('Win32::ShellQuote' => 0)
213 # DWIW does not compile (./configure even) on win32
214 : ('JSON::DWIW' => 0 )
215 ,
216 }
217 },
218
556c4fe6 219 test_leaks_heavy => {
f6b26571 220 req => {
556c4fe6 221 'Class::MethodCache' => '0.02',
222 'PadWalker' => '1.06',
a109c954 223 },
224 },
f6b26571 225
68de9438 226 test_dt => {
227 req => $datetime_basic,
228 },
229
230 test_dt_sqlite => {
a109c954 231 req => {
68de9438 232 %$datetime_basic,
f6b26571 233 # t/36datetime.t
234 # t/60core.t
235 'DateTime::Format::SQLite' => '0',
68de9438 236 },
237 },
f6b26571 238
68de9438 239 test_dt_mysql => {
240 req => {
241 %$datetime_basic,
9c92bb1c 242 # t/inflate/datetime_mysql.t
243 # (doesn't need Mysql itself)
68de9438 244 'DateTime::Format::MySQL' => '0',
245 },
246 },
9c92bb1c 247
68de9438 248 test_dt_pg => {
249 req => {
250 %$datetime_basic,
9c92bb1c 251 # t/inflate/datetime_pg.t
252 # (doesn't need PG itself)
ab35aeab 253 'DateTime::Format::Pg' => '0.16004',
f6b26571 254 },
8057ed01 255 },
256
68de9438 257 test_cdbicompat => {
f6b26571 258 req => {
f6b26571 259 'Class::DBI::Plugin::DeepAbstractSearch' => '0',
d9bd5195 260 %$datetime_basic,
f6b26571 261 'Time::Piece::MySQL' => '0',
f6b26571 262 'Date::Simple' => '3.03',
263 },
8057ed01 264 },
265
be68095d 266 # this is just for completeness as SQLite
267 # is a core dep of DBIC for testing
268 rdbms_sqlite => {
269 req => {
270 %$rdbms_sqlite,
271 },
272 pod => {
273 title => 'SQLite support',
274 desc => 'Modules required to connect to SQLite',
275 },
276 },
277
278 rdbms_pg => {
279 req => {
a4fc1239 280 # when changing this list make sure to adjust xt/optional_deps.t
be68095d 281 %$rdbms_pg,
282 },
283 pod => {
284 title => 'PostgreSQL support',
285 desc => 'Modules required to connect to PostgreSQL',
286 },
287 },
288
289 rdbms_mssql_odbc => {
290 req => {
291 %$rdbms_mssql_odbc,
292 },
293 pod => {
294 title => 'MSSQL support via DBD::ODBC',
295 desc => 'Modules required to connect to MSSQL via DBD::ODBC',
296 },
297 },
298
299 rdbms_mssql_sybase => {
300 req => {
301 %$rdbms_mssql_sybase,
302 },
303 pod => {
304 title => 'MSSQL support via DBD::Sybase',
56dca25f 305 desc => 'Modules required to connect to MSSQL via DBD::Sybase',
306 },
307 },
308
309 rdbms_mssql_ado => {
310 req => {
311 %$rdbms_mssql_ado,
312 },
313 pod => {
314 title => 'MSSQL support via DBD::ADO (Windows only)',
315 desc => 'Modules required to connect to MSSQL via DBD::ADO. This particular DBD is available on Windows only',
be68095d 316 },
317 },
318
726c8f65 319 rdbms_msaccess_odbc => {
320 req => {
321 %$rdbms_msaccess_odbc,
322 },
323 pod => {
324 title => 'MS Access support via DBD::ODBC',
325 desc => 'Modules required to connect to MS Access via DBD::ODBC',
326 },
327 },
328
329 rdbms_msaccess_ado => {
330 req => {
331 %$rdbms_msaccess_ado,
332 },
333 pod => {
334 title => 'MS Access support via DBD::ADO (Windows only)',
335 desc => 'Modules required to connect to MS Access via DBD::ADO. This particular DBD is available on Windows only',
336 },
337 },
338
be68095d 339 rdbms_mysql => {
340 req => {
341 %$rdbms_mysql,
342 },
343 pod => {
344 title => 'MySQL support',
345 desc => 'Modules required to connect to MySQL',
346 },
347 },
348
349 rdbms_oracle => {
350 req => {
351 %$rdbms_oracle,
352 },
353 pod => {
354 title => 'Oracle support',
355 desc => 'Modules required to connect to Oracle',
356 },
357 },
358
359 rdbms_ase => {
360 req => {
361 %$rdbms_ase,
362 },
363 pod => {
364 title => 'Sybase ASE support',
365 desc => 'Modules required to connect to Sybase ASE',
366 },
367 },
368
369 rdbms_db2 => {
370 req => {
371 %$rdbms_db2,
372 },
373 pod => {
374 title => 'DB2 support',
375 desc => 'Modules required to connect to DB2',
376 },
377 },
378
199fbc45 379 rdbms_db2_400 => {
380 req => {
381 %$rdbms_db2_400,
382 },
383 pod => {
384 title => 'DB2 on AS/400 support',
385 desc => 'Modules required to connect to DB2 on AS/400',
386 },
387 },
388
389 rdbms_informix => {
390 req => {
391 %$rdbms_informix,
392 },
393 pod => {
394 title => 'Informix support',
395 desc => 'Modules required to connect to Informix',
396 },
8273e845 397 },
199fbc45 398
399 rdbms_sqlanywhere => {
400 req => {
401 %$rdbms_sqlanywhere,
402 },
403 pod => {
404 title => 'SQLAnywhere support',
405 desc => 'Modules required to connect to SQLAnywhere',
406 },
8273e845 407 },
199fbc45 408
409 rdbms_sqlanywhere_odbc => {
410 req => {
411 %$rdbms_sqlanywhere_odbc,
412 },
413 pod => {
414 title => 'SQLAnywhere support via DBD::ODBC',
415 desc => 'Modules required to connect to SQLAnywhere via DBD::ODBC',
416 },
8273e845 417 },
199fbc45 418
419 rdbms_firebird => {
420 req => {
421 %$rdbms_firebird,
422 },
423 pod => {
424 title => 'Firebird support',
425 desc => 'Modules required to connect to Firebird',
426 },
8273e845 427 },
199fbc45 428
429 rdbms_firebird_interbase => {
430 req => {
431 %$rdbms_firebird_interbase,
432 },
433 pod => {
434 title => 'Firebird support via DBD::InterBase',
435 desc => 'Modules required to connect to Firebird via DBD::InterBase',
436 },
8273e845 437 },
199fbc45 438
439 rdbms_firebird_odbc => {
440 req => {
441 %$rdbms_firebird_odbc,
442 },
443 pod => {
444 title => 'Firebird support via DBD::ODBC',
445 desc => 'Modules required to connect to Firebird via DBD::ODBC',
446 },
8273e845 447 },
199fbc45 448
be68095d 449# the order does matter because the rdbms support group might require
450# a different version that the test group
68de9438 451 test_rdbms_pg => {
f6b26571 452 req => {
453 $ENV{DBICTEST_PG_DSN}
454 ? (
a4fc1239 455 # when changing this list make sure to adjust xt/optional_deps.t
be68095d 456 %$rdbms_pg,
f6b26571 457 'DBD::Pg' => '2.009002',
f6b26571 458 ) : ()
459 },
8057ed01 460 },
461
afae8507 462 test_rdbms_mssql_odbc => {
463 req => {
464 $ENV{DBICTEST_MSSQL_ODBC_DSN}
465 ? (
be68095d 466 %$rdbms_mssql_odbc,
afae8507 467 ) : ()
468 },
469 },
470
56dca25f 471 test_rdbms_mssql_ado => {
472 req => {
473 $ENV{DBICTEST_MSSQL_ADO_DSN}
474 ? (
475 %$rdbms_mssql_ado,
476 ) : ()
477 },
478 },
479
afae8507 480 test_rdbms_mssql_sybase => {
481 req => {
482 $ENV{DBICTEST_MSSQL_DSN}
483 ? (
be68095d 484 %$rdbms_mssql_sybase,
afae8507 485 ) : ()
486 },
487 },
488
726c8f65 489 test_rdbms_msaccess_odbc => {
490 req => {
491 $ENV{DBICTEST_MSACCESS_ODBC_DSN}
492 ? (
493 %$rdbms_msaccess_odbc,
494 %$datetime_basic,
495 'Data::GUID' => '0',
496 ) : ()
497 },
498 },
499
500 test_rdbms_msaccess_ado => {
501 req => {
502 $ENV{DBICTEST_MSACCESS_ADO_DSN}
503 ? (
504 %$rdbms_msaccess_ado,
505 %$datetime_basic,
506 'Data::GUID' => 0,
507 ) : ()
508 },
509 },
510
68de9438 511 test_rdbms_mysql => {
f6b26571 512 req => {
513 $ENV{DBICTEST_MYSQL_DSN}
514 ? (
be68095d 515 %$rdbms_mysql,
f6b26571 516 ) : ()
517 },
8057ed01 518 },
519
68de9438 520 test_rdbms_oracle => {
f6b26571 521 req => {
522 $ENV{DBICTEST_ORA_DSN}
523 ? (
be68095d 524 %$rdbms_oracle,
f6b26571 525 'DateTime::Format::Oracle' => '0',
e1b7e9b4 526 'DBD::Oracle' => '1.24',
f6b26571 527 ) : ()
528 },
8057ed01 529 },
530
68de9438 531 test_rdbms_ase => {
f6b26571 532 req => {
533 $ENV{DBICTEST_SYBASE_DSN}
534 ? (
be68095d 535 %$rdbms_ase,
f6b26571 536 ) : ()
537 },
8057ed01 538 },
539
68de9438 540 test_rdbms_db2 => {
f58a165c 541 req => {
542 $ENV{DBICTEST_DB2_DSN}
543 ? (
be68095d 544 %$rdbms_db2,
f58a165c 545 ) : ()
546 },
547 },
548
199fbc45 549 test_rdbms_db2_400 => {
550 req => {
551 $ENV{DBICTEST_DB2_400_DSN}
552 ? (
553 %$rdbms_db2_400,
554 ) : ()
555 },
556 },
557
558 test_rdbms_informix => {
559 req => {
560 $ENV{DBICTEST_INFORMIX_DSN}
561 ? (
562 %$rdbms_informix,
563 ) : ()
564 },
565 },
566
567 test_rdbms_sqlanywhere => {
568 req => {
569 $ENV{DBICTEST_SQLANYWHERE_DSN}
570 ? (
571 %$rdbms_sqlanywhere,
572 ) : ()
573 },
574 },
575
576 test_rdbms_sqlanywhere_odbc => {
577 req => {
578 $ENV{DBICTEST_SQLANYWHERE_ODBC_DSN}
579 ? (
580 %$rdbms_sqlanywhere_odbc,
581 ) : ()
582 },
583 },
584
585 test_rdbms_firebird => {
586 req => {
587 $ENV{DBICTEST_FIREBIRD_DSN}
588 ? (
589 %$rdbms_firebird,
590 ) : ()
591 },
592 },
593
594 test_rdbms_firebird_interbase => {
595 req => {
596 $ENV{DBICTEST_FIREBIRD_INTERBASE_DSN}
597 ? (
598 %$rdbms_firebird_interbase,
599 ) : ()
600 },
601 },
602
e02b39b4 603 test_rdbms_firebird_odbc => {
604 req => {
605 $ENV{DBICTEST_FIREBIRD_ODBC_DSN}
606 ? (
607 %$rdbms_firebird_odbc,
608 ) : ()
609 },
610 },
611
42168332 612 test_memcached => {
613 req => {
614 $ENV{DBICTEST_MEMCACHED}
615 ? (
616 'Cache::Memcached' => 0,
617 ) : ()
618 },
619 },
620
344f1f52 621 dist_dir => {
622 req => {
3ade80ee 623 %$test_and_dist_json_any,
b81d8515 624 'ExtUtils::MakeMaker' => '6.64',
06fc872a 625 'Pod::Inherit' => '0.91',
626 },
344f1f52 627 },
628
629 dist_upload => {
630 req => {
631 'CPAN::Uploader' => '0.103001',
632 },
633 },
634
8057ed01 635};
636
f6b26571 637
3ca0dcf0 638
639### Public API
640
641# OO for (mistakenly considered) ease of extensibility, not due to any need to
642# carry state of any sort. This API is currently used outside, so leave as-is.
643# FIXME - make sure to not propagate this further if module is extracted as a
644# standalone library - keep the stupidity to a DBIC-secific shim!
645#
fb39747c 646sub req_list_for {
647 my ($class, $group) = @_;
648
3f5e367a 649 croak "req_list_for() expects a requirement group name"
fb39747c 650 unless $group;
651
f6b26571 652 my $deps = $reqs->{$group}{req}
3f5e367a 653 or croak "Requirement group '$group' does not exist";
fb39747c 654
655 return { %$deps };
656}
657
3ca0dcf0 658sub req_group_list {
659 return { map { $_ => { %{ $reqs->{$_}{req} || {} } } } (keys %$reqs) };
660}
fb39747c 661
3ca0dcf0 662sub req_errorlist_for {
344f1f52 663 my ($class, $group) = @_;
664
3ca0dcf0 665 croak "req_errorlist_for() expects a requirement group name"
344f1f52 666 unless $group;
667
3ca0dcf0 668 return $class->_check_deps($group)->{errorlist};
344f1f52 669}
670
fb39747c 671sub req_ok_for {
672 my ($class, $group) = @_;
673
3f5e367a 674 croak "req_ok_for() expects a requirement group name"
fb39747c 675 unless $group;
676
d8799bab 677 return $class->_check_deps($group)->{status};
fb39747c 678}
679
680sub req_missing_for {
681 my ($class, $group) = @_;
682
3f5e367a 683 croak "req_missing_for() expects a requirement group name"
fb39747c 684 unless $group;
685
d8799bab 686 return $class->_check_deps($group)->{missing};
fb39747c 687}
688
3ca0dcf0 689sub die_unless_req_ok_for {
fb39747c 690 my ($class, $group) = @_;
691
3ca0dcf0 692 croak "die_unless_req_ok_for() expects a requirement group name"
fb39747c 693 unless $group;
694
3ca0dcf0 695 $class->_check_deps($group)->{status}
696 or die sprintf( "Required modules missing, unable to continue: %s\n", $class->_check_deps($group)->{missing} );
fb39747c 697}
698
3ca0dcf0 699
700
701### Private API
702
703our %req_availability_cache;
fb39747c 704sub _check_deps {
705 my ($class, $group) = @_;
706
d8799bab 707 return $req_availability_cache{$group} ||= do {
708
709 my $deps = $class->req_list_for ($group);
710
711 my %errors;
712 for my $mod (keys %$deps) {
713 my $req_line = "require $mod;";
714 if (my $ver = $deps->{$mod}) {
715 $req_line .= "$mod->VERSION($ver);";
716 }
717
718 eval $req_line;
719
720 $errors{$mod} = $@ if $@;
721 }
722
723 my $res;
fb39747c 724
d8799bab 725 if (keys %errors) {
34d2deae 726 my $missing = join (', ', map { $deps->{$_} ? qq("${_}~>=$deps->{$_}") : $_ } (sort keys %errors) );
727 $missing .= " (see $class documentation for details)" if $reqs->{$group}{pod};
d8799bab 728 $res = {
729 status => 0,
730 errorlist => \%errors,
731 missing => $missing,
732 };
fb39747c 733 }
734 else {
d8799bab 735 $res = {
736 status => 1,
737 errorlist => {},
738 missing => '',
739 };
fb39747c 740 }
741
d8799bab 742 $res;
743 };
fb39747c 744}
745
e3fc11e1 746# This is to be called by the author only (automatically in Makefile.PL)
f6b26571 747sub _gen_pod {
47589465 748 my ($class, $distver, $pod_dir) = @_;
31fa1764 749
47589465 750 die "No POD root dir supplied" unless $pod_dir;
31fa1764 751
ccebe1f1 752 $distver ||=
31fa1764 753 eval { require DBIx::Class; DBIx::Class->VERSION; }
754 ||
ccebe1f1 755 die
31fa1764 756"\n\n---------------------------------------------------------------------\n" .
757'Unable to load core DBIx::Class module to determine current version, '.
758'possibly due to missing dependencies. Author-mode autodocumentation ' .
759"halted\n\n" . $@ .
760"\n\n---------------------------------------------------------------------\n"
31fa1764 761 ;
762
3d4c5a84 763 # do not ask for a recent version, use 1.x API calls
47589465 764 # this *may* execute on a smoker with old perl or whatnot
765 require File::Path;
766
767 (my $modfn = __PACKAGE__ . '.pm') =~ s|::|/|g;
768
769 (my $podfn = "$pod_dir/$modfn") =~ s/\.pm$/\.pod/;
770 (my $dir = $podfn) =~ s|/[^/]+$||;
771
772 File::Path::mkpath([$dir]);
773
e3fc11e1 774 my $sqltver = $class->req_list_for ('deploy')->{'SQL::Translator'}
775 or die "Hrmm? No sqlt dep?";
7e3dc46f 776
3ca0dcf0 777
778 my @chunks;
779
780#@@
781#@@ HEADER
782#@@
783 push @chunks, (
6343a203 784 <<"EOC",
af4ac504 785#########################################################################
786##################### A U T O G E N E R A T E D ########################
787#########################################################################
788#
789# The contents of this POD file are auto-generated. Any changes you make
790# will be lost. If you need to change the generated text edit _gen_pod()
791# at the end of $modfn
792#
793EOC
f6b26571 794 '=head1 NAME',
7e3dc46f 795 "$class - Optional module dependency specifications (for module authors)",
3ca0dcf0 796 );
797
798
799#@@
800#@@ SYNOPSIS HEADING
801#@@
802 push @chunks, (
e3fc11e1 803 '=head1 SYNOPSIS',
d8799bab 804 <<"EOS",
7e3dc46f 805Somewhere in your build-file (e.g. L<Module::Install>'s Makefile.PL):
806
807 ...
808
809 configure_requires 'DBIx::Class' => '$distver';
810
811 require $class;
812
be68095d 813 my \$deploy_deps = $class->req_list_for('deploy');
7e3dc46f 814
815 for (keys %\$deploy_deps) {
816 requires \$_ => \$deploy_deps->{\$_};
817 }
818
819 ...
820
821Note that there are some caveats regarding C<configure_requires()>, more info
822can be found at L<Module::Install/configure_requires>
823EOS
3ca0dcf0 824 );
825
826
827#@@
828#@@ DESCRIPTION HEADING
829#@@
830 push @chunks, (
f6b26571 831 '=head1 DESCRIPTION',
832 <<'EOD',
833Some of the less-frequently used features of L<DBIx::Class> have external
834module dependencies on their own. In order not to burden the average user
835with modules he will never use, these optional dependencies are not included
836in the base Makefile.PL. Instead an exception with a descriptive message is
837thrown when a specific feature is missing one or several modules required for
838its operation. This module is the central holding place for the current list
7e3dc46f 839of such dependencies, for DBIx::Class core authors, and DBIx::Class extension
840authors alike.
f6b26571 841EOD
3ca0dcf0 842 );
843
844
845#@@
846#@@ REQUIREMENT GROUPLIST HEADING
847#@@
848 push @chunks, (
f6b26571 849 '=head1 CURRENT REQUIREMENT GROUPS',
850 <<'EOD',
851Dependencies are organized in C<groups> and each group can list one or more
852required modules, with an optional minimum version (or 0 for any version).
ecb68746 853The group name can be used in the
f6b26571 854EOD
855 );
856
857 for my $group (sort keys %$reqs) {
858 my $p = $reqs->{$group}{pod}
859 or next;
860
861 my $modlist = $reqs->{$group}{req}
862 or next;
863
864 next unless keys %$modlist;
865
866 push @chunks, (
867 "=head2 $p->{title}",
868 "$p->{desc}",
869 '=over',
870 ( map { "=item * $_" . ($modlist->{$_} ? " >= $modlist->{$_}" : '') } (sort keys %$modlist) ),
871 '=back',
872 "Requirement group: B<$group>",
873 );
874 }
875
3ca0dcf0 876
877#@@
878#@@ API DOCUMENTATION HEADING
879#@@
f6b26571 880 push @chunks, (
881 '=head1 METHODS',
e3fc11e1 882 '=head2 req_group_list',
883 '=over',
d8799bab 884 '=item Arguments: none',
fb13a49f 885 '=item Return Value: \%list_of_requirement_groups',
e3fc11e1 886 '=back',
d8799bab 887 <<'EOD',
e3fc11e1 888This method should be used by DBIx::Class packagers, to get a hashref of all
889dependencies keyed by dependency group. Each key (group name) can be supplied
890to one of the group-specific methods below.
891EOD
892
f6b26571 893 '=head2 req_list_for',
894 '=over',
895 '=item Arguments: $group_name',
fb13a49f 896 '=item Return Value: \%list_of_module_version_pairs',
f6b26571 897 '=back',
d8799bab 898 <<'EOD',
f6b26571 899This method should be used by DBIx::Class extension authors, to determine the
7e3dc46f 900version of modules a specific feature requires in the B<current> version of
e3fc11e1 901DBIx::Class. See the L</SYNOPSIS> for a real-world
7e3dc46f 902example.
f6b26571 903EOD
904
905 '=head2 req_ok_for',
906 '=over',
907 '=item Arguments: $group_name',
fb13a49f 908 '=item Return Value: 1|0',
f6b26571 909 '=back',
d8799bab 910 <<'EOD',
911Returns true or false depending on whether all modules required by
912C<$group_name> are present on the system and loadable.
913EOD
f6b26571 914
915 '=head2 req_missing_for',
916 '=over',
917 '=item Arguments: $group_name',
fb13a49f 918 '=item Return Value: $error_message_string',
f6b26571 919 '=back',
d8799bab 920 <<"EOD",
f6b26571 921Returns a single line string suitable for inclusion in larger error messages.
922This method would normally be used by DBIx::Class core-module author, to
923indicate to the user that he needs to install specific modules before he will
924be able to use a specific feature.
925
e3fc11e1 926For example if some of the requirements for C<deploy> are not available,
927the returned string could look like:
f6b26571 928
34d2deae 929 "SQL::Translator~>=$sqltver" (see $class documentation for details)
f6b26571 930
931The author is expected to prepend the necessary text to this message before
932returning the actual error seen by the user.
933EOD
934
344f1f52 935 '=head2 die_unless_req_ok_for',
936 '=over',
937 '=item Arguments: $group_name',
938 '=back',
939 <<'EOD',
940Checks if L</req_ok_for> passes for the supplied C<$group_name>, and
941in case of failure throws an exception including the information
942from L</req_missing_for>.
943EOD
944
f6b26571 945 '=head2 req_errorlist_for',
946 '=over',
947 '=item Arguments: $group_name',
fb13a49f 948 '=item Return Value: \%list_of_loaderrors_per_module',
f6b26571 949 '=back',
950 <<'EOD',
4a0eed52 951Returns a hashref containing the actual errors that occurred while attempting
f6b26571 952to load each module in the requirement group.
953EOD
3ca0dcf0 954 );
955
956
957#@@
958#@@ FOOTER
959#@@
960 push @chunks, (
a2bd3796 961 '=head1 FURTHER QUESTIONS?',
962 'Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.',
963 '=head1 COPYRIGHT AND LICENSE',
964 <<'EOL',
965This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
966by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
967redistribute it and/or modify it under the same terms as the
968L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
969EOL
970
f6b26571 971 );
972
3ca0dcf0 973
3f5e367a 974 eval {
975 open (my $fh, '>', $podfn) or die;
976 print $fh join ("\n\n", @chunks) or die;
977 print $fh "\n" or die;
978 close ($fh) or die;
979 } or croak( "Unable to write $podfn: " . ( $! || $@ || 'unknown error') );
f6b26571 980}
981
8057ed01 9821;