Skip to content
Permalink
87dd847b52
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
510 lines (422 sloc) 14.5 KB
#!/bin/bash
#
# bee-install - install a bee-pkg
#
# Copyright (C) 2009-2012
# Marius Tolzmann <tolzmann@molgen.mpg.de>
# Tobias Dreyer <dreyer@molgen.mpg.de>
# and other bee developers
#
# This file is part of bee.
#
# bee 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 3 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, see <http://www.gnu.org/licenses/>.
#
if [ -z "${BEE_VERSION}" ] ; then
echo >&2 "BEE-ERROR: please call $0 from bee .."
exit 1
fi
VERSION=${BEE_VERSION}
: ${BEE_BINDIR:=@BINDIR@}
function debug_msg() {
if [ "${OPT_DEBUG}" != "1" ] ; then
return
fi
info=( $(caller 0) )
echo "${info[2]}:${info[1]}:${info[0]}: ${@}" >&2
}
function start_cmd() {
debug_msg "executing '${@}'"
if [ "${OPT_NOOP}" = "no" ] ; then
"${@}"
fi
}
function assert() {
if [ ! "${@}" ] ; then
local info=( $(caller 0) )
echo "${info[2]}:${info[1]}:${info[0]}: Assertion [ ${@} ] failed. exiting.." >&2
exit 250
fi
}
##### usage ###################################################################
function usage() {
cat <<-EOF
bee-install v${VERSION} 2009-2012
by Marius Tolzmann and Tobias Dreyer <{tolzmann,dreyer}@molgen.mpg.de>
Max Planck Institute for Molecular Genetics Berlin Dahlem
Usage: bee install [options] <package>
Usage: bee update [options] <package>
'bee update' is short form of 'bee install --update'
Options:
-f, --force can be used to force installation come what may
-v, --verbose bee more verbose (can be used twice e.g. -vv)
-u, --update,
--upgrade install a package and remove old version afterwards
-r, --remove-all when updating: remove all old versions of the package
-n, --noop do not install; just print what would be installed
-h, --help display this help
EOF
}
###############################################################################
##
##
function pkg_install_all() {
for pkg in "${@}" ; do
pkg_install "${pkg}"
done
}
function begins_with() {
string=${1}
substring=${2}
length=${#substring}
if [ ${#substring} -gt ${#string} ] ; then
return 1
fi
if [ "${string:0:${length}}" = "${substring}" ] ; then
return 0
fi
return 1
}
###############################################################################
### pkg_install ###
##
## IN: search-pattern
##
## OUT: ...
##
## DESCRIPTION: ...
##
function pkg_install() {
search=${1}
assert "x${search}" != "x"
# install specific package
if [ -f "${search}" ] ; then
if beeversion "${search}" >/dev/null 2>&1 ; then
do_install "${search}"
return
fi
if [[ "${search}" =~ "/" ]] ; then
echo >&2 "bee-install: ${search}:" \
"Invalid package name. Aborting."
return
fi
echo >&2 "bee-install: ${search}:" \
"Invalid package name. Skipping local file. Continuing."
elif [[ "${search}" =~ "/" ]] ; then
echo >&2 "bee-install: ${search}: No such file or directory."
return
fi
# install package from repository
if [ -f "${BEE_PKGDIR}/${search}" ] ; then
do_install "${BEE_PKGDIR}/${search}"
return
fi
# pkg not found yet - lets search a little deeper
available=( $(${BEE_LIBEXECDIR}/bee/bee.d/bee-list --available "${search}") )
if [ ${#available[@]} -eq 0 ] ; then
echo >&2 "bee-install: ${search}: No packages available matching your query."
return
fi
sfullname=$(${BEE_BINDIR}/beeversion --pkgfullname ${search%%-} 2>/dev/null)
availpkgs=()
fullname=
for i in ${available[@]} ; do
f=$(${BEE_BINDIR}/beeversion --pkgfullname ${i})
availpkgs=( ${availpkgs[@]} ${f} )
if [ "${f}" = "${search%%-}" -o "${f}" = "${sfullname}" ] ; then
fullname=${f}
break
fi
done
availpkgs=( $(${BEE_BINDIR}/beeuniq ${availpkgs[@]}) )
if [ -z "${fullname}" -a ${#availpkgs[@]} -gt 1 ] ; then
echo >&2 "bee-install: Your query (${search}) is ambiguous. Available packages matching your query:"
for i in $(${BEE_BINDIR}/beeuniq ${availpkgs[@]}) ; do
echo >&2 " ${i}"
done
return
fi
if [ -z "${fullname}" ] ; then
echo >&2 "bee-install: Your query (${search}) is too loose (fullpackagename needed). Did you mean: "
echo >&2 " bee install ${availpkgs}"
return
fi
available=( $(${BEE_LIBEXECDIR}/bee/bee.d/bee-list --available --exact "${fullname}" | grep ${search}) )
maxavail=$(${BEE_BINDIR}/beeversion -max ${available[@]})
fileavail=( $(${BEE_LIBEXECDIR}/bee/bee.d/bee-list --available --exact --display-pathname ${maxavail}) )
assert "${#fileavail[@]}" = 1
do_install "${fileavail}"
return
}
function do_remove() {
for p in "${@}" ; do
if [ "${OPT_NOOP}" = "yes" ] ; then
echo "REMOVE ${p}"
continue
fi
${BEE_LIBEXECDIR}/bee/bee.d/bee-remove ${p}
done
}
###############################################################################
### do_install ###
##
## IN: filename
##
## OUT: n/a
##
## DESCRIPTION:
## - installs package
##
function do_install() {
local file=${1}
assert "x${file}" != "x"
local pkg=$(${BEE_BINDIR}/beeversion --format="%A" ${file} 2>/dev/null)
local fullname=$(${BEE_BINDIR}/beeversion --pkgfullname ${file} 2>/dev/null)
local maxinst=
local maxall=${pkg}
if [ "y${pkg}" = "y" ] ; then
echo >&2 "bee-install: ${file}: Invalid input file. Skipping."
return 1
fi
assert "z${fullname}" != "z"
debug_msg "do_install file=${file}"
debug_msg "do_install pkg=${pkg}"
installed=( $(${BEE_LIBEXECDIR}/bee/bee.d/bee-list --installed --exact "${fullname}" | grep -v "${pkg}") )
isinstalled=( $(${BEE_LIBEXECDIR}/bee/bee.d/bee-list --installed --exact "${pkg}") )
assert ${#isinstalled[@]} -le 1
if [ -n "${installed}" -o -n "${isinstalled}" ] ; then
maxinst=$(${BEE_BINDIR}/beeversion -max ${installed[@]} ${isinstalled})
maxall=$(${BEE_BINDIR}/beeversion -max ${pkg} ${maxinst})
fi
debug_msg "installed[@]=${installed[@]}"
debug_msg "isinstalled[@]=${isinstalled[@]}"
debug_msg "maxinst=${maxinst}"
debug_msg "maxall=${maxall}"
# no version of this package is already installed?
if [ -z "${maxinst}" ] ; then
debug_msg "==> INSTALL NEW ${pkg}"
do_install_file ${file}
return
fi
# !--update and --force => just install it..
if [ "${OPT_FORCE}" = "yes" -a "${OPT_UPDATE}" = "no" ] ; then
debug_msg "==> INSTALL FORCE ${pkg}"
do_install_file ${file}
return
fi
if [ -n "${isinstalled}" ] ; then
if [ "${OPT_FORCE}" = "no" ] ; then
echo >&2 "Installation of ${pkg} failed: ${pkg} is already installed"
echo >&2 " use bee install --force (-f) to force reinstallation."
if [ ${#installed[@]} -eq 1 ] ; then
echo >&2 " use bee update --force (-f) to update and to remove other versions."
elif [ ${#installed[@]} -gt 1 ] ; then
echo >&2 " use bee update --force --remove-all (-f -r) to update and to remove all other versions."
fi
return
fi
fi
# isinstalled XNOR force
# multiple alternative versions of this pkg are installed
# warn --update --remove-all => install and remove all alternatives
# warn --force !--update => just install it.. (handled above)
if [ ${#installed[@]} -gt 1 ] ; then
debug_msg "more than one (excluding this) package already installed.."
if [ "${OPT_UPDATE}" = "yes" -a "${OPT_REMOVEALL}" = "no" ] ; then
echo >&2 "Installation of ${pkg} failed: multiple versions are installed."
echo >&2 " use bee update --remove-all (-r) to update and to remove all other versions."
echo >&2 " use bee install --force to (re)install without removing."
return
fi
fi
if [ "${maxinst}" = "${pkg}" ] ; then
# isinstalled && force && update
assert -n "${isinstalled}" -a "${OPT_FORCE}" = "yes" -a "${OPT_UPDATE}" = "yes"
# ${#installed[@]} -gt 1 => update && removeall
debug_msg "REINSTALL UPDATE ${file}"
do_install_file ${file}
do_remove "${installed[@]}"
return
fi
if [ "${maxall}" = "${pkg}" ] ; then
if [ "${OPT_UPDATE}" = "no" ] ; then
echo >&2 "Installation of ${pkg} failed: ${maxinst} is already installed."
echo >&2 " use bee update to update to ${pkg}."
echo >&2 " use bee install --force (-f) to install as additional version. (not recommended)"
return
fi
debug_msg "UPDATE ${file}"
do_install_file ${file}
do_remove "${installed[@]}"
return
fi
if [ "${maxall}" = "${maxinst}" ] ; then
# if [ "${OPT_DOWNGRADE}" = "no" ] ; then
# debug_msg "Use --update --downgrade to downgrade or just --force to install without removing."
# return
# fi
if [ "${OPT_UPDATE}" = "no" -o "${OPT_FORCE}" = "no" ] ; then
echo >&2 "Installation of ${pkg} failed: ${maxinst} has a higher version."
echo >&2 " use bee update --force to downgrade"
echo >&2 " use bee install --force to install as additional version. (not recommended)"
return
fi
debug_msg "DOWNGRADE ${file}"
do_install_file ${file}
do_remove "${installed[@]}"
return
fi
echo >&2 "YOU HIT A BUG #101: you should have never reached this point"
return
}
function bee-cache() {
${BEE_LIBEXECDIR}/bee/bee.d/bee-cache "${@}"
}
function do_install_file() {
local file=$1
local beefile="$(${BEE_BINDIR}/beeversion ${pkg} --format='%F').bee"
local pkg=$(${BEE_BINDIR}/beeversion --format='%A' $file)
local vv=""
if [ "${OPT_NOOP}" = "yes" ] ; then
echo "INSTALL ${file}"
return
fi
echo "installing ${file} .."
if [ ${OPT_VERBOSE} -ge 1 ] ; then
vv="vv"
fi
if [ -n "${BEE_BEEDESTDIR}" ] ; then
changedir="--transform=s,^/,${BEE_BEEDESTDIR}/,"
fi
start_cmd tar -x --dereference -${vv}Pf ${file} \
${changedir} \
--transform="s,^FILES$,${BEE_METADIR}/${pkg}/CONTENT.FILES," \
--transform="s,^CONTENT$,${BEE_METADIR}/${pkg}/CONTENT.INSTALL," \
--transform="s,^BUILD$,${BEE_METADIR}/${pkg}/${beefile}," \
--transform="s,^META$,${BEE_METADIR}/${pkg}/META," \
--transform="s,^PATCHES,${BEE_METADIR}/${pkg}/PATCHES," \
--transform="s,^DEPENDENCIES$,${BEE_METADIR}/${pkg}/DEPENDENCIES.deprecated," \
--show-transformed-names
if [ ! -e "${BEE_METADIR}/${pkg}/CONTENT.INSTALL" ] ; then
# create CONTENT.INSTALL from CONTENT.FILES
${BEE_LIBEXECDIR}/bee/compat-filesfile2contentfile \
${BEE_METADIR}/${pkg}/CONTENT.FILES \
>${BEE_METADIR}/${pkg}/CONTENT.INSTALL
rm ${BEE_METADIR}/${pkg}/CONTENT.FILES
fi
egrep "//$" ${BEE_METADIR}/${pkg}/CONTENT.INSTALL \
>${BEE_METADIR}/${pkg}/CONTENT.FIX
if [ -s ${BEE_METADIR}/${pkg}/CONTENT.FIX ] ; then
${BEE_LIBEXECDIR}/bee/content2filelist \
${BEE_METADIR}/${pkg}/CONTENT.FIX \
| ${BEE_LIBEXECDIR}/bee/filelist2content \
>> ${BEE_METADIR}/${pkg}/CONTENT.INSTALL
sed -i ${BEE_METADIR}/${pkg}/CONTENT.INSTALL \
-e '/\/\/$/d'
echo >&2 "bee-install: WARNING: corrupted CONTENT file found and fixed."
echo >&2 "bee-install: this may be caused by a bug in bee-1.0 and can be fixed permanently"
echo >&2 "bee-install: by rebuilding the package with bee-1.1 or newer."
else
rm ${BEE_METADIR}/${pkg}/CONTENT.FIX
fi
# create CONTENT file from CONTENT.INSTALL
mv ${BEE_METADIR}/${pkg}/CONTENT{.INSTALL,}
bee-cache update ${pkg}
run_hooks post-install ${pkg}
last=""
while read p f ; do
if [ "${last}" != "${p}" ] ; then
echo -e " Conflicts with installed package found: ${p}:"
last=${p}
fi
echo " $f"
done < <(bee-cache print-conflicts ${pkg} -f1,8- | sort -k2 -k1 -u )
}
function run_hooks() {
local action=${1}
local pkg=${2}
for t in ${BEE_LIBEXECDIR}/bee/hooks.d/* ; do
${t} ${action} ${pkg}
done
}
###############################################################################
###############################################################################
###############################################################################
options=$(${BEE_BINDIR}/beegetopt --name bee-install \
--no-skip-unknown-option \
--option update/upgrade/u \
--option verbose/v \
--option force/f \
--option help/h \
--option debug/D \
--option downgrade/d \
--option noop/n \
--option remove-all/r \
-- "$@")
if [ $? != 0 ] ; then
usage
exit 1
fi
eval set -- "${options}"
declare -i OPT_VERBOSE=0
declare -i OPT_DEBUG=0
declare OPT_NOOP="no"
declare OPT_UPDATE="no"
declare OPT_DOWNGRADE="no"
declare OPT_FORCE="no"
declare OPT_REMOVEALL="no"
while true ; do
case "$1" in
--verbose)
shift
OPT_VERBOSE=${OPT_VERBOSE}+1
;;
--force)
shift
OPT_FORCE="yes"
;;
--help)
usage
exit 0
;;
--update)
shift
OPT_UPDATE="yes"
;;
--downgrade)
shift
OPT_DOWNGRADE="yes"
;;
--debug)
shift
OPT_DEBUG=${OPT_DEBUG}+1
;;
--noop)
shift
OPT_NOOP="yes"
;;
--remove-all)
OPT_REMOVEALL="yes"
shift
;;
--)
shift
if [ -z "${1}" ] ; then
usage
exit 1
fi
pkg_install_all "${@}"
exit 0
;;
esac
done