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