Fix RT61503 (bump DateTime::Format::Pg dep)
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Optional / Dependencies.pm
CommitLineData
8057ed01 1package DBIx::Class::Optional::Dependencies;
2
3use warnings;
4use strict;
5
fb39747c 6use Carp;
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
2b48ebff 14my $moose_basic = {
68de9438 15 'Moose' => '0.98',
16 'MooseX::Types' => '0.21',
17};
18
19my $replicated = {
20 %$moose_basic,
21 'Hash::Merge' => '0.12',
2b48ebff 22};
23
ebcd0e4f 24my $admin_basic = {
25 %$moose_basic,
68de9438 26 'MooseX::Types::Path::Class' => '0.05',
27 'MooseX::Types::JSON' => '0.02',
28 'JSON::Any' => '1.22',
29 'namespace::autoclean' => '0.09',
30};
31
32my $datetime_basic = {
33 'DateTime' => '0.55',
34 'DateTime::Format::Strptime' => '1.2',
ebcd0e4f 35};
36
8057ed01 37my $reqs = {
38 dist => {
39 #'Module::Install::Pod::Inherit' => '0.01',
40 },
41
42 replicated => {
68de9438 43 req => $replicated,
f6b26571 44 pod => {
45 title => 'Storage::Replicated',
46 desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
47 },
8057ed01 48 },
49
68de9438 50 test_replicated => {
51 req => {
52 %$replicated,
53 'Test::Moose' => '0',
54 },
55 },
56
57
8057ed01 58 admin => {
2b48ebff 59 req => {
ebcd0e4f 60 %$admin_basic,
61 },
62 pod => {
63 title => 'DBIx::Class::Admin',
64 desc => 'Modules required for the DBIx::Class administrative library',
65 },
66 },
67
a4a02f15 68 admin_script => {
ebcd0e4f 69 req => {
2b48ebff 70 %$moose_basic,
ebcd0e4f 71 %$admin_basic,
2b48ebff 72 'Getopt::Long::Descriptive' => '0.081',
2b48ebff 73 'Text::CSV' => '1.16',
74 },
e144415f 75 pod => {
76 title => 'dbicadmin',
77 desc => 'Modules required for the CLI DBIx::Class interface dbicadmin',
78 },
8057ed01 79 },
80
81 deploy => {
f6b26571 82 req => {
9e34d554 83 'SQL::Translator' => '0.11006',
f6b26571 84 },
85 pod => {
86 title => 'Storage::DBI::deploy()',
87 desc => 'Modules required for L<DBIx::Class::Storage::DBI/deploy> and L<DBIx::Class::Storage::DBI/deploymen_statements>',
88 },
8057ed01 89 },
90
a109c954 91
92 test_pod => {
f6b26571 93 req => {
14d17d71 94 'Test::Pod' => '1.41',
a109c954 95 },
96 },
97
98 test_podcoverage => {
99 req => {
f6b26571 100 'Test::Pod::Coverage' => '1.08',
101 'Pod::Coverage' => '0.20',
a109c954 102 },
103 },
104
105 test_notabs => {
106 req => {
d146b340 107 'Test::NoTabs' => '0.9',
a109c954 108 },
109 },
110
111 test_eol => {
112 req => {
d146b340 113 'Test::EOL' => '0.6',
f6b26571 114 },
8057ed01 115 },
116
a109c954 117 test_cycle => {
f6b26571 118 req => {
f6b26571 119 'Test::Memory::Cycle' => '0',
120 'Devel::Cycle' => '1.10',
a109c954 121 },
122 },
f6b26571 123
68de9438 124 test_dt => {
125 req => $datetime_basic,
126 },
127
128 test_dt_sqlite => {
a109c954 129 req => {
68de9438 130 %$datetime_basic,
f6b26571 131 # t/36datetime.t
132 # t/60core.t
133 'DateTime::Format::SQLite' => '0',
68de9438 134 },
135 },
f6b26571 136
68de9438 137 test_dt_mysql => {
138 req => {
139 %$datetime_basic,
9c92bb1c 140 # t/inflate/datetime_mysql.t
141 # (doesn't need Mysql itself)
68de9438 142 'DateTime::Format::MySQL' => '0',
143 },
144 },
9c92bb1c 145
68de9438 146 test_dt_pg => {
147 req => {
148 %$datetime_basic,
9c92bb1c 149 # t/inflate/datetime_pg.t
150 # (doesn't need PG itself)
ab35aeab 151 'DateTime::Format::Pg' => '0.16004',
f6b26571 152 },
8057ed01 153 },
154
68de9438 155 test_cdbicompat => {
f6b26571 156 req => {
157 'DBIx::ContextualFetch' => '0',
158 'Class::DBI::Plugin::DeepAbstractSearch' => '0',
159 'Class::Trigger' => '0',
160 'Time::Piece::MySQL' => '0',
161 'Clone' => '0',
162 'Date::Simple' => '3.03',
163 },
8057ed01 164 },
165
68de9438 166 test_rdbms_pg => {
f6b26571 167 req => {
168 $ENV{DBICTEST_PG_DSN}
169 ? (
170 'Sys::SigAction' => '0',
171 'DBD::Pg' => '2.009002',
f6b26571 172 ) : ()
173 },
8057ed01 174 },
175
68de9438 176 test_rdbms_mysql => {
f6b26571 177 req => {
178 $ENV{DBICTEST_MYSQL_DSN}
179 ? (
f6b26571 180 'DBD::mysql' => '0',
181 ) : ()
182 },
8057ed01 183 },
184
68de9438 185 test_rdbms_oracle => {
f6b26571 186 req => {
187 $ENV{DBICTEST_ORA_DSN}
188 ? (
189 'DateTime::Format::Oracle' => '0',
e1b7e9b4 190 'DBD::Oracle' => '1.24',
f6b26571 191 ) : ()
192 },
8057ed01 193 },
194
68de9438 195 test_rdbms_ase => {
f6b26571 196 req => {
197 $ENV{DBICTEST_SYBASE_DSN}
198 ? (
199 'DateTime::Format::Sybase' => 0,
200 ) : ()
201 },
8057ed01 202 },
203
68de9438 204 test_rdbms_db2 => {
f58a165c 205 req => {
206 $ENV{DBICTEST_DB2_DSN}
207 ? (
208 'DBD::DB2' => 0,
209 ) : ()
210 },
211 },
212
8057ed01 213};
214
f6b26571 215
fb39747c 216sub req_list_for {
217 my ($class, $group) = @_;
218
f6b26571 219 croak "req_list_for() expects a requirement group name"
fb39747c 220 unless $group;
221
f6b26571 222 my $deps = $reqs->{$group}{req}
223 or croak "Requirement group '$group' does not exist";
fb39747c 224
225 return { %$deps };
226}
227
228
229our %req_availability_cache;
230sub req_ok_for {
231 my ($class, $group) = @_;
232
233 croak "req_ok_for() expects a requirement group name"
234 unless $group;
235
d8799bab 236 return $class->_check_deps($group)->{status};
fb39747c 237}
238
239sub req_missing_for {
240 my ($class, $group) = @_;
241
242 croak "req_missing_for() expects a requirement group name"
243 unless $group;
244
d8799bab 245 return $class->_check_deps($group)->{missing};
fb39747c 246}
247
248sub req_errorlist_for {
249 my ($class, $group) = @_;
250
251 croak "req_errorlist_for() expects a requirement group name"
252 unless $group;
253
d8799bab 254 return $class->_check_deps($group)->{errorlist};
fb39747c 255}
256
257sub _check_deps {
258 my ($class, $group) = @_;
259
d8799bab 260 return $req_availability_cache{$group} ||= do {
261
262 my $deps = $class->req_list_for ($group);
263
264 my %errors;
265 for my $mod (keys %$deps) {
266 my $req_line = "require $mod;";
267 if (my $ver = $deps->{$mod}) {
268 $req_line .= "$mod->VERSION($ver);";
269 }
270
271 eval $req_line;
272
273 $errors{$mod} = $@ if $@;
274 }
275
276 my $res;
fb39747c 277
d8799bab 278 if (keys %errors) {
279 my $missing = join (', ', map { $deps->{$_} ? "$_ >= $deps->{$_}" : $_ } (sort keys %errors) );
280 $missing .= " (see $class for details)" if $reqs->{$group}{pod};
281 $res = {
282 status => 0,
283 errorlist => \%errors,
284 missing => $missing,
285 };
fb39747c 286 }
287 else {
d8799bab 288 $res = {
289 status => 1,
290 errorlist => {},
291 missing => '',
292 };
fb39747c 293 }
294
d8799bab 295 $res;
296 };
fb39747c 297}
298
e3fc11e1 299sub req_group_list {
300 return { map { $_ => { %{ $reqs->{$_}{req} || {} } } } (keys %$reqs) };
301}
302
303# This is to be called by the author only (automatically in Makefile.PL)
f6b26571 304sub _gen_pod {
ccebe1f1 305 my ($class, $distver) = @_;
31fa1764 306
af4ac504 307 my $modfn = __PACKAGE__ . '.pm';
308 $modfn =~ s/\:\:/\//g;
f6b26571 309
31fa1764 310 my $podfn = __FILE__;
311 $podfn =~ s/\.pm$/\.pod/;
312
ccebe1f1 313 $distver ||=
31fa1764 314 eval { require DBIx::Class; DBIx::Class->VERSION; }
315 ||
ccebe1f1 316 die
31fa1764 317"\n\n---------------------------------------------------------------------\n" .
318'Unable to load core DBIx::Class module to determine current version, '.
319'possibly due to missing dependencies. Author-mode autodocumentation ' .
320"halted\n\n" . $@ .
321"\n\n---------------------------------------------------------------------\n"
31fa1764 322 ;
323
e3fc11e1 324 my $sqltver = $class->req_list_for ('deploy')->{'SQL::Translator'}
325 or die "Hrmm? No sqlt dep?";
7e3dc46f 326
f6b26571 327 my @chunks = (
d8799bab 328 <<'EOC',
af4ac504 329#########################################################################
330##################### A U T O G E N E R A T E D ########################
331#########################################################################
332#
333# The contents of this POD file are auto-generated. Any changes you make
334# will be lost. If you need to change the generated text edit _gen_pod()
335# at the end of $modfn
336#
337EOC
f6b26571 338 '=head1 NAME',
7e3dc46f 339 "$class - Optional module dependency specifications (for module authors)",
e3fc11e1 340 '=head1 SYNOPSIS',
d8799bab 341 <<"EOS",
7e3dc46f 342Somewhere in your build-file (e.g. L<Module::Install>'s Makefile.PL):
343
344 ...
345
346 configure_requires 'DBIx::Class' => '$distver';
347
348 require $class;
349
350 my \$deploy_deps = $class->req_list_for ('deploy');
351
352 for (keys %\$deploy_deps) {
353 requires \$_ => \$deploy_deps->{\$_};
354 }
355
356 ...
357
358Note that there are some caveats regarding C<configure_requires()>, more info
359can be found at L<Module::Install/configure_requires>
360EOS
f6b26571 361 '=head1 DESCRIPTION',
362 <<'EOD',
363Some of the less-frequently used features of L<DBIx::Class> have external
364module dependencies on their own. In order not to burden the average user
365with modules he will never use, these optional dependencies are not included
366in the base Makefile.PL. Instead an exception with a descriptive message is
367thrown when a specific feature is missing one or several modules required for
368its operation. This module is the central holding place for the current list
7e3dc46f 369of such dependencies, for DBIx::Class core authors, and DBIx::Class extension
370authors alike.
f6b26571 371EOD
372 '=head1 CURRENT REQUIREMENT GROUPS',
373 <<'EOD',
374Dependencies are organized in C<groups> and each group can list one or more
375required modules, with an optional minimum version (or 0 for any version).
ecb68746 376The group name can be used in the
f6b26571 377EOD
378 );
379
380 for my $group (sort keys %$reqs) {
381 my $p = $reqs->{$group}{pod}
382 or next;
383
384 my $modlist = $reqs->{$group}{req}
385 or next;
386
387 next unless keys %$modlist;
388
389 push @chunks, (
390 "=head2 $p->{title}",
391 "$p->{desc}",
392 '=over',
393 ( map { "=item * $_" . ($modlist->{$_} ? " >= $modlist->{$_}" : '') } (sort keys %$modlist) ),
394 '=back',
395 "Requirement group: B<$group>",
396 );
397 }
398
399 push @chunks, (
400 '=head1 METHODS',
e3fc11e1 401 '=head2 req_group_list',
402 '=over',
d8799bab 403 '=item Arguments: none',
e3fc11e1 404 '=item Returns: \%list_of_requirement_groups',
405 '=back',
d8799bab 406 <<'EOD',
e3fc11e1 407This method should be used by DBIx::Class packagers, to get a hashref of all
408dependencies keyed by dependency group. Each key (group name) can be supplied
409to one of the group-specific methods below.
410EOD
411
f6b26571 412 '=head2 req_list_for',
413 '=over',
414 '=item Arguments: $group_name',
415 '=item Returns: \%list_of_module_version_pairs',
416 '=back',
d8799bab 417 <<'EOD',
f6b26571 418This method should be used by DBIx::Class extension authors, to determine the
7e3dc46f 419version of modules a specific feature requires in the B<current> version of
e3fc11e1 420DBIx::Class. See the L</SYNOPSIS> for a real-world
7e3dc46f 421example.
f6b26571 422EOD
423
424 '=head2 req_ok_for',
425 '=over',
426 '=item Arguments: $group_name',
427 '=item Returns: 1|0',
428 '=back',
d8799bab 429 <<'EOD',
430Returns true or false depending on whether all modules required by
431C<$group_name> are present on the system and loadable.
432EOD
f6b26571 433
434 '=head2 req_missing_for',
435 '=over',
436 '=item Arguments: $group_name',
437 '=item Returns: $error_message_string',
438 '=back',
d8799bab 439 <<"EOD",
f6b26571 440Returns a single line string suitable for inclusion in larger error messages.
441This method would normally be used by DBIx::Class core-module author, to
442indicate to the user that he needs to install specific modules before he will
443be able to use a specific feature.
444
e3fc11e1 445For example if some of the requirements for C<deploy> are not available,
446the returned string could look like:
f6b26571 447
e3fc11e1 448 SQL::Translator >= $sqltver (see $class for details)
f6b26571 449
450The author is expected to prepend the necessary text to this message before
451returning the actual error seen by the user.
452EOD
453
454 '=head2 req_errorlist_for',
455 '=over',
456 '=item Arguments: $group_name',
457 '=item Returns: \%list_of_loaderrors_per_module',
458 '=back',
459 <<'EOD',
460Returns a hashref containing the actual errors that occured while attempting
461to load each module in the requirement group.
462EOD
fb8ae353 463 '=head1 AUTHOR',
464 'See L<DBIx::Class/CONTRIBUTORS>.',
465 '=head1 LICENSE',
466 'You may distribute this code under the same terms as Perl itself',
f6b26571 467 );
468
31fa1764 469 open (my $fh, '>', $podfn) or croak "Unable to write to $podfn: $!";
f6b26571 470 print $fh join ("\n\n", @chunks);
471 close ($fh);
472}
473
8057ed01 4741;