Ask for newer M::I
[dbsrgits/DBIx-Class-Historic.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
8057ed01 14my $reqs = {
15 dist => {
16 #'Module::Install::Pod::Inherit' => '0.01',
17 },
18
19 replicated => {
f6b26571 20 req => {
21 'Moose' => '0.98',
22 'MooseX::Types' => '0.21',
23 'namespace::clean' => '0.11',
24 'Hash::Merge' => '0.11',
25 },
26 pod => {
27 title => 'Storage::Replicated',
28 desc => 'Modules required for L<DBIx::Class::Storage::DBI::Replicated>',
29 },
8057ed01 30 },
31
32 admin => {
33 },
34
35 deploy => {
f6b26571 36 req => {
37 'SQL::Translator' => '0.11002',
38 },
39 pod => {
40 title => 'Storage::DBI::deploy()',
41 desc => 'Modules required for L<DBIx::Class::Storage::DBI/deploy> and L<DBIx::Class::Storage::DBI/deploymen_statements>',
42 },
8057ed01 43 },
44
45 author => {
f6b26571 46 req => {
47 'Test::Pod' => '1.26',
48 'Test::Pod::Coverage' => '1.08',
49 'Pod::Coverage' => '0.20',
50 #'Test::NoTabs' => '0.9',
51 #'Test::EOL' => '0.6',
52 },
8057ed01 53 },
54
55 core => {
f6b26571 56 req => {
57 # t/52cycle.t
58 'Test::Memory::Cycle' => '0',
59 'Devel::Cycle' => '1.10',
60
61 # t/36datetime.t
62 # t/60core.t
63 'DateTime::Format::SQLite' => '0',
64
65 # t/96_is_deteministic_value.t
66 'DateTime::Format::Strptime'=> '0',
67 },
8057ed01 68 },
69
70 cdbicompat => {
f6b26571 71 req => {
72 'DBIx::ContextualFetch' => '0',
73 'Class::DBI::Plugin::DeepAbstractSearch' => '0',
74 'Class::Trigger' => '0',
75 'Time::Piece::MySQL' => '0',
76 'Clone' => '0',
77 'Date::Simple' => '3.03',
78 },
8057ed01 79 },
80
81 rdbms_pg => {
f6b26571 82 req => {
83 $ENV{DBICTEST_PG_DSN}
84 ? (
85 'Sys::SigAction' => '0',
86 'DBD::Pg' => '2.009002',
87 'DateTime::Format::Pg' => '0',
88 ) : ()
89 },
8057ed01 90 },
91
92 rdbms_mysql => {
f6b26571 93 req => {
94 $ENV{DBICTEST_MYSQL_DSN}
95 ? (
96 'DateTime::Format::MySQL' => '0',
97 'DBD::mysql' => '0',
98 ) : ()
99 },
8057ed01 100 },
101
102 rdbms_oracle => {
f6b26571 103 req => {
104 $ENV{DBICTEST_ORA_DSN}
105 ? (
106 'DateTime::Format::Oracle' => '0',
107 ) : ()
108 },
8057ed01 109 },
110
111 rdbms_ase => {
f6b26571 112 req => {
113 $ENV{DBICTEST_SYBASE_DSN}
114 ? (
115 'DateTime::Format::Sybase' => 0,
116 ) : ()
117 },
8057ed01 118 },
119
120 rdbms_asa => {
f6b26571 121 req => {
122 grep $_, @ENV{qw/DBICTEST_SYBASE_ASA_DSN DBICTEST_SYBASE_ASA_ODBC_DSN/}
123 ? (
124 'DateTime::Format::Strptime' => 0,
125 ) : ()
126 },
8057ed01 127 },
128};
129
f6b26571 130
0d4740b3 131sub _all_optional_requirements {
f6b26571 132 return { map { %{ $reqs->{$_}{req} || {} } } (keys %$reqs) };
8057ed01 133}
134
fb39747c 135sub req_list_for {
136 my ($class, $group) = @_;
137
f6b26571 138 croak "req_list_for() expects a requirement group name"
fb39747c 139 unless $group;
140
f6b26571 141 my $deps = $reqs->{$group}{req}
142 or croak "Requirement group '$group' does not exist";
fb39747c 143
144 return { %$deps };
145}
146
147
148our %req_availability_cache;
149sub req_ok_for {
150 my ($class, $group) = @_;
151
152 croak "req_ok_for() expects a requirement group name"
153 unless $group;
154
155 $class->_check_deps ($group) unless $req_availability_cache{$group};
156
157 return $req_availability_cache{$group}{status};
158}
159
160sub req_missing_for {
161 my ($class, $group) = @_;
162
163 croak "req_missing_for() expects a requirement group name"
164 unless $group;
165
166 $class->_check_deps ($group) unless $req_availability_cache{$group};
167
168 return $req_availability_cache{$group}{missing};
169}
170
171sub req_errorlist_for {
172 my ($class, $group) = @_;
173
174 croak "req_errorlist_for() expects a requirement group name"
175 unless $group;
176
177 $class->_check_deps ($group) unless $req_availability_cache{$group};
178
179 return $req_availability_cache{$group}{errorlist};
180}
181
182sub _check_deps {
183 my ($class, $group) = @_;
184
f6b26571 185 my $deps = $class->req_list_for ($group);
fb39747c 186
187 my %errors;
188 for my $mod (keys %$deps) {
189 if (my $ver = $deps->{$mod}) {
190 eval "use $mod $ver ()";
191 }
192 else {
193 eval "require $mod";
194 }
195
196 $errors{$mod} = $@ if $@;
197 }
198
199 if (keys %errors) {
f6b26571 200 my $missing = join (', ', map { $deps->{$_} ? "$_ >= $deps->{$_}" : $_ } (sort keys %errors) );
201 $missing .= " (see $class for details)" if $reqs->{$group}{pod};
fb39747c 202 $req_availability_cache{$group} = {
203 status => 0,
204 errorlist => { %errors },
f6b26571 205 missing => $missing,
fb39747c 206 };
207 }
208 else {
209 $req_availability_cache{$group} = {
210 status => 1,
211 errorlist => {},
212 missing => '',
213 };
214 }
215}
216
f6b26571 217sub _gen_pod {
218 my $class = shift;
af4ac504 219 my $modfn = __PACKAGE__ . '.pm';
220 $modfn =~ s/\:\:/\//g;
f6b26571 221
222 my @chunks = (
af4ac504 223 <<"EOC",
224#########################################################################
225##################### A U T O G E N E R A T E D ########################
226#########################################################################
227#
228# The contents of this POD file are auto-generated. Any changes you make
229# will be lost. If you need to change the generated text edit _gen_pod()
230# at the end of $modfn
231#
232EOC
f6b26571 233 '=head1 NAME',
234 "$class - Optional module dependency specifications",
235 '=head1 DESCRIPTION',
236 <<'EOD',
237Some of the less-frequently used features of L<DBIx::Class> have external
238module dependencies on their own. In order not to burden the average user
239with modules he will never use, these optional dependencies are not included
240in the base Makefile.PL. Instead an exception with a descriptive message is
241thrown when a specific feature is missing one or several modules required for
242its operation. This module is the central holding place for the current list
243of such dependencies.
244EOD
245 '=head1 CURRENT REQUIREMENT GROUPS',
246 <<'EOD',
247Dependencies are organized in C<groups> and each group can list one or more
248required modules, with an optional minimum version (or 0 for any version).
249The group name can be used in the
250EOD
251 );
252
253 for my $group (sort keys %$reqs) {
254 my $p = $reqs->{$group}{pod}
255 or next;
256
257 my $modlist = $reqs->{$group}{req}
258 or next;
259
260 next unless keys %$modlist;
261
262 push @chunks, (
263 "=head2 $p->{title}",
264 "$p->{desc}",
265 '=over',
266 ( map { "=item * $_" . ($modlist->{$_} ? " >= $modlist->{$_}" : '') } (sort keys %$modlist) ),
267 '=back',
268 "Requirement group: B<$group>",
269 );
270 }
271
272 push @chunks, (
273 '=head1 METHODS',
274 '=head2 req_list_for',
275 '=over',
276 '=item Arguments: $group_name',
277 '=item Returns: \%list_of_module_version_pairs',
278 '=back',
279 <<EOD,
280This method should be used by DBIx::Class extension authors, to determine the
281version of modules which a specific feature requires in the current version of
282DBIx::Class. For example if you write a module/extension that requires
283DBIx::Class and also requires the availability of
284L<DBIx::Class::Storage::DBI/deploy>, you can do the following in your
285C<Makefile.PL> or C<Build.PL>
286
287 require $class;
288 my \$dep_list = $class->req_list_for ('deploy');
289
290Which will give you a list of module/version pairs necessary for the particular
291feature to function with this version of DBIx::Class.
292EOD
293
294 '=head2 req_ok_for',
295 '=over',
296 '=item Arguments: $group_name',
297 '=item Returns: 1|0',
298 '=back',
af4ac504 299 'Returns true or false depending on whether all modules required by C<$group_name> are present on the system and loadable',
f6b26571 300
301 '=head2 req_missing_for',
302 '=over',
303 '=item Arguments: $group_name',
304 '=item Returns: $error_message_string',
305 '=back',
306 <<EOD,
307Returns a single line string suitable for inclusion in larger error messages.
308This method would normally be used by DBIx::Class core-module author, to
309indicate to the user that he needs to install specific modules before he will
310be able to use a specific feature.
311
312For example if the requirements for C<replicated> are not available, the
313returned string would look like:
314
315 Moose >= 0.98, MooseX::Types >= 0.21, namespace::clean (see $class for details)
316
317The author is expected to prepend the necessary text to this message before
318returning the actual error seen by the user.
319EOD
320
321 '=head2 req_errorlist_for',
322 '=over',
323 '=item Arguments: $group_name',
324 '=item Returns: \%list_of_loaderrors_per_module',
325 '=back',
326 <<'EOD',
327Returns a hashref containing the actual errors that occured while attempting
328to load each module in the requirement group.
329EOD
330
331 );
332
333 my $fn = __FILE__;
334 $fn =~ s/\.pm$/\.pod/;
335
336 open (my $fh, '>', $fn) or croak "Unable to write to $fn: $!";
337 print $fh join ("\n\n", @chunks);
338 close ($fh);
339}
340
8057ed01 3411;