Permalink
Cannot retrieve contributors at this time
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?
bee/src/bee-install.sh.in
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
521 lines (430 sloc)
14.5 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# bee-install - install a bee-pkg | |
# | |
# Copyright (C) 2009-2016 | |
# Marius Tolzmann <m@rius.berlin> | |
# 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@} | |
: ${BEE_LIBEXECDIR:=@LIBEXECDIR@} | |
function bee-cache() { | |
${BEE_LIBEXECDIR}/bee/bee.d/bee-cache "${@}" | |
} | |
function bee-list() { | |
${BEE_LIBEXECDIR}/bee/bee.d/bee-list "${@}" | |
} | |
function bee-remove() { | |
${BEE_LIBEXECDIR}/bee/bee.d/bee-remove "${@}" | |
} | |
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-2016 | |
by Marius Tolzmann <m@rius.berlin> and Tobias Dreyer <dreyer@molgen.mpg.de> | |
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 which files 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-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-list --available --exact "${fullname}" | grep ${search}) ) | |
maxavail=$(${BEE_BINDIR}/beeversion -max ${available[@]}) | |
fileavail=( $(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-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-list --installed --exact "${fullname}" | grep -v "${pkg}") ) | |
isinstalled=( $(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 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}/,S" | |
fi | |
umask 022 | |
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 \ | |
|| exit 1 | |
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 |