#!/bin/bash # rpmdev-newspec -- generate new rpm .spec file from template # # Copyright (c) Warren Togami , # Ville Skyttä # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA SPECDIR=/etc/rpmdevtools DEFTYPE=minimal DEFSPEC=newpackage.spec CONFIG=/etc/rpmdevtools/newspec.conf # Don't load config at rpm build time so it won't affect the man page if [[ -z $RPM_BUILD_ROOT && -f $CONFIG ]] ; then . "$CONFIG" fi version() { cat <, Ville Skyttä This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. EOF } help() { cat <, component rpmdevtools," echo "or at ." } usage() { # Don't emit available types at build time to avoid them from being # embedded in the man page. types= if [[ -z $RPM_BUILD_ROOT ]] ; then indent=" " types=$(ls $SPECDIR/spectemplate-*.spec 2>/dev/null | \ sed 's,.*spectemplate-,,;s,\.spec$,,' | tr '\n' ' ' | \ fmt -w 60 | sed "s/^/$indent/") [[ -z $types ]] && types="${indent}None ($SPECDIR/spectemplate-*.spec)" fi cat <, or "$DEFSPEC" if is not given. -t TYPE, --type TYPE Force use of the TYPE spec template. The default is guessed from , falling back to "$DEFTYPE" if the guesswork does not result in a more specific one or if is not given.${types:+ Available types: $types} -m, --macros Emit templates using macros instead of shell style variables. Configuration variable: NEWSPEC_PREFER_MACROS, default is off. -r VERSION, --rpm-version VERSION Filter out some spec file constructs not needed by the specified rpm(build) version and newer ones. Configuration variable: NEWSPEC_MIN_RPMVER, default is system rpm version. -h, --help Show this usage message and exit. -v, --version Print version information and exit. Files: $SPECDIR Directory for specfile templates. $CONFIG System wide configuration. EOF } appname= specfile= spectype= specfile_set= while [[ $1 ]] ; do case $1 in -t|--type) shift spectype="$1" ;; -o|--output) shift specfile="$1" specfile_set=1 case $specfile in *.spec) [[ -z $appname ]] && appname="$(basename $1 .spec)" ;; esac ;; -m|--macros) NEWSPEC_PREFER_MACROS=1 ;; -r|--rpm-version) shift NEWSPEC_MIN_RPMVER="$1" ;; -h|--help) help exit 0 ;; -v|--version) version exit 0 ;; *.spec) [[ -z $specfile ]] && specfile="$1" appname="$(basename $1 .spec)" ;; *) appname="$1" [[ -z $specfile ]] && specfile="$appname.spec" ;; esac shift done rpmmaj=4 rpmmin=4 rpmver="${NEWSPEC_MIN_RPMVER:-$RPMVER}" # RPMVER: 2.0 backwards compat [[ $rpmver ]] || rpmver=$(rpm --version 2>/dev/null) if [[ $rpmver =~ (^|.* )([0-9]{1,})(\.([0-9]{1,}))? ]] ; then rpmmaj=${BASH_REMATCH[2]} rpmmin=${BASH_REMATCH[4]:-0} else echo "Unrecognized rpm version '$rpmver', using $rpmmaj.$rpmmin" \ > /dev/stderr fi # major * 10000 + minor * 100 ( + micro perhaps later ) rpmver=$(( $rpmmaj * 10000 + $rpmmin * 100 )) specfilter= if [[ -z $spectype ]] ; then case $appname in ocaml-*) spectype="${appname%%-*}" libname="${appname##ocaml-}" specfilter=" s/^%define\\s+libname\\s[^\\n]*\\n//Mg s/%\\{libname}/$libname/g " ;; perl-*) spectype="${appname%%-*}" cpandist="${appname##perl-}" specfilter=" s/^%setup.*/%setup -q -n $cpandist-%{version}/Mg s|^(URL:[ \\t]*)[^\\n]*|\\1http://search.cpan.org/dist/$cpandist/|IMg " ;; php-pear-*) spectype=php-pear ;; [Pp]y*) spectype=python ;; R-*) spectype="${appname%%-*}" packname="${appname##R-}" specfilter=" s/^%define\\s+packname\\s[^\\n]*\\n//Mg s/%\\{packname}/$packname/g " ;; ruby-*) spectype="${appname%%-*}" ;; lib*|*-lib|*-libs) spectype=lib ;; *-fonts|*-fonts-simple) spectype=fonts-simple appname="${appname%%-simple}" specfilter="s//${appname%%-fonts}/g" [[ $specfile_set ]] || specfile="$appname.spec" ;; *-fonts-multi) spectype=fonts-multi appname="${appname%%-multi}" specfilter="s//${appname%%-fonts}/g" [[ $specfile_set ]] || specfile="$appname.spec" ;; *) spectype=$DEFTYPE ;; esac fi tempspec="$SPECDIR/spectemplate-$spectype.spec" if [[ ! -f $tempspec ]] ; then echo "Template \"$tempspec\" not found, exiting." exit 1 fi [[ -z $specfile ]] && specfile="$DEFSPEC" if [[ -f $specfile ]] ; then echo "Output file \"$specfile\" already exists, exiting." exit 2 elif [[ $specfile == - ]] ; then specfile=/dev/stdout fi # If enabling more versions, remember to update bash completion too. if [[ $rpmver -ge 40400 ]] ; then # >= 4.4 # filter %defattr(-,root,root(,-)) immediately after %files specfilter+=" s/^(%files\\b[^\\n]*\\n)%defattr[ \\t]*\\([ \\t]*-[ \\t]*,[ \\t]*root[ \\t]*,[ \\t]*root([ \\t]*,[ \\t]*-[ \\t]*)?\\)[^\\n]*\\n/\\1/Mg " fi if [[ $rpmver -ge 40600 ]] ; then # >= 4.6 # filter BuildRoot and Group tags specfilter+=" s/^(BuildRoot|Group)[ \\t]*:[^\\n]*\\n//IMg " fi if [[ $rpmver -ge 40800 ]] ; then # >= 4.8 # filter unnecessary basic %clean section, up to next section specfilter+=" s|^%clean\\s*((/bin/)?rm\\|%\\{?__rm\\}?)[ \\t]+-[rRf]+[ \\t]+\\\$RPM_BUILD_ROOT\\s{2,}^%|%|Mg " # use %make_install instead of make install DESTDIR=... specfilter+=" s|^make install DESTDIR=\\\$RPM_BUILD_ROOT|%make_install|Mg " fi if [[ $NEWSPEC_PREFER_MACROS ]] ; then # This assumes templates are written using the shell style variables, # without surrounding curly braces. specfilter+=" s/\\\$RPM_SOURCE_DIR\\b/%{_sourcedir}/g s/\\\$RPM_BUILD_DIR\\b/%{_builddir}/g s/\\\$RPM_OPT_FLAGS\\b/%{optflags}/g s/\\\$RPM_ARCH\\b/%{_arch}/g s/\\\$RPM_OS\\b/%{_os}/g s/\\\$RPM_DOC_DIR\\b/%{_docdir}/g s/\\\$RPM_PACKAGE_NAME\\b/%{name}/g s/\\\$RPM_PACKAGE_VERSION\\b/%{version}/g s/\\\$RPM_PACKAGE_RELEASE\\b/%{release}/g s/\\\$RPM_BUILD_ROOT\\b/%{buildroot}/g " fi cat "$tempspec" | sed -rne " 1h 1!H $ { g s/^(Name:[ \\t]*)[^\\n]*/\\1$appname/IMg $specfilter p }" > "$specfile" if [[ $specfile != /dev/stdout ]] ; then echo "$specfile created; type $spectype, rpm version >= $rpmmaj.$rpmmin." fi