ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/staticperl/perl/installman
Revision: 1.1
Committed: Thu Jun 30 14:26:41 2005 UTC (21 years, 2 months ago) by root
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #!./perl -w
2     BEGIN { @INC = qw(lib) }
3     use strict;
4     use Config;
5     use Getopt::Long;
6     use File::Find;
7     use File::Copy;
8     use File::Path qw(mkpath);
9     use ExtUtils::Packlist;
10     use Pod::Man;
11     use subs qw(unlink chmod rename link);
12     use vars qw($packlist);
13    
14     if ($Config{d_umask}) {
15     umask(022); # umasks like 077 aren't that useful for installations
16     }
17    
18     $ENV{SHELL} = 'sh' if $^O eq 'os2';
19    
20     my $ver = $Config{version}; # Not used presently.
21     my $release = substr($],0,3); # Not used presently.
22     my $patchlevel = substr($],3,2);
23     die "Patchlevel of perl ($patchlevel)",
24     "and patchlevel of config.sh ($Config{'PERL_VERSION'}) don't match\n"
25     if $patchlevel != $Config{'PERL_VERSION'};
26    
27     my $usage =
28     "Usage: installman --man1dir=/usr/wherever --man1ext=1
29     --man3dir=/usr/wherever --man3ext=3
30     --batchlimit=40
31     --notify --verbose --silent --help
32     Defaults are:
33     man1dir = $Config{'installman1dir'};
34     man1ext = $Config{'man1ext'};
35     man3dir = $Config{'installman3dir'};
36     man3ext = $Config{'man3ext'};
37     --notify (or -n) just lists commands that would be executed.
38     --verbose (or -V) report all progress.
39     --silent (or -S) be silent. Only report errors.\n";
40    
41     my %opts;
42     GetOptions( \%opts,
43     qw( man1dir=s man1ext=s man3dir=s man3ext=s batchlimit=i
44     destdir:s notify n help silent S verbose V))
45     || die $usage;
46     die $usage if $opts{help};
47    
48     $opts{man1dir} = "$opts{destdir}$Config{'installman1dir'}"
49     unless defined($opts{man1dir});
50     $opts{man1ext} = $Config{'man1ext'}
51     unless defined($opts{man1ext});
52     $opts{man3dir} = "$opts{destdir}$Config{'installman3dir'}"
53     unless defined($opts{man3dir});
54     $opts{man3ext} = $Config{'man3ext'}
55     unless defined($opts{man3ext});
56     $opts{silent} ||= $opts{S};
57     $opts{notify} ||= $opts{n};
58     $opts{verbose} ||= $opts{V} || $opts{notify};
59    
60     #Sanity checks
61    
62     -x "./perl$Config{exe_ext}"
63     or warn "./perl$Config{exe_ext} not found! Have you run make?\n";
64     -d "$opts{destdir}$Config{'installprivlib'}"
65     || warn "Perl library directory $Config{'installprivlib'} not found.
66     Have you run make install?. (Installing anyway.)\n";
67     -x "t/perl$Config{exe_ext}" || warn "WARNING: You've never run 'make test'!!!",
68     " (Installing anyway.)\n";
69    
70     $packlist = ExtUtils::Packlist->new("$opts{destdir}$Config{installarchlib}/.packlist");
71    
72    
73     # Install the main pod pages.
74     pod2man('pod', $opts{man1dir}, $opts{man1ext});
75    
76     # Install the pods for library modules.
77     pod2man('lib', $opts{man3dir}, $opts{man3ext});
78    
79     # Install the pods embedded in the installed scripts
80     my $has_man1dir = $opts{man1dir} ne '' && -d $opts{man1dir};
81     open UTILS, "utils.lst" or die "Can't open 'utils.lst': $!";
82     while (<UTILS>) {
83     next if /^#/;
84     chomp;
85     $_ = $1 if /#.*pod\s*=\s*(\S+)/;
86     my ($where, $what) = m|^(\S*)/(\S+)|;
87     pod2man($where, $opts{man1dir}, $opts{man1ext}, $what);
88     if ($has_man1dir) {
89     if (my ($where2, $what2) = m|#.*link\s*=\s*(\S+)/(\S+)|) {
90     my $old = "$opts{man1dir}/$what.$opts{man1ext}";
91     my $new = "$opts{man1dir}/$what2.$opts{man1ext}";
92     unlink($new);
93     link($old, $new);
94     my $xold = $old;
95     $xold =~ s/^\Q$opts{'destdir'}\E// if $opts{'destdir'};
96     my $xnew = $new;
97     $xnew =~ s/^\Q$opts{'destdir'}\E// if $opts{'destdir'};
98     $packlist->{$xnew} = { from => $xold, type => 'link' };
99     }
100     }
101     }
102    
103     sub pod2man {
104     # @script is scripts names if we are installing manpages embedded
105     # in scripts, () otherwise
106     my($poddir, $mandir, $manext, @script) = @_;
107     if ($mandir eq ' ' or $mandir eq '') {
108     if (@script) {
109     warn "Skipping installation of $poddir/$_ man page.\n"
110     foreach @script;
111     } else {
112     warn "Skipping installation of $poddir man pages.\n";
113     }
114     return;
115     }
116    
117     print "installing from $poddir\n" if $opts{verbose};
118    
119     mkpath($mandir, $opts{verbose}, 0777) unless $opts{notify}; # In File::Path
120     # Make a list of all the .pm and .pod files in the directory. We avoid
121     # chdir because we are running with @INC = '../lib', and modules may wish
122     # to dynamically require Carp::Heavy or other diagnostics warnings.
123     # Hash the names of files we find, keys are names relative to perl build
124     # dir ('.'), values are names relative to $poddir.
125     my %modpods;
126     if (@script) {
127     %modpods = (map {+"$poddir/$_", $_} @script);
128     }
129     else {
130     File::Find::find({no_chdir=>1,
131     wanted => sub {
132     # $_ is $File::Find::name when using no_chdir
133     if (-f $_ and /\.p(?:m|od)$/) {
134     my $fullname = $_;
135     s!^\Q$poddir\E/!!;
136     $modpods{$fullname} = $_;
137     }
138     }},
139     $poddir);
140     }
141     my @to_process;
142     foreach my $mod (sort keys %modpods) {
143     my $manpage = $modpods{$mod};
144     my $tmp;
145     # Skip .pm files that have corresponding .pod files, and Functions.pm.
146     next if (($tmp = $mod) =~ s/\.pm$/.pod/ && -f $tmp);
147     next if $mod =~ m:/t/:; # no pods from test directories
148     next if ($manpage eq 'Pod/Functions.pm'); #### Used only by pod itself
149    
150     # Skip files without pod docs
151     my $has_pod;
152     if (open T, $mod)
153     {
154     local $_;
155     while (<T>)
156     {
157     ++$has_pod and last if /^=(?:head\d+|item|pod)\b/;
158     }
159    
160     close T;
161     }
162    
163     unless ($has_pod)
164     {
165     warn "no documentation in $mod\n";
166     next;
167     }
168    
169     # Convert name from File/Basename.pm to File::Basename.3 format,
170     # if necessary.
171     $manpage =~ s#\.p(m|od)$##;
172     if ($^O eq 'os2' || $^O eq 'amigaos' || $^O eq 'uwin' || $^O eq 'cygwin') {
173     $manpage =~ s#/#.#g;
174     }
175     else {
176     $manpage =~ s#/#::#g;
177     }
178     $tmp = "${mandir}/${manpage}.tmp";
179     $manpage = "${mandir}/${manpage}.${manext}";
180     push @to_process, [$mod, $tmp, $manpage];
181     }
182    
183     my $parser = Pod::Man->new( section => $manext,
184     official=> 1,
185     center => 'Perl Programmers Reference Guide'
186     );
187     foreach my $page (@to_process) {
188     my($pod, $tmp, $manpage) = @$page;
189    
190     my $xmanpage = $manpage;
191     $xmanpage =~ s/^\Q$opts{'destdir'}\E// if $opts{'destdir'};
192     print " $xmanpage\n";
193     if (!$opts{notify} && $parser->parse_from_file($pod, $tmp)) {
194     if (-s $tmp) {
195     if (rename($tmp, $manpage)) {
196     $packlist->{$xmanpage} = { type => 'file' };
197     next;
198     }
199     }
200     unlink($tmp);
201     }
202     }
203     }
204    
205     $packlist->write() unless $opts{notify};
206     print " Installation complete\n" if $opts{verbose};
207    
208     exit 0;
209    
210    
211     ###############################################################################
212     # Utility subroutines from installperl
213    
214     sub unlink {
215     my(@names) = @_;
216     my $cnt = 0;
217    
218     foreach my $name (@names) {
219     next unless -e $name;
220     chmod 0777, $name if $^O eq 'os2';
221     print " unlink $name\n" if $opts{verbose};
222     ( CORE::unlink($name) and ++$cnt
223     or warn "Couldn't unlink $name: $!\n" ) unless $opts{notify};
224     }
225     return $cnt;
226     }
227    
228     sub link {
229     my($from,$to) = @_;
230     my($success) = 0;
231    
232     print " ln $from $to\n" if $opts{verbose};
233     eval {
234     CORE::link($from, $to)
235     ? $success++
236     : ($from =~ m#^/afs/# || $to =~ m#^/afs/#)
237     ? die "AFS" # okay inside eval {}
238     : warn "Couldn't link $from to $to: $!\n"
239     unless $opts{notify};
240     };
241     if ($@) {
242     File::Copy::copy($from, $to)
243     ? $success++
244     : warn "Couldn't copy $from to $to: $!\n"
245     unless $opts{notify};
246     }
247     $success;
248     }
249    
250     sub rename {
251     my($from,$to) = @_;
252     if (-f $to and not unlink($to)) {
253     my($i);
254     for ($i = 1; $i < 50; $i++) {
255     last if CORE::rename($to, "$to.$i");
256     }
257     warn("Cannot rename to `$to.$i': $!"), return 0
258     if $i >= 50; # Give up!
259     }
260     link($from,$to) || return 0;
261     unlink($from);
262     }
263    
264     sub chmod {
265     my($mode,$name) = @_;
266    
267     printf " chmod %o %s\n", $mode, $name if $opts{verbose};
268     CORE::chmod($mode,$name) || warn sprintf("Couldn't chmod %o %s: $!\n",$mode,$name)
269     unless $opts{notify};
270     }
271    
272     sub samepath {
273     my($p1, $p2) = @_;
274     my($dev1, $ino1, $dev2, $ino2);
275    
276     if ($p1 ne $p2) {
277     ($dev1, $ino1) = stat($p1);
278     ($dev2, $ino2) = stat($p2);
279     ($dev1 == $dev2 && $ino1 == $ino2);
280     }
281     else {
282     1;
283     }
284     }