2 # Copyright (C) 2020-2022 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2, or (at your option)
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 use 5.014; # first version with HTTP::Tiny
20 use feature
'unicode_strings';
21 use warnings FATAL
=> 'all';
23 use Fcntl qw
(S_IMODE
);
26 use File
::Temp qw
(tempfile
);
30 # From outside to inside: locations in our source tree where to put
31 # files retrieved from other projects; the savannah.gnu.org project
32 # name of each project to retrieve files from; and the set of files
33 # to retrieve from that project into that location.
34 # Files put into a directory named 'Autom4te' are subject to "editing"
35 # (see the $edit parameter to sub fetch).
52 'build-aux/announce-gen',
53 'build-aux/gendocs.sh',
54 'build-aux/git-version-gen',
55 'build-aux/gitlog-to-changelog',
57 'build-aux/move-if-change',
58 'build-aux/update-copyright',
59 'build-aux/useless-if-before-free',
60 'build-aux/vc-list-files',
68 'doc/gendocs_template',
71 'gnustandards/fdl.texi',
72 'gnustandards/gnu-oids.texi',
73 'gnustandards/make-stds.texi',
74 'gnustandards/standards.texi',
79 'lib/Automake/ChannelDefs.pm',
80 'lib/Automake/Channels.pm',
81 'lib/Automake/Configure_ac.pm',
82 'lib/Automake/FileUtils.pm',
83 'lib/Automake/Getopt.pm',
84 'lib/Automake/XFile.pm',
95 # Shorthands for catfile and splitpath.
96 # File::Spec::Functions was only added in 5.30, which is much too new.
99 return File
::Spec
->catfile (@_);
104 return File
::Spec
->splitpath (@_);
109 # Returns $s, %-quoted appropriately for interpolation into the
110 # path or query component of a URL. Assumes that non-ASCII characters
111 # should be encoded in UTF-8 before quoting.
119 [^./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
~-]
121 sprintf("%%%02X", ord($&))
127 # savannah_url($repo, $filename)
128 # Returns the URL from which the contents of $filename within $repo
129 # can be retrieved, assuming $repo is the name of a savannah.gnu.org
133 my ($repo, $filename) = @_;
135 $repo = urlquote
($repo);
136 $filename = urlquote
($filename);
138 # The GNU Coding Standards are still maintained in CVS.
139 if ($repo eq 'gnustandards')
141 my $cvsweb_base = 'https://cvs.savannah.gnu.org/viewvc/*checkout*/';
142 return $cvsweb_base . $repo . '/' . $filename;
146 my $cgit_base = 'https://git.savannah.gnu.org/cgit/';
147 my $cgit_op = '.git/plain/';
149 return $cgit_base . $repo . $cgit_op . $filename;
155 # Read the contents of $filename into a scalar and return them.
156 # If $filename does not exist, return undef; any other error is fatal.
160 local $/; # engage slurp mode
161 if (open my $fh, '<', $filename)
171 die "$filename: $!\n";
176 # replace_if_change ($file, $newcontents, $quiet)
177 # If $newcontents is different from the contents of $file,
178 # atomically replace $file's contents with $newcontents.
179 # This function assumes POSIX semantics for rename over an existing
180 # file (i.e. atomic replacement, not an error).
181 sub replace_if_change
($$$)
183 my ($file, $newcontents, $quiet) = @_;
184 my $oldcontents = slurp
$file;
186 if (defined $oldcontents && $oldcontents eq $newcontents)
188 print STDERR
"$file is unchanged\n" unless $quiet;
192 my (undef, $subdir, undef) = splitpath
$file;
193 my ($tmp_fh, $tmp_name) = tempfile
(DIR
=> $subdir);
198 print $tmp_fh $newcontents;
201 or die "$0: writing to $tmp_name: $!\n";
203 # Preserve the permissions of the original file, if it exists.
204 if (defined $oldcontents)
207 chmod (S_IMODE
($st->mode), $tmp_name)
208 or die "$0: setting permissions on $tmp_name: $!\n";
211 rename $tmp_name, $file
212 or die "$0: rename($tmp_name, $file): $!\n";
214 print STDERR
"$file updated\n";
218 # fetch ($path, $repo, $destdir, $edit, $quiet, $client)
219 # Retrieve $path from repository $repo,
220 # writing it to $destdir/$(basename $path).
221 # If $edit is true, perform s/\bAutomake::/Autom4te::/g on the file's
223 # If $quiet is true, don't print progress reports.
224 # $client must be a HTTP::Tiny instance.
227 my ($path, $repo, $destdir, $edit, $quiet, $client) = @_;
228 my (undef, undef, $file) = splitpath
($path);
229 my $destpath = catfile
($destdir, $file);
231 my $uri = savannah_url
($repo, $path);
232 print STDERR
"fetch $destpath <- $uri ...\n" unless $quiet;
234 my $resp = $client->get ($uri);
236 die "$uri: $resp->{status} $resp->{reason}\n"
237 unless $resp->{success
};
239 my $content = $resp->{content
};
240 # don't use \s here or it will eat blank lines
241 $content =~ s/[ \t]+$//gm;
242 $content =~ s/\bAutomake::/Autom4te::/g if $edit;
244 replace_if_change
($destpath, $content, $quiet);
251 GetOptions
('quiet|q' => \
$quiet)
252 or die "usage: $0 [-q] destination-directory\n";
254 my $topdestdir = shift @ARGV
255 or die "usage: $0 [-q] destination-directory\n";
258 or die "usage: $0 [-q] destination-directory\n";
260 my $client = HTTP
::Tiny
->new(
261 agent
=> 'autoconf-fetch.pl/1.0 ',
266 my ($can_ssl, $whynot) = $client->can_ssl;
267 die "$0: HTTPS support not available"
268 . " (do you need to install IO::Socket::SSL?\n"
272 while (my ($subdir, $groups) = each %to_fetch)
274 my $edit = $subdir =~ m!/Autom4te$!;
275 my $destdir = catfile
($topdestdir, $subdir);
276 while (my ($project, $files) = each %$groups)
278 fetch
$_, $project, $destdir, $edit, $quiet, $client
286 ### Setup "GNU" style for perl-mode and cperl-mode.
288 ## perl-indent-level: 2
289 ## perl-continued-statement-offset: 2
290 ## perl-continued-brace-offset: 0
291 ## perl-brace-offset: 0
292 ## perl-brace-imaginary-offset: 0
293 ## perl-label-offset: -2
294 ## cperl-indent-level: 2
295 ## cperl-brace-offset: 0
296 ## cperl-continued-brace-offset: 0
297 ## cperl-label-offset: -2
298 ## cperl-extra-newline-before-brace: t
299 ## cperl-merge-trailing-else: nil
300 ## cperl-continued-statement-offset: 2