source: rpmbuild-bot/rpmbuild-bot.sh@ 833

Last change on this file since 833 was 833, checked in by dmik, 9 years ago

rpmbuild-bot: Support per-package ARCH specification in -env.sh.

This is to be used to restrict (or enhance) the package list for
specific package needs. One use case is to limit the number of
architectures to one for packages composed from pre-built
binaries (often available for only a single architecture).

File size: 24.9 KB
Line 
1#!/bin/sh
2
3#
4# rpmbuild-bot.sh: RPM Build Bot version 1.1.0.
5#
6# Author: Dmitriy Kuminov <coding@dmik.org>
7#
8# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
9# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
10#
11# Synopsis
12# --------
13#
14# This script performs a build of RPM packages from a given .spec file in
15# controlled environment to guarantee consistent results when building RPMs
16# different machines. It uses a separate file rpmbuild-bot-env.sh located
17# in the same directory to set up the environment and control the build
18# process. The main purpose of this script is to build RPM packages for a
19# specific distribution channel maintaining distribution-siecific rules.
20#
21# Usage
22# -----
23#
24# > rpmbuild-bot.sh SPEC[=VERSION]
25# > [ upload[=REPO] | test[=MODE] | clean[=test] |
26# > move[=FROM_REPO=TO_REPO] | remove[=REPO] ]
27# > [-f]
28#
29# MYAPP is the name of the RPM package spec file (extension is optional,
30# .spec is assumed). The spec file is searched in the SPECS directory of the
31# rpmbuild tree (usually $USER/rpmbuild/SPECS, rpmbuild --eval='%_specdir'
32# will show the exact location). This may be overriden by giving a spec file
33# with a path specification.
34#
35# The second argument defines the command to perform. The default command is
36# "build". The following sections will describe each command.
37#
38# Building packages
39# -----------------
40#
41# The "build" is the main command which is used to generate packages for
42# distribution. This command does the following:
43#
44# 1. Build all RPM packages for all architectures specified in
45# $RPMBUILD_BOT_ARCH_LIST. The packages are stored in the RPMS
46# directory of the rpmbuild tree.
47# 2. Build the source RPM. Stored in the SRPMS directory.
48# 3. Create a ZIP package from the RPMs for the architecture specified
49# last in $RPMBUILD_BOT_ARCH_LIST.
50#
51# The build process for each architecture is stored in a log file in the logs
52# directory of the rpmbuild tree (`rpmbuild --eval='%_topdir'/logs`). Creation
53# of the source RPM and ZIP files is also logged, into separate log files.
54#
55# The "build" command will fail if the log directory contains files from a
56# successfull run of another "build" command for this package. This is to
57# prevent overwriting successfully built packages that are not yet uploaded to
58# the distribution repository (see the "upload" command). You should either
59# run the "upload" command or use the -f option to force removal of these
60# log files and the corresponding package files if you are absolutely sure they
61# should be discarded.
62#
63# The "build" command will also check if there is a directory named SPEC in the
64# same directory where the given .spec file resides. If such a directory
65# exists, all files in it are assumed to be auxiliary source files used by the
66# .spec file via SourceN: directives. These files will be automatically copied
67# to the SOURCES directory in the rpmbuild tree befure starting the build
68# process.
69#
70# Doing test builds
71# -----------------
72#
73# The "test" command is used to build packages for one architecture for testing
74# purposes. In this more, neither the source RPM nor the ZIP file is created.
75# Also, a special option is automatically passed to rpmbuild to clear the %dist
76# variable to indicate that this is a local, non-distribution build. Such
77# packages will always be "older" than the corresponding builds with %dist
78# so that they will be automatically updated on the next yum update to the
79# %dist ones. The packages built in "test" mode are NOT intended for
80# distribution, they are meant only for local testing before performing the
81# full build of everything.
82#
83# It is possible to configure which steps of the build to perform using the MODE
84# parameter to the "test" command which may take one of the following values:
85#
86# prep Execute the %prep section of the spec file only.
87# build Execute the %build section only (requres %prep to be executed
88# before). May be run multiple times.
89# install Execute the %install sectuion only (requires "prep" and "build"
90# to be executed before). May be run multiple times.
91# pack Create the RPM packages (requires "prep", "build" and "install"
92# to be executed before). Note that this step will also execute
93# the %clean section so that a new "install" execution is
94# necessary for "pack" to succeed.
95#
96# When no MODE parameter is given, all steps are executed in a proper order.
97#
98# The results of the "test" command are stored in a log file in the logs/test
99# directory of the rpmbuild tree. The previous log file, if any, is given a .bak
100# extension (the previous .bak file will be deleted).
101#
102# The "test" command will copy auxiliary source files for the .spec file, if any,
103# to the proper location before rpmbuild execution -- the same way the "build"
104# command does it.
105#
106# Uploading packages
107# ------------------
108#
109# The "upload" command will upload the packages built with the "build"
110# command to the official distribution channel configured in
111# rpmbuild-bot-env.sh. The REPO parameter specifies one of the configured
112# repositories. When REPO is not given, the default repository is used
113# (usually experimental or similar).
114#
115# Note that the "upload" command needs log files from the "build" command
116# and will fail otherwise.
117#
118# Upon successful completion, the "upload" command will remove all uploaded
119# RPM and ZIP packages and will move all "build" log files to logs/archive.
120#
121# Cleaning packages
122# -----------------
123#
124# The "clean" command will delete packages built with the "build" command
125# and their log files without uploading them to a repository. This is useful
126# when the successful build needs to be canceled for some reason (wrong source
127# tree state, wrong patches etc.). Note that normally you don't need to use
128# this command; it's an emergency-only tool.
129#
130# The "clean" command needs log files from the "build" command and will fail
131# otherwise.
132#
133# If the "clean" command is given a "test" parameter, it will clean up the
134# results of the "test" command instead of "build". The log file from the
135# "test" command needs to be present or the command will fail.
136#
137# Moving packages between repositories
138# ------------------------------------
139#
140# The "move" command allows to move a particular version of the packages
141# built with the "build" command and uploaded with the "upload" command from one
142# repository to another one. The "move" command is normally used to move
143# packages from a test repository to a production one when they are ready for
144# wide distribution.
145#
146# The "move" command needs log files from the "build" and "upload" commands
147# and will fail otherwise. It also requires the VERSION parameter for the SPEC
148# argument to be given (to specify the version of the packages to remove) and
149# requires the FROM_REPO=TO_REPO parameter itself to specify the source
150# repository and the target repository, respectively.
151#
152# The log files from the "build" and "upload" commands are not removed by the
153# "move" command so it may be performed multiple times. The current location
154# of the packages is not tracked in the log files so the command will fail
155# if the source repository doesn't have the package files or if the target
156# repository already has them.
157#
158# Removing packages
159# -----------------
160#
161# The "remove" command allows to remove a particular version of the packages
162# built with the "build" command and uploaded with the "upload" command from a
163# repository. This is useful when the successful build needs to be canceled for
164# some reason (wrong source tree state, wrong patches etc.). Note that normally
165# you don't need to use this command; it's an emergency-only tool.
166#
167# The "remove" command needs log files from the "build" and "upload" commands
168# and will fail otherwise. It also requires the VERSION parameter for the SPEC
169# argument to be given (to specify the version of the packages to remove) and
170# accepts the REPO parameter itself just like the "upload" command does (to
171# specify a repository to remove the packages from).
172#
173# Note that the log files from the "build" and "upload" commands are also
174# removed by this command upon sucessful package removal.
175#
176# Return value
177# ------------
178#
179# The rpmbuild-bot.sh script will return a zero exit code upon successful
180# completion and non-zero otherwise. The script output and log files should be
181# inspected to check for a reason of the failure.
182#
183
184#
185# Helpers.
186#
187
188print_elapsed()
189{
190 # $1 = start timestamp, in seconds (as returned by `date +%s`)
191 # $2 = string containg \$e (will be replaced with the elapsed time)
192
193 [ -z "$1" -o -z "$2" ] && return
194
195 local e=$(($(date +%s) - $1))
196 local e_min=$(($e / 60))
197 local e_sec=$(($e % 60))
198 local e_hrs=$((e_min / 60))
199 e_min=$((e_min % 60))
200 e="${e_hrs}h ${e_min}m ${e_sec}s"
201
202 eval "echo \"$2\""
203}
204
205quit()
206{
207 if [ -n "$start_time" ] ; then
208 echo "Build ended on $(date -R)."
209 if [ $1 = 0 ] ; then
210 print_elapsed start_time "Build succeeded (took \$e)."
211 else
212 print_elapsed start_time "Build failed (took \$e)."
213 fi
214 fi
215 exit $1
216}
217
218run()
219{
220 "$@"
221 local rc=$?
222 if test $rc != 0 ; then
223 echo "ERROR: The following command failed with error code $rc:"
224 echo $@
225 quit $rc
226 fi
227}
228
229log_run()
230{
231 log="$1"
232 shift
233 rm -f "$log"
234 "$@" >"$log" 2>&1
235 local rc=$?
236 if test $rc != 0 ; then
237 echo "ERROR: The following command failed with error code $rc:"
238 echo $@
239 echo "You will find more information in file '$log'."
240 echo "Here are the last 10 lines of output:"
241 echo "------------------------------------------------------------------------------"
242 tail "$log" -n 10
243 echo "------------------------------------------------------------------------------"
244 quit $rc
245 fi
246}
247
248warn()
249{
250 echo "WARNING: $1"
251}
252
253die()
254{
255 echo "ERROR: $1"
256 quit 1
257}
258
259check_dir_var()
260{
261 eval local val="\$$1"
262 [ -n "$val" ] || die "$1 is empty."
263 [ -d "$val" ] || die "$1 is '$val', not a valid directory."
264}
265
266read_file_list()
267{
268 # $1 = file list filename
269 # $2 = var name where to save the list of read file names (optional)
270 # $3 = function name to call for each file (optional), it may assign a new
271 # file name to $file and also set $file_pre and $file_post that will
272 # be prepended and appended to $file when saving it to the list in $2
273 # (but not when checking for file existence and timestamp)
274
275 local list="$1"
276 local _read_file_list_ret=
277
278 # Check timestamps.
279 while read l; do
280 local file_pre=
281 local file_post=
282 local file="${l#*|}"
283 local ts="${l%%|*}"
284 [ "$file" = "$ts" ] && die "Line '$l' in '$list' does not contain timestamps."
285 [ -n "$3" ] && eval $3
286 [ -f "$file" ] || die "File '$file' is not found."
287 echo "Checking timestamp of $file..."
288 local act_ts=`stat -c '%Y' "$file"`
289 # Drop fractional part of seconds reported by older coreutils
290 ts="${ts%%.*}"
291 act_ts="${act_ts%%.*}"
292 if [ "$ts" != "$act_ts" ] ; then
293 die "Recorded timestamp $ts doesn't match actual timestamp $act_ts for '$file'."
294 fi
295 _read_file_list_ret="$_read_file_list_ret${_read_file_list_ret:+ }$file_pre$file$file_post"
296 done < "$list"
297 # Return the files (if requested).
298 [ -n "$2" ] && eval "$2=\$_read_file_list_ret"
299}
300
301usage()
302{
303 echo "Usage:"
304 sed -n -e "s/rpmbuild-bot.sh/${0##*/}/g" -e 's/^# > / /p' < "$0"
305 quit 255
306}
307
308sync_aux_src()
309{
310 [ -n "$src_dir" ] || die "src_dir is empty."
311 [ -n "$spec_full" ] || die "spec_full is empty."
312
313 # Aux source dir is expected along the .spec file.
314 local aux_src_dir="${spec_full%.spec}"
315
316 # Return early if there is no aux source dir.
317 [ -d "$aux_src_dir" ] || return
318
319 echo "Copying auxiliary sources for '$spec' to $src_dir..."
320
321 for f in "$aux_src_dir"/* ; do
322 local ts=`stat -c '%Y' "$f"`
323 local trg_ts=
324 local trg_f="$src_dir/${f##*/}"
325 [ -f "$trg_f" ] && trg_ts=`stat -c '%Y' "$trg_f"`
326 if [ "$ts" != "$trg_ts" ] ; then
327 echo "Copying $f..."
328 run cp -p "$f" "$trg_f"
329 fi
330 done
331}
332
333build_cmd()
334{
335 eval local arch_list="\${RPMBUILD_BOT_ARCH_LIST_${spec_name}}"
336 [ -z "$arch_list" ] && arch_list="${RPMBUILD_BOT_ARCH_LIST}"
337
338 local base_arch="${arch_list##* }"
339
340 echo "Spec file: $spec_full"
341 echo "Targets: $arch_list + SRPM + ZIP ($base_arch)"
342
343 sync_aux_src
344
345 if [ -f "$spec_list" ] ; then
346 if [ -z "$force" ] ; then
347 die "File '$spec_list' already exists.
348This file indicates a successful build that was not yet uploaded.
349Either run the '"'upload'"' command to upload the generated RPM and ZIP
350packages to the distribution repository or use the -f option to
351force their removal if you are sure they should be discarded."
352 fi
353
354 echo "Detected successful build in $spec_list, cleaning up due to -f option..."
355 local files=
356 read_file_list "$spec_list" files
357 for f in $files; do
358 echo "Removing $f..."
359 run rm -f "$f"
360 done
361 unset files
362
363 echo "Removing $log_base.*.log and .list files..."
364 rm -f "$log_base".*.log "$log_base".*.list "$log_base".list
365 fi
366
367 local start_time=
368
369 # Generate RPMs.
370 for arch in $arch_list ; do
371 echo "Creating RPMs for '$arch' target (logging to $log_base.$arch.log)..."
372 start_time=$(date +%s)
373 log_run "$log_base.$arch.log" rpmbuild.exe --target=$arch -bb "$spec_full"
374 print_elapsed start_time "Completed in \$e."
375 done
376
377 # Generate SRPM.
378 echo "Creating SRPM (logging to $log_base.srpm.log)..."
379 start_time=$(date +%s)
380 log_run "$log_base.srpm.log" rpmbuild -bs "$spec_full"
381 print_elapsed start_time "Completed in \$e."
382
383 # Find SRPM file name in the log.
384 local src_rpm=`grep "^Wrote: \+.*\.src\.rpm$" "$log_base.srpm.log" | sed -e "s#^Wrote: \+##g"`
385 [ -n "$src_rpm" ] || die "Cannot find .src.rpm file name in '$log_base.srpm.log'."
386
387 # Find package version.
388 local ver_full="${src_rpm%.src.rpm}"
389 ver_full="${ver_full##*/}"
390 [ "${ver_full%%-[0-9]*}" = "$spec_name" ] || die \
391"SRPM name '${src_rpm##*/}' does not match .spec name ('$spec_name').
392Either rename '$spec_name.spec' to '${ver_full%%-[0-9]*}.spec' or set 'Name:' tag to '$spec_name'."
393 ver_full="${ver_full#${spec_name}-}"
394 [ -n "$ver_full" ] || die "Cannot deduce package version from '$src_rpm'."
395
396 # Find all RPM packages for the base arch (note the quotes around `` - it's to preserve multi-line result).
397 local rpms="`grep "^Wrote: \+.*\.\($base_arch\.rpm\|noarch\.rpm\)$" "$log_base.$base_arch.log" | sed -e "s#^Wrote: \+##g"`"
398 [ -n "$rpms" ] || die "Cannot find .$base_arch.rpm/.noarch.rpm file names in '$log_base.base_arch.log'."
399
400 local ver_full_zip=`echo $ver_full | tr . _`
401 local zip="$zip_dir/$spec_name-$ver_full_zip.zip"
402
403 # Generate ZIP.
404 echo "Creating ZIP (logging to $log_base.zip.log)..."
405 start_time=$(date +%s)
406 create_zip()
407 {(
408 run cd "$zip_dir"
409 rm -r "@unixroot" 2> /dev/null
410 # Note no quoters around $rpms - it's to split at EOL.
411 for f in $rpms ; do
412 echo "Unpacking $f..."
413 run rpm2cpio "$f" | cpio -idm
414 done
415 rm -f "$zip" 2> /dev/null
416 echo "Creating '$zip'..."
417 run zip -mry9 "$zip" "@unixroot"
418 )}
419 log_run "$log_base.zip.log" create_zip
420 print_elapsed start_time "Completed in \$e."
421
422 local ver_list="$log_base.$ver_full.list"
423
424 # Generate list of all generated packages for further reference.
425 echo "Creating list file ($ver_list)..."
426 rm -f "$ver_list"
427 echo `stat -c '%Y' "$src_rpm"`"|$src_rpm" > "$ver_list"
428 echo `stat -c '%Y' "$zip"`"|$zip" >> "$ver_list"
429 # Save base arch RPMs.
430 for f in $rpms ; do
431 echo `stat -c '%Y' "$f"`"|$f" >> "$ver_list"
432 done
433 # Save other arch RPMs.
434 for arch in ${arch_list%${base_arch}} ; do
435 rpms="`grep "^Wrote: \+.*\.$arch\.rpm$" "$log_base.$arch.log" | sed -e "s#^Wrote: \+##g"`"
436 [ -n "$rpms" ] || die "Cannot find .$arch.rpm file names in '$log_base.arch.log'."
437 for f in $rpms ; do
438 echo `stat -c '%Y' "$f"`"|$f" >> "$ver_list"
439 done
440 done
441
442 # Everything succeeded. Symlink the list file so that "upload" can find it.
443 run ln -s "${ver_list##*/}" "$log_base.list"
444}
445
446test_cmd()
447{
448 echo "Spec file: $spec_full"
449
450 sync_aux_src
451
452 local base_arch="${RPMBUILD_BOT_ARCH_LIST##* }"
453 local cmds=
454
455 [ -z "$command_arg" ] && command_arg="all"
456
457 case "$command_arg" in
458 all)
459 cmds="$cmds -bb"
460 ;;
461 prep)
462 cmds="$cmds -bp --short-circuit"
463 ;;
464 build)
465 cmds="$cmds -bc --short-circuit"
466 ;;
467 install)
468 cmds="$cmds -bi --short-circuit"
469 ;;
470 pack)
471 cmds="$cmds -bb --short-circuit"
472 ;;
473 *)
474 die "Invalid test build sub-command '$command_arg'."
475 ;;
476 esac
477
478 local log_file="$log_dir/test/$spec_name.log"
479
480 if [ -f "$log_file" ] ; then
481 rm -f "$log_file.bak"
482 run mv "$log_file" "$log_file.bak"
483 fi
484
485 echo "Doing test RPM build for '$base_arch' target (logging to $log_file)..."
486 log_run "$log_file" rpmbuild.exe "--define=dist %nil" --target=$base_arch $cmds $spec_full
487
488 # Show the generated RPMs when appropriate.
489 if [ "$command_arg" = "all" -o "$command_arg" = "pack" ] ; then
490 # Find all RPM packages for the base arch (note the quotes around `` - it's to preserve multi-line result).
491 local rpms="`grep "^Wrote: \+.*\.\($base_arch\.rpm\|noarch\.rpm\)$" "$log_file" | sed -e "s#^Wrote: \+##g"`"
492 if [ -n "$rpms" ] ; then
493 echo "Successfully generated the following RPMs:"
494 for f in $rpms; do
495 echo "$f"
496 done
497 else
498 warn "Cannot find .$base_arch.rpm/.noarch.rpm file names in '$log_file'."
499 fi
500 fi
501}
502
503repo_dir_for_file()
504{
505 # $1 = input file name
506 # $2 = var name to save dir to
507
508 [ -n "$1" -a -n "$2" ] || die "Invalid arguments."
509
510 local _repo_dir_for_file_ret=
511 case "$1" in
512 *.src.rpm)
513 eval _repo_dir_for_file_ret="$RPMBUILD_BOT_UPLOAD_REPO_LAYOUT_srpm"
514 ;;
515 *.*.rpm)
516 local arch="${1%.rpm}"
517 arch="${arch##*.}"
518 [ -n "$arch" ] || die "No arch spec in file name '$1'."
519 eval _repo_dir_for_file_ret="$RPMBUILD_BOT_UPLOAD_REPO_LAYOUT_rpm"
520 ;;
521 *.zip)
522 eval _repo_dir_for_file_ret="$RPMBUILD_BOT_UPLOAD_REPO_LAYOUT_zip"
523 ;;
524 esac
525
526 eval "$2=\$_repo_dir_for_file_ret"
527}
528
529upload_cmd()
530{
531 # Check settings.
532 test -n "$RPMBUILD_BOT_UPLOAD_REPO_LIST" || die "RPMBUILD_BOT_UPLOAD_REPO_LIST is empty."
533
534 local repo="$command_arg"
535 [ -z "$repo" ] && repo="${RPMBUILD_BOT_UPLOAD_REPO_LIST%% *}"
536
537 check_dir_var "RPMBUILD_BOT_UPLOAD_${repo}_DIR"
538
539 eval local base="\$RPMBUILD_BOT_UPLOAD_${repo}_DIR"
540
541 [ -f "$spec_list" ] || die \
542"File '$spec_list' is not found.
543You may need to build the packages using the 'build' command."
544
545 local files=
546 read_file_list "$spec_list" files
547 for f in $files; do
548 local d=
549 repo_dir_for_file "$f" d
550 [ -n "$d" ] || die "Unsupported file name '$f' in '$spec_list'."
551 [ -d "$d" ] || die "'$d' is not a directory."
552 [ -f "$d/${f##*/}" -a -z "$force" ] && die \
553"File '$d/${f##*/}' already exists.
554Use the -f option to force uploading if you are sure the existing
555packages in the repository should be discarded."
556 echo "Copying $f to $d..."
557 run cp -p "$f" "$d"
558 done
559
560 # On success, delete the uploaded packages and archive log files.
561 for f in $files; do
562 echo "Removing $f..."
563 run rm -f "$f"
564 done
565
566 # Note: versioned .list file will remain in archive forever (for further reference).
567 echo "Removing old '$spec_name' logs from $log_dir/archive..."
568 rm -f "$log_dir/archive/$spec_name".*.log "$log_dir/archive/$spec_name".list
569 echo "Moving '$spec_name' logs to $log_dir/archive..."
570 run mv "$log_base".*.log "$log_base".*.list "$log_base".list "$log_dir/archive/"
571}
572
573clean_cmd()
574{
575 if [ "$command_arg" = "test" ] ; then
576 # Cleanup after "test" command.
577 local base_arch="${RPMBUILD_BOT_ARCH_LIST##* }"
578 local log_file="$log_dir/test/$spec_name.log"
579
580 [ -f "$log_file" ] || die "File '$test_log' is not found."
581
582 # Find all RPM packages for the base arch (note the quotes around `` - it's to preserve multi-line result).
583 local rpms="`grep "^Wrote: \+.*\.\($base_arch\.rpm\|noarch\.rpm\)$" "$log_file" | sed -e "s#^Wrote: \+##g"`"
584 if [ -n "$rpms" ] ; then
585 for f in $rpms; do
586 echo "Removing $f..."
587 run rm -f "$f"
588 done
589 echo "Removing $log_file[.bak]..."
590 run rm -f "$log_file" "$log_file".bak
591 else
592 die "Cannot find .$base_arch.rpm/.noarch.rpm file names in '$log_file'."
593 fi
594
595 return
596 fi
597
598 # Cleanup after "build command".
599 [ -f "$spec_list" ] || die \
600"File '$spec_list' is not found.
601You man need to build the packages using the 'build' command."
602
603 local files=
604 read_file_list "$spec_list" files
605
606 for f in $files; do
607 echo "Removing $f..."
608 run rm -f "$f"
609 done
610
611 echo "Removing '$spec_name' logs from $log_dir..."
612 rm -f "$log_base".*.log "$log_base".*.list "$log_base".list
613}
614
615move_cmd()
616{
617 # Check settings.
618 [ -n "$spec_ver" ] || die "SPEC parameter lacks version specification."
619
620 test -n "$RPMBUILD_BOT_UPLOAD_REPO_LIST" || die "RPMBUILD_BOT_UPLOAD_REPO_LIST is empty."
621
622 local from_repo="${command_arg%%=*}"
623 local to_repo="${command_arg#*=}"
624
625 [ -n "$from_repo" ] || die "FROM_REPO parameter is missing."
626 [ "$from_repo" = "$to_repo" ] && die "TO_REPO parameter is missing (or equals to FROM_REPO)."
627
628 check_dir_var "RPMBUILD_BOT_UPLOAD_${from_repo}_DIR"
629 check_dir_var "RPMBUILD_BOT_UPLOAD_${to_repo}_DIR"
630
631 local ver_list="$log_dir/archive/$spec_name.$spec_ver.list"
632 [ -f "$ver_list" ] || die "File '$ver_list' is not found."
633
634 eval local from_base="\$RPMBUILD_BOT_UPLOAD_${from_repo}_DIR"
635 eval local to_base="\$RPMBUILD_BOT_UPLOAD_${to_repo}_DIR"
636
637 local files=
638 read_file_list "$ver_list" files '
639local dir=
640local base="$from_base"; repo_dir_for_file "$file" dir; file="${dir}/${file##*/}"
641base="$to_base"; repo_dir_for_file "$file" dir; file_post=">${dir}"
642'
643 for f in $files; do
644 local from="${f%%>*}"
645 local to="${f#*>}"
646 echo "Moving $from to $to/..."
647 run mv "$from" "$to/"
648 done
649}
650
651remove_cmd()
652{
653 # Check settings.
654 [ -n "$spec_ver" ] || die "SPEC parameter lacks version specification."
655
656 test -n "$RPMBUILD_BOT_UPLOAD_REPO_LIST" || die "RPMBUILD_BOT_UPLOAD_REPO_LIST is empty."
657
658 local repo="$command_arg"
659 [ -z "$repo" ] && repo="${RPMBUILD_BOT_UPLOAD_REPO_LIST%% *}"
660
661 check_dir_var "RPMBUILD_BOT_UPLOAD_${repo}_DIR"
662
663 local ver_list="$log_dir/archive/$spec_name.$spec_ver.list"
664 [ -f "$ver_list" ] || die "File '$ver_list' is not found."
665
666 eval local base="\$RPMBUILD_BOT_UPLOAD_${repo}_DIR"
667
668 local files=
669 read_file_list "$ver_list" files 'local dir=; repo_dir_for_file $file dir; file="${dir}/${file##*/}"'
670
671 for f in $files; do
672 echo "Removing $f..."
673 run rm -f "$f"
674 done
675
676 echo "Removing $ver_list..."
677 run rm -f "$ver_list"
678
679 # Also remove the logs of last "build" if we are removing the last "build" package.
680 if [ -L "$log_dir/archive/$spec_name.list" -a \
681 `readlink "$log_dir/archive/$spec_name.list"` = "$spec_name.$spec_ver.list" ] ; then
682 echo "Removing '$spec_name' logs from $log_dir/archive..."
683 rm -f "$log_dir/archive/$spec_name".*.log "$log_dir/archive/$spec_name".list
684 fi
685}
686
687#
688# Main.
689#
690
691# Parse command line.
692while [ -n "$1" ] ; do
693 case "$1" in
694 -*)
695 options="$*"
696 while [ -n "$1" ] ; do
697 case "$1" in
698 -f) force="-f"
699 ;;
700 *) usage
701 ;;
702 esac
703 shift
704 done
705 break
706 ;;
707 *)
708 if [ -z "$spec" ] ; then
709 spec="$1"
710 else
711 command="$1"
712 fi
713 ;;
714 esac
715 shift
716done
717
718[ -n "$spec" ] || usage
719[ -z "$command" ] && command="build"
720
721spec_ver="${spec#*=}"
722spec="${spec%=*}"
723[ "$spec" = "$spec_ver" ] && spec_ver=
724
725command_name="${command%%=*}"
726command_arg="${command#*=}"
727[ "$command_name" = "$command_arg" ] && command_arg=
728
729need_spec_file=
730
731# Validate commands.
732case "$command_name" in
733 build|test)
734 need_spec_file=1
735 ;;
736 upload|clean|move|remove)
737 ;;
738 *) usage
739 ;;
740esac
741
742# Query all rpmbuild macros in a single run as it may be slow.
743eval `rpmbuild.exe --eval='rpmbuild_dir="%_topdir" ; spec_dir="%_specdir" ; src_dir="%_sourcedir"' | tr '\\\' /`
744
745[ -n "$rpmbuild_dir" -a -d "$rpmbuild_dir" ] || die "Falied to get %_topdir from rpmbuild or not directory ($rpmbuild_dir)."
746[ -n "$spec_dir" -a -d "$spec_dir" ] || die "Falied to get %_specdir from rpmbuild or not directory ($spec_dir)."
747[ -n "$src_dir" -a -d "$src_dir" ] || die "Falied to get %_sourcedir from rpmbuild or not directory ($src_dir)."
748
749log_dir="$rpmbuild_dir/logs"
750zip_dir="$rpmbuild_dir/zip"
751
752spec=`echo $spec | tr '\\\' /`
753
754spec_name="${spec##*/}"
755
756if [ "$spec_name" = "$spec" ] ; then
757 # No path information, use SPECS
758 spec_full="$spec_dir/${spec_name%.spec}.spec"
759else
760 # Has some path, use it.
761 spec_full="${spec%.spec}.spec"
762fi
763
764spec_name="${spec_name%.spec}"
765
766[ -z "$need_spec_file" -o -f "$spec_full" ] || die "Spec file '$spec_full' is not found."
767
768# Prepare some (non-rpmbuild-standard) directories.
769run mkdir -p "$log_dir"
770run mkdir -p "$log_dir/archive"
771run mkdir -p "$log_dir/test"
772run mkdir -p "$zip_dir"
773
774log_base="$log_dir/$spec_name"
775spec_list="$log_base.list"
776
777start_time=$(date +%s)
778
779echo "Build started on $(date -R)."
780echo "Package: $spec_name"
781echo "Command: $command $options"
782
783# Set up the rpmbuild-bot environment.
784. "${0%%.sh}-env.sh"
785
786# Check common settings.
787test -n "$RPMBUILD_BOT_ARCH_LIST" || die "RPMBUILD_BOT_ARCH_LIST is empty."
788
789run eval "${command_name}_cmd"
790
791quit 0
Note: See TracBrowser for help on using the repository browser.