silent-rules: fix alignment of less verbose output.
[automake.git] / lib / gnupload
blob7c34784e41641ecaed0b9acfa5574e30071cc9a7
1 #!/bin/sh
2 # Sign files and upload them.
4 scriptversion=2009-03-05.20
6 # Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3, or (at your option)
11 # any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 # Originally written by Alexandre Duret-Lutz <adl@gnu.org>.
23 set -e
25 GPG='gpg --batch --no-tty'
26 conffile=.gnuploadrc
27 to=
28 dry_run=false
29 symlink_files=
30 delete_files=
31 delete_symlinks=
32 collect_var=
33 dbg=
35 usage="Usage: $0 [OPTIONS]... [COMMAND] FILES... [[COMMAND] FILES...]
37 Sign all FILES, and upload them to selected destinations, according to
38 <http://www.gnu.org/prep/maintain/html_node/Automated-FTP-Uploads.html>.
40 Commands:
41 --delete delete FILES from destination
42 --symlink create symbolic links
43 --rmsymlink remove symbolic links
44 -- treat the remaining arguments as files to upload
46 Options:
47 --help print this help text and exit
48 --to DEST specify one destination for FILES
49 (multiple --to options are allowed)
50 --user NAME sign with key NAME
51 --symlink-regex[=EXPR] use sed script EXPR to compute symbolic link names
52 --dry-run do nothing, show what would have been done
53 --version output version information and exit
55 If --symlink-regex is given without EXPR, then the link target name
56 is created by replacing the version information with \`-latest', e.g.:
58 foo-1.3.4.tar.gz -> foo-latest.tar.gz
60 Recognized destinations are:
61 alpha.gnu.org:DIRECTORY
62 savannah.gnu.org:DIRECTORY
63 savannah.nongnu.org:DIRECTORY
64 ftp.gnu.org:DIRECTORY
65 build directive files and upload files by FTP
66 download.gnu.org.ua:{alpha|ftp}/DIRECTORY
67 build directive files and upload files by SFTP
68 [user@]host:DIRECTORY upload files with scp
70 Options and commands are applied in order. If the file $conffile exists
71 in the current working directory, its contents are prepended to the
72 actual command line options. Use this to keep your defaults. Comments
73 (#) and empty lines in $conffile are allowed.
75 Examples:
76 1. Upload automake-1.8.2b.tar.gz and automake-1.8.2b.tar.bz2 to two sites:
77 gnupload --to sources.redhat.com:~ftp/pub/automake \\
78 --to alpha.gnu.org:automake \\
79 automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
81 2. Same as above, but also create symbolic links to automake-latest.tar.*:
82 gnupload --to sources.redhat.com:~ftp/pub/automake \\
83 --to alpha.gnu.org:automake \\
84 --symlink-regex \\
85 automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
87 3. Symlink automake-1.8.2b.tar.gz to automake-latest.tar.gz and
88 automake-1.8.2b.tar.bz2 to automake-latest.tar.bz2 on both sites:
90 gnupload --to sources.redhat.com:~ftp/pub/automake \\
91 --to alpha.gnu.org:automake \\
92 --symlink automake-1.8.2b.tar.gz automake-latest.tar.gz \\
93 automake-1.8.2b.tar.bz2 automake-latest.tar.bz2
95 4. Delete automake-1.8.2a.tar.gz and .bz2, remove symlink
96 automake-latest.tar.gz and upload automake-1.8.2b.tar.gz:
98 gnupload --to sources.redhat.com:~ftp/pub/automake \\
99 --to alpha.gnu.org:automake \\
100 --delete automake-1.8.2a.tar.gz automake-1.8.2a.tar.bz2 \\
101 --rmsymlink automake-latest.tar.gz \\
102 -- \\
103 automake-1.8.2b.tar.gz automake-1.8.2b.tar.bz2
105 Report bugs to <bug-automake@gnu.org>.
106 Send patches to <automake-patches@gnu.org>."
108 # Read local configuration file
109 if test -r "$conffile"; then
110 echo "$0: Reading configuration file $conffile"
111 eval set x "`sed 's/#.*$//;/^$/d' \"$conffile\" | tr '\012\015' ' '` \"\$@\""
112 shift
115 while test -n "$1"; do
116 case $1 in
118 collect_var=
119 case $1 in
120 --help)
121 echo "$usage"
122 exit $?
124 --to)
125 if test -z "$2"; then
126 echo "$0: Missing argument for --to" 1>&2
127 exit 1
128 else
129 to="$to $2"
130 shift
133 --user)
134 if test -z "$2"; then
135 echo "$0: Missing argument for --user" 1>&2
136 exit 1
137 else
138 GPG="$GPG --local-user $2"
139 shift
142 --delete)
143 collect_var=delete_files
145 --rmsymlink)
146 collect_var=delete_symlinks
148 --symlink-regex=*)
149 symlink_expr=`expr "$1" : '[^=]*=\(.*\)'`
151 --symlink-regex)
152 symlink_expr='s|-[0-9][0-9\.]*\(-[0-9][0-9]*\)\{0,1\}\.|-latest.|'
154 --symlink)
155 collect_var=symlink_files
157 --dry-run|-n)
158 dry_run=:
160 --version)
161 echo "gnupload $scriptversion"
162 exit $?
165 shift
166 break
169 echo "$0: Unknown option \`$1', try \`$0 --help'" 1>&2
170 exit 1
172 esac
175 if test -z "$collect_var"; then
176 break
177 else
178 eval "$collect_var=\"\$$collect_var $1\""
181 esac
182 shift
183 done
185 dprint()
187 echo "Running $*..."
190 if $dry_run; then
191 dbg=dprint
194 if test -z "$to"; then
195 echo "$0: Missing destination sites" >&2
196 exit 1
199 if test -n "$symlink_files"; then
200 x=`echo "$symlink_files" | sed 's/[^ ]//g;s/ //g'`
201 if test -n "$x"; then
202 echo "$0: Odd number of symlink arguments" >&2
203 exit 1
207 if test $# = 0; then
208 if test -z "${symlink_files}${delete_files}${delete_symlinks}"; then
209 echo "$0: No file to upload" 1>&2
210 exit 1
212 else
213 # Make sure all files exist. We don't want to ask
214 # for the passphrase if the script will fail.
215 for file
217 if test ! -f $file; then
218 echo "$0: Cannot find \`$file'" 1>&2
219 exit 1
220 elif test -n "$symlink_expr"; then
221 linkname=`echo $file | sed "$symlink_expr"`
222 if test -z "$linkname"; then
223 echo "$0: symlink expression produces empty results" >&2
224 exit 1
225 elif test "$linkname" = $file; then
226 echo "$0: symlink expression does not alter file name" >&2
227 exit 1
230 done
233 # Make sure passphrase is not exported in the environment.
234 unset passphrase
236 # Reset PATH to be sure that echo is a built-in. We will later use
237 # `echo $passphrase' to output the passphrase, so it is important that
238 # it is a built-in (third-party programs tend to appear in `ps'
239 # listings with their arguments...).
240 # Remember this script runs with `set -e', so if echo is not built-in
241 # it will exit now.
242 PATH=/empty echo -n "Enter GPG passphrase: "
243 stty -echo
244 read -r passphrase
245 stty echo
246 echo
248 if test $# -ne 0; then
249 for file
251 echo "Signing $file..."
252 rm -f $file.sig
253 echo "$passphrase" | $dbg $GPG --passphrase-fd 0 -ba -o $file.sig $file
254 done
258 # mkdirective DESTDIR BASE FILE STMT
259 # Arguments: See upload, below
260 mkdirective ()
262 stmt="$4"
263 if test -n "$3"; then
264 stmt="
265 filename: $3$stmt"
268 cat >${2}.directive<<EOF
269 version: 1.1
270 directory: $1
271 comment: gnupload v. $scriptversion$stmt
273 if $dry_run; then
274 echo "File ${2}.directive:"
275 cat ${2}.directive
276 echo "File ${2}.directive:" | sed 's/./-/g'
280 mksymlink ()
282 while test $# -ne 0
284 echo "symlink: $1 $2"
285 shift
286 shift
287 done
290 # upload DEST DESTDIR BASE FILE STMT FILES
291 # Arguments:
292 # DEST Destination site;
293 # DESTDIR Destination directory;
294 # BASE Base name for the directive file;
295 # FILE Name of the file to distribute (may be empty);
296 # STMT Additional statements for the directive file;
297 # FILES List of files to upload.
298 upload ()
300 dest=$1
301 destdir=$2
302 base=$3
303 file=$4
304 stmt=$5
305 files=$6
307 rm -f $base.directive $base.directive.asc
308 case $dest in
309 alpha.gnu.org:*)
310 mkdirective "$destdir" "$base" "$file" "$stmt"
311 echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
312 $dbg ncftpput ftp-upload.gnu.org /incoming/alpha $files $base.directive.asc
314 ftp.gnu.org:*)
315 mkdirective "$destdir" "$base" "$file" "$stmt"
316 echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
317 $dbg ncftpput ftp-upload.gnu.org /incoming/ftp $files $base.directive.asc
319 savannah.gnu.org:*)
320 if test -z "$files"; then
321 echo "$0: warning: standalone directives not applicable for $dest" >&2
323 $dbg ncftpput savannah.gnu.org /incoming/savannah/$destdir $files
325 savannah.nongnu.org:*)
326 if test -z "$files"; then
327 echo "$0: warning: standalone directives not applicable for $dest" >&2
329 $dbg ncftpput savannah.nongnu.org /incoming/savannah/$destdir $files
331 download.gnu.org.ua:alpha/*|download.gnu.org.ua:ftp/*)
332 destdir_p1=`echo "$destdir" | sed 's,^[^/]*/,,'`
333 destdir_topdir=`echo "$destdir" | sed 's,/.*,,'`
334 mkdirective "$destdir_p1" "$base" "$file" "$stmt"
335 echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
336 for f in $files $base.directive.asc
338 echo put $f
339 done | $dbg sftp -b - puszcza.gnu.org.ua:/incoming/$destdir_topdir
342 dest_host=`echo "$dest" | sed 's,:.*,,'`
343 mkdirective "$destdir" "$base" "$file" "$stmt"
344 echo "$passphrase" | $dbg $GPG --passphrase-fd 0 --clearsign $base.directive
345 $dbg cp $files $base.directive.asc $dest_host
348 if test -z "$files"; then
349 echo "$0: warning: standalone directives not applicable for $dest" >&2
351 $dbg scp $files $dest
353 esac
354 rm -f $base.directive $base.directive.asc
357 #####
358 # Process any standalone directives
359 stmt=
360 if test -n "$symlink_files"; then
361 stmt="$stmt
362 `mksymlink $symlink_files`"
365 for file in $delete_files
367 stmt="$stmt
368 archive: $file"
369 done
371 for file in $delete_symlinks
373 stmt="$stmt
374 rmsymlink: $file"
375 done
377 if test -n "$stmt"; then
378 for dest in $to
380 destdir=`echo $dest | sed 's/[^:]*://'`
381 upload "$dest" "$destdir" "`hostname`-$$" "" "$stmt"
382 done
385 # Process actual uploads
386 for dest in $to
388 for file
390 echo "Uploading $file to $dest..."
391 stmt=
392 files="$file $file.sig"
393 destdir=`echo $dest | sed 's/[^:]*://'`
394 if test -n "$symlink_expr"; then
395 linkname=`echo $file | sed "$symlink_expr"`
396 stmt="$stmt
397 symlink: $file $linkname
398 symlink: $file.sig $linkname.sig"
400 upload "$dest" "$destdir" "$file" "$file" "$stmt" "$files"
401 done
402 done
404 exit 0
406 # Local variables:
407 # eval: (add-hook 'write-file-hooks 'time-stamp)
408 # time-stamp-start: "scriptversion="
409 # time-stamp-format: "%:y-%02m-%02d.%02H"
410 # time-stamp-end: "$"
411 # End: