Skip to content

Instantly share code, notes, and snippets.

@devxom
Created August 8, 2016 17:08
Show Gist options
  • Save devxom/5cf8e0c3c086b139c1152b459c8715f7 to your computer and use it in GitHub Desktop.
Save devxom/5cf8e0c3c086b139c1152b459c8715f7 to your computer and use it in GitHub Desktop.
Unpack an rpm into a build dir #fedora #centos #rpm
#!/bin/bash
# $Id: unrpm 4036 2010-04-13 23:16:41Z agriffis $
#
# unrpm: unpack an rpm into a build dir
#
# Copyright 2007 Aron Griffis <[email protected]>
# Released under the GNU General Public License v2
#
main() {
declare cmd=${0##*/}
declare dum version
read dum version dum <<<'$Revision: 4036 $'
case $cmd in
unrpm|rpmbuild) true ;;
*) die "unrpm: I don't know how to be $cmd" ;;
esac
$cmd "$@"
exit $?
}
unrpm() {
declare args usage
read -d '' usage <<EOT
usage: unrpm pkg-1.0.src.rpm...
-f --force Unpack into an existing dir
-l --list List contents rather than unpack
-p --prep Prep sources after unpack
-v --verbose Be louder
--help Show this help message
--version Show version information
EOT
# Use /usr/bin/getopt which supports GNU-style long options
declare opt_force=false
declare opt_list=false
declare opt_prep=false
declare opt_verbose=false
args=$(getopt -n "$0" \
-o flpv --long force,help,list,prep,verbose,version -- "$@") || exit
eval set -- "$args"
while true; do
case $1 in
-f|--force) opt_force=true ; shift ;;
-l|--list) opt_list=true ; shift ;;
-p|--prep) opt_prep=true ; shift ;;
-v|--verbose) opt_verbose=true ; shift ;;
--help) echo "$usage"; exit 0 ;;
--version) echo "$cmd $version"; exit 0 ;;
--) shift; break ;;
*) die "failed to process cmdline args" ;;
esac
done
if [[ -z $1 ]]; then
die "missing argument, try --help"
elif [[ ! -r $1 ]]; then
die "can't read: $1"
fi
set -e
declare dirs rpm repo v
$opt_verbose && v=v ||:
for rpm in "$@"; do
repo=$(rpm -qp --qf '%{N}-%{V}-%{R}' "$rpm")
dirs=( "$repo/"{BUILD,RPMS,SOURCES,SPECS,SRPMS} )
if $opt_list; then
rpm2cpio $rpm | cpio --quiet -it$v | \
sed "s|^[./]*/*|$repo/SOURCES/|;/\\.spec/s/SOURCES/SPECS/"
continue
fi
if $opt_force; then
mkdir -p$v "${dirs[@]}"
else
mkdir ${v:+-v} $repo "${dirs[@]}"
fi
rm -f$v $repo/SOURCES/* $repo/SPECS/*
rpm2cpio $rpm | ( cd $repo/SOURCES; cpio --quiet -imd$v; )
mv ${v:+-v} $repo/SOURCES/*.spec $repo/SPECS
if $opt_prep; then
rpmbuild -bp $repo/SPECS/*.spec
fi
done
}
echo() {
printf '%s\n' "$*"
}
die() {
declare status=1
if [[ $1 == ?* && $1 != *[!0-9]* ]]; then
status=$1
shift
fi
echo "$cmd: ${*:-error}" >&2
exit $status
}
rpmbuild() {
declare x topdir
for x; do
if [[ $x == *.spec ]]; then
topdir=$(cd $(dirname $x)/..; pwd)
break
elif [[ $1 == -t* ]]; then
case $x in
*.tar.gz|*.tar.bz2) topdir=${x%.*.*}; break ;;
*.tgz|*.tbz2) topdir=${x%.*}; break ;;
esac
fi
done
set -e
declare cmd status=0
# it sucks when rpmbuild bombs because of missing dirs
[[ -z $topdir ]] || topdir=$(readlink -f $topdir)
[[ -z $topdir ]] || mkdir -p "$topdir/"{SPECS,SOURCES,BUILD,RPMS,SRPMS}
# can't use simple "wrapped $0" because we might have been called as unrpm
cmd=(
"$(wrapped "$(dirname "$(type -P "$0")")"/rpmbuild)"
${topdir:+--define="_topdir $topdir"}
"$@"
)
printf "%q " "${cmd[@]}"; echo
# log rpmbuild output
[[ -z $topdir ]] || exec 3>&1 4>&2 1> >(tee $topdir/rpmbuild-$$.out) 2>&1
"${cmd[@]}" || status=$?
[[ -z $topdir ]] || exec 1>&3- 2>&4-
set +e
return $status
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment