]> TLD Linux GIT Repositories - packages/rpm-build-tools.git/blob - builder.sh
- move setting pkgrev right after package is built
[packages/rpm-build-tools.git] / builder.sh
1 #!/bin/ksh
2 #
3 # This program is free software, distributed under the terms of
4 # the GNU General Public License Version 2.
5 #
6 # -----------
7 # Exit codes:
8 #         0 - succesful
9 #         1 - help displayed
10 #         2 - no spec file name in cmdl parameters
11 #         3 - spec file not stored in repo
12 #         4 - some source, patch or icon files not stored in repo
13 #         5 - package build failed
14 #         6 - spec file with errors
15 #         7 - wrong source in /etc/poldek.conf
16 #         8 - Failed installing buildrequirements and subrequirements
17 #         9 - Requested tag already exist
18 #        10 - Refused to build fractional release
19 #       100 - Unknown error (should not happen)
20 #   110 - Functions not yet implemented
21
22 # Notes (todo/bugs):
23 # - when Icon: field is present, -5 and -a5 doesn't work
24 # - builder -R skips installing BR if spec is not present before builder invocation (need to run builder twice)
25 # - does not respect NoSource: X, and tries to cvs up such files [ example: VirtualBox-bin.spec and its Source0 ]
26 # TODO:
27 # - ability to do ./builder -bb foo.spec foo2.spec foo3.spec
28 # - funny bug, if source-md5 is set then builder will download from distfiles even if there is no url present:
29 #   Source10:   forwardfix.pl
30 #   # Source10-md5:     8bf85f7368933a4e0cb4f875bac28733
31 # - builder --help:
32 #       basename: missing operand
33 #       Try `basename --help' for more information.
34 #       -- and the normal usage info --
35
36 PROGRAM=${0##*/}
37 APPDIR=$(d=$0; [ -L "$d" ] && d=$(readlink -f "$d"); dirname "$d")
38 VERSION="v0.35"
39 VERSIONSTRING="\
40 Build package utility from PLD Linux Packages repository
41 $VERSION (C) 1999-2020 Free Penguins".
42
43 # Clean PATH without /usr/local or user paths
44 CLEAN_PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
45
46 # required rpm-build-macros
47 RPM_MACROS_VER=1.534
48
49 COMMAND="build"
50 TARGET=""
51
52 SPECFILE=""
53 BE_VERBOSE=""
54 QUIET=""
55 CLEAN=""
56 DEBUG=""
57 NOURLS=""
58 NOCVSSPEC=""
59 NODIST=""
60 NOINIT=""
61 PREFMIRRORS=""
62 UPDATE=""
63 ADD5=""
64 NO5=""
65 ALWAYS_CVSUP=${ALWAYS_CVSUP:-"yes"}
66
67 # use rpm 4.4.6+ digest format instead of comments if non-zero
68 USEDIGEST=
69
70 # user agent when fetching files
71 USER_AGENT="TLD/Builder($VERSION)"
72
73 # It can be used i.e. in log file naming.
74 # See LOGFILE example.
75 DATE=`date +%Y-%m-%d_%H-%M-%S`
76
77 # target arch, can also be used for log file naming
78 TARGET=$(rpm -E %{_target})
79
80 # Note the *single* quotes, this allows using shell variables expanded at build time
81 # Example: LOGFILE='../log.$PACKAGE_NAME'
82 # Example: LOGFILE='../LOGS/log.$PACKAGE_NAME.$DATE'
83 # Example: LOGFILE='$PACKAGE_NAME/$PACKAGE_NAME.$DATE.log'
84 # Example: LOGFILE='$PACKAGE_NAME.$DATE.log'
85 # Example: LOGFILE='.log.$PACKAGE_NAME-$PACKAGE_VERSION-$PACKAGE_RELEASE.$TARGET.$DATE'
86 LOGFILE=''
87
88 # use teeboth Perl wrapper
89 # temporary option to disable if broken
90 USE_TEEBOTH=no
91
92 LOGDIR=""
93 LOGDIROK=""
94 LOGDIRFAIL=""
95 LASTLOG_FILE=""
96
97 CHMOD="no"
98 CHMOD_MODE="0644"
99 RPMOPTS=""
100 RPMBUILDOPTS=""
101 BCOND=""
102 GROUP_BCONDS="no"
103
104 # create symlinks for tools in PACKAGE_DIR, see get_spec()
105 SYMLINK_TOOLS="yes"
106
107 PATCHES=""
108 SOURCES=""
109 ICONS=""
110 PACKAGE_RELEASE=""
111 PACKAGE_VERSION=""
112 PACKAGE_NAME=""
113 ASSUMED_NAME=""
114 PROTOCOL="http"
115 IPOPT=""
116
117 # use lftp by default when available
118 test -z "${USE_LFTP+x}" && lftp --version > /dev/null 2>&1 && USE_LFTP=yes
119 PARALLEL_DOWNLOADS=10
120
121 WGET_RETRIES=${MAX_WGET_RETRIES:-0}
122
123 # rsync repository with git refs of packages
124 PKGREVS_URL="http://pkgrevs.tld-linux.org"
125 SETPKGREV="false"
126
127 # TLD git/df config
128 TLD_GIT_SERVER="git://git.tld-linux.org"
129 TLD_GIT_PUSH="git@git.tld-linux.org:7272"
130 TLD_PACKAGES_DIR="packages"
131 TLD_DISTFILES_SERVER="://df.tld-linux.org"
132
133 # PLD git/df config
134 PLD_GIT_SERVER="git://git.pld-linux.org"
135 PLD_GIT_PUSH="git@git.pld-linux.org"
136 PLD_PACKAGES_DIR="packages"
137 PLD_DISTFILES_SERVER="://distfiles.pld-linux.org"
138
139 CVS_FORCE=""
140 CVSIGNORE_DF="yes"
141 CVSTAG=""
142 GIT_SERVER=${TLD_GIT_SERVER}
143 GIT_PUSH=${TLD_GIT_PUSH}
144 PACKAGES_DIR=${TLD_PACKAGES_DIR}
145 HEAD_DETACHED=""
146 DEPTH=""
147 ALL_BRANCHES=""
148 REMOTE_PLD="origin"
149 NEW_REPO=""
150
151 RES_FILE=""
152
153 DISTFILES_SERVER=${TLD_DISTFILES_SERVER}
154
155 DEF_NICE_LEVEL=19
156 SCHEDTOOL="auto"
157
158 FAIL_IF_NO_SOURCES="yes"
159
160 # let get_files skip over files which are present to get those damn files fetched
161 SKIP_EXISTING_FILES="no"
162
163 TRY_UPGRADE=""
164 # should the specfile be restored if upgrade failed?
165 REVERT_BROKEN_UPGRADE="yes"
166
167 if rpm --specsrpm 2>/dev/null; then
168         FETCH_BUILD_REQUIRES_RPMSPECSRPM="yes"
169         FETCH_BUILD_REQUIRES_RPMGETDEPS="no"
170 else
171         FETCH_BUILD_REQUIRES_RPMSPECSRPM="no"
172         if [ -x /usr/bin/rpm-getdeps ]; then
173                 FETCH_BUILD_REQUIRES_RPMGETDEPS="yes"
174         else
175                 FETCH_BUILD_REQUIRES_RPMGETDEPS="no"
176         fi
177 fi
178
179 UPDATE_POLDEK_INDEXES_OPTS=""
180
181 # Here we load saved user environment used to
182 # predefine options set above, or passed to builder
183 # in command line.
184 # This one reads global system environment settings:
185 if [ -f ~/etc/builderrc ]; then
186         . ~/etc/builderrc
187 fi
188 # And this one cascades settings using user personal
189 # builder settings.
190 # Example of ~/.builderrc:
191 #
192 #UPDATE_POLDEK_INDEXES="yes"
193 #UPDATE_POLDEK_INDEXES_OPTS="--mo=nodiff"
194 #FETCH_BUILD_REQUIRES="yes"
195 #REMOVE_BUILD_REQUIRES="force"
196 #GROUP_BCONDS="yes"
197 #LOGFILE='../LOGS/log.$PACKAGE_NAME.$DATE'
198 #TITLECHANGE=no
199
200 SU_SUDO="sudo"
201
202 if [ -n "$HOME_ETC" ]; then
203         USER_CFG="$HOME_ETC/.builderrc"
204         BUILDER_MACROS="$HOME_ETC/.builder-rpmmacros"
205 else
206         USER_CFG=~/.builderrc
207         BUILDER_MACROS=~/.builder-rpmmacros
208 fi
209
210 [ -f "$USER_CFG" ] && . "$USER_CFG"
211
212 if [ "$SCHEDTOOL" = "auto" ]; then
213         if [ -x /usr/bin/schedtool ] && schedtool -B -e echo >/dev/null; then
214                 SCHEDTOOL="schedtool -B -e"
215         else
216                 SCHEDTOOL="no"
217         fi
218 fi
219
220 if [ -n "$USE_PROZILLA" ]; then
221         GETURI=download_proz
222 elif [ -n "$USE_AXEL" ]; then
223         GETURI=download_axel
224 elif [ -n "$USE_LFTP" ]; then
225         GETURI=download_lftp
226 else
227         GETURI=download_wget
228 fi
229
230 GETLOCAL=${GETLOCAL:-cp -a}
231
232 RPM="rpm"
233 RPMBUILD="rpmbuild"
234
235 #
236 # sanity checks
237 #
238 if [ -d $HOME/rpm/SOURCES ]; then
239         echo "ERROR: ~/rpm/{SPECS,SOURCES} structure is obsolete" >&2
240         echo "ERROR: get rid of your ~/rpm/SOURCES" >&2
241         exit 1
242 fi
243
244 POLDEK_INDEX_DIR="$($RPM --eval %_rpmdir)/"
245 POLDEK_CMD="$SU_SUDO /usr/bin/poldek"
246
247 # TODO: add teeboth
248 # TODO: what this function does?
249 run_poldek() {
250         RES_FILE=$(tempfile)
251         if [ -n "$LOGFILE" ]; then
252                 LOG=`eval echo $LOGFILE`
253                 if [ -n "$LASTLOG_FILE" ]; then
254                         echo "LASTLOG=$LOG" > $LASTLOG_FILE
255                 fi
256                 (${NICE_COMMAND} ${POLDEK_CMD} --noask `while test $# -gt 0; do echo "$1 ";shift;done` ; echo $? > ${RES_FILE})|tee -a $LOG
257                 # FIXME $exit_pldk undefined
258                 return $exit_pldk
259         else
260                 (${NICE_COMMAND} ${POLDEK_CMD} --noask `while test $# -gt 0; do echo "$1 ";shift;done` ; echo $? > ${RES_FILE}) 1>&2 >/dev/null
261                 return `cat ${RES_FILE}`
262                 rm -rf ${RES_FILE}
263         fi
264 }
265
266 #---------------------------------------------
267 # functions
268
269 download_prozilla() {
270         local outfile=$1 url=$2 retval
271
272         proz --no-getch -r -P ./ -t$WGET_RETRIES $PROZILLA_OPTS -O "$outfile" "$url"
273         retval=$?
274
275         return $retval
276 }
277
278 download_axel() {
279         local outfile=$1 url=$2 retval
280
281         axel -a $AXEL_OPTS -o "$outfile" "$url"
282         retval=$?
283
284         return $retval
285 }
286
287 download_wget() {
288         local outfile=$1 url=$2 retval wget_help
289         if [ -z "${WGET_OPTS_SET+x}" ]; then
290                 wget_help="$(wget --help 2>&1)"
291                 echo "$wget_help" | grep -q -- ' --no-check-certificate ' && WGET_OPTS="$WGET_OPTS --no-check-certificate"
292                 echo "$wget_help" | grep -q -- ' --inet ' && WGET_OPTS="$WGET_OPTS --inet"
293                 echo "$wget_help" | grep -q -- ' --retry-connrefused ' && WGET_OPTS="$WGET_OPTS --retry-connrefused"
294                 echo "$wget_help" | grep -q -- ' --no-iri ' && WGET_OPTS="$WGET_OPTS --no-iri"
295                 WGET_OPTS="-c -nd -t$WGET_RETRIES $WGET_OPTS --user-agent=$USER_AGENT $IPOPT --passive-ftp"
296                 WGET_OPTS_SET=1
297         fi
298
299         wget $WGET_OPTS -O "$outfile" "$url"
300         retval=$?
301         if [ $retval -ne 0 ]; then
302                 if [ "`echo $url | grep -E 'ftp://'`" ]; then
303                         ${GETURI} -O "$outfile" "$url"
304                         retval=$?
305                 fi
306         fi
307         return $retval
308 }
309
310 download_lftp() {
311         local outfile=$1 url=$2 retval tmpfile
312         tmpfile=$(tempfile) || exit 1
313         lftp -c "
314                 $([ "$DEBUG" = "yes" ] && echo "debug 5;")
315                 $([ "$IPOPT" = "-4" ] && echo "set dns:order \"inet\";")
316                 $([ "$IPOPT" = "-6" ] && echo "set dns:order \"inet6\";")
317                 set ssl:verify-certificate no;
318                 set net:max-retries $WGET_RETRIES;
319                 set http:user-agent \"$USER_AGENT\";
320                 pget -n $PARALLEL_DOWNLOADS -c \"$url\" -o \"$tmpfile\"
321         "
322
323         retval=$?
324         if [ $retval -eq 0 ]; then
325                 mv -f "$tmpfile" "$outfile"
326         else
327                 rm -f "$tmpfile"
328         fi
329         return $retval
330 }
331
332 usage() {
333         if [ -n "$DEBUG" ]; then set -xv; fi
334 # NOTE:
335 # to make this output parseable by bash-completion _parse_help()
336 # if the line contains short and long option, it will take only the long option
337 # but if you want both being completed, put the short option to separate line
338         echo "\
339 Usage: builder [--all-branches] [-D|--debug] [-V|--version] [--short-version]  [-a|--add_cvs] [-b|-ba|--build]
340 [-bb|--build-binary] [-bs|--build-source] [-bc] [-bi] [-bl] [-u|--try-upgrade]
341 [{-cf|--cvs-force}] [{-B|--branch} <branch>] [--depth <number>]
342 [-g|--get] [-h|--help] [--ftp] [--http] [{-l|--logtofile} <logfile>] [-m|--mr-proper]
343 [-q|--quiet] [--date <yyyy-mm-dd> [-r <tag>] [{-T|--tag <tag>]
344 [-Tvs|--tag-version-stable] [-Ts|--tag-stable] [-Tv|--tag-version]
345 [{-Tp|--tag-prefix} <prefix>] [{-tt|--test-tag}]
346 [-nu|--no-urls] [-v|--verbose] [--opts <rpm opts>] [--short-circuit]
347 [--show-bconds] [--with/--without <feature>] [--define <macro> <value>]
348 [--git-pld|--git-tld] [--pkgrev] [-lp]
349 <package>[.spec][:tag]
350
351 -4                  - force IPv4 when transferring files
352 -6                  - force IPv6 when transferring files
353 -5,
354 --update-md5        - update md5 comments in spec, implies -nd -ncs
355 -a5,
356 --add-md5           - add md5 comments to URL sources, implies -nc -nd -ncs
357 --all-branches      - make shallow fetch of all branches; --depth required
358 -n5, --no-md5       - ignore md5 comments in spec
359 -D, --debug         - enable builder script debugging mode,
360 -debug              - produce rpm debug package (same as --opts -debug)
361 -V, --version       - output builder version string
362 --short-version     - output builder short version
363 -a                  - try add new package to PLD repo.
364 -b,
365 -ba
366                     - get all files from PLD repo or HTTP/FTP and build package
367                       from <package>.spec,
368 -bb                 - get all files from PLD repo or HTTP/FTP and build binary
369                       only package from <package>.spec,
370 -bp                 - execute the %prep phase of <package>.spec,
371 -bc                 - execute the %build phase of <package>.spec,
372 -bi                 - execute the %install phase of <package>.spec
373 -bl                 - execute the %files phase of <package>.spec
374 -bs                 - get all files from PLD repo or HTTP/FTP and only pack
375                       them into src.rpm,
376 --short-circuit     - short-circuit build
377 -B, --branch        - add branch
378 -c,
379 --clean             - clean all temporarily created files (in BUILD\$RPM_BUILD_ROOT) after rpmbuild commands.
380                       may be used with building process.
381 -m, --mr-proper     - clean all temporarily created files (in BUILD, SOURCES,
382                       SPECS and \$RPM_BUILD_ROOT). Doesn't run any rpm building.
383 -cf, --cvs-force    - use -f when tagging
384 --define '<macro> <value>'
385                     - define a macro <macro> with value <value>,
386 --depth <number>    - make shallow fetch
387 --alt_kernel <kernel>
388                     - same as --define 'alt_kernel <kernel>'
389 --nodeps            - rpm won't check any dependences
390 -g
391 --get               - get <package>.spec and all related files from PLD repo
392 -h, --help          - this message,
393 -j N                - set %_smp_mflags to propagate concurrent jobs
394 --ftp               - use FTP protocol to access distfiles server
395 --http              - use HTTP protocol to access distfiles server
396 -l <logfile>, --logtofile=<logfile>
397                     - log all to file,
398 -ncs, --no-cvs-specs
399                     - don't pull from PLD repo
400 -nd, --no-distfiles - don't download from distfiles
401 -nm, --no-mirrors   - don't download from mirror, if source URL is given,
402 -nu, --no-urls      - don't try to download from FTP/HTTP location,
403 -ns, --no-srcs      - don't download Sources/Patches
404 -ns0, --no-source0  - don't download Source0
405 -nn, --no-net       - don't download anything from the net
406 -p N                - set PARALLEL_DOWNLOADS to N (default $PARALLEL_DOWNLOADS)
407 -pm, --prefer-mirrors
408                     - prefer mirrors (if any) over distfiles for SOURCES
409 --no-init           - don't initialize builder paths (SPECS and SOURCES)
410 -ske,
411 --skip-existing-files
412                     - skip existing files in get_files
413 --opts <rpm opts>   - additional options for rpm
414 -q, --quiet         - be quiet,
415 --date yyyy-mm-dd   - build package using resources from specified date,
416 -r <tag>, --cvstag <ref>
417                     - build package using resources from specified branch/tag,
418 -A                  - build package using master branch as any sticky tags/branch/date being reset.
419 -R, --fetch-build-requires
420                     - fetch what is BuildRequired,
421 -RB, --remove-build-requires
422                     - remove all you fetched with -R or --fetch-build-requires
423                       remember, this option requires confirmation,
424 -FRB, --force-remove-build-requires
425                     - remove all you fetched with -R or --fetch-build-requires
426                       remember, this option works without confirmation,
427 -sd, --source-distfiles
428                     - list sources available from distfiles (intended for offline
429                       operations; does not work when Icon field is present
430                       but icon file is absent),
431 -sc, --source-cvs   - list sources available from PLD repo
432 -sdp, --source-distfiles-paths
433                     - list sources available from distfiles -
434                       paths relative to distfiles directory (intended for offline
435                       operations; does not work when Icon field is present
436                       but icon file is absent),
437 -sf, --source-files - list sources - bare filenames (intended for offline
438                       operations; does not work when Icon field is present
439                       but icon file is absent),
440 -lsp, --source-paths
441                     - list sources - filenames with full local paths (intended for
442                       offline operations; does not work when Icon field is present
443                       but icon file is absent),
444 -su, --source-urls  - list urls - urls to sources and patches
445                       intended for copying urls with spec with lots of macros in urls
446 -T <tag> , --tag <tag>
447                     - add git tag <tag> for files,
448 -Tvs, --tag-version-stable
449                     - add git tags STABLE and NAME-VERSION-RELEASE for files,
450 -Ts, --tag-stable
451                     - add git tag STABLE for files,
452 -Tv,
453 --tag-version       - add git tag NAME-VERSION-RELEASE for files,
454 -Tp, --tag-prefix <prefix>
455                     - add <prefix> to NAME-VERSION-RELEASE tags,
456 -tt, --test-tag <prefix>
457                     - fail if tag is already present,
458 -ir, --integer-release-only
459                     - allow only integer and snapshot releases
460 -v, --verbose       - be verbose,
461 -u, --try-upgrade   - check version, and try to upgrade package
462 -un, --try-upgrade-with-float-version
463                     - as above, but allow float version
464                       php-pear-Services_Digg/
465 --upgrade-version   - upgrade to specified version in try-upgrade
466 -U, --update        - refetch sources, don't use distfiles, and update md5 comments
467 -Upi, --update-poldek-indexes
468                     - refresh or make poldek package index files.
469 -sp <patchnumber>,
470 --skip-patch <patchnumber>
471                     - don't apply <patchnumber>. may be repeated.
472 -np <patchnumber>,
473 --nopatch <patchnumber>
474                     - abort instead of applying patch <patchnumber>
475 --noinit
476                     - do not initialize SPECS_DIR and SOURCES_DIR (set them to .)
477 --show-bconds       - show available conditional builds, which can be used
478                     - with --with and/or --without switches.
479 --show-bcond-args   - show active bconds, from ~/.bcondrc. this is used by ./repackage.sh script.
480                       In other words, the output is parseable by scripts.
481 --show-avail-bconds - show available bconds
482 --with <feature>,
483 --without <feature>
484                     - conditional build package depending on %_with_<feature>/
485                       %_without_<feature> macro switch.  You may now use
486                       --with feat1 feat2 feat3 --without feat4 feat5 --with feat6
487                       constructions. Set GROUP_BCONDS to yes to make use of it.
488 --target <platform>, --target=<platform>
489                     - build for platform <platform>.
490 --init-rpm-dir, --init
491                     - initialize ~/rpm directory structure
492 --git-pld           - force use of PLD git and distfiles
493 --git-tld           - force use of TLD git and distfiles (note: it will fall
494                       back to PLD git/df if package doesn't exist in TLD git)
495 --pkgrev            - save git revision of package being built into pkgrevs
496                       (note: only official TLD source builders are allowed to do so)
497 -lp                 - list pkgrevs for specified package
498 "
499 }
500
501 is_rpmorg() {
502         local v
503
504         v=$(LC_ALL=C LANG=C rpm --version 2>&1)
505         v=${v#RPM version } # rpm 4
506         v=${v#rpm \(RPM\) } # rpm 5
507
508         case "$v" in
509                 4.5|5.*)
510                         return 1
511                         ;;
512                 4.*)
513                         return 0;
514                         ;;
515                 *)
516                         echo "ERROR: unsupported RPM version $v" >&2
517                         exit 1
518         esac
519 }
520
521 # create tempfile. as secure as possible
522 tempfile() {
523         local prefix=builder.$PACKAGE_NAME${1:+.$1}
524         mktemp --tmpdir -t $prefix.XXXXXX || echo ${TMPDIR:-/tmp}/$prefix.$RANDOM.$$
525 }
526
527 tempdir() {
528         local prefix=builder.$PACKAGE_NAME${1:+.$1}
529         mktemp --tmpdir -d $prefix.XXXXXX
530 }
531
532 # inserts git log instead of %changelog
533 # @output directory containing modified specfile
534 insert_gitlog() {
535         local SPECFILE=$1 specdir=$(tempdir) gitlog=$(tempfile) speclog=$(tempfile)
536
537         # allow this being customized
538         local log_entries=$(rpm -E '%{?_buildchangelogtruncate}')
539
540         # rpm5.org/rpm.org do not parse any other date format than 'Wed Jan 1 1997'
541         # otherwise i'd use --date=iso here
542         # http://rpm5.org/cvs/fileview?f=rpm/build/parseChangelog.c&v=2.44.2.1
543         # http://rpm.org/gitweb?p=rpm.git;a=blob;f=build/parseChangelog.c;h=56ba69daa41d65ec9fd18c9f371b8ff14118cdca;hb=a113baa510a004476edc44b5ebaaf559238a18b6#l33
544         # NOTE: changelog date is always in UTC for rpmbuild
545         # * 1265749244 +0000 Random Hacker <nikt@pld-linux.org> 9370900
546         git rev-list --date-order -${log_entries:-20} HEAD 2>/dev/null | while read sha1; do
547                 local logfmt='%B%n'
548                 git notes list $sha1 > /dev/null 2>&1 && logfmt='%N'
549                 git log -n 1 $sha1 --format=format:"* %ad %an <%ae> %h%n- ${logfmt}%n" --date=raw | sed -re 's/^- +- */- /'| sed '/^$/q'
550         done > $gitlog
551
552         # add link to full git logs
553         local giturl="http://git.tld-linux.org/?p=packages/${SPECFILE%.spec}.git;a=log"
554         if [ -n "$CVSTAG" ]; then
555                 giturl="$giturl;h=$CVSTAG"
556         fi
557         local gitauthor="TLD Linux <feedback@tld-linux.org>"
558         LC_ALL=C gawk -vgiturl="$giturl" -vgitauthor="$gitauthor" -vpackage=$PACKAGE_NAME 'BEGIN{
559                 printf("* %s %s\n- For complete changelog see: %s\n", strftime("%a %b %d %Y"), gitauthor, giturl);
560                 print;
561                 exit
562         }' > $speclog
563
564         LC_ALL=C gawk '/^\* /{printf("* %s %s\n", strftime("%a %b %d %Y", $2), substr($0, length($1)+length($2)+length($3)+4)); next}{print}' $gitlog >> $speclog
565         sed '/^%changelog/,$d' $SPECFILE | sed -e "\${
566                         a%changelog
567                         r $speclog
568                 }
569         " > $specdir/$SPECFILE
570         rm -f $gitlog $speclog
571         echo $specdir
572 }
573
574 # @param string logfile
575 # @param varargs... commands to execute
576 teeboth() {
577         local rc
578         # use teeboth from toys/cleanbuild, if available and enabled
579         if [ "$USE_TEEBOTH" = "yes" ] && [ -x $APPDIR/teeboth ]; then
580                 $APPDIR/teeboth "$@"
581                 rc=$?
582         else
583                 local efile rc logfile=$1; shift
584                 if [ "$logfile" ]; then
585                         efile=$(tempfile)
586                         { "$@" 2>&1; echo $? > $efile; } | tee $logfile
587                         rc=$(< $efile)
588                         rm -f $efile
589                 else
590                         "$@"
591                         rc=$?
592                 fi
593         fi
594         return $rc
595 }
596
597 # change dependency to specname
598 # common changes:
599 # - perl(Package::Name) -> perl-Package-Name
600 depspecname() {
601         local DEPS
602
603         if [ $# -gt 0 ]; then
604                 DEPS="$@"
605         else
606                 DEPS=$(cat)
607         fi
608
609         echo "$DEPS" | tr ' ' '\n' | sed -re '
610                 # perl virtual deps
611                 /perl\(.*\)/{
612                         s/perl\((.*)\)/perl-\1/
613                         s/::/-/g
614                 }
615
616                 s/apache\(EAPI\)-devel/apache-devel/
617
618                 s/db-devel/db5.3-devel/
619                 s/libjpeg-devel/libjpeg-turbo-devel/
620         '
621 }
622
623 update_shell_title() {
624         [ -t 2 ] || return
625         local len=${COLUMNS:-80}
626         local msg="$(echo "$*" | cut -c-$len)"
627
628         if [ -n "$BE_VERBOSE" ]; then
629                 echo >&2 "$(date +%s.%N) $*"
630         fi
631
632         if [ "x$TITLECHANGE" = "xyes" -o "x$TITLECHANGE" = "x" ]; then
633                 local pkg
634                 if [ -n "$PACKAGE_NAME" ]; then
635                         pkg=${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}
636                 else
637                         pkg=${SPECFILE}
638                 fi
639
640                 msg="$pkg: ${SHELL_TITLE_PREFIX:+$SHELL_TITLE_PREFIX }$msg"
641                 msg=$(echo $msg | tr -d '\n\r')
642                 case "$TERM" in
643                         cygwin|xterm*)
644                         echo >&2 -ne "\033]1;$msg\007\033]2;$msg\007"
645                 ;;
646                         screen*)
647                         echo >&2 -ne "\033]0;$msg\007"
648                 ;;
649                 esac
650         fi
651 }
652
653 # set TARGET from BuildArch: from SPECFILE
654 set_spec_target() {
655         if [ -n "$SPECFILE" ] && [ -z "$TARGET" ]; then
656                 local tmp=$(awk '/^BuildArch:/ { print $NF; exit }' $ASSUMED_NAME/$SPECFILE)
657                 if [ "$tmp" ]; then
658                                 local target_platform=$(rpm -E '%{_target_vendor}-%{_target_os}%{?_gnu}')
659                                 TARGET="$tmp"
660                                 case "$RPMBUILD" in
661                                 "rpmbuild")
662                                         TARGET_SWITCH="--target ${TARGET}-${target_platform}" ;;
663                                 "rpm")
664                                         TARGET_SWITCH="--target=$TARGET" ;;
665                                 esac
666                 fi
667         fi
668 }
669
670 # runs rpm with minimal macroset
671 minirpm() {
672         # TODO: move these to /usr/lib/rpm/macros
673         cat > $BUILDER_MACROS <<'EOF'
674 %x8664 x86_64 amd64 ia32e
675 %alt_kernel %{nil}
676 %_alt_kernel %{nil}
677 %bootstrap_release() %{1}
678 %requires_releq_kernel_up(s:n:) %{nil}
679 %requires_releq_kernel_smp(s:n:) %{nil}
680 %requires_releq_kernel(s:n:) %{nil}
681 %requires_releq() %{nil}
682 %pyrequires_eq() %{nil}
683 %requires_eq() %{nil}
684 %requires_eq_to() %{nil}
685 %requires_ge() %{nil}
686 %requires_ge_to() %{nil}
687 %requires_ge() %{nil}
688 %releq_kernel_up(n:) ERROR
689 %releq_kernel_smp(n:) ERROR
690 %releq_kernel(n:) ERROR
691 %py_postclean(x:) ERROR
692 %kgcc_package ERROR
693 %_fontsdir ERROR
694 %ruby_version ERROR
695 %ruby_ver_requires_eq() %{nil}
696 %ruby_mod_ver_requires_eq() %{nil}
697 %__php_api_requires() %{nil}
698 %php_major_version ERROR
699 %php_api_version ERROR
700 %requires_xorg_xserver_extension %{nil}
701 %requires_xorg_xserver_xinput %{nil}
702 %requires_xorg_xserver_font %{nil}
703 %requires_xorg_xserver_videodrv %{nil}
704 %py_ver ERROR
705 %perl_vendorarch ERROR
706 %perl_vendorlib ERROR
707 # damn. need it here! - copied from /usr/lib/rpm/macros.build
708 %tmpdir         %(echo "${TMPDIR:-/tmp}")
709 %patchset_source(f:b:) %(
710         base=%{-b*}%{!-b*:10000};
711         start=$(expr $base + %1);
712         end=$(expr $base + %{?2}%{!?2:%{1}});
713         # we need to call seq twice as it doesn't allow two formats
714         seq -f 'Patch%g:' $start $end > %{tmpdir}/__ps1;
715         seq -f '%{-f*}' %1 %{?2}%{!?2:%{1}} > %{tmpdir}/__ps2;
716         paste %{tmpdir}/__ps{1,2};
717         rm -f %{tmpdir}/__ps{1,2};
718 ) \
719 %{nil}
720 %add_etc_shells(p) %{p:<lua>}
721 %remove_etc_shells(p) %{p:<lua>}
722 %lua_add_etc_shells()  %{nil}
723 %lua_remove_etc_shells() %{nil}
724 %required_jdk jdk
725 %buildrequires_jdk %{nil}
726 %pear_package_print_optionalpackages %{nil}
727 EOF
728         if [ "$NOINIT" = "yes" ] ; then
729                 cat >> $BUILDER_MACROS <<'EOF'
730 %_specdir ./
731 %_sourcedir ./
732 EOF
733         fi
734         if ! is_rpmorg; then
735                 local safe_macrofiles
736                 safe_macrofiles=$(rpm $TARGET_SWITCH --showrc | awk -F: '/^macrofiles/ { gsub(/^macrofiles[ \t]+:/, "", $0); print $0 } ')
737                 eval PATH=$CLEAN_PATH $RPMBUILD $TARGET_SWITCH --macros "$safe_macrofiles:$BUILDER_MACROS" $QUIET $RPMOPTS $RPMBUILDOPTS $BCOND $* 2>&1
738         else
739                 eval PATH=$CLEAN_PATH $RPMBUILD $TARGET_SWITCH --load "$BUILDER_MACROS" $QUIET $RPMOPTS $RPMBUILDOPTS $BCOND $* 2>&1
740         fi
741 }
742
743 cache_rpm_dump() {
744         local SPEC_PATH
745         if [ -n "$DEBUG" ]; then
746                 set -x
747                 set -v
748         fi
749
750         if [ ! -z "$1" ]; then
751                 SPEC_PATH="$1"
752         else
753                 SPEC_PATH="$PACKAGE_DIR/$SPECFILE"
754         fi
755         if [ -x /usr/bin/rpm-specdump ]; then
756                 update_shell_title "cache_rpm_dump using rpm-specdump command"
757                 rpm_dump_cache=$(eval rpm-specdump $TARGET_SWITCH $BCOND $RPMOPTS --define \'_specdir $PACKAGE_DIR\' --define \'_sourcedir $PACKAGE_DIR\' $SPEC_PATH)
758         else
759                 update_shell_title "cache_rpm_dump using rpmbuild command"
760                 local rpm_dump
761                 rpm_dump=`
762                         # what we need from dump is NAME, VERSION, RELEASE and PATCHES/SOURCES.
763                         dump='%{echo:dummy: PACKAGE_NAME %{name} }%dump'
764                         case "$RPMBUILD" in
765                         rpm)
766                                 ARGS='-bp'
767                                 ;;
768                         rpmbuild)
769                                 ARGS='--nodigest --nosignature --nobuild'
770                                 ;;
771                         esac
772                         minirpm $ARGS --define "'prep $dump'" --nodeps $SPECFILE
773                 `
774                 if [ $? -gt 0 ]; then
775                         error=$(echo "$rpm_dump" | sed -ne '/^error:/,$p')
776                         echo "$error" >&2
777                         Exit_error err_build_fail
778                 fi
779
780                 # make small dump cache
781                 rpm_dump_cache=`echo "$rpm_dump" | awk '
782                         $2 ~ /^SOURCEURL/ {print}
783                         $2 ~ /^PATCHURL/  {print}
784                         $2 ~ /^nosource/ {print}
785                         $2 ~ /^PACKAGE_/ {print}
786                 '`
787         fi
788
789         update_shell_title "cache_rpm_dump: OK!"
790 }
791
792 rpm_dump() {
793         if [ -z "$rpm_dump_cache" ] ; then
794                 echo >&2 "internal error: cache_rpm_dump not called! (missing %prep?)"
795         fi
796         echo "$rpm_dump_cache"
797 }
798
799 get_icons() {
800         update_shell_title "get icons"
801         ICONS=$(awk '/^Icon:/ {print $2}' $PACKAGE_DIR/${SPECFILE})
802         if [ -z "$ICONS" ]; then
803                 return
804         fi
805
806         rpm_dump_cache="kalasaba" NODIST="yes" get_files $ICONS
807 }
808
809 parse_spec() {
810         update_shell_title "parsing specfile"
811         if [ -n "$DEBUG" ]; then
812                 set -x
813                 set -v
814         fi
815
816         # icons are needed for successful spec parse
817         get_icons
818
819         cd $PACKAGE_DIR
820         cache_rpm_dump "$1"
821
822         if rpm_dump | grep -qEi ":.*nosource.*1"; then
823                 FAIL_IF_NO_SOURCES="no"
824         fi
825
826         if [ "$NOSRCS" != "yes" ]; then
827                 SOURCES=$(rpm_dump | awk '$2 ~ /^SOURCEURL[0-9]+/ {print substr($2, length("SOURCEURL") + 1), $3}' | LC_ALL=C sort -n | awk '{print $2}')
828                 PATCHES=$(rpm_dump | awk '$2 ~ /^PATCHURL[0-9]+/ {print substr($2, length("PATCHURL") + 1), $3}' | LC_ALL=C sort -n | awk '{print $2}')
829                 ICONS=$(awk '/^Icon:/ {print $2}' ${SPECFILE})
830         fi
831
832         PACKAGE_NAME=$(rpm_dump | awk '$2 == "PACKAGE_NAME" { print $3; exit}')
833         PACKAGE_VERSION=$(rpm_dump | awk '$2 == "PACKAGE_VERSION" { print $3; exit}')
834         PACKAGE_RELEASE=$(rpm_dump | awk '$2 == "PACKAGE_RELEASE" { print $3; exit}')
835
836         if [ "$PACKAGE_NAME" != "$ASSUMED_NAME" ]; then
837                 echo >&2 "WARNING! Spec name ($ASSUMED_NAME) does not agree with package name ($PACKAGE_NAME)"
838         fi
839
840         if [ -n "$BE_VERBOSE" ]; then
841                 echo "- Sources :  `nourl $SOURCES`"
842                 if [ -n "$PATCHES" ]; then
843                         echo "- Patches :  `nourl $PATCHES`"
844                 else
845                         echo "- Patches :  *no patches needed*"
846                 fi
847                 if [ -n "$ICONS" ]; then
848                         echo "- Icon    :  `nourl $ICONS`"
849                 else
850                         echo "- Icon    :  *no package icon*"
851                 fi
852                 echo "- Name    : $PACKAGE_NAME"
853                 echo "- Version : $PACKAGE_VERSION"
854                 echo "- Release : $PACKAGE_RELEASE"
855         fi
856
857         update_shell_title "parse_spec: OK!"
858 }
859
860 # aborts program abnormally
861 die() {
862         local rc=${2:-1}
863         echo >&2 "$PROGRAM: ERROR: $*"
864         exit $rc
865 }
866
867 Exit_error() {
868         if [ -n "$DEBUG" ]; then
869                 set -x
870                 set -v
871         fi
872
873         cd "$__PWD"
874
875         case "$1" in
876                 "err_no_spec_in_cmdl" )
877                         remove_build_requires
878                         echo >&2 "ERROR: spec file name not specified."
879                         exit 2 ;;
880                 "err_invalid_cmdline" )
881                         echo >&2 "ERROR: invalid command line arg ($2)."
882                         exit 2 ;;
883                 "err_no_spec_in_repo" )
884                         remove_build_requires
885                         echo >&2 "Error: spec file not stored in repository."
886                         if [ -n "$2" ]; then
887                                 echo >&2 "Tried: $2"
888                         fi
889
890                         exit 3 ;;
891                 "err_no_source_in_repo" )
892                         remove_build_requires
893                         echo >&2 "Error: some source, patch or icon files not stored in PLD repo. ($2)"
894                         exit 4 ;;
895                 "err_cvs_add_failed" )
896                         echo >&2 "Error: failed to add package to PLD repo."
897                         exit 4 ;;
898                 "err_build_fail" )
899                         remove_build_requires
900                         echo >&2 "Error: package build failed. (${2:-no more info})"
901                         exit 5 ;;
902                 "err_no_package_data" )
903                         remove_build_requires
904                         echo >&2 "Error: couldn't get out package name/version/release from spec file."
905                         exit 6 ;;
906                 "err_tag_exists" )
907                         remove_build_requires
908                         echo >&2 "Tag ${2} already exists"
909                         exit 9 ;;
910                 "err_fract_rel" )
911                         remove_build_requires
912                         echo >&2 "Release ${2} not integer and not a snapshot."
913                         exit 10 ;;
914                 "err_branch_exists" )
915                         remove_build_requires
916                         echo >&2 "Tree branch already exists (${2})."
917                         exit 11 ;;
918                 "err_acl_deny" )
919                         remove_build_requires
920                         echo >&2 "Error: conditions reject building this spec (${2})."
921                         exit 12 ;;
922                 "err_remote_problem" )
923                         remove_build_requires
924                         echo >&2 "Error: problem with remote (${2})"
925                         exit 13 ;;
926                 "err_no_checkut" )
927                         echo >&2 "Error: cannot checkout ${2}"
928                         exit 14 ;;
929                 "err_pkgrev_set" )
930                         echo >&2 "Error: failed to set package revision for tag ${2}"
931                         exit 15 ;;
932                 "err_pkgrev_get" )
933                         echo >&2 "Error: failed to get package revision for tag ${2}"
934                         exit 16 ;;
935                 "err_not_implemented" )
936                         remove_build_requires
937                         echo >&2 "Error: functionality not yet imlemented"
938                         exit 110 ;;
939         esac
940         echo >&2 "Unknown error."
941         exit 100
942 }
943
944 init_builder() {
945         if [ -n "$DEBUG" ]; then
946                 set -x
947                 set -v
948         fi
949
950         if [ "$NOINIT" != "yes" ] ; then
951                 TOP_DIR=$(eval $RPM $RPMOPTS --eval '%{_topdir}')
952
953                 local macros_ver=$(rpm -E %?rpm_build_macros)
954                 if [ -z "$macros_ver" ]; then
955                         REPO_DIR=$TOP_DIR/packages
956                         PACKAGE_DIR=$TOP_DIR/packages/$ASSUMED_NAME
957                 else
958                         if awk "BEGIN{exit($macros_ver>=$RPM_MACROS_VER)}"; then
959                                 echo >&2 "builder requires rpm-build-macros >= $RPM_MACROS_VER"
960                                 exit 1
961                         fi
962                         REPO_DIR=$TOP_DIR
963                         PACKAGE_DIR=$REPO_DIR/$ASSUMED_NAME
964                 fi
965         else
966                 TOP_DIR=$(pwd)
967                 PACKAGE_DIR=$TOP_DIR
968                 REPO_DIR=$PACKAGE_DIR
969                 RPMBUILDOPTS="$RPMBUILDOPTS --define '_topdir $TOP_DIR' --define '_builddir %_topdir' --define '_rpmdir %_topdir' --define '_srcrpmdir %_topdir'"
970         fi
971         export GIT_WORK_TREE=$PACKAGE_DIR
972         export GIT_DIR=$PACKAGE_DIR/.git
973
974         if [ -d "$GIT_DIR" ] &&  [ -z "$CVSTAG" ] && git rev-parse --verify -q HEAD > /dev/null; then
975                 if CVSTAG=$(GIT_DIR=$GIT_DIR git symbolic-ref HEAD) 2>/dev/null; then
976                         CVSTAG=${CVSTAG#refs/heads/}
977                         if [ "$CVSTAG" != "master" ]; then
978                                 echo >&2 "builder: Active branch $CVSTAG. Use -r BRANCHNAME to override"
979                         fi
980                 else
981                         echo >&2 "On detached HEAD. Use -r BRANCHNAME to override"
982                         HEAD_DETACHED="yes"
983                 fi
984         elif [ "$CVSTAG" = "HEAD" ]; then
985                 # assume -r HEAD is same as -A
986                 CVSTAG="master"
987         fi
988
989         __PWD=$(pwd)
990 }
991
992 create_git_repo() {
993         update_shell_title "add_package"
994
995         if [ -n "$DEBUG" ]; then
996                 set -x
997                 set -v
998         fi
999
1000         cd "$REPO_DIR"
1001         SPECFILE=$(basename $SPECFILE)
1002         if [ ! -f "$ASSUMED_NAME/$SPECFILE" ]; then
1003                 echo "ERROR: No package to add ($ASSUMED_NAME/$SPECFILE)" >&2
1004                 exit 101
1005         fi
1006         [ -d "$ASSUMED_NAME/.git" ] || NEW_REPO=yes
1007         ssh $GIT_PUSH create ${ASSUMED_NAME} || Exit_error err_cvs_add_failed
1008         (
1009         set -e
1010         git init
1011         git remote add $REMOTE_PLD ${GIT_SERVER}/${PACKAGES_DIR}/${ASSUMED_NAME}.git
1012         git remote set-url --push $REMOTE_PLD ssh://${GIT_PUSH}/${PACKAGES_DIR}/${ASSUMED_NAME}
1013
1014         git config --local push.default current
1015         git config --local branch.master.remote $REMOTE_PLD
1016         git config --local branch.master.merge refs/heads/master
1017         )
1018         test $? = 0 || Exit_error err_remote_problem $REMOTE_PLD
1019 }
1020
1021 get_spec() {
1022
1023         update_shell_title "get_spec"
1024
1025         if [ -n "$DEBUG" ]; then
1026                 set -x
1027                 set -v
1028         fi
1029
1030         cd "$REPO_DIR"
1031         SPECFILE=$(basename $SPECFILE)
1032         if [ "$NOCVSSPEC" != "yes" ]; then
1033                 if [ -z "$DEPTH" ]; then
1034                         if [ -d "$PACKAGE_DIR/.git" ]; then
1035                                 git fetch $IPOPT $REMOTE_PLD || Exit_error err_no_spec_in_repo
1036                         elif [ "$ADD_PACKAGE_CVS" = "yes" ]; then
1037                                 if [ ! -r "$PACKAGE_DIR/$SPECFILE" ]; then
1038                                         echo "ERROR: No package to add ($PACKAGE_DIR/$SPECFILE)" >&2
1039                                         exit 101
1040                                 fi
1041                                 Exit_error err_not_implemented
1042                         else
1043                                 (
1044                                         unset GIT_WORK_TREE
1045                                         git clone $IPOPT -o $REMOTE_PLD ${GIT_SERVER}/${PACKAGES_DIR}/${ASSUMED_NAME}.git || {
1046                                                 # softfail if new package, i.e not yet added to PLD rep
1047                                                 [ ! -f "$PACKAGE_DIR/$SPECFILE" ] && Exit_error err_no_spec_in_repo
1048                                                 echo "Warning: package not in Git - assuming new package"
1049                                                 NOCVSSPEC="yes"
1050                                         }
1051                                         git config --local --add "remote.$REMOTE_PLD.fetch" 'refs/notes/*:refs/notes/*'
1052                                         git config --local --add "remote.$REMOTE_PLD.push" 'refs/notes/*:refs/notes/*'
1053                                         git config --local --add "remote.$REMOTE_PLD.push" HEAD
1054                                         git config --local push.default current
1055                                         git remote set-url --push  $REMOTE_PLD ssh://${GIT_PUSH}/${PACKAGES_DIR}/${ASSUMED_NAME}
1056                                 )
1057                         fi
1058                 else
1059                         if [ ! -d "$PACKAGE_DIR/.git" ]; then
1060                                 if [ ! -d "$PACKAGE_DIR" ]; then
1061                                         install -d $PACKAGE_DIR
1062                                 fi
1063                                 git init
1064                                 git remote add $REMOTE_PLD ${GIT_SERVER}/${PACKAGES_DIR}/${ASSUMED_NAME}.git
1065                                 git config --local --add "remote.$REMOTE_PLD.fetch" 'refs/notes/*:refs/notes/*'
1066                                 git config --local --add "remote.$REMOTE_PLD.push" 'refs/heads/*:refs/remotes/origin/*'
1067                                 git config --local --add "remote.$REMOTE_PLD.push" HEAD
1068                                 git config --local push.default current
1069                                 git remote set-url --push  $REMOTE_PLD ssh://${GIT_PUSH}/${PACKAGES_DIR}/${ASSUMED_NAME}
1070                                 CVSTAG=${CVSTAG:-"master"}
1071                         fi
1072                         local refs=''
1073                         if [ -z "$ALL_BRANCHES" ]; then
1074                                 refs="${CVSTAG}:remotes/${REMOTE_PLD}/${CVSTAG}"
1075                         fi
1076                         git fetch $IPOPT $DEPTH $REMOTE_PLD $refs || {
1077                                 echo >&2 "Error: branch $CVSTAG does not exist"
1078                                 exit 3
1079                         }
1080                 fi
1081                 git fetch $IPOPT $REMOTE_PLD 'refs/notes/*:refs/notes/*'
1082
1083                 cvsignore_df .gitignore
1084
1085                 # add default log format to .gitignore if it is relative to package dir
1086                 if [ -n "$LOGFILE" -a "$LOGFILE" = "${LOGFILE##*/}" ]; then
1087                         # substitute known "macros" to glob
1088                         local logfile=$(echo "$LOGFILE" | sed -r -e 's,\$(PACKAGE_(NAME|VERSION|RELEASE)|DATE|TARGET),*,g')
1089                         if [ "$logfile" ]; then
1090                                 cvsignore_df "$logfile"
1091                         fi
1092                 fi
1093
1094                 # create symlinks for tools
1095                 if [ "$SYMLINK_TOOLS" != "no" -a -d "$PACKAGE_DIR" ]; then
1096                         for a in dropin md5 builder {relup,compile,repackage,rsync,pearize}.sh; do
1097                                 # skip tools that don't exist in top dir
1098                                 [ -f $a ] || continue
1099                                 # skip tools that already exist
1100                                 [ -f $PACKAGE_DIR/$a ] && continue
1101                                 ln -s ../$a $PACKAGE_DIR
1102                                 cvsignore_df $a
1103                         done
1104                 fi
1105         fi
1106
1107         if [ -n "$CVSTAG" ]; then
1108                 local _rev=$(get_pkgrev "$CVSTAG")
1109                 echo "$_rev" | grep -q -E "^ERROR$" || CVSTAG="$_rev"
1110                 if git rev-parse --verify -q "$CVSTAG" >/dev/null; then
1111                         # checkout only if differs, so this will not trash git reflog
1112                         if [ $(git rev-parse "$CVSTAG") != $(git rev-parse HEAD) ]; then
1113                                 git checkout "$CVSTAG" --
1114                         fi
1115                 elif git rev-parse --verify -q "refs/remotes/${REMOTE_PLD}/$CVSTAG"; then
1116                         git checkout -t "refs/remotes/${REMOTE_PLD}/$CVSTAG" > /dev/null
1117                 fi
1118                 if [ $(git rev-parse "$CVSTAG") != $(git rev-parse HEAD) ]; then
1119                         Exit_error "err_no_checkut" "$CVSTAG"
1120                 fi
1121
1122                 git merge --ff-only '@{u}'
1123                 git symbolic-ref -q HEAD > /dev/null && [ "$NOCVSSPEC" != "yes" ] &&
1124                 if [ -n "$CVSDATE" ]; then
1125                         git checkout $(git rev-list -n1 --before="'$CVSDATE'" $CVSTAG) || exit 1
1126                 fi
1127         fi
1128
1129         if [ ! -f "$PACKAGE_DIR/$SPECFILE" ]; then
1130                 Exit_error err_no_spec_in_repo "$PACKAGE_DIR/$SPECFILE"
1131         fi
1132
1133         if [ "$CHMOD" = "yes" -a -n "$SPECFILE" ]; then
1134                 chmod $CHMOD_MODE $PACKAGE_DIR/$SPECFILE
1135         fi
1136         unset OPTIONS
1137         [ -n "$DONT_PRINT_REVISION" ] || grep -E -m 1 "^#.*Revision:.*Date" $PACKAGE_DIR/$SPECFILE
1138
1139         set_spec_target
1140 }
1141
1142 # find mirrors in this order. first match wins:
1143 # - package dir (~/rpm/packages/foo)
1144 # - repository dir (~/rpm/packages)
1145 # - tools dir dir (~/rpm/packages/rpm-build-tools)
1146 find_mirror() {
1147         local url="$1"
1148
1149         update_shell_title "find_mirror[$url][$REPO_DIR]"
1150
1151         # NOTE: as while loop runs in subshell,
1152         # we use exit 2 to indicate  that the match was found
1153         # otherwise we end up outputing mirror url and origin url.
1154
1155         local origin mirror name rest ol prefix
1156         IFS="|"
1157         cat "$PACKAGE_DIR/mirrors" "$REPO_DIR/mirrors" "$REPO_DIR/../rpm-build-tools/mirrors" /dev/null 2>/dev/null | \
1158         while read origin mirror name rest; do
1159                 # skip comments and empty lines
1160                 if [ -z "$origin" ] || [ "${origin#\#}" != "$origin" ]; then
1161                         continue
1162                 fi
1163                 ol=$(echo -n "$origin" | wc -c)
1164                 prefix=$(echo -n "$url" | head -c $ol)
1165                 if [ "$prefix" = "$origin" ] ; then
1166                         suffix=$(echo "$url" | cut -b $((ol+1))-)
1167                         echo -n "$mirror$suffix"
1168                         exit 2
1169                 fi
1170         done && echo "$url"
1171 }
1172
1173 # Warning: unpredictable results if same URL used twice
1174 src_no() {
1175         local file="$1"
1176         # escape some regexp characters if part of file name
1177         file=$(echo "$file" | sed -e 's#\([\+\*\.\&\#\?]\)#\\\1#g')
1178         cd $PACKAGE_DIR
1179         rpm_dump | \
1180         grep -E "(SOURCE|PATCH)URL[0-9]*[       ]*${file}""[    ]*$" | \
1181         sed -e 's/.*\(SOURCE\|PATCH\)URL\([0-9][0-9]*\).*/\1\2/' | \
1182         head -n 1 | tr OURCEATH ourceath | xargs
1183 }
1184
1185 src_md5() {
1186         [ "$NO5" = "yes" ] && return
1187         no=$(src_no "$1")
1188         [ -z "$no" ] && return
1189         cd $PACKAGE_DIR
1190         local md5
1191
1192         # use "sources" file from package dir, like vim
1193         if [ -f sources ]; then
1194                 md5=$(grep -s -v '^#' sources | \
1195                 grep -E "[      *]$(basename "$1")([    ,]|\$)" | \
1196                 sed -e 's/^\([0-9a-f]\{32\}\).*/\1/' | \
1197                 grep -E '^[0-9a-f]{32}$')
1198
1199                 if [ "$md5" ]; then
1200                         if [ $(echo "$md5" | wc -l) != 1 ] ; then
1201                                 echo "$SPECFILE: more then one entry in sources for $1" 1>&2
1202                         fi
1203                         echo "$md5" | tail -n 1
1204                         return
1205                 fi
1206         fi
1207
1208         source_md5=$(grep -iE "^#[      ]*(No)?$no-md5[         ]*:" $SPECFILE | sed -e 's/.*://')
1209         if [ -n "$source_md5" ]; then
1210                 echo $source_md5
1211         else
1212                 source_md5=`grep -i "BuildRequires:[    ]*digest(%SOURCE$no)[   ]*=" $SPECFILE | sed -e 's/.*=//'`
1213                 if [ -n "$source_md5" ]; then
1214                         echo $source_md5
1215                 else
1216                         # we have empty SourceX-md5, but it is still possible
1217                         # that we have NoSourceX-md5 AND NoSource: X
1218                         nosource_md5=`grep -i "^#[       ]*No$no-md5[    ]*:" $SPECFILE | sed -e 's/.*://'`
1219                         if [ -n "$nosource_md5" -a -n "`grep -i "^NoSource:[     ]*$no$" $SPECFILE`" ] ; then
1220                                 echo $nosource_md5
1221                         fi
1222                 fi
1223         fi
1224 }
1225
1226 distfiles_path() {
1227         echo "by-md5/$(src_md5 "$1" | sed -e 's|^\(.\)\(.\)|\1/\2/&|')/$(basename "$1")"
1228 }
1229
1230 distfiles_url() {
1231         echo "$PROTOCOL$DISTFILES_SERVER/$(distfiles_path "$1")"
1232 }
1233
1234 good_md5() {
1235         md5=$(src_md5 "$1")
1236         [ "$md5" = "" ] || \
1237         [ "$md5" = "$(md5sum $(nourl "$1") 2> /dev/null | sed -e 's/ .*//')" ]
1238 }
1239
1240 good_size() {
1241         size=$(find $(nourl "$1") -printf "%s" 2>/dev/null)
1242         [ -n "$size" -a "$size" -gt 0 ]
1243 }
1244
1245 cvsignore_df() {
1246         if [ "$CVSIGNORE_DF" != "yes" ]; then
1247                 return
1248         fi
1249         local cvsignore=${PACKAGE_DIR}/.git/info/exclude
1250
1251         # add only if not yet there
1252         if ! awk -vf="$1" -vc=1 '$0 == f { c = 0 } END { exit c }' $cvsignore 2>/dev/null; then
1253                 echo "$1" >> $cvsignore
1254         fi
1255 }
1256
1257 # returns true if "$1" is ftp, http or https protocol url
1258 is_url() {
1259         case "$1" in
1260         ftp://*|http://*|https://*)
1261                 return 0
1262         ;;
1263         esac
1264         return 1
1265 }
1266
1267 update_md5() {
1268         if [ $# -eq 0 ]; then
1269                 return
1270         fi
1271
1272         update_shell_title "update md5"
1273         if [ -n "$DEBUG" ]; then
1274                 set -x
1275                 set -v
1276         fi
1277
1278         cd "$PACKAGE_DIR"
1279
1280         # pass 1: check files to be fetched
1281         local todo
1282         local need_files
1283         for i in "$@"; do
1284                 local fp=$(nourl "$i")
1285                 local srcno=$(src_no "$i")
1286                 if [ -n "$ADD5" ]; then
1287                         [ "$fp" = "$i" ] && continue # FIXME what is this check doing?
1288                         grep -qiE '^#[  ]*'$srcno'-md5[         ]*:' $PACKAGE_DIR/$SPECFILE && continue
1289                         grep -qiE '^BuildRequires:[     ]*digest[(]%SOURCE'$srcno'[)][  ]*=' $PACKAGE_DIR/$SPECFILE && continue
1290                 else
1291                         grep -qiE '^#[  ]*'$srcno'-md5[         ]*:' $PACKAGE_DIR/$SPECFILE || grep -qiE '^BuildRequires:[      ]*digest[(]%SOURCE'$srcno'[)][  ]*=' $PACKAGE_DIR/$SPECFILE || continue
1292                 fi
1293                 if [ ! -f "$fp" ] || [ $ALWAYS_CVSUP = "yes" ]; then
1294                         need_files="$need_files $i"
1295                 fi
1296         done
1297
1298         # pass 1a: get needed files
1299         if [ "$need_files" ]; then
1300                 get_files $need_files
1301         fi
1302
1303         # pass 2: proceed with md5 adding or updating
1304         for i in "$@"; do
1305                 local fp=$(nourl "$i")
1306                 local srcno=$(src_no "$i")
1307                 local md5=$(grep -iE '^#[       ]*(No)?'$srcno'-md5[    ]*:' $PACKAGE_DIR/$SPECFILE )
1308                 if [ -z "$md5" ]; then
1309                         md5=$(grep -iE '^[      ]*BuildRequires:[       ]*digest[(]%SOURCE'$srcno'[)][  ]*=' $PACKAGE_DIR/$SPECFILE )
1310                 fi
1311                 if [ -n "$ADD5" ] && is_url $i || [ -n "$md5" ]; then
1312                         local tag="# $srcno-md5:\t"
1313                         if [[ "$md5" == *NoSource* ]]; then
1314                                 tag="# No$srcno-md5:\t"
1315                         elif [ -n "$USEDIGEST" ]; then
1316                                 tag="BuildRequires:\tdigest(%SOURCE$srcno) = "
1317                         fi
1318                         md5=$(md5sum "$fp" | cut -f1 -d' ')
1319                         echo "Updating $srcno ($md5: $fp)."
1320                         perl -i -ne '
1321                                 print unless (/^\s*#\s*(No)?'$srcno'-md5\s*:/i or /^\s*BuildRequires:\s*digest\(%SOURCE'$srcno'\)/i);
1322                                 print "'"$tag$md5"'\n" if /^'$srcno'\s*:\s+/i;
1323                         ' \
1324                         $PACKAGE_DIR/$SPECFILE
1325                 fi
1326         done
1327 }
1328
1329 check_md5() {
1330         local bad
1331         [ "$NO5" = "yes" ] && return
1332
1333         update_shell_title "check md5"
1334
1335         for i in "$@"; do
1336                 bad=0
1337                 if ! good_md5 "$i"; then
1338                         echo -n "MD5 sum mismatch."
1339                         bad=1
1340                 fi
1341                 if ! good_size "$i"; then
1342                         echo -n "0 sized file."
1343                         bad=1
1344                 fi
1345
1346                 if [ $bad -eq 1 ]; then
1347                         echo " Use -U to refetch sources,"
1348                         echo "or -5 to update md5 sums, if you're sure files are correct."
1349                         Exit_error err_no_source_in_repo $i
1350                 fi
1351         done
1352 }
1353
1354 get_files() {
1355         update_shell_title "get_files"
1356
1357         if [ -n "$DEBUG" ]; then
1358                 set -x
1359                 set -v
1360         fi
1361
1362         if [ $# -gt 0 ]; then
1363                 cd "$PACKAGE_DIR"
1364
1365                 local nc=0
1366                 local get_files_cvs=""
1367                 for i in "$@"; do
1368                         nc=$((nc + 1))
1369                         local cvsup=0
1370                         SHELL_TITLE_PREFIX="get_files[$nc/$#]"
1371                         update_shell_title "$i"
1372                         local fp=`nourl "$i"`
1373                         if [ "$SKIP_EXISTING_FILES" = "yes" ] && [ -f "$fp" ]; then
1374                                 continue
1375                         fi
1376
1377                         FROM_DISTFILES=0
1378                         local srcmd5=$(src_md5 "$i")
1379
1380                         # we know if source/patch is present in cvs/distfiles
1381                         # - has md5 (in distfiles)
1382                         # - in cvs... ideas?
1383
1384                         # CHECK: local file didn't exist or always cvs up (first) requested.
1385                         if [ ! -f "$fp" ] || [ $ALWAYS_CVSUP = "yes" ]; then
1386                                 if echo $i | grep -vE '(http|ftp|https|cvs|svn)://' | grep -qE '\.(gz|bz2)$']; then
1387                                         echo "Warning: no URL given for $i"
1388                                 fi
1389                                 target="$fp"
1390
1391                                 if [ -z "$NODIST" ] && [ -n "$srcmd5" ]; then
1392                                         if good_md5 "$i" && good_size "$i"; then
1393                                                 echo "$fp having proper md5sum already exists"
1394                                                 continue
1395                                         fi
1396
1397                                         # optionally prefer mirror over distfiles if there's mirror
1398                                         # TODO: build url list and then try each url from the list
1399                                         if [ -n "$PREFMIRRORS" ] && [ -z "$NOMIRRORS" ] && im=$(find_mirror "$i") && [ "$im" != "$i" ]; then
1400                                                 url="$im"
1401                                         else
1402                                                 url=$(distfiles_url "$i")
1403                                         fi
1404
1405                                         FROM_DISTFILES=1
1406                                         # is $url local file?
1407                                         if [[ "$url" = [./]* ]]; then
1408                                                 update_shell_title "${GETLOCAL%% *}: $url"
1409                                                 ${GETLOCAL} $url $target
1410                                         else
1411                                                 local uri=${url}
1412                                                 # make shorter message for distfiles urls
1413                                                 if [[ "$uri" = ${PROTOCOL}${DISTFILES_SERVER}* ]]; then
1414                                                         uri=${uri#${PROTOCOL}${DISTFILES_SERVER}/by-md5/?/?/*/}
1415                                                         uri="df: $uri"
1416                                                 fi
1417                                                 update_shell_title "${GETURI%% *}: $uri"
1418                                                 ${GETURI} "$target" "$url"
1419                                         fi
1420
1421
1422                                         if [ -s "$target" ]; then
1423                                                 cvsignore_df $target
1424                                         else
1425                                                 rm -f "$target"
1426                                                 FROM_DISTFILES=0
1427                                         fi
1428                                 fi
1429
1430                                 if [ -z "$NOURLS" ] && [ ! -f "$fp" -o -n "$UPDATE" ] && [ "`echo $i | grep -E 'ftp://|http://|https://'`" ]; then
1431                                         if [ -z "$NOMIRRORS" ]; then
1432                                                 im=$(find_mirror "$i")
1433                                         else
1434                                                 im="$i"
1435                                         fi
1436                                         update_shell_title "${GETURI%% *}: $im"
1437                                         ${GETURI} "$target" "$im"
1438                                         test -s "$target" || rm -f "$target"
1439                                 fi
1440
1441                                 if [ "$cvsup" = 1 ]; then
1442                                         continue
1443                                 fi
1444
1445                         fi
1446
1447                         # the md5 check must be moved elsewhere as if we've called from update_md5 the md5 is wrong.
1448                         if [ ! -f "$fp" -a "$FAIL_IF_NO_SOURCES" != "no" ]; then
1449                                 Exit_error err_no_source_in_repo $i
1450                         fi
1451
1452                         # we check md5 here just only to refetch immediately
1453                         if good_md5 "$i" && good_size "$i"; then
1454                                 :
1455                         elif [ "$FROM_DISTFILES" = 1 ]; then
1456                                 # wrong md5 from distfiles: remove the file and try again
1457                                 # but only once ...
1458                                 echo "MD5 sum mismatch. Trying full fetch."
1459                                 FROM_DISTFILES=2
1460                                 rm -f $target
1461                                 update_shell_title "${GETURI%% *}: $url"
1462                                 ${GETURI} "$target" "$url"
1463                                 test -s "$target" || rm -f "$target"
1464                         fi
1465                 done
1466                 SHELL_TITLE_PREFIX=""
1467
1468
1469                 if [ "$CHMOD" = "yes" ]; then
1470                         CHMOD_FILES=$(nourl "$@")
1471                         if [ -n "$CHMOD_FILES" ]; then
1472                                 chmod $CHMOD_MODE $CHMOD_FILES
1473                         fi
1474                 fi
1475         fi
1476 }
1477
1478 tag_exist() {
1479 # If tag exists and points to other commit exit with error
1480 # If it existsts and points to HEAD return 1
1481 # If it doesn't exist return 0
1482         local _tag="$1"
1483         local sha1=$(git rev-parse HEAD)
1484         echo "Searching for tag $_tag..."
1485         if [ -n "$DEPTH" ]; then
1486                 local ref=$(git ls-remote $REMOTE_PLD "refs/tags/$_tag"  | cut -c -40)
1487         else
1488                 local ref=$(git show-ref -s "refs/tags/$_tag")
1489         fi
1490         [ -z "$ref" ] && return 0
1491         [ "$ref" = "$sha1" ] || Exit_error err_tag_exists "$_tag"
1492         return 1
1493 }
1494
1495 make_tagver() {
1496         if [ -n "$DEBUG" ]; then
1497                 set -x
1498                 set -v
1499         fi
1500
1501         # Check whether first character of PACKAGE_NAME is legal for tag name
1502         if [ -z "${PACKAGE_NAME##[_0-9]*}" -a -z "$TAG_PREFIX" ]; then
1503                 TAG_PREFIX=tag_
1504         fi
1505
1506         # NOTE: CVS tags may must not contain the characters `$,.:;@'
1507         TAGVER=$(echo $TAG_PREFIX$PACKAGE_NAME-$PACKAGE_VERSION-$PACKAGE_RELEASE)
1508
1509         # Remove @kernel.version_release from TAGVER because tagging sources
1510         # could occur with different kernel-headers than kernel-headers used at build time.
1511         # besides, %{_kernel_ver_str} is not expanded.
1512
1513         # TAGVER=auto-ac-madwifi-ng-0-0_20070225_1@%{_kernel_ver_str}
1514         # TAGVER=auto-ac-madwifi-ng-0-0_20070225_1
1515
1516         TAGVER=${TAGVER%@*}
1517         echo -n "$TAGVER"
1518 }
1519
1520 tag_files() {
1521         if [ -n "$DEBUG" ]; then
1522                 set -x
1523                 set -v
1524         fi
1525
1526         echo "Version: $PACKAGE_VERSION"
1527         echo "Release: $PACKAGE_RELEASE"
1528
1529         local _tag
1530         if [ "$TAG_VERSION" = "yes" ]; then
1531                 _tag=`make_tagver`
1532         fi
1533         if [ -n "$TAG" ]; then
1534                 _tag="$TAG"
1535         fi
1536         echo "tag: $_tag"
1537
1538         local OPTIONS="tag $CVS_FORCE"
1539
1540         cd "$PACKAGE_DIR"
1541
1542         if tag_exist $_tag || [ -n "$CVS_FORCE" ]; then
1543                 update_shell_title "tag sources: $_tag"
1544                 git $OPTIONS $_tag || exit
1545                 git push $IPOPT $CVS_FORCE $REMOTE_PLD tag $_tag || Exit_error err_remote_problem $REMOTE_PLD
1546         else
1547                 echo "Tag $_tag already exists and points to the same commit"
1548         fi
1549 }
1550
1551 get_pkgrev() {
1552         [ -z "$1" ] && return 1
1553         local _tmp=$(mktemp /tmp/.builder-XXXX)
1554         rm $_tmp 2>/dev/null
1555         $GETURI $OUTFILEOPT $_tmp $PKGREVS_URL/get/$1 1>/dev/null 2>&1 || Exit_error err_pkgrev_get "$1"
1556         local result=$(cat $_tmp)
1557         rm $_tmp 2>/dev/null
1558         echo -n "$result"
1559 }
1560
1561 set_pkgrev() {
1562         local _tag
1563         parse_spec "$1"
1564         if [ "$TAG_VERSION" = "yes" ]; then
1565                 _tag=`make_tagver`
1566         fi
1567         if [ -n "$TAG" ]; then
1568                 _tag="$TAG"
1569         fi
1570         echo "Writing git revision for tag $_tag"
1571         local _tmp=$(mktemp /tmp/.builder-XXXX)
1572         rm $_tmp 2>/dev/null
1573         local _rev=$(git rev-parse HEAD)
1574         $GETURI $OUTFILEOPT $_tmp $PKGREVS_URL/set/$_rev/$_tag 1>/dev/null 2>&1 || Exit_error err_pkgrev_get "$1"
1575         local result=$(cat $_tmp)
1576         rm $_tmp 2>/dev/null
1577         [ "$(get_pkgrev "$_tag")" = "$CVSTAG" ] && return 0
1578         echo "$result" | grep -q -E "^OK$" && return 0
1579         echo "$result" | grep -q -E "^EXISTS$" && Exit_error err_tag_exists "$_tag"
1580         Exit_error err_pkgrev_set
1581 }
1582
1583 list_pkgrev() {
1584         local _tmp=$(mktemp /tmp/.builder-XXXX)
1585         rm $_tmp 2>/dev/null
1586         $GETURI $OUTFILEOPT $_tmp $PKGREVS_URL/list/$PACKAGE_NAME 1>/dev/null 2>&1
1587         cat $_tmp
1588         rm $_tmp 2>/dev/null
1589 }
1590
1591 branch_files() {
1592         TAG=$1
1593         echo "Git branch: $TAG"
1594         shift
1595
1596         if [ -n "$DEBUG" ]; then
1597                 set -x
1598                 set -v
1599         fi
1600
1601         local OPTIONS="branch $CVS_FORCE"
1602
1603         cd "$PACKAGE_DIR"
1604         git $OPTIONS $TAG || exit
1605 }
1606
1607
1608 # this function should exit early if package can't be built for this arch
1609 # this avoids unneccessary BR filling.
1610 check_buildarch() {
1611         local out ret
1612         out=$(minirpm --short-circuit -bp --define "'prep exit 0'" --nodeps $SPECFILE 2>&1)
1613         ret=$?
1614         if [ $ret -ne 0 ]; then
1615                 echo >&2 "$out"
1616                 exit $ret
1617         fi
1618 }
1619
1620 # from relup.sh
1621 set_release() {
1622         local specfile="$1"
1623         local rel="$2"
1624         local newrel="$3"
1625         sed -i -e "
1626                 s/^\(%define[ \t]\+_\?rel[ \t]\+\)$rel\$/\1$newrel/
1627                 s/^\(Release:[ \t]\+\)$rel\$/\1$newrel/
1628         " $specfile
1629 }
1630
1631 set_version() {
1632         local specfile="$1"
1633         local ver="$2" subver=$ver
1634         local newver="$3" newsubver=$newver
1635
1636         # try handling subver, everything that's not numeric-dotted in version
1637         if grep -Eq '%define\s+subver' $specfile; then
1638                 subver=$(echo "$ver" | sed -re 's,^[0-9.]+,,')
1639                 ver=${ver%$subver}
1640                 newsubver=$(echo "$newver" | sed -re 's,^[0-9.]+,,')
1641                 newver=${newver%$newsubver}
1642         fi
1643         sed -i -e "
1644                 s/^\(%define[ \t]\+_\?ver[ \t]\+\)$ver\$/\1$newver/
1645                 s/^\(%define[ \t]\+subver[ \t]\+\)$subver\$/\1$newsubver/
1646                 s/^\(Version:[ \t]\+\)$ver\$/\1$newver/
1647         " $specfile
1648 }
1649
1650 # try to upgrade .spec to new version
1651 # if --upgrade-version is specified, use that as new version, otherwise invoke pldnotify to find new version
1652 #
1653 # return 1: if .spec was updated
1654 # return 0: no changes to .spec
1655 # exit 1 in case of error
1656 try_upgrade() {
1657         if [ -z "$TRY_UPGRADE" ]; then
1658                 return 0
1659         fi
1660
1661         local TNOTIFY TNEWVER TOLDVER
1662         update_shell_title "build_package: try_upgrade"
1663
1664         cd "$PACKAGE_DIR"
1665
1666         if [ "$UPGRADE_VERSION" ]; then
1667                 TNEWVER=$UPGRADE_VERSION
1668                 echo "Updating spec file to version $TNEWVER"
1669         else
1670                 if [ -n "$FLOAT_VERSION" ]; then
1671                         TNOTIFY=$(pldnotify ${BE_VERBOSE:+-vDEBUG=1} $SPECFILE -n) || exit 1
1672                 else
1673                         TNOTIFY=$(pldnotify ${BE_VERBOSE:+-vDEBUG=1} $SPECFILE) || exit 1
1674                 fi
1675
1676                 # pldnotify does not set exit codes, but it has match for ERROR
1677                 # in output which means so.
1678                 if [[ "$TNOTIFY" = *ERROR* ]]; then
1679                         echo >&2 "$TNOTIFY"
1680                         exit 1
1681                 fi
1682
1683                 TOLDVER=`echo $TNOTIFY | awk '{ print $3; }'`
1684                 echo "New version found, updating spec file from $TOLDVER to version $TNEWVER"
1685
1686                 TNEWVER=$(echo $TNOTIFY | awk '{ match($4,/\[NEW\]/); print $5 }')
1687         fi
1688
1689         if [ -z "$TNEWVER" ]; then
1690                 return 0
1691         fi
1692
1693         if [ "$REVERT_BROKEN_UPGRADE" = "yes" ]; then
1694                 cp -f $SPECFILE $SPECFILE.bak
1695         fi
1696         chmod +w $SPECFILE
1697         set_version $SPECFILE $PACKAGE_VERSION $TNEWVER
1698         set_release $SPECFILE $PACKAGE_RELEASE 1
1699         parse_spec
1700         if [ "$PACKAGE_VERSION" != "$TNEWVER" ]; then
1701                 echo >&2 "Upgrading version failed, you need to update spec yourself"
1702                 exit 1
1703         fi
1704         return 1
1705 }
1706
1707 build_package() {
1708         update_shell_title "build_package"
1709         if [ -n "$DEBUG" ]; then
1710                 set -x
1711                 set -v
1712         fi
1713
1714         cd "$PACKAGE_DIR"
1715
1716         case "$COMMAND" in
1717                 build )
1718                         BUILD_SWITCH="-ba" ;;
1719                 build-binary )
1720                         BUILD_SWITCH="-bb" ;;
1721                 build-source )
1722                         BUILD_SWITCH="-bs --nodeps" ;;
1723                 build-prep )
1724                         BUILD_SWITCH="-bp --nodeps" ;;
1725                 build-build )
1726                         BUILD_SWITCH="-bc" ;;
1727                 build-install )
1728                         BUILD_SWITCH="-bi" ;;
1729                 build-list )
1730                         BUILD_SWITCH="-bl" ;;
1731
1732         esac
1733
1734         update_shell_title "build_package: $COMMAND"
1735         local logfile retval
1736         if [ -n "$LOGFILE" ]; then
1737                 logfile=`eval echo $LOGFILE`
1738                 if [ -d "$logfile" ]; then
1739                         echo "Log file $logfile is a directory."
1740                         echo "Parse error in the spec?"
1741                         Exit_error err_build_fail
1742                 fi
1743                 if [ -n "$LASTLOG_FILE" ]; then
1744                         echo "LASTLOG=$logfile" > $LASTLOG_FILE
1745                 fi
1746         fi
1747
1748         # unset these, should not be exposed to builder shell!
1749         unset GIT_WORK_TREE GIT_DIR
1750         # these are set by jenkins
1751         unset GIT_PREVIOUS_COMMIT GIT_URL GIT_PREVIOUS_SUCCESSFUL_COMMIT GIT_BRANCH GIT_COMMIT
1752         # this may be set by user
1753         unset GIT_SSH
1754         # may be set by user
1755         unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_TESTING_PORCELAIN_COMMAND_LIST
1756         # fail if something still set
1757         env | grep ^GIT_ && Exit_error err_build_fail
1758
1759         local specdir=$(insert_gitlog $SPECFILE)
1760         ulimit -c unlimited
1761         # If required exclude directories with systemd related files from package contents
1762         if grep -q -E 'systemd(unitdir|userunitdir|tmpfilesdir)' $specdir/$SPECFILE; then
1763                 sed -i -e '/^%exclude_systemd_files/d; /^%files/s/$/\n%exclude_systemd_files/g;' $specdir/$SPECFILE
1764         fi
1765         # Enable/disable distro wide bconds based on ~/.distbcond
1766         process_distbcond "$specdir/$SPECFILE"
1767         # Add %tld macro to release to allow release control
1768         sed -i -r -e '/^Release:/s/%\{\?tld\}//g; s/^Release:\s+(.*)$/Release:\t\1%{?tld}/;' $specdir/$SPECFILE
1769         # FIXME: eval here is exactly why?
1770         PATH=$CLEAN_PATH eval teeboth "'$logfile'" ${TIME_COMMAND} ${NICE_COMMAND} $RPMBUILD $TARGET_SWITCH $BUILD_SWITCH -v $QUIET $CLEAN $RPMOPTS $RPMBUILDOPTS $BCOND --define \'_specdir $PACKAGE_DIR\' --define \'_sourcedir $PACKAGE_DIR\' $specdir/$SPECFILE
1771         retval=$?
1772
1773         # Set pkgrev if requested and build status is OK
1774         if [ ! -z "$SETPKGREV" ] && [ "$SETPKGREV" = "true" ] && [ "$retval" -eq "0" ]; then
1775                 set_pkgrev "$specdir/$SPECFILE"
1776         fi
1777
1778         rm -r $specdir
1779
1780         if [ -n "$logfile" ] && [ -n "$LOGDIROK" ] && [ -n "$LOGDIRFAIL" ]; then
1781                 if [ "$retval" -eq "0" ]; then
1782                         mv $logfile $LOGDIROK
1783                 else
1784                         mv $logfile $LOGDIRFAIL
1785                 fi
1786         fi
1787
1788         if [ "$retval" -ne "0" ]; then
1789                 if [ -n "$TRY_UPGRADE" ]; then
1790                         echo "\nUpgrade package to new version failed."
1791                         if [ "$REVERT_BROKEN_UPGRADE" = "yes" ]; then
1792                                 echo "Restoring old spec file."
1793                                 mv -f $SPECFILE.bak $SPECFILE
1794                         fi
1795                         echo ""
1796                 fi
1797                 Exit_error err_build_fail
1798         fi
1799         unset BUILD_SWITCH
1800 }
1801
1802 nourl() {
1803         echo "$@" | sed 's#\<\(ftp\|http\|https\|cvs\|svn\)://[^ ]*/##g'
1804 }
1805
1806 install_required_packages() {
1807         run_poldek -vi $1
1808         return $?
1809 }
1810
1811 find_spec_bcond() { # originally from /usr/lib/rpm/find-spec-bcond
1812         local SPEC="$1"
1813         awk -F"\n" '
1814         /^%changelog/ { exit }
1815         /^%bcond_with/{
1816                 match($0, /bcond_with(out)?[ \t]+[_a-zA-Z0-9]+/);
1817                 bcond = substr($0, RSTART + 6, RLENGTH - 6);
1818                 gsub(/[ \t]+/, "_", bcond);
1819                 print bcond
1820         }' $SPEC | LC_ALL=C sort -u
1821 }
1822
1823 process_bcondrc() {
1824         # expand bconds from ~/.bcondrc
1825         # The file structure is like gentoo's package.use:
1826         # ---
1827         # * -selinux
1828         # samba -mysql -pgsql
1829         # w32codec-installer license_agreement
1830         # php +mysqli
1831         # ---
1832         if [ -f $HOME/.bcondrc ] || ([ -n $HOME_ETC ] && [ -f $HOME_ETC/.bcondrc ]); then
1833                 :
1834         else
1835                 return
1836         fi
1837
1838         SN=${SPECFILE%%\.spec}
1839
1840         local bcondrc=$HOME/.bcondrc
1841         [ -n $HOME_ETC ] && [ -f $HOME_ETC/.bcondrc ] && bcondrc=$HOME_ETC/.bcondrc
1842
1843         local bcond_avail=$(find_spec_bcond $SPECFILE)
1844
1845         while read pkg flags; do
1846                 # ignore comments
1847                 [[ "$pkg" == \#* ]] && continue
1848
1849                 # any package or current package?
1850                 if [ "$pkg" = "*" ] || [ "$pkg" = "$PACKAGE_NAME" ] || [ "$pkg" = "$SN" ]; then
1851                         for flag in $flags; do
1852                                 local opt=${flag#[+-]}
1853
1854                                 # use only flags which are in this package.
1855                                 if [[ $bcond_avail = *${opt}* ]]; then
1856                                         if [[ $flag = -* ]]; then
1857                                                 if [[ $BCOND != *--with?${opt}* ]]; then
1858                                                         BCOND="$BCOND --without $opt"
1859                                                 fi
1860                                         else
1861                                                 if [[ $BCOND != *--without?${opt}* ]]; then
1862                                                         BCOND="$BCOND --with $opt"
1863                                                 fi
1864                                         fi
1865                                 fi
1866                         done
1867                 fi
1868         done < $bcondrc
1869         update_shell_title "parse ~/.bcondrc: DONE!"
1870 }
1871
1872 process_distbcond() {
1873         # apply bconds from ~/.distbcond to spec
1874         # The file structure is like gentoo's package.use:
1875         # ---
1876         # * -selinux
1877         # samba -mysql -pgsql
1878         # w32codec-installer license_agreement
1879         # php +mysqli
1880         # ---
1881         if [ -f $HOME/.distbcond ] || ([ -n $HOME_ETC ] && [ -f $HOME_ETC/.distbcond ]); then
1882                 :
1883         else
1884                 return
1885         fi
1886
1887         SN=${SPECFILE%%\.spec}
1888
1889         local distbcond=$HOME/.distbcond
1890         [ -n $HOME_ETC ] && [ -f $HOME_ETC/.distbcond ] && distbcond=$HOME_ETC/.distbcond
1891
1892         local bcond_avail=$(find_spec_bcond $SPECFILE)
1893
1894         while read pkg flags; do
1895                 # ignore comments
1896                 [[ "$pkg" == \#* ]] && continue
1897
1898                 # any package or current package?
1899                 if [ "$pkg" = "*" ] || [ "$pkg" = "$PACKAGE_NAME" ] || [ "$pkg" = "$SN" ]; then
1900                         for flag in $flags; do
1901                                 local opt=${flag#[+-]}
1902
1903                                 # use only flags which are in this package.
1904                                 if [[ $bcond_avail = *${opt}* ]]; then
1905                                         if [[ $flag = -* ]]; then
1906                                                 sed -i -r -e '/^%bcond_(with|without)\s+'$opt'/s/^%bcond_(with|without)/%bcond_with/g;' "$1"
1907                                         elif [[ $flag = +* ]]; then
1908                                                 sed -i -r -e '/^%bcond_(with|without)\s+'$opt'/s/^%bcond_(with|without)/%bcond_without/g;' "$1"
1909                                         fi
1910                                 fi
1911                         done
1912                 fi
1913         done < $distbcond
1914         update_shell_title "parse ~/.distbcond: DONE!"
1915 }
1916
1917 set_bconds_values() {
1918         update_shell_title "set bcond values"
1919
1920         AVAIL_BCONDS_WITHOUT=""
1921         AVAIL_BCONDS_WITH=""
1922
1923         if grep -Eq '^# *_with' ${SPECFILE}; then
1924                 echo >&2 "ERROR: This spec has old style bconds."
1925                 exit 1
1926         fi
1927
1928         if ! grep -q '^%bcond' ${SPECFILE}; then
1929                 return
1930         fi
1931
1932         local bcond_avail=$(find_spec_bcond $SPECFILE)
1933         process_bcondrc "$SPECFILE"
1934
1935         update_shell_title "parse bconds"
1936
1937         local opt bcond
1938         for opt in $bcond_avail; do
1939                 case "$opt" in
1940                 without_*)
1941                         bcond=${opt#without_}
1942                         case "$BCOND" in
1943                         *--without?${bcond}\ *|*--without?${bcond})
1944                                 AVAIL_BCONDS_WITHOUT="$AVAIL_BCONDS_WITHOUT <$bcond>"
1945                                 ;;
1946                         *)
1947                                 AVAIL_BCONDS_WITHOUT="$AVAIL_BCONDS_WITHOUT $bcond"
1948                                 ;;
1949                         esac
1950                         ;;
1951                 with_*)
1952                         bcond=${opt#with_}
1953                         case "$BCOND" in
1954                         *--with?${bcond}\ *|*--with?${bcond})
1955                                 AVAIL_BCONDS_WITH="$AVAIL_BCONDS_WITH <$bcond>"
1956                                 ;;
1957                         *)
1958                                 AVAIL_BCONDS_WITH="$AVAIL_BCONDS_WITH $bcond"
1959                                 ;;
1960                         esac
1961                         ;;
1962                 *)
1963                         echo >&2 "ERROR: unexpected '$opt' in set_bconds_values"
1964                         exit 1
1965                         ;;
1966                 esac
1967         done
1968 }
1969
1970 run_sub_builder() {
1971         package_name="${1}"
1972         update_shell_title "run_sub_builder $package_name"
1973         #
1974         # No i tutaj bym chciaÅ‚ zrobić sztucznÄ… inteligencjÄ™, która spróbuje tego
1975         # pakieta zbudować. Aktualnie niewiele dziala, bo generalnie nie widze do
1976         # konca algorytmu... Ale damy rade. :) Na razie po prostu sie wyjebie tak samo
1977         # jakby nie bylo tego kawalka kodu.
1978         #
1979         # Update: PoprawiÅ‚em parÄ™ rzeczy i zaczęło generować pakiety spoza zadanej listy.
1980         #         Jednym sÅ‚owem budowanie niespoldkowanych zależnoÅ›ci dziaÅ‚a w paru przypadkach.
1981         #
1982         #
1983         # y0shi.
1984         # kurwa. translate that ^^^^
1985
1986         parent_spec_name=''
1987
1988         # Istnieje taki spec? ${package}.spec
1989         if [ -f "${PACKAGE_DIR}/${package}.spec" ]; then
1990                 parent_spec_name=${package}.spec
1991         elif [ -f "${PACKAGE_DIR}/$(echo ${package_name} | sed -e s,-devel.*,,g -e s,-static,,g).spec" ]; then
1992                 parent_spec_name="$(echo ${package_name} | sed -e s,-devel.*,,g -e s,-static,,g).spec"
1993         else
1994                 for provides_line in $(grep -r ^Provides:.*$package ${PACKAGE_DIR}); do
1995                         echo $provides_line
1996                 done
1997         fi
1998
1999         if [ "${parent_spec_name}" != "" ]; then
2000                 spawn_sub_builder $parent_spec_name
2001         fi
2002         NOT_INSTALLED_PACKAGES="$NOT_INSTALLED_PACKAGES $package_name"
2003 }
2004
2005 # install package with poldek
2006 # @return exit code from poldek
2007 #
2008 # this requires following sudo rules:
2009 # - poldek --noask --caplookup -ug
2010 poldek_install() {
2011         LC_ALL=C LANG=C $POLDEK_CMD --noask --caplookup --uniq -ug "$@"
2012 }
2013
2014 # install packages
2015 #
2016 # this requires following sudo rules:
2017 # - poldek -q --update --upa
2018 install_packages() {
2019         # sync poldek indexes once per invocation
2020         if [ -z "$package_indexes_updated" ]; then
2021                 update_shell_title "poldek: update indexes"
2022                 $POLDEK_CMD -q --update --upa --mo=nodesc
2023                 package_indexes_updated=true
2024         fi
2025
2026         update_shell_title "install packages: $*"
2027         poldek_install "$@" && return
2028
2029         # retry install, install packages one by one
2030         # this is slower one
2031         local rc=0 package
2032         for package in $*; do
2033                 package=$(depspecname $package)
2034                 update_shell_title "install package: $package"
2035                 poldek_install "$package" || rc=$?
2036         done
2037         return $rc
2038 }
2039
2040 uninstall_packages() {
2041         update_shell_title "uninstall packages: $*"
2042         $POLDEK_CMD --noask --nofollow -ev "$@"
2043 }
2044
2045 spawn_sub_builder() {
2046         package_name="${1}"
2047         update_shell_title "spawn_sub_builder $package_name"
2048
2049         sub_builder_opts=''
2050         if [ "${FETCH_BUILD_REQUIRES}" = "yes" ]; then
2051                 sub_builder_opts="${sub_builder_opts} -R"
2052         fi
2053         if [ "${REMOVE_BUILD_REQUIRES}" = "nice" ]; then
2054                 sub_builder_opts="${sub_builder_opts} -RB"
2055         elif [ "${REMOVE_BUILD_REQUIRES}" = "force" ]; then
2056                 sub_builder_opts="${sub_builder_opts} -FRB"
2057         fi
2058         if [ "${UPDATE_POLDEK_INDEXES}" = "yes" ]; then
2059                 sub_builder_opts="${sub_builder_opts} -Upi"
2060         fi
2061
2062         cd "${PACKAGE_DIR}"
2063         ./builder ${sub_builder_opts} "$@"
2064 }
2065
2066 remove_build_requires() {
2067         if [ "$INSTALLED_PACKAGES" != "" ]; then
2068                 case "$REMOVE_BUILD_REQUIRES" in
2069                         "force")
2070                                 run_poldek --noask -ve $INSTALLED_PACKAGES
2071                                 ;;
2072                         "nice")
2073                                 run_poldek --ask -ve $INSTALLED_PACKAGES
2074                                 ;;
2075                         *)
2076                                 echo You may want to manually remove following BuildRequires fetched:
2077                                 echo $INSTALLED_PACKAGES
2078                                 echo "Try poldek -e \`cat $(pwd)/.${SPECFILE}_INSTALLED_PACKAGES\`"
2079                                 ;;
2080                 esac
2081         fi
2082 }
2083
2084 display_bconds() {
2085         if [ "$AVAIL_BCONDS_WITH" -o "$AVAIL_BCONDS_WITHOUT" ]; then
2086                 if [ "$BCOND" ]; then
2087                         echo ""
2088                         echo "Building $SPECFILE with the following conditional flags:"
2089                         echo -n "$BCOND"
2090                 else
2091                         echo ""
2092                         echo "No conditional flags passed"
2093                 fi
2094                 echo ""
2095                 echo "from available:"
2096                 echo "--with   :\t$AVAIL_BCONDS_WITH"
2097                 echo "--without:\t$AVAIL_BCONDS_WITHOUT"
2098                 echo ""
2099         fi
2100 }
2101
2102 display_branches() {
2103         echo -n "Available branches: "
2104         git branch -r 2>/dev/null | grep "^  ${REMOTE_PLD}" | grep -v ${REMOTE_PLD}/HEAD | sed "s#^ *${REMOTE_PLD}/##" | xargs
2105 }
2106
2107 # checks a given list of packages/files/provides against current rpmdb.
2108 # outputs all dependencies which current rpmdb doesn't satisfy.
2109 # input can be either STDIN or parameters
2110 _rpm_prov_check() {
2111         local deps out
2112
2113         if [ $# -gt 0 ]; then
2114                 deps="$@"
2115         else
2116                 deps=$(cat)
2117         fi
2118
2119         out=$(LC_ALL=C rpm -q --whatprovides $deps 2>&1)
2120
2121         # packages
2122         echo "$out" | awk '/^no package provides/ { print $NF }'
2123
2124         # other deps (files)
2125         echo "$out" | sed -rne 's/file (.*): No such file or directory/\1/p'
2126 }
2127
2128 # checks if given package/files/provides exists in rpmdb.
2129 # input can be either stdin or parameters
2130 # returns packages which are present in the rpmdb
2131 _rpm_cnfl_check() {
2132         local DEPS
2133
2134         if [ $# -gt 0 ]; then
2135                 DEPS="$@"
2136         else
2137                 DEPS=$(cat)
2138         fi
2139
2140         LC_ALL=C LANG=C rpm -q --whatprovides $DEPS 2>/dev/null | awk '!/no package provides/ { print }'
2141 }
2142
2143 # install deps via information from 'rpm-getdeps' or 'rpm --specsrpm'
2144 install_build_requires_rpmdeps() {
2145         local DEPS CNFL
2146         if [ "$FETCH_BUILD_REQUIRES_RPMGETDEPS" = "yes" ]; then
2147                 # TODO: Conflicts list doesn't check versions
2148                 CNFL=$(eval rpm-getdeps $BCOND $RPMOPTS $SPECFILE 2> /dev/null | awk '/^\-/ { print $3 } ' | _rpm_cnfl_check | xargs)
2149                 DEPS=$(eval rpm-getdeps $BCOND $RPMOPTS $SPECFILE 2> /dev/null | awk '/^\+/ { print $3 } ' | _rpm_prov_check | xargs)
2150         fi
2151         if [ "$FETCH_BUILD_REQUIRES_RPMSPECSRPM" = "yes" ]; then
2152                 CNFL=$(eval rpm -q --specsrpm --conflicts $BCOND $RPMOPTS $SPECFILE | awk '{print $1}' | _rpm_cnfl_check | xargs)
2153                 DEPS=$(eval rpm -q --specsrpm --requires $BCOND $RPMOPTS $SPECFILE | awk '{print $1}' | _rpm_prov_check | xargs)
2154         fi
2155
2156         if [ -n "$CNFL" ]; then
2157                 echo "Uninstall conflicting packages: $CNFL"
2158                 uninstall_packages $CNFL
2159         fi
2160
2161         if [ -n "$DEPS" ]; then
2162                 echo "Install dependencies: $DEPS"
2163                 install_packages $DEPS
2164         fi
2165 }
2166
2167 fetch_build_requires()
2168 {
2169         if [ "${FETCH_BUILD_REQUIRES}" != "yes" ]; then
2170                 return
2171         fi
2172
2173         update_shell_title "fetch build requires"
2174         if [ "$FETCH_BUILD_REQUIRES_RPMGETDEPS" = "yes" ] || [ "$FETCH_BUILD_REQUIRES_RPMSPECSRPM" = "yes" ]; then
2175                 install_build_requires_rpmdeps
2176                 return
2177         fi
2178
2179         die "need rpm-getdeps tool"
2180 }
2181
2182 init_repository() {
2183         local remoterepo=$1
2184         local localrepo=$2
2185
2186         if [ ! -e $localrepo ]; then
2187                 git clone $IPOPT -o $REMOTE_PLD ${GIT_SERVER}/$remoterepo $localrepo
2188                 git --git-dir=$localrepo/.git remote set-url --push  $REMOTE_PLD ssh://${GIT_PUSH}/$remoterepo
2189         fi
2190 }
2191
2192 init_rpm_dir() {
2193         local TOP_DIR=$(eval $RPM $RPMOPTS --eval '%{_topdir}')
2194         local rpmdir=$(eval $RPM $RPMOPTS --eval '%{_rpmdir}')
2195         local buildir=$(eval $RPM $RPMOPTS --eval '%{_builddir}')
2196         local srpmdir=$(eval $RPM $RPMOPTS --eval '%{_srcrpmdir}')
2197         local TEMPLATES=template-specs
2198         local tmp
2199
2200         echo "Initializing rpm directories to $TOP_DIR from $GIT_SERVER"
2201         mkdir -p $TOP_DIR $rpmdir $buildir $srpmdir
2202
2203         cd "$TOP_DIR"
2204         init_repository ${PACKAGES_DIR}/rpm-build-tools.git ../rpm-build-tools
2205         init_repository projects/$TEMPLATES ../$TEMPLATES
2206         for a in builder fetchsrc_request compile repackage; do
2207                 ln -sf ../rpm-build-tools/${a}.sh $a
2208         done
2209         for a in md5; do
2210                 ln -sf ../rpm-build-tools/${a} $a
2211         done
2212         ln -sf ../rpm-build-tools/mirrors mirrors
2213         init_builder
2214 }
2215
2216 mr_proper() {
2217         init_builder
2218         NOCVSSPEC="yes"
2219         DONT_PRINT_REVISION="yes"
2220
2221         # remove spec and sources
2222         PATH=$CLEAN_PATH $RPMBUILD --clean --rmsource --rmspec --nodeps --define "__urlgetfile() %nil" --define "_specdir $PACKAGE_DIR" --define "_sourcedir $PACKAGE_DIR" --define "_builddir $builddir" $PACKAGE_DIR/$SPECFILE
2223         rm -rf $PACKAGE_DIR/{.git,.gitignore}
2224         rmdir --ignore-fail-on-non-empty $PACKAGE_DIR
2225 }
2226
2227 #---------------------------------------------
2228 # main()
2229
2230 if [ $# = 0 ]; then
2231         usage
2232         exit 1
2233 fi
2234
2235 # stuff global $BUILDER_OPTS from env as args
2236 if [ "$BUILDER_OPTS" ]; then
2237         set -- "$BUILDER_OPTS" "$@"
2238 fi
2239
2240 while [ $# -gt 0 ]; do
2241         case "${1}" in
2242                 -4|-6)
2243                         IPOPT="${1}"
2244                         shift
2245                         ;;
2246                 -5 | --update-md5)
2247                         COMMAND="update_md5"
2248                         NODIST="yes"
2249                         NOCVSSPEC="yes"
2250                         shift ;;
2251                 -a5 | --add-md5 )
2252                         COMMAND="update_md5"
2253                         NODIST="yes"
2254                         NOCVSSPEC="yes"
2255                         ADD5="yes"
2256                         shift ;;
2257                 -n5 | --no-md5 )
2258                         NO5="yes"
2259                         shift ;;
2260                 -D | --debug )
2261                         DEBUG="yes"; shift ;;
2262                 -V | --version )
2263                         COMMAND="version"; shift ;;
2264                 --short-version )
2265                         COMMAND="short-version"; shift ;;
2266                 -a | --add_cvs)
2267                         COMMAND="add_cvs";
2268                         shift ;;
2269                 --all-branches )
2270                         ALL_BRANCHES="yes"
2271                         shift ;;
2272                 -b | -ba | --build )
2273                         COMMAND="build"; shift ;;
2274                 -bb | --build-binary )
2275                         COMMAND="build-binary"; shift ;;
2276                 -bc )
2277                         COMMAND="build-build"; shift ;;
2278                 -bi )
2279                         COMMAND="build-install"; shift ;;
2280                 -bl )
2281                         COMMAND="build-list"; shift ;;
2282                 -bp | --build-prep )
2283                         COMMAND="build-prep"; shift ;;
2284                 -bs | --build-source )
2285                         COMMAND="build-source"; shift ;;
2286                 -B | --branch )
2287                         COMMAND="branch"; shift; TAG="${1}"; shift;;
2288                 -c | --clean )
2289                         CLEAN="--clean"; shift ;;
2290                 -cf | --cvs-force )
2291                         CVS_FORCE="-f"; shift;;
2292                 --depth )
2293                         DEPTH="--depth=$2"
2294                         shift 2
2295                         ;;
2296                 -g | --get )
2297                         COMMAND="get"; shift ;;
2298                 -h | --help )
2299                         COMMAND="usage"; shift ;;
2300                 --ftp )
2301                         PROTOCOL="ftp"; shift ;;
2302                 --http )
2303                         PROTOCOL="http"; shift ;;
2304                 -j)
2305                         RPMOPTS="${RPMOPTS} --define \"_smp_mflags -j$2\""
2306                         shift 2
2307                         ;;
2308                 -j[0-9]*)
2309                         RPMOPTS="${RPMOPTS} --define \"_smp_mflags $1\""
2310                         shift
2311                         ;;
2312                 -p)
2313                         PARALLEL_DOWNLOADS=$2
2314                         shift 2
2315                         ;;
2316                 -p[0-9])
2317                         PARALLEL_DOWNLOADS=${1#-p}
2318                         shift
2319                         ;;
2320                 -l | --logtofile )
2321                         shift; LOGFILE="${1}"; shift ;;
2322                 -ni| --nice )
2323                         shift; DEF_NICE_LEVEL=${1}; shift ;;
2324                 -ske | --skip-existing-files)
2325                         SKIP_EXISTING_FILES="yes"; shift ;;
2326                 -m | --mr-proper )
2327                         COMMAND="mr-proper"; shift ;;
2328                 -ncs | --no-cvs-specs )
2329                         NOCVSSPEC="yes"; shift ;;
2330                 -nd | --no-distfiles )
2331                         NODIST="yes"; shift ;;
2332                 -nm | --no-mirrors )
2333                         NOMIRRORS="yes"; shift ;;
2334                 -nu | --no-urls )
2335                         NOURLS="yes"; shift ;;
2336                 -ns | --no-srcs )
2337                         NOSRCS="yes"; shift ;;
2338                 -ns0 | --no-source0 )
2339                         NOSOURCE0="yes"; shift ;;
2340                 -nn | --no-net )
2341                         NOCVSSPEC="yes"
2342                         NODIST="yes"
2343                         NOMIRRORS="yes"
2344                         NOURLS="yes"
2345                         NOSRCS="yes"
2346                         ALWAYS_CVSUP="no"
2347                         shift;;
2348                 -pm | --prefer-mirrors )
2349                         PREFMIRRORS="yes"
2350                         shift;;
2351                 --noinit | --no-init )
2352                         NOINIT="yes"
2353                         shift;;
2354                 --opts )
2355                         shift; RPMOPTS="${RPMOPTS} ${1}"; shift ;;
2356                 --nopatch | -np )
2357                         shift; RPMOPTS="${RPMOPTS} --define \"patch${1} : ignoring patch${1}; exit 1; \""; shift ;;
2358                 --skip-patch | -sp )
2359                         shift; RPMOPTS="${RPMOPTS} --define \"patch${1} : skiping patch${1}\""; shift ;;
2360                 --topdir)
2361                         RPMOPTS="${RPMOPTS} --define \"_topdir $2\""
2362                         shift 2
2363                         ;;
2364                 --with | --without )
2365                         case $GROUP_BCONDS in
2366                                 "yes")
2367                                         COND=${1}
2368                                         shift
2369                                         # XXX: broken: ./builder -bb ucspi-tcp.spec --without mysql
2370                                         while ! `echo ${1}|grep -qE '(^-|spec)'`
2371                                         do
2372                                                 BCOND="$BCOND $COND $1"
2373                                                 shift
2374                                         done;;
2375                                 "no")
2376                                         if [[ "$2" = *,* ]]; then
2377                                                 for a in $(echo "$2" | tr , ' '); do
2378                                                         BCOND="$BCOND $1 $a"
2379                                                 done
2380                                         else
2381                                                 BCOND="$BCOND $1 $2"
2382                                         fi
2383                                         shift 2 ;;
2384                         esac
2385                         ;;
2386                 --target )
2387                         shift; TARGET="${1}"; shift ;;
2388                 --target=* )
2389                         TARGET=$(echo "${1}" | sed 's/^--target=//'); shift ;;
2390                 -q | --quiet )
2391                         QUIET="--quiet"; shift ;;
2392                 --date )
2393                         CVSDATE="${2}"; shift 2
2394                         date -d "$CVSDATE" > /dev/null 2>&1 || { echo >&2 "No valid date specified"; exit 3; }
2395                         ;;
2396                 -r | --cvstag )
2397                         CVSTAG="$2"
2398                         shift 2
2399                         ;;
2400                 -A)
2401                         shift
2402                         CVSTAG="master"
2403                         ;;
2404                 -R | --fetch-build-requires)
2405                         FETCH_BUILD_REQUIRES="yes"
2406                         NOT_INSTALLED_PACKAGES=
2407                         shift ;;
2408                 -RB | --remove-build-requires)
2409                         REMOVE_BUILD_REQUIRES="nice"
2410                         shift ;;
2411                 -FRB | --force-remove-build-requires)
2412                         REMOVE_BUILD_REQUIRES="force"
2413                         shift ;;
2414                 -sc | --source-cvs)
2415                         COMMAND="list-sources-cvs"
2416                         shift ;;
2417                 -sd | --source-distfiles)
2418                         COMMAND="list-sources-distfiles"
2419                         shift ;;
2420                 -sdp | --source-distfiles-paths)
2421                         COMMAND="list-sources-distfiles-paths"
2422                         shift ;;
2423                 -sf | --source-files)
2424                         COMMAND="list-sources-files"
2425                         shift ;;
2426                 -lsp | --source-paths)
2427                         COMMAND="list-sources-local-paths"
2428                         shift ;;
2429                 -su | --source-urls)
2430                         COMMAND="list-sources-urls"
2431                         shift ;;
2432                 -Tvs | --tag-version-stable )
2433                         COMMAND="tag"
2434                         TAG="STABLE"
2435                         TAG_VERSION="yes"
2436                         shift;;
2437                 -Ts | --tag-stable )
2438                         COMMAND="tag"
2439                         TAG="STABLE"
2440                         TAG_VERSION="no"
2441                         shift;;
2442                 -Tv | --tag-version )
2443                         COMMAND="tag"
2444                         TAG=""
2445                         TAG_VERSION="yes"
2446                         shift;;
2447                 -Tp | --tag-prefix )
2448                         TAG_PREFIX="$2"
2449                         shift 2;;
2450                 -tt | --test-tag )
2451                         TEST_TAG="yes"
2452                         shift;;
2453                 -T | --tag )
2454                         COMMAND="tag"
2455                         shift
2456                         TAG="$1"
2457                         TAG_VERSION="no"
2458                         shift;;
2459                 -ir | --integer-release-only )
2460                         INTEGER_RELEASE="yes"
2461                         shift;;
2462                 -U | --update )
2463                         COMMAND="update_md5"
2464                         UPDATE="yes"
2465                         NOCVSSPEC="yes"
2466                         NODIST="yes"
2467                         shift ;;
2468                 -Upi | --update-poldek-indexes )
2469                         UPDATE_POLDEK_INDEXES="yes"
2470                         shift ;;
2471                 --init-rpm-dir|--init)
2472                         COMMAND="init_rpm_dir"
2473                         shift ;;
2474                 -u | --try-upgrade )
2475                         TRY_UPGRADE="1"; shift ;;
2476                 --upgrade-version )
2477                         shift; UPGRADE_VERSION="$1"; shift;;
2478                 -un | --try-upgrade-with-float-version )
2479                         TRY_UPGRADE="1"; FLOAT_VERSION="1"; shift ;;
2480                 -v | --verbose )
2481                         BE_VERBOSE="1"; shift ;;
2482                 --define)
2483                         shift
2484                         MACRO="${1}"
2485                         shift
2486                         if echo "${MACRO}" | grep -q '\W'; then
2487                                 RPMOPTS="${RPMOPTS} --define \"${MACRO}\""
2488                         else
2489                                 VALUE="${1}"
2490                                 shift
2491                                 RPMOPTS="${RPMOPTS} --define \"${MACRO} ${VALUE}\""
2492                         fi
2493                         ;;
2494                 --alt_kernel)
2495                         shift
2496                         RPMOPTS="${RPMOPTS} --define \"alt_kernel $1\" --define \"build_kernels $1\""
2497                         shift
2498                         ;;
2499                 --short-circuit)
2500                         RPMBUILDOPTS="${RPMBUILDOPTS} --short-circuit"
2501                         shift
2502                         ;;
2503                 --show-bconds | -show-bconds | -print-bconds | --print-bconds | -display-bconds | --display-bconds )
2504                         COMMAND="show_bconds"
2505                         shift
2506                         ;;
2507                 --show-bcond-args)
2508                         COMMAND="show_bcond_args"
2509                         shift
2510                         ;;
2511                 --show-avail-bconds)
2512                         COMMAND="show_avail_bconds"
2513                         shift
2514                         ;;
2515                 --nodeps)
2516                         shift
2517                         RPMOPTS="${RPMOPTS} --nodeps"
2518                         ;;
2519                 -debug)
2520                         RPMBUILDOPTS="${RPMBUILDOPTS} -debug"; shift
2521                         ;;
2522                 --git-pld)
2523                         shift
2524                         GIT_SERVER=${PLD_GIT_SERVER}
2525                         GIT_PUSH=${PLD_GIT_PUSH}
2526                         PACKAGES_DIR=${PLD_PACKAGES_DIR}
2527                         DISTFILES_SERVER=${PLD_DISTFILES_SERVER}
2528                         ;;
2529                 --git-tld)
2530                         shift
2531                         GIT_SERVER=${TLD_GIT_SERVER}
2532                         GIT_PUSH=${TLD_GIT_PUSH}
2533                         PACKAGES_DIR=${TLD_PACKAGES_DIR}
2534                         DISTFILES_SERVER=${TLD_DISTFILES_SERVER}
2535                         ;;
2536                 --pkgrev)
2537                         SETPKGREV="true"
2538                         COMMAND="build-source"
2539                         shift;;
2540                 -lp)
2541                         COMMAND="list_pkgrev"
2542                         shift;;
2543                 -*)
2544                         Exit_error err_invalid_cmdline "$1"
2545                         ;;
2546                 *)
2547                         SPECFILE=${1%/}; shift
2548                         # check if specname was passed as specname:cvstag
2549                         if [ "${SPECFILE##*:}" != "${SPECFILE}" ]; then
2550                                 CVSTAG="${SPECFILE##*:}"
2551                                 SPECFILE="${SPECFILE%%:*}"
2552                         fi
2553                         # always have SPECFILE ending with .spec extension
2554                         SPECFILE=${SPECFILE%%.spec}.spec
2555                         ASSUMED_NAME=$(basename ${SPECFILE%%.spec})
2556         esac
2557 done
2558
2559 # Check if given package exists in TLD git
2560 if ! git ls-remote --heads ${GIT_SERVER}/${PACKAGES_DIR}/${ASSUMED_NAME} 1>/dev/null 2>&1; then
2561         # Nope, we don't have it in TLD, switch to PLD repositories
2562         GIT_SERVER=${PLD_GIT_SERVER}
2563         GIT_PUSH=${PLD_GIT_PUSH}
2564         PACKAGES_DIR=${PLD_PACKAGES_DIR}
2565         DISTFILES_SERVER=${PLD_DISTFILES_SERVER}
2566 fi
2567
2568 if [ "$CVSTAG" ]; then
2569         # pass $CVSTAG used by builder to rpmbuild too, so specs could use it
2570         RPMOPTS="$RPMOPTS --define \"_cvstag $CVSTAG\""
2571 fi
2572
2573 if [ -n "$ALL_BRANCHES" -a -z "$DEPTH" ]; then
2574         echo >&2 "--all branches requires --depth <number>"
2575         Exit_error err_invalid_cmdline
2576 fi
2577
2578 if [ -n "$DEBUG" ]; then
2579         set -x
2580         set -v
2581 fi
2582
2583 if [ -n "$TARGET" ]; then
2584         case "$RPMBUILD" in
2585                 "rpmbuild")
2586                         TARGET_SWITCH="--target $TARGET" ;;
2587                 "rpm")
2588                         TARGET_SWITCH="--target=$TARGET" ;;
2589         esac
2590 fi
2591
2592 if [ "$SCHEDTOOL" != "no" ]; then
2593         NICE_COMMAND="$SCHEDTOOL"
2594 else
2595         NICE_COMMAND="nice -n ${DEF_NICE_LEVEL}"
2596 fi
2597
2598 # see time(1) for output format that could be used
2599 TIME_COMMAND="time -p"
2600
2601 update_shell_title "$COMMAND"
2602 case "$COMMAND" in
2603         "show_bconds")
2604                 init_builder
2605                 if [ -z "$SPECFILE" ]; then
2606                         Exit_error err_no_spec_in_cmdl
2607                 fi
2608                 get_spec > /dev/null
2609                 parse_spec
2610                 set_bconds_values
2611                 display_bconds
2612                 ;;
2613         "show_bcond_args")
2614                 init_builder
2615                 if [ -z "$SPECFILE" ]; then
2616                         Exit_error err_no_spec_in_cmdl
2617                 fi
2618                 get_spec > /dev/null
2619                 parse_spec
2620                 set_bconds_values
2621                 echo "$BCOND"
2622                 ;;
2623         "show_avail_bconds")
2624                 init_builder
2625                 if [ -z "$SPECFILE" ]; then
2626                         Exit_error err_no_spec_in_cmdl
2627                 fi
2628
2629                 get_spec > /dev/null
2630                 parse_spec
2631                 local bcond_avail=$(find_spec_bcond $SPECFILE)
2632                 local opt bcond bconds
2633                 for opt in $bcond_avail; do
2634                         case "$opt" in
2635                         without_*)
2636                                 bcond=${opt#without_}
2637                                 bconds="$bconds $bcond"
2638                                 ;;
2639                         with_*)
2640                                 bcond=${opt#with_}
2641                                 bconds="$bconds $bcond"
2642                                 ;;
2643                         *)
2644                                 echo >&2 "ERROR: unexpected '$opt' in show_avail_bconds"
2645                                 exit 1
2646                                 ;;
2647                         esac
2648                 done
2649                 echo $bconds
2650
2651                 ;;
2652         "build" | "build-binary" | "build-source" | "build-prep" | "build-build" | "build-install" | "build-list")
2653                 init_builder
2654                 if [ -z "$SPECFILE" ]; then
2655                         Exit_error err_no_spec_in_cmdl
2656                 fi
2657
2658                 # display SMP make flags if set
2659                 smp_mflags=$(rpm -E %{?_smp_mflags})
2660                 if [ "$smp_mflags" ]; then
2661                         echo "builder: SMP make flags are set to $smp_mflags"
2662                 fi
2663
2664                 get_spec
2665                 parse_spec
2666                 set_bconds_values
2667                 display_bconds
2668                 display_branches
2669                 if [ "$COMMAND" != "build-source" ]; then
2670                         check_buildarch
2671                 fi
2672                 fetch_build_requires
2673                 if [ "$INTEGER_RELEASE" = "yes" ]; then
2674                         echo "Checking release $PACKAGE_RELEASE..."
2675                         if echo $PACKAGE_RELEASE | grep -q '^[^.]*\.[^.]*$' 2>/dev/null ; then
2676                                 Exit_error err_fract_rel "$PACKAGE_RELEASE"
2677                         fi
2678                 fi
2679
2680                 # ./builder -bs test.spec -r AC-branch -Tp auto-ac- -tt
2681                 if [ -n "$TEST_TAG" ]; then
2682                         local TAGVER=`
2683                         make_tagver`
2684                         tag_exist $TAGVER || [ $TAGVER = $CVSTAG ] || Exit_error err_tag_exists $TAGVER
2685                         # check also tags created in CVS
2686                         local TAGVER_CVS=$(echo $TAGVER | tr '[.@]' '[_#]')
2687                         local CVSTAG_CVS=$(echo $CVSTAG | tr '[.@]' '[_#]')
2688                         tag_exist $TAGVER_CVS || [ $TAGVER_CVS = $CVSTAG_CVS ] \
2689                                 || Exit_error err_tag_exists $TAGVER_CVS
2690                         # - do not allow to build from HEAD when XX-branch exists
2691                         TREE_PREFIX=$(echo "$TAG_PREFIX" | sed -e 's#^auto/\([a-zA-Z]\+\)/.*#\1#g')
2692                         if [ "$TAGVER" != "$CVSTAG" -a "$TAGVER_CVS" != "$CVSTAG" -a  "$TREE_PREFIX" != "$TAG_PREFIX" ]; then
2693                                 TAG_BRANCH="${TREE_PREFIX}-branch"
2694                                 if [ -n "$DEPTH" ]; then
2695                                         cmd_branches="git ls-remote --heads"
2696                                         ref_prefix=refs/heads
2697                                 else
2698                                         cmd_branches="git show-ref"
2699                                         ref_prefix=refs/remotes/${REMOTE_PLD}
2700                                 fi
2701                                 TAG_STATUS=$($cmd_branches | grep -i "${ref_prefix}/$TAG_BRANCH$" | cut -c'-40')
2702                                 if [ -n "$TAG_STATUS" -a "$TAG_STATUS" != $(git rev-parse "$CVSTAG") ]; then
2703                                         Exit_error err_branch_exists "$TAG_STATUS"
2704                                 fi
2705                         fi
2706
2707                 fi
2708
2709                 if [ -n "$NOSOURCE0" ] ; then
2710                         SOURCES=`echo $SOURCES | xargs | sed -e 's/[^ ]*//'`
2711                 fi
2712                 try_upgrade
2713                 case $? in
2714                         0)
2715                                 get_files $SOURCES $PATCHES
2716                                 check_md5 $SOURCES $PATCHES
2717                                 ;;
2718                         *)
2719                                 NODIST="yes" get_files $SOURCES $PATCHES
2720                                 update_md5 $SOURCES $PATCHES
2721                                 ;;
2722                 esac
2723                 build_package
2724                 if [ "$UPDATE_POLDEK_INDEXES" = "yes" ] && [ "$COMMAND" = "build" -o "$COMMAND" = "build-binary" ]; then
2725                         run_poldek --sdir="${POLDEK_INDEX_DIR}" ${UPDATE_POLDEK_INDEXES_OPTS} --mkidxz
2726                 fi
2727                 remove_build_requires
2728                 ;;
2729         "branch" )
2730                 init_builder
2731                 if [ -z "$SPECFILE" ]; then
2732                         Exit_error err_no_spec_in_cmdl
2733                 fi
2734
2735                 get_spec
2736                 parse_spec
2737                 branch_files $TAG
2738                 ;;
2739         "add_cvs" )
2740                 init_builder
2741                 if [ -z "$SPECFILE" ]; then
2742                         Exit_error err_no_spec_in_cmdl
2743                 fi
2744
2745                 create_git_repo
2746                 if [ -n "$NEW_REPO" ]; then
2747                         parse_spec
2748                         local file
2749                         for file in $SOURCES $PATCHES; do
2750                                 if [ -z $(src_md5 "$file") ]; then
2751                                         git add $file || Exit_error err_no_source_in_repo $file
2752                                 else
2753                                         cvsignore_df `nourl $file`
2754                                 fi
2755                         done
2756                         git add $SPECFILE
2757                         echo "When you are ready commit your changes and run git push origin master"
2758                 else
2759                         echo "You had already git repository. Push chosen branches to remote: ${REMOTE_PLD}"
2760                 fi
2761                 ;;
2762         "get" )
2763                 init_builder
2764                 if [ -z "$SPECFILE" ]; then
2765                         Exit_error err_no_spec_in_cmdl
2766                 fi
2767
2768                 get_spec
2769                 parse_spec
2770
2771                 if [ -n "$NOSOURCE0" ] ; then
2772                         SOURCES=`echo $SOURCES | xargs | sed -e 's/[^ ]*//'`
2773                 fi
2774                 get_files $SOURCES $PATCHES
2775                 check_md5 $SOURCES
2776                 fetch_build_requires
2777                 ;;
2778         "update_md5" )
2779                 init_builder
2780                 if [ -z "$SPECFILE" ]; then
2781                         Exit_error err_no_spec_in_cmdl
2782                 fi
2783
2784                 get_spec
2785                 parse_spec
2786
2787                 if [ -n "$NOSOURCE0" ] ; then
2788                         SOURCES=`echo $SOURCES | xargs | sed -e 's/[^ ]*//'`
2789                 fi
2790                 update_md5 $SOURCES $PATCHES
2791                 ;;
2792         "tag" )
2793                 NOURLS=1
2794                 NODIST="yes"
2795                 init_builder
2796                 if [ -z "$SPECFILE" ]; then
2797                         Exit_error err_no_spec_in_cmdl
2798                 fi
2799
2800                 parse_spec
2801                 if  [ ! -d .git ]; then
2802                         echo "No git reposiotory" >&2
2803                         exit 101
2804                 fi
2805                 tag_files
2806                 ;;
2807         "mr-proper" )
2808                 mr_proper
2809                 ;;
2810         "list-sources-files" )
2811                 init_builder
2812                 NOCVSSPEC="yes"
2813                 DONT_PRINT_REVISION="yes"
2814                 get_spec
2815                 parse_spec
2816                 for SAP in $SOURCES $PATCHES; do
2817                         echo $SAP | awk '{gsub(/.*\//,"") ; print}'
2818                 done
2819                 ;;
2820         "list-sources-urls" )
2821                 init_builder >&2
2822                 NOCVSSPEC="yes"
2823                 DONT_PRINT_REVISION="yes"
2824                 get_spec >&2
2825                 parse_spec >&2
2826                 SAPS="$SOURCES $PATCHES"
2827                 for SAP in $SAPS; do
2828                         echo $SAP
2829                 done
2830                 ;;
2831         "list-sources-local-paths" )
2832                 init_builder
2833                 NOCVSSPEC="yes"
2834                 DONT_PRINT_REVISION="yes"
2835                 get_spec
2836                 parse_spec
2837                 for SAP in $SOURCES $PATCHES; do
2838                         echo $PACKAGE_DIR/$(echo $SAP | awk '{gsub(/.*\//,"") ; print }')
2839                 done
2840                 ;;
2841         "list-sources-distfiles-paths" )
2842                 init_builder
2843                 NOCVSSPEC="yes"
2844                 DONT_PRINT_REVISION="yes"
2845                 get_spec
2846                 parse_spec
2847                 for SAP in $SOURCES $PATCHES; do
2848                         if [ -n "$(src_md5 "$SAP")" ]; then
2849                                 distfiles_path "$SAP"
2850                         fi
2851                 done
2852                 ;;
2853         "list-sources-distfiles" )
2854                 init_builder
2855                 NOCVSSPEC="yes"
2856                 DONT_PRINT_REVISION="yes"
2857                 get_spec
2858                 parse_spec
2859                 for SAP in $SOURCES $PATCHES; do
2860                         if [ -n "$(src_md5 "$SAP")" ]; then
2861                                 distfiles_url "$SAP"
2862                         fi
2863                 done
2864                 ;;
2865         "list-sources-cvs" )
2866                 init_builder
2867 #               NOCVSSPEC="yes"
2868                 DONT_PRINT_REVISION="yes"
2869                 get_spec
2870                 parse_spec
2871                 for SAP in $SOURCES $PATCHES; do
2872                         if [ -z "$(src_md5 "$SAP")" ]; then
2873                                 echo $SAP | awk '{gsub(/.*\//,"") ; print}'
2874                         fi
2875                 done
2876                 ;;
2877         "init_rpm_dir")
2878                 init_rpm_dir
2879                 ;;
2880         "usage" )
2881                 usage
2882                 ;;
2883         "short-version" )
2884                 echo "$VERSION"
2885                 ;;
2886         "version" )
2887                 echo "$VERSIONSTRING"
2888                 ;;
2889         "list_pkgrev" )
2890                 init_builder
2891                 if [ -z "$SPECFILE" ]; then
2892                         Exit_error err_no_spec_in_cmdl
2893                 fi
2894                 get_spec > /dev/null
2895                 parse_spec
2896                 list_pkgrev
2897                 ;;
2898 esac
2899 if [ -f "`pwd`/.${SPECFILE}_INSTALLED_PACKAGES" -a "$REMOVE_BUILD_REQUIRES" != "" ]; then
2900         rm "`pwd`/.${SPECFILE}_INSTALLED_PACKAGES"
2901 fi
2902 cd "$__PWD"
2903
2904 # vi:syntax=sh:ts=4:sw=4:noet