~ubuntu-branches/debian/sid/bugzilla/sid

« back to all changes in this revision

Viewing changes to Bugzilla/Install/Requirements.pm

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Bossek
  • Date: 2008-06-27 22:34:34 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080627223434-0ib57vstn43bb4a3
Tags: 3.0.4.1-1
* Update of French, Russian and German translations. (closes: #488251)
* Added Bulgarian and Belarusian translations.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- Mode: perl; indent-tabs-mode: nil -*-
2
 
#
3
 
# The contents of this file are subject to the Mozilla Public
4
 
# License Version 1.1 (the "License"); you may not use this file
5
 
# except in compliance with the License. You may obtain a copy of
6
 
# the License at http://www.mozilla.org/MPL/
7
 
#
8
 
# Software distributed under the License is distributed on an "AS
9
 
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
 
# implied. See the License for the specific language governing
11
 
# rights and limitations under the License.
12
 
#
13
 
# The Original Code is the Bugzilla Bug Tracking System.
14
 
#
15
 
# Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
16
 
#                 Marc Schumann <wurblzap@gmail.com>
17
 
 
18
 
package Bugzilla::Install::Requirements;
19
 
 
20
 
# NOTE: This package MUST NOT "use" any Bugzilla modules other than
21
 
# Bugzilla::Constants, anywhere. We may "use" standard perl modules.
22
 
#
23
 
# Subroutines may "require" and "import" from modules, but they
24
 
# MUST NOT "use."
25
 
 
26
 
use strict;
27
 
 
28
 
use List::Util qw(max);
29
 
use POSIX ();
30
 
use Safe;
31
 
 
32
 
use base qw(Exporter);
33
 
our @EXPORT = qw(
34
 
    REQUIRED_MODULES
35
 
    OPTIONAL_MODULES
36
 
 
37
 
    check_requirements
38
 
    check_graphviz
39
 
    display_version_and_os
40
 
    have_vers
41
 
    vers_cmp
42
 
    install_command
43
 
);
44
 
 
45
 
use Bugzilla::Constants;
46
 
 
47
 
# The below two constants are subroutines so that they can implement
48
 
# a hook. Other than that they are actually constants.
49
 
 
50
 
# "package" is the perl package we're checking for. "module" is the name
51
 
# of the actual module we load with "require" to see if the package is
52
 
# installed or not. "version" is the version we need, or 0 if we'll accept
53
 
# any version.
54
 
#
55
 
# "blacklist" is an arrayref of regular expressions that describe versions that
56
 
# are 'blacklisted'--that is, even if the version is high enough, Bugzilla
57
 
# will refuse to say that it's OK to run with that version.
58
 
sub REQUIRED_MODULES {
59
 
    my $perl_ver = sprintf('%vd', $^V);
60
 
    my @modules = (
61
 
    {
62
 
        package => 'CGI.pm',
63
 
        module  => 'CGI',
64
 
        # Perl 5.10 requires CGI 3.33 due to a taint issue when
65
 
        # uploading attachments, see bug 416382.
66
 
        version => (vers_cmp($perl_ver, '5.10') > -1) ? '3.33' : '2.93'
67
 
    },
68
 
    {
69
 
        package => 'TimeDate',
70
 
        module  => 'Date::Format',
71
 
        version => '2.21'
72
 
    },
73
 
    {
74
 
        package => 'DBI',
75
 
        module  => 'DBI',
76
 
        version => '1.41'
77
 
    },
78
 
    {
79
 
        package => 'PathTools',
80
 
        module  => 'File::Spec',
81
 
        version => '0.84'
82
 
    },
83
 
    {
84
 
        package => 'Template-Toolkit',
85
 
        module  => 'Template',
86
 
        version => '2.12'
87
 
    },
88
 
    {
89
 
        package => 'Email-Send',
90
 
        module  => 'Email::Send',
91
 
        version => ON_WINDOWS ? '2.16' : '2.00'
92
 
    },
93
 
    {
94
 
        # This will pull in Email::MIME for us, also. 
95
 
        package => 'Email-MIME-Modifier',
96
 
        module  => 'Email::MIME::Modifier',
97
 
        version => 0
98
 
    },
99
 
    );
100
 
 
101
 
    my $all_modules = _get_extension_requirements(
102
 
        'REQUIRED_MODULES', \@modules);
103
 
    return $all_modules;
104
 
};
105
 
 
106
 
sub OPTIONAL_MODULES {
107
 
    my @modules = (
108
 
    {
109
 
        package => 'GD',
110
 
        module  => 'GD',
111
 
        version => '1.20',
112
 
        feature => 'Graphical Reports, New Charts, Old Charts'
113
 
    },
114
 
    {
115
 
        package => 'Template-GD',
116
 
        # This module tells us whether or not Template-GD is installed
117
 
        # on Template-Toolkits after 2.14, and still works with 2.14 and lower.
118
 
        module  => 'Template::Plugin::GD::Image',
119
 
        version => 0,
120
 
        feature => 'Graphical Reports'
121
 
    },
122
 
    {
123
 
        package => 'Chart',
124
 
        module  => 'Chart::Base',
125
 
        version => '1.0',
126
 
        feature => 'New Charts, Old Charts'
127
 
    },
128
 
    {
129
 
        package => 'GDGraph',
130
 
        module  => 'GD::Graph',
131
 
        version => 0,
132
 
        feature => 'Graphical Reports'
133
 
    },
134
 
    { 
135
 
        package => 'GDTextUtil',
136
 
        module  => 'GD::Text',
137
 
        version => 0,
138
 
        feature => 'Graphical Reports'
139
 
    },
140
 
    {
141
 
        package => 'XML-Twig',
142
 
        module  => 'XML::Twig',
143
 
        version => 0,
144
 
        feature => 'Move Bugs Between Installations'
145
 
    },
146
 
    {
147
 
        package => 'MIME-tools',
148
 
        # MIME::Parser is packaged as MIME::Tools on ActiveState Perl
149
 
        module  => ON_WINDOWS ? 'MIME::Tools' : 'MIME::Parser',
150
 
        version => '5.406',
151
 
        feature => 'Move Bugs Between Installations'
152
 
    },
153
 
    {
154
 
        package => 'libwww-perl',
155
 
        module  => 'LWP::UserAgent',
156
 
        version => 0,
157
 
        feature => 'Automatic Update Notifications'
158
 
    },
159
 
    {
160
 
        package => 'PatchReader',
161
 
        module  => 'PatchReader',
162
 
        version => '0.9.4',
163
 
        feature => 'Patch Viewer'
164
 
    },
165
 
    {
166
 
        package => 'PerlMagick',
167
 
        module  => 'Image::Magick',
168
 
        version => 0,
169
 
        feature => 'Optionally Convert BMP Attachments to PNGs'
170
 
    },
171
 
    {
172
 
        package => 'perl-ldap',
173
 
        module  => 'Net::LDAP',
174
 
        version => 0,
175
 
        feature => 'LDAP Authentication'
176
 
    },
177
 
    {
178
 
        package => 'SOAP-Lite',
179
 
        module  => 'SOAP::Lite',
180
 
        version => 0,
181
 
        feature => 'XML-RPC Interface'
182
 
    },
183
 
    {
184
 
        # We need the 'utf8_mode' method of HTML::Parser, for HTML::Scrubber.
185
 
        package => 'HTML-Parser',
186
 
        module  => 'HTML::Parser',
187
 
        version => '3.40',
188
 
        feature => 'More HTML in Product/Group Descriptions'
189
 
    },
190
 
    {
191
 
        package => 'HTML-Scrubber',
192
 
        module  => 'HTML::Scrubber',
193
 
        version => 0,
194
 
        feature => 'More HTML in Product/Group Descriptions'
195
 
    },
196
 
 
197
 
    # Inbound Email
198
 
    {
199
 
        package => 'Email-MIME-Attachment-Stripper',
200
 
        module  => 'Email::MIME::Attachment::Stripper',
201
 
        version => 0,
202
 
        feature => 'Inbound Email'
203
 
    },
204
 
    {
205
 
        package => 'Email-Reply',
206
 
        module  => 'Email::Reply',
207
 
        version => 0,
208
 
        feature => 'Inbound Email'
209
 
    },
210
 
 
211
 
    # mod_perl
212
 
    {
213
 
        package => 'mod_perl',
214
 
        module  => 'mod_perl2',
215
 
        version => '1.999022',
216
 
        feature => 'mod_perl'
217
 
    },
218
 
    );
219
 
 
220
 
    # Even very new releases of perl (5.8.5) don't come with this version,
221
 
    # so I didn't want to make it a general requirement just for
222
 
    # running under mod_cgi.
223
 
    # If Perl 5.10 is installed, then CGI 3.33 is already required. So this
224
 
    # check is only relevant with Perl 5.8.x.
225
 
    my $perl_ver = sprintf('%vd', $^V);
226
 
    if (vers_cmp($perl_ver, '5.10') < 0) {
227
 
        push(@modules, { package => 'CGI.pm',
228
 
                         module  => 'CGI',
229
 
                         version => '3.11',
230
 
                         feature => 'mod_perl' });
231
 
    }
232
 
 
233
 
    my $all_modules = _get_extension_requirements(
234
 
        'OPTIONAL_MODULES', \@modules);
235
 
    return $all_modules;
236
 
};
237
 
 
238
 
# This implements the install-requirements hook described in Bugzilla::Hook.
239
 
sub _get_extension_requirements {
240
 
    my ($function, $base_modules) = @_;
241
 
    my @all_modules;
242
 
    # get a list of all extensions
243
 
    my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*");
244
 
    foreach my $extension (@extensions) {
245
 
        my $file = "$extension/code/install-requirements.pl";
246
 
        if (-e $file) {
247
 
            my $safe = new Safe;
248
 
            # This is a very liberal Safe.
249
 
            $safe->permit(qw(:browse require entereval caller));
250
 
            $safe->rdo($file);
251
 
            if ($@) {
252
 
                warn $@;
253
 
                next;
254
 
            }
255
 
            my $modules = eval { &{$safe->varglob($function)}($base_modules) };
256
 
            next unless $modules;
257
 
            push(@all_modules, @$modules);
258
 
        }
259
 
    }
260
 
 
261
 
    unshift(@all_modules, @$base_modules);
262
 
    return \@all_modules;
263
 
};
264
 
 
265
 
sub check_requirements {
266
 
    my ($output) = @_;
267
 
 
268
 
    print "\nChecking perl modules...\n" if $output;
269
 
    my $root = ROOT_USER;
270
 
    my %missing = _check_missing(REQUIRED_MODULES, $output);
271
 
 
272
 
    print "\nChecking available perl DBD modules...\n" if $output;
273
 
    my $have_one_dbd = 0;
274
 
    my $db_modules = DB_MODULE;
275
 
    foreach my $db (keys %$db_modules) {
276
 
        my $dbd = $db_modules->{$db}->{dbd};
277
 
        $have_one_dbd = 1 if have_vers($dbd, $output);
278
 
    }
279
 
 
280
 
    print "\nThe following Perl modules are optional:\n" if $output;
281
 
    my %missing_optional = _check_missing(OPTIONAL_MODULES, $output);
282
 
 
283
 
    # If we're running on Windows, reset the input line terminator so that
284
 
    # console input works properly - loading CGI tends to mess it up
285
 
    $/ = "\015\012" if ON_WINDOWS;
286
 
 
287
 
    my $pass = !scalar(keys %missing) && $have_one_dbd;
288
 
    return {
289
 
        pass     => $pass,
290
 
        one_dbd  => $have_one_dbd,
291
 
        missing  => \%missing,
292
 
        optional => \%missing_optional,
293
 
        any_missing => !$pass || scalar(keys %missing_optional),
294
 
    };
295
 
}
296
 
 
297
 
# A helper for check_requirements
298
 
sub _check_missing {
299
 
    my ($modules, $output) = @_;
300
 
 
301
 
    my %missing;
302
 
    foreach my $module (@$modules) {
303
 
        unless (have_vers($module, $output)) {
304
 
            $missing{$module->{package}} = $module;
305
 
        }
306
 
    }
307
 
 
308
 
    return %missing;
309
 
}
310
 
 
311
 
# Returns the build ID of ActivePerl. If several versions of
312
 
# ActivePerl are installed, it won't be able to know which one
313
 
# you are currently running. But that's our best guess.
314
 
sub _get_activestate_build_id {
315
 
    eval 'use Win32::TieRegistry';
316
 
    return 0 if $@;
317
 
    my $key = Win32::TieRegistry->new('LMachine\Software\ActiveState\ActivePerl')
318
 
      or return 0;
319
 
    return $key->GetValue("CurrentVersion");
320
 
}
321
 
 
322
 
sub print_module_instructions {
323
 
    my ($check_results, $output) = @_;
324
 
 
325
 
    # We only print these notes if we have to.
326
 
    if ((!$output && %{$check_results->{missing}})
327
 
        || ($output && $check_results->{any_missing}))
328
 
    {
329
 
        print "\n* NOTE: You must run any commands listed below as "
330
 
              . ROOT_USER . ".\n\n";
331
 
 
332
 
        if (ON_WINDOWS) {
333
 
            my $perl_ver = sprintf('%vd', $^V);
334
 
            
335
 
            # URL when running Perl 5.8.x.
336
 
            my $url_to_theory58S = 'http://theoryx5.uwinnipeg.ca/ppms';
337
 
            my $repo_up_cmd =
338
 
'*                                                                     *';
339
 
            # Packages for Perl 5.10 are not compatible with Perl 5.8.
340
 
            if (vers_cmp($perl_ver, '5.10') > -1) {
341
 
                $url_to_theory58S = 'http://cpan.uwinnipeg.ca/PPMPackages/10xx/';
342
 
            }
343
 
            # ActivePerl older than revision 819 require an additional command.
344
 
            if (_get_activestate_build_id() < 819) {
345
 
                $repo_up_cmd = <<EOT;
346
 
*                                                                     *
347
 
* Then you have to do (also as an Administrator):                     *
348
 
*                                                                     *
349
 
*   ppm repo up theory58S                                             *
350
 
*                                                                     *
351
 
* Do that last command over and over until you see "theory58S" at the *
352
 
* top of the displayed list.                                          *
353
 
EOT
354
 
            }
355
 
            print <<EOT;
356
 
***********************************************************************
357
 
* Note For Windows Users                                              *
358
 
***********************************************************************
359
 
* In order to install the modules listed below, you first have to run * 
360
 
* the following command as an Administrator:                          *
361
 
*                                                                     *
362
 
*   ppm repo add theory58S $url_to_theory58S
363
 
$repo_up_cmd
364
 
***********************************************************************
365
 
EOT
366
 
        }
367
 
    }
368
 
 
369
 
    # Required Modules
370
 
    if (my %missing = %{$check_results->{missing}}) {
371
 
        print <<EOT;
372
 
***********************************************************************
373
 
* REQUIRED MODULES                                                    *
374
 
***********************************************************************
375
 
* Bugzilla requires you to install some Perl modules which are either *
376
 
* missing from your system, or the version on your system is too old. *
377
 
*                                                                     *
378
 
* The latest versions of each module can be installed by running the  *
379
 
* commands below.                                                     *
380
 
***********************************************************************
381
 
EOT
382
 
 
383
 
        print "COMMANDS:\n\n";
384
 
        foreach my $package (keys %missing) {
385
 
            my $command = install_command($missing{$package});
386
 
            print "    $command\n";
387
 
        }
388
 
        print "\n";
389
 
    }
390
 
 
391
 
    if (!$check_results->{one_dbd}) {
392
 
        print <<EOT;
393
 
***********************************************************************
394
 
* DATABASE ACCESS                                                     *
395
 
***********************************************************************
396
 
* In order to access your database, Bugzilla requires that the        *
397
 
* correct "DBD" module be installed for the database that you are     *
398
 
* running.                                                            *
399
 
*                                                                     *
400
 
* Pick and run the correct command below for the database that you    *
401
 
* plan to use with Bugzilla.                                          *
402
 
***********************************************************************
403
 
COMMANDS:
404
 
 
405
 
EOT
406
 
 
407
 
        my %db_modules = %{DB_MODULE()};
408
 
        foreach my $db (keys %db_modules) {
409
 
            my $command = install_command($db_modules{$db}->{dbd});
410
 
            printf "%10s: \%s\n", $db_modules{$db}->{name}, $command;
411
 
            print ' ' x 12 . "Minimum version required: "
412
 
                  . $db_modules{$db}->{dbd}->{version} . "\n";
413
 
        }
414
 
        print "\n";
415
 
    }
416
 
 
417
 
    return unless $output;
418
 
 
419
 
    if (my %missing = %{$check_results->{optional}}) {
420
 
        print <<EOT;
421
 
**********************************************************************
422
 
* OPTIONAL MODULES                                                   *
423
 
**********************************************************************
424
 
* Certain Perl modules are not required by Bugzilla, but by          *
425
 
* installing the latest version you gain access to additional        *
426
 
* features.                                                          *
427
 
*                                                                    *
428
 
* The optional modules you do not have installed are listed below,   *
429
 
* with the name of the feature they enable. If you want to install   *
430
 
* one of these modules, just run the appropriate command in the      *
431
 
* "COMMANDS TO INSTALL" section.                                     *
432
 
**********************************************************************
433
 
 
434
 
EOT
435
 
        # We want to sort them so that they are ordered by feature.
436
 
        my @missing_names = sort {$missing{$a}->{feature} 
437
 
                                  cmp $missing{$b}->{feature}} (keys %missing);
438
 
 
439
 
        # Now we have to determine how large the table cols will be.
440
 
        my $longest_name = max(map(length($_), @missing_names));
441
 
 
442
 
        # The first column header is at least 11 characters long.
443
 
        $longest_name = 11 if $longest_name < 11;
444
 
 
445
 
        # The table is 71 characters long. There are seven mandatory
446
 
        # characters (* and space) in the string. So, we have a total
447
 
        # of 64 characters to work with.
448
 
        my $remaining_space = 64 - $longest_name;
449
 
        print '*' x 71 . "\n";
450
 
        printf "* \%${longest_name}s * %-${remaining_space}s *\n",
451
 
               'MODULE NAME', 'ENABLES FEATURE(S)';
452
 
        print '*' x 71 . "\n";
453
 
        foreach my $name (@missing_names) {
454
 
            printf "* \%${longest_name}s * %-${remaining_space}s *\n",
455
 
                   $name, $missing{$name}->{feature};
456
 
        }
457
 
        print '*' x 71 . "\n";
458
 
 
459
 
        print "COMMANDS TO INSTALL:\n\n";
460
 
        foreach my $module (@missing_names) {
461
 
            my $command = install_command($missing{$module});
462
 
            printf "%15s: $command\n", $module;
463
 
        }
464
 
    }
465
 
}
466
 
 
467
 
sub check_graphviz {
468
 
    my ($output) = @_;
469
 
 
470
 
    return 1 if (Bugzilla->params->{'webdotbase'} =~ /^https?:/);
471
 
 
472
 
    printf("Checking for %15s %-9s ", "GraphViz", "(any)") if $output;
473
 
 
474
 
    my $return = 0;
475
 
    if(-x Bugzilla->params->{'webdotbase'}) {
476
 
        print "ok: found\n" if $output;
477
 
        $return = 1;
478
 
    } else {
479
 
        print "not a valid executable: " . Bugzilla->params->{'webdotbase'} . "\n";
480
 
    }
481
 
 
482
 
    my $webdotdir = bz_locations()->{'webdotdir'};
483
 
    # Check .htaccess allows access to generated images
484
 
    if (-e "$webdotdir/.htaccess") {
485
 
        my $htaccess = new IO::File("$webdotdir/.htaccess", 'r') 
486
 
            || die "$webdotdir/.htaccess: " . $!;
487
 
        if (!grep(/png/, $htaccess->getlines)) {
488
 
            print "Dependency graph images are not accessible.\n";
489
 
            print "delete $webdotdir/.htaccess and re-run checksetup.pl to fix.\n";
490
 
        }
491
 
        $htaccess->close;
492
 
    }
493
 
 
494
 
    return $return;
495
 
}
496
 
 
497
 
sub display_version_and_os {
498
 
    # Display version information
499
 
    printf "\n* This is Bugzilla " . BUGZILLA_VERSION . " on perl %vd\n",
500
 
           $^V;
501
 
    my @os_details = POSIX::uname;
502
 
    # 0 is the name of the OS, 2 is the major version,
503
 
    my $os_name = $os_details[0] . ' ' . $os_details[2];
504
 
    if (ON_WINDOWS) {
505
 
        require Win32;
506
 
        $os_name = Win32::GetOSName();
507
 
    }
508
 
    # 3 is the minor version.
509
 
    print "* Running on $os_name $os_details[3]\n"
510
 
}
511
 
 
512
 
# This was originally clipped from the libnet Makefile.PL, adapted here to
513
 
# use the below vers_cmp routine for accurate version checking.
514
 
sub have_vers {
515
 
    my ($params, $output) = @_;
516
 
    my $module  = $params->{module};
517
 
    my $package = $params->{package};
518
 
    if (!$package) {
519
 
        $package = $module;
520
 
        $package =~ s/::/-/g;
521
 
    }
522
 
    my $wanted  = $params->{version};
523
 
 
524
 
    my ($msg, $vnum, $vstr);
525
 
    no strict 'refs';
526
 
    printf("Checking for %15s %-9s ", $package, !$wanted?'(any)':"(v$wanted)") 
527
 
        if $output;
528
 
 
529
 
    eval "require $module;";
530
 
 
531
 
    # VERSION is provided by UNIVERSAL::
532
 
    $vnum = eval { $module->VERSION } || -1;
533
 
 
534
 
    # CGI's versioning scheme went 2.75, 2.751, 2.752, 2.753, 2.76
535
 
    # That breaks the standard version tests, so we need to manually correct
536
 
    # the version
537
 
    if ($module eq 'CGI' && $vnum =~ /(2\.7\d)(\d+)/) {
538
 
        $vnum = $1 . "." . $2;
539
 
    }
540
 
 
541
 
    if ($vnum eq "-1") { # string compare just in case it's non-numeric
542
 
        $vstr = "not found";
543
 
    }
544
 
    elsif (vers_cmp($vnum,"0") > -1) {
545
 
        $vstr = "found v$vnum";
546
 
    }
547
 
    else {
548
 
        $vstr = "found unknown version";
549
 
    }
550
 
 
551
 
    my $vok = (vers_cmp($vnum,$wanted) > -1);
552
 
    my $blacklisted;
553
 
    if ($vok && $params->{blacklist}) {
554
 
        $blacklisted = grep($vnum =~ /$_/, @{$params->{blacklist}});
555
 
        $vok = 0 if $blacklisted;
556
 
    }
557
 
 
558
 
    my $ok = $vok ? "ok:" : "";
559
 
    my $black_string = $blacklisted ? "(blacklisted)" : "";
560
 
    print "$ok $vstr $black_string\n" if $output;
561
 
    return $vok ? 1 : 0;
562
 
}
563
 
 
564
 
# This is taken straight from Sort::Versions 1.5, which is not included
565
 
# with perl by default.
566
 
sub vers_cmp {
567
 
    my ($a, $b) = @_;
568
 
 
569
 
    # Remove leading zeroes - Bug 344661
570
 
    $a =~ s/^0*(\d.+)/$1/;
571
 
    $b =~ s/^0*(\d.+)/$1/;
572
 
 
573
 
    my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/g);
574
 
    my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/g);
575
 
 
576
 
    my ($A, $B);
577
 
    while (@A and @B) {
578
 
        $A = shift @A;
579
 
        $B = shift @B;
580
 
        if ($A eq '-' and $B eq '-') {
581
 
            next;
582
 
        } elsif ( $A eq '-' ) {
583
 
            return -1;
584
 
        } elsif ( $B eq '-') {
585
 
            return 1;
586
 
        } elsif ($A eq '.' and $B eq '.') {
587
 
            next;
588
 
        } elsif ( $A eq '.' ) {
589
 
            return -1;
590
 
        } elsif ( $B eq '.' ) {
591
 
            return 1;
592
 
        } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
593
 
            if ($A =~ /^0/ || $B =~ /^0/) {
594
 
                return $A cmp $B if $A cmp $B;
595
 
            } else {
596
 
                return $A <=> $B if $A <=> $B;
597
 
            }
598
 
        } else {
599
 
            $A = uc $A;
600
 
            $B = uc $B;
601
 
            return $A cmp $B if $A cmp $B;
602
 
        }
603
 
    }
604
 
    @A <=> @B;
605
 
}
606
 
 
607
 
sub install_command {
608
 
    my $module = shift;
609
 
    my ($command, $package);
610
 
 
611
 
    if (ON_WINDOWS) {
612
 
        $command = 'ppm install %s';
613
 
        $package = $module->{package};
614
 
    }
615
 
    else {
616
 
        $command = "$^X -MCPAN -e 'install \"\%s\"'";
617
 
        # Non-Windows installations need to use module names, because
618
 
        # CPAN doesn't understand package names.
619
 
        $package = $module->{module};
620
 
    }
621
 
    return sprintf $command, $package;
622
 
}
623
 
 
624
 
 
625
 
1;
626
 
 
627
 
__END__
628
 
 
629
 
=head1 NAME
630
 
 
631
 
Bugzilla::Install::Requirements - Functions and variables dealing
632
 
  with Bugzilla's perl-module requirements.
633
 
 
634
 
=head1 DESCRIPTION
635
 
 
636
 
This module is used primarily by C<checksetup.pl> to determine whether
637
 
or not all of Bugzilla's prerequisites are installed. (That is, all the
638
 
perl modules it requires.)
639
 
 
640
 
=head1 CONSTANTS
641
 
 
642
 
=over 4
643
 
 
644
 
=item C<REQUIRED_MODULES>
645
 
 
646
 
An arrayref of hashrefs that describes the perl modules required by 
647
 
Bugzilla. The hashes have two keys, C<name> and C<version>, which
648
 
represent the name of the module and the version that we require.
649
 
 
650
 
=back
651
 
 
652
 
=head1 SUBROUTINES
653
 
 
654
 
=over 4
655
 
 
656
 
=item C<check_requirements($output)>
657
 
 
658
 
 Description: This checks what optional or required perl modules
659
 
              are installed, like C<checksetup.pl> does.
660
 
 
661
 
 Params:      C<$output> - C<true> if you want the function to print
662
 
                           out information about what it's doing,
663
 
                           and the versions of everything installed.
664
 
                           If you don't pass the minimum requirements,
665
 
                           the will always print out something, 
666
 
                           regardless of this parameter.
667
 
 
668
 
 Returns:    A hashref containing three values:
669
 
             C<pass> - Whether or not we have all the mandatory 
670
 
                       requirements.
671
 
             C<missing> - A hash showing which mandatory requirements
672
 
                          are missing. The key is the module name,
673
 
                          and the value is the version we require.
674
 
             C<optional> - Which optional modules are installed and
675
 
                           up-to-date enough for Bugzilla.
676
 
 
677
 
=item C<check_graphviz($output)>
678
 
 
679
 
Description: Checks if the graphviz binary specified in the 
680
 
  C<webdotbase> parameter is a valid binary, or a valid URL.
681
 
 
682
 
Params:      C<$output> - C<$true> if you want the function to
683
 
                 print out information about what it's doing.
684
 
 
685
 
Returns:     C<1> if the check was successful, C<0> otherwise.
686
 
 
687
 
=item C<vers_cmp($a, $b)>
688
 
 
689
 
 Description: This is a comparison function, like you would use in
690
 
              C<sort>, except that it compares two version numbers.
691
 
              It's actually identical to versioncmp from 
692
 
              L<Sort::Versions>.
693
 
 
694
 
 Params:      c<$a> and C<$b> are versions you want to compare.
695
 
 
696
 
 Returns:     -1 if $a is less than $b, 0 if they are equal, and
697
 
              1 if $a is greater than $b.
698
 
 
699
 
=item C<have_vers($module, $output)>
700
 
 
701
 
 Description: Tells you whether or not you have the appropriate
702
 
              version of the module requested. It also prints
703
 
              out a message to the user explaining the check
704
 
              and the result.
705
 
 
706
 
 Params:      C<$module> - A hashref, in the format of an item from 
707
 
                           L</REQUIRED_MODULES>.
708
 
              C<$output> - Set to true if you want this function to
709
 
                           print information to STDOUT about what it's
710
 
                           doing.
711
 
 
712
 
 Returns:   C<1> if you have the module installed and you have the
713
 
            appropriate version. C<0> otherwise.
714
 
 
715
 
=item C<install_command($module)>
716
 
 
717
 
 Description: Prints out the appropriate command to install the
718
 
              module specified, depending on whether you're
719
 
              on Windows or Linux.
720
 
 
721
 
 Params:      C<$module> - A hashref, in the format of an item from
722
 
                           L</REQUIRED_MODULES>.
723
 
 
724
 
 Returns:     nothing
725
 
 
726
 
=back