Project

General

Profile

Download (10.4 KB) Statistics
| Branch: | Tag: | Revision:
#!/bin/bash
#
# Copyright 2013 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public License,
# version 2 (GPLv2). There is NO WARRANTY for this software, express or
# implied, including the implied warranties of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
# along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
#
# Red Hat trademarks are not licensed under GPLv2. No permission is
# granted to use or replicate Red Hat trademarks that are incorporated
# in this software or its documentation.
#
# Builds an rpm out of command line options
#
# $Id$

PATH=$PATH:/usr/bin

NAME=useless
EPOCH=
VERSION=1.0.0
RELEASE=1
ARCH=noarch
GROUP="Applications/System"
SUMMARY="Dummy package"
DESCRIPTION="The package description"
PACKAGER="(none)"
VENDOR="(none)"

usage() {
echo "Usage:"
echo "$0 [OPTIONS] [FILES]"
echo "Builds an rpm from the specified command line options, optionally"
echo "including files"
echo
echo " OPTIONS:"
echo " --help display usage and exit"
echo " --name use this name for the rpm [$NAME]"
echo " --epoch use this epoch [default is null]"
echo " --version use this version [$VERSION]"
echo " --release use this release [$RELEASE]"
echo " --arch build the package for this arch [$ARCH]"
echo " --group group this package belongs [$GROUP]"
echo " --packager packager [$PACKAGER]"
echo " --vendor vendor [$VENDOR]"
echo " --summary package summary"
echo " --description package description"
echo " --requires make the generated rpm require this"
echo " --provides make the generated rpm provide this"
echo " --conflicts make the generated rpm conflict with this"
echo " --obsoletes make the generated rpm obsolete with this"
echo " --buildreq make the generated source rpm require this to build"
echo " --post path to a postinstall script"
echo " --pre path to a preinstall script"
echo " --postun path to a post-uninstall script"
echo " --preun path to a pre-uninstall script"
echo
echo " FILES: <file-spec>*"
echo " <file-spec> ::== <dest-path>[:mode]=<source-path>"
echo " adds <source-path> in the RPM package, at <dest-path>"
echo " NOTE: <dest-path> has to be a filename"
echo
echo "Example:"
echo " $0 --name useless --version 0.99 --release 1 /var/foo=/var/log/messages"
exit $1
}

ensure_file_exists() {
file=$1
sectname=$2

if [ "$file" -a ! -s "$file" ]; then
echo "Cannot read $sectname section from $file"
exit -1
fi

}

# Generates the post/pre/postun/preun sections
generate_section() {
file=$1
sectname=$2
if [ "$file" ]; then
echo "%$sectname"
cat $file
echo
fi
}

# Builds the requires/provides/conflicts/obsoletes
generate_depend_section() {
sectname=$1
shift
while [ "$1" ]; do
val=$1
shift
echo "$sectname: $val"
done | sort | uniq
}

# Array we use for grabbing the files
declare -a PARAMS
declare -a REQUIRES
declare -a PROVIDES
declare -a CONFLICTS
declare -a OBSOLETES
declare -a BUILDREQS

POST=""
PRE=""
POSTUN=""
PREUN=""

while true; do
case "$1" in
--help)
usage 0
;;
--name)
case "$2" in
"") echo "No parameter specified for --name"; break;;
*) NAME=$2; shift 2;;
esac;;
--epoch)
case "$2" in
"") echo "No parameter specified for --epoch"; break;;
*) EPOCH=$2; shift 2;;
esac;;
--version)
case "$2" in
"") echo "No parameter specified for --version"; break;;
*) VERSION=$2; shift 2;;
esac;;
--release)
case "$2" in
"") echo "No parameter specified for --release"; break;;
*) RELEASE=$2; shift 2;;
esac;;
--arch)
case "$2" in
"") echo "No parameter specified for --arch"; break;;
*) ARCH=$2; shift 2;;
esac;;
--group)
case "$2" in
"") echo "No parameter specified for --group"; break;;
*) GROUP=$2; shift 2;;
esac;;
--summary)
case "$2" in
"") echo "No parameter specified for --summary"; break;;
*) SUMMARY=$2; shift 2;;
esac;;
--description)
case "$2" in
"") echo "No parameter specified for --description"; break;;
*) DESCRIPTION=$2; shift 2;;
esac;;
--packager)
case "$2" in
"") echo "No parameter specified for --packager"; break;;
*) PACKAGER=$2; shift 2;;
esac;;
--vendor)
case "$2" in
"") echo "No parameter specified for --vendor"; break;;
*) VENDOR=$2; shift 2;;
esac;;
--post)
case "$2" in
"") echo "No parameter specified for --post"; break;;
*) POST=$2; shift 2;;
esac;;
--pre)
case "$2" in
"") echo "No parameter specified for --pre"; break;;
*) PRE=$2; shift 2;;
esac;;
--postun)
case "$2" in
"") echo "No parameter specified for --postun"; break;;
*) POSTUN=$2; shift 2;;
esac;;
--preun)
case "$2" in
"") echo "No parameter specified for --preun"; break;;
*) PREUN=$2; shift 2;;
esac;;
--requires)
case "$2" in
"") echo "No parameter specified for --requires"; break;;
*) REQUIRES[${#REQUIRES[*]}]=$2; shift 2;;
esac;;
--provides)
case "$2" in
"") echo "No parameter specified for --provides"; break;;
*) PROVIDES[${#PROVIDES[*]}]=$2; shift 2;;
esac;;
--conflicts)
case "$2" in
"") echo "No parameter specified for --conflicts"; break;;
*) CONFLICTS[${#CONFLICTS[*]}]=$2; shift 2;;
esac;;
--obsoletes)
case "$2" in
"") echo "No parameter specified for --obsoletes"; break;;
*) OBSOLETES[${#OBSOLETES[*]}]=$2; shift 2;;
esac;;
--buildreq)
case "$2" in
"") echo "No parameter specified for --buildreq"; break;;
*) BUILDREQ[${#BUILDREQ[*]}]=$2; shift 2;;
esac;;
"") break;;
*)
ftwo=`echo $1 | (read -n 2 foo; echo $foo)`
if [ $ftwo == '--' ]; then
echo "Unknown option $1"
usage 1
fi
PARAMS[${#PARAMS[*]}]=$1
shift
esac
done

ensure_file_exists "$PRE" "pre"
ensure_file_exists "$POST" "post"
ensure_file_exists "$PREUN" "preun"
ensure_file_exists "$POSTUN" "postun"

# End of the command-line processing stage

RPM_BUILD_DIR=/tmp/$NAME-$VERSION-build
DIRNAME=$NAME-$VERSION
TARBALL=$NAME-$VERSION.tar.gz

echo "Building $NAME-$VERSION-$RELEASE.$ARCH.rpm"

rm -rf $RPM_BUILD_DIR
install --verbose -d $RPM_BUILD_DIR/$DIRNAME

# Prepare the tar file
i=0
while [ $i -lt ${#PARAMS[*]} ]; do
echo ${PARAMS[$i]} | (
IFS== read dstmod src
echo ${dstmod} | (IFS=: read dst mod
echo "${src} -> ${RPM_BUILD_DIR}/${DIRNAME}/${dst}"
mkdir --parents --verbose ${RPM_BUILD_DIR}/${DIRNAME}/`dirname "${dst}"`; cp ${src} ${RPM_BUILD_DIR}/${DIRNAME}/${dst}
)
)
i=$[$i+1]
done

# Build the install section
installsect=`i=0
while [ $i -lt ${#PARAMS[*]} ]; do
echo ${PARAMS[$i]} | (
IFS== read dstmod src
echo ${dstmod} | (IFS=: read dst mod
echo "install --verbose -d \\\$RPM_BUILD_ROOT\`dirname ${dst}\`"
echo "install --verbose .${dst} \\\$RPM_BUILD_ROOT${dst}")
)
i=$[$i+1]
done | sort | uniq | while read line; do echo -n "$line\n"; done`

# Build the file section
filesect=`i=0
while [ $i -lt ${#PARAMS[*]} ]; do
echo ${PARAMS[$i]} | (
IFS== read dstmod src
echo ${dstmod} | (IFS=: read dst mod
# Now split mod into the actual mode, the user and the group
# Default to 0644,-,-
# NOTE there's already a %defattr(-,root,root), so if there's no u
# or g defined, set it to '-' by default
echo $mod | (IFS=, read m u g
echo "%attr(${m:-0644},${u:--},${g:--}) ${dst}"
)
)
)
i=$[$i+1]
done | sort | uniq | while read line; do echo -n "$line\n"; done`

cat > $RPM_BUILD_DIR/$DIRNAME/$NAME.spec << EOF
Name: $NAME
$(if [ -n "$EPOCH" ]; then echo "Epoch: $EPOCH"; fi)
Version: $VERSION
Release: $RELEASE
Group: $GROUP
License: GPL
BuildArch: $ARCH
Source: %{name}-%{version}.tar.gz
BuildRoot: /var/tmp/%{name}-%{version}-root
Summary: $SUMMARY
Packager: $PACKAGER
Vendor: $VENDOR
`generate_depend_section Requires "${REQUIRES[@]}"`
`generate_depend_section Provides "${PROVIDES[@]}"`
`generate_depend_section Conflicts "${CONFLICTS[@]}"`
`generate_depend_section Obsoletes "${OBSOLETES[@]}"`
`generate_depend_section BuildRequires "${BUILDREQ[@]}"`

%description
`echo -e $DESCRIPTION`

%prep
%setup

%build

%install
rm -rf \$RPM_BUILD_ROOT
install -d \$RPM_BUILD_ROOT
`echo -e $installsect`

%clean
rm -rf \$RPM_BUILD_ROOT

`generate_section "$POST" post`
`generate_section "$PRE" pre`
`generate_section "$POSTUN" postun`
`generate_section "$PREUN" preun`

%files
`echo -e $filesect`
EOF

# Build the tarball
(cd $RPM_BUILD_DIR; tar cf - $DIRNAME | gzip -c > $RPM_BUILD_DIR/$TARBALL)
rm -rf $RPM_BUILD_DIR/$DIRNAME

# Build the rpm from that tarball
RPMOPTS="--define \"_topdir $RPM_BUILD_DIR\"\
--define '_builddir %{_topdir}'\
--define '_sourcedir %{_topdir}'\
--define '_specdir %{_topdir}'\
--define '_rpmdir %{_topdir}'\
--define '_srcrpmdir %{_topdir}'\
--define '_source_payload nil'\
--define '_binary_payload nil'"

eval "rpmbuild -ta $RPMOPTS --clean $RPM_BUILD_DIR/$TARBALL" || exit 1

mv $RPM_BUILD_DIR/$ARCH/$NAME-$VERSION-$RELEASE.$ARCH.rpm .
mv $RPM_BUILD_DIR/$NAME-$VERSION-$RELEASE.src.rpm .
rm -rf $RPM_BUILD_DIR
(4-4/9)