summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/lib/ExtUtils/Command/MM.pm
blob: 484fa5b69d5b225f01171d7c120c8b68e6bd5a5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
package ExtUtils::Command::MM;

require 5.006;

use strict;
use warnings;

require Exporter;
our @ISA = qw(Exporter);

our @EXPORT  = qw(test_harness pod2man perllocal_install uninstall
                  warn_if_old_packlist test_s cp_nonempty);
our $VERSION = '7.44';
$VERSION =~ tr/_//d;

my $Is_VMS = $^O eq 'VMS';

sub mtime {
  no warnings 'redefine';
  local $@;
  *mtime = (eval { require Time::HiRes } && defined &Time::HiRes::stat)
    ? sub { (Time::HiRes::stat($_[0]))[9] }
    : sub { (             stat($_[0]))[9] }
  ;
  goto &mtime;
}

=head1 NAME

ExtUtils::Command::MM - Commands for the MM's to use in Makefiles

=head1 SYNOPSIS

  perl "-MExtUtils::Command::MM" -e "function" "--" arguments...


=head1 DESCRIPTION

B<FOR INTERNAL USE ONLY!>  The interface is not stable.

ExtUtils::Command::MM encapsulates code which would otherwise have to
be done with large "one" liners.

Any $(FOO) used in the examples are make variables, not Perl.

=over 4

=item B<test_harness>

  test_harness($verbose, @test_libs);

Runs the tests on @ARGV via Test::Harness passing through the $verbose
flag.  Any @test_libs will be unshifted onto the test's @INC.

@test_libs are run in alphabetical order.

=cut

sub test_harness {
    require Test::Harness;
    require File::Spec;

    $Test::Harness::verbose = shift;

    # Because Windows doesn't do this for us and listing all the *.t files
    # out on the command line can blow over its exec limit.
    require ExtUtils::Command;
    my @argv = ExtUtils::Command::expand_wildcards(@ARGV);

    local @INC = @INC;
    unshift @INC, map { File::Spec->rel2abs($_) } @_;
    Test::Harness::runtests(sort { lc $a cmp lc $b } @argv);
}



=item B<pod2man>

  pod2man( '--option=value',
           $podfile1 => $manpage1,
           $podfile2 => $manpage2,
           ...
         );

  # or args on @ARGV

pod2man() is a function performing most of the duties of the pod2man
program.  Its arguments are exactly the same as pod2man as of 5.8.0
with the addition of:

    --perm_rw   octal permission to set the resulting manpage to

And the removal of:

    --verbose/-v
    --help/-h

If no arguments are given to pod2man it will read from @ARGV.

If Pod::Man is unavailable, this function will warn and return undef.

=cut

sub pod2man {
    local @ARGV = @_ ? @_ : @ARGV;

    {
        local $@;
        if( !eval { require Pod::Man } ) {
            warn "Pod::Man is not available: $@".
                 "Man pages will not be generated during this install.\n";
            return 0;
        }
    }
    require Getopt::Long;

    # We will cheat and just use Getopt::Long.  We fool it by putting
    # our arguments into @ARGV.  Should be safe.
    my %options = ();
    Getopt::Long::config ('bundling_override');
    Getopt::Long::GetOptions (\%options,
                'section|s=s', 'release|r=s', 'center|c=s',
                'date|d=s', 'fixed=s', 'fixedbold=s', 'fixeditalic=s',
                'fixedbolditalic=s', 'official|o', 'quotes|q=s', 'lax|l',
                'name|n=s', 'perm_rw=i', 'utf8|u'
    );
    delete $options{utf8} unless $Pod::Man::VERSION >= 2.17;

    # If there's no files, don't bother going further.
    return 0 unless @ARGV;

    # Official sets --center, but don't override things explicitly set.
    if ($options{official} && !defined $options{center}) {
        $options{center} = q[Perl Programmer's Reference Guide];
    }

    # This isn't a valid Pod::Man option and is only accepted for backwards
    # compatibility.
    delete $options{lax};
    my $count = scalar @ARGV / 2;
    my $plural = $count == 1 ? 'document' : 'documents';
    print "Manifying $count pod $plural\n";

    do {{  # so 'next' works
        my ($pod, $man) = splice(@ARGV, 0, 2);

        next if ((-e $man) &&
                 (mtime($man) > mtime($pod)) &&
                 (mtime($man) > mtime("Makefile")));

        my $parser = Pod::Man->new(%options);
        $parser->parse_from_file($pod, $man)
          or do { warn("Could not install $man\n");  next };

        if (exists $options{perm_rw}) {
            chmod(oct($options{perm_rw}), $man)
              or do { warn("chmod $options{perm_rw} $man: $!\n"); next };
        }
    }} while @ARGV;

    return 1;
}


=item B<warn_if_old_packlist>

  perl "-MExtUtils::Command::MM" -e warn_if_old_packlist <somefile>

Displays a warning that an old packlist file was found.  Reads the
filename from @ARGV.

=cut

sub warn_if_old_packlist {
    my $packlist = $ARGV[0];

    return unless -f $packlist;
    print <<"PACKLIST_WARNING";
WARNING: I have found an old package in
    $packlist.
Please make sure the two installations are not conflicting
PACKLIST_WARNING

}


=item B<perllocal_install>

    perl "-MExtUtils::Command::MM" -e perllocal_install
        <type> <module name> <key> <value> ...

    # VMS only, key|value pairs come on STDIN
    perl "-MExtUtils::Command::MM" -e perllocal_install
        <type> <module name> < <key>|<value> ...

Prints a fragment of POD suitable for appending to perllocal.pod.
Arguments are read from @ARGV.

'type' is the type of what you're installing.  Usually 'Module'.

'module name' is simply the name of your module.  (Foo::Bar)

Key/value pairs are extra information about the module.  Fields include:

    installed into      which directory your module was out into
    LINKTYPE            dynamic or static linking
    VERSION             module version number
    EXE_FILES           any executables installed in a space separated
                        list

=cut

sub perllocal_install {
    my($type, $name) = splice(@ARGV, 0, 2);

    # VMS feeds args as a piped file on STDIN since it usually can't
    # fit all the args on a single command line.
    my @mod_info = $Is_VMS ? split /\|/, <STDIN>
                           : @ARGV;

    my $pod;
    my $time = gmtime($ENV{SOURCE_DATE_EPOCH} || time);
    $pod = sprintf <<'POD', scalar($time), $type, $name, $name;
 =head2 %s: C<%s> L<%s|%s>

 =over 4

POD

    do {
        my($key, $val) = splice(@mod_info, 0, 2);

        $pod .= <<POD
 =item *

 C<$key: $val>

POD

    } while(@mod_info);

    $pod .= "=back\n\n";
    $pod =~ s/^ //mg;
    print $pod;

    return 1;
}

=item B<uninstall>

    perl "-MExtUtils::Command::MM" -e uninstall <packlist>

A wrapper around ExtUtils::Install::uninstall().  Warns that
uninstallation is deprecated and doesn't actually perform the
uninstallation.

=cut

sub uninstall {
    my($packlist) = shift @ARGV;

    require ExtUtils::Install;

    print <<'WARNING';

Uninstall is unsafe and deprecated, the uninstallation was not performed.
We will show what would have been done.

WARNING

    ExtUtils::Install::uninstall($packlist, 1, 1);

    print <<'WARNING';

Uninstall is unsafe and deprecated, the uninstallation was not performed.
Please check the list above carefully, there may be errors.
Remove the appropriate files manually.
Sorry for the inconvenience.

WARNING

}

=item B<test_s>

   perl "-MExtUtils::Command::MM" -e test_s <file>

Tests if a file exists and is not empty (size > 0).
I<Exits> with 0 if it does, 1 if it does not.

=cut

sub test_s {
  exit(-s $ARGV[0] ? 0 : 1);
}

=item B<cp_nonempty>

  perl "-MExtUtils::Command::MM" -e cp_nonempty <srcfile> <dstfile> <perm>

Tests if the source file exists and is not empty (size > 0). If it is not empty
it copies it to the given destination with the given permissions.

=back

=cut

sub cp_nonempty {
  my @args = @ARGV;
  return 0 unless -s $args[0];
  require ExtUtils::Command;
  {
    local @ARGV = @args[0,1];
    ExtUtils::Command::cp(@ARGV);
  }
  {
    local @ARGV = @args[2,1];
    ExtUtils::Command::chmod(@ARGV);
  }
}


1;