#!/bin/sh # # Copyright (C) 2012-2016 Etersoft # Copyright (C) 2012-2016 Vitaly Lipatov <lav@etersoft.ru> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # load_helper epm-query load_helper epm-assure load_helper epm-check_updated_repo # TODO: use when run install with epm --skip-installed install filter_out_installed_packages() { [ -z "$skip_installed" ] && cat && return case $PKGFORMAT in "rpm") LANG=C LC_ALL=C xargs -n1 rpm -q 2>&1 | grep 'is not installed' | sed -e 's|^.*package \(.*\) is not installed.*|\1|g' ;; # dpkg -l lists some non ii status (un, etc) #"deb") # LANG=C LC_ALL=C xargs -n1 dpkg -l 2>&1 | grep -i 'no packages found matching' | # sed -e 's|\.\+$||g' -e 's|^.*[Nn]o packages found matching \(.*\)|\1|g' # ;; *) for i in $(cat) ; do is_installed $i || echo $i done ;; esac | sed -e "s|rpm-build-altlinux-compat[^ ]*||g" | filter_strip_spaces } # for zypper before SUSE/11.0 __use_zypper_no_gpg_checks() { a= zypper install --help 2>&1 | grep -q -- "--no-gpg-checks" && echo "--no-gpg-checks" } # args: cmd_reinstall, cmd_install, packages __separate_sudocmd_foreach() { local cmd_re=$1 local cmd_in=$2 shift 2 separate_installed $@ if [ -n "$pkg_noninstalled" ] ; then sudocmd_foreach "$cmd_re" $pkg_noninstalled || return fi if [ -n "$pkg_installed" ] ; then sudocmd_foreach "$cmd_in" $pkg_installed || return fi return 0 } # args: cmd_reinstall, cmd_install, packages __separate_sudocmd() { local cmd_re=$1 local cmd_in=$2 shift 2 separate_installed $@ if [ -n "$pkg_noninstalled" ] ; then sudocmd "$cmd_re" $pkg_noninstalled || return fi if [ -n "$pkg_installed" ] ; then sudocmd "$cmd_in" $pkg_installed || return fi return 0 } # copied from etersoft-build-utils/share/eterbuild/functions/rpmpkg epm_install_names() { if [ -n "$non_interactive" ] ; then epm_ni_install_names "$@" return fi [ -z "$1" ] && return case $PMTYPE in apt-rpm|apt-dpkg) sudocmd apt-get $APTOPTIONS $noremove install $@ return ;; aptitude-dpkg) sudocmd aptitude install $@ return ;; deepsolver-rpm) sudocmd ds-install $@ return ;; urpm-rpm) sudocmd urpmi $URPMOPTIONS $@ return ;; pkgsrc) sudocmd pkg_add -r $@ return ;; pkgng) sudocmd pkg install $@ return ;; emerge) sudocmd emerge -uD $@ return ;; pacman) sudocmd pacman -S $force $nodeps $@ return ;; aura) sudocmd aura -A $force $nodeps $@ return ;; yum-rpm) sudocmd yum $YUMOPTIONS install $@ return ;; dnf-rpm) sudocmd dnf install $@ return ;; snappy) sudocmd snappy install $@ return ;; zypper-rpm) sudocmd zypper install $ZYPPEROPTIONS $@ return ;; mpkg) sudocmd mpkg install $@ return ;; conary) sudocmd conary update $@ return ;; npackd) # FIXME: correct arg __separate_sudocmd_foreach "npackdcl add --package=" "npackdcl update --package=" $@ return ;; slackpkg) __separate_sudocmd_foreach "/usr/sbin/slackpkg install" "/usr/sbin/slackpkg upgrade" $@ return ;; homebrew) # FIXME: sudo and quote SUDO= __separate_sudocmd "brew install" "brew upgrade" $@ return ;; ipkg) [ -n "$force" ] && force=-force-depends sudocmd ipkg $force install $@ return ;; nix) __separate_sudocmd "nix-env --install" "nix-env --upgrade" $@ return ;; apk) sudocmd apk add $@ return ;; tce) sudocmd tce-load -wi $@ return ;; guix) __separate_sudocmd "guix package -i" "guix package -i" $@ return ;; android) fatal "We still have no idea how to use package repository, ever if it is F-Droid." return ;; aptcyg) sudocmd apt-cyg install $@ return ;; xbps) sudocmd xbps-install $@ return ;; *) fatal "Have no suitable install command for $PMTYPE" ;; esac } # Non interactive install epm_ni_install_names() { [ -z "$1" ] && return case $PMTYPE in apt-rpm|apt-dpkg) export DEBIAN_FRONTEND=noninteractive sudocmd apt-get -y $noremove --force-yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" $APTOPTIONS install $@ return ;; aptitude-dpkg) sudocmd aptitude -y install $@ return ;; yum-rpm) sudocmd yum -y $YUMOPTIONS install $@ return ;; dnf-rpm) sudocmd dnf -y $YUMOPTIONS install $@ return ;; urpm-rpm) sudocmd urpmi --auto $URPMOPTIONS $@ return ;; zypper-rpm) # FIXME: returns true ever no package found, need check for "no found", "Nothing to do." yes | sudocmd zypper --non-interactive $ZYPPEROPTIONS install $@ return ;; pkgsrc) sudocmd pkg_add -r $@ return ;; pkgng) sudocmd pkg install -y $@ return ;; emerge) sudocmd emerge -uD $@ return ;; pacman) sudocmd pacman -S --noconfirm $force $nodeps $@ return ;; aura) sudocmd aura -A $force $nodeps $@ return ;; npackd) # npackdcl update --package=<package> (remove old and install new) sudocmd npackdcl add --package=$@ return ;; chocolatey) docmd chocolatey install $@ return ;; ipkg) sudocmd ipkg -force-defaults install $@ return ;; nix) sudocmd nix-env --install $@ return ;; apk) sudocmd apk add $@ return ;; tce) sudocmd tce-load -wi $@ return ;; xbps) sudocmd xbps-install -y $@ return ;; homebrew) # FIXME: sudo and quote SUDO= __separate_sudocmd "brew install" "brew upgrade" $@ return ;; #android) # sudocmd pm install $@ # return ;; slackpkg) # FIXME: broken status when use batch and default answer __separate_sudocmd_foreach "/usr/sbin/slackpkg -batch=on -default_answer=yes install" "/usr/sbin/slackpkg -batch=on -default_answer=yes upgrade" $@ return ;; *) fatal "Have no suitable appropriate install command for $PMTYPE" ;; esac } __epm_check_if_rpm_already_installed() { # Not: we can make optimize if just check version? LANG=C $SUDO rpm -Uvh $force $nodeps $@ 2>&1 | grep -q "is already installed" } # TODO: rewrite to convert (get some code from Korinf?) __epm_check_if_try_install_deb() { local pkg local debpkgs="" for pkg in $@ ; do [ "$(get_package_type "$pkg")" = "deb" ] || return 1 [ -e "$pkg" ] || fatal "Can't read $pkg" debpkgs="$debpkgs $(realpath $pkg)" done [ -n "$debpkgs" ] || return 1 assure_exists alien local TDIR=$(mktemp -d) cd $TDIR for pkg in $debpkgs ; do # TODO: fakeroot for non ALT? showcmd_store_output alien -r -k --scripts "$pkg" || fatal local RPMCONVERTED=$(grep "rpm generated" $RC_STDOUT | sed -e "s| generated||g") clean_store_output epm install $RPMCONVERTED done rm -f $TDIR/* rmdir $TDIR/ return 0 } # TODO: rewrite to convert (get some code from Korinf?) __epm_check_if_try_install_rpm() { local pkg local rpmpkgs="" for pkg in $@ ; do [ "$(get_package_type "$pkg")" = "rpm" ] || return 1 [ -e "$pkg" ] || fatal "Can't read $pkg" rpmpkgs="$rpmpkgs $(realpath $pkg)" done [ -n "$rpmpkgs" ] || return 1 assure_exists alien assure_exists fakeroot local TDIR=$(mktemp -d) cd $TDIR for pkg in $rpmpkgs ; do showcmd_store_output fakeroot alien -d -k --scripts "$pkg" clean_store_output local DEBCONVERTED=$(grep "deb generated" $RC_STDOUT | sed -e "s| generated||g") clean_store_output epm install $DEBCONVERTED done rm -f $TDIR/* rmdir $TDIR/ return 0 } __handle_direct_install() { case "$DISTRNAME" in "ALTLinux") load_helper epm-download local pkg url for pkg in $pkg_names ; do url=$(__epm_get_altpkg_url $pkg) [ -n "$url" ] || continue # TODO: use estrlist pkg_urls="$pkg_urls $url" done # FIXME: need remove pkg_names="" ;; esac } epm_install_files() { [ -z "$1" ] && return # TODO: check read permissions # sudo test -r FILE # do not fallback to install_names if we have no permissions case $PMTYPE in apt-rpm) __epm_check_if_try_install_deb $@ && return # do not use low-level for install by file path if ! is_dirpath "$@" || [ "$(get_package_type "$@")" = "rpm" ] ; then sudocmd rpm -Uvh $force $nodeps $@ && return local RES=$? # TODO: check rpm result code and convert it to compatible format if possible __epm_check_if_rpm_already_installed $@ && return # if run with --nodeps, do not fallback on hi level [ -n "$nodeps" ] && return $RES fi # use install_names ;; apt-dpkg|aptitude-dpkg) # the new version of the conf. file is installed with a .dpkg-dist suffix if [ -n "$non_interactive" ] ; then DPKGOPTIONS="--force-confdef --force-confold" fi __epm_check_if_try_install_rpm $@ && return # FIXME: return false in case no install and in case install with broken deps sudocmd dpkg $DPKGOPTIONS -i $@ local RES=$? # if run with --nodeps, do not fallback on hi level [ -n "$nodeps" ] && return $RES # fall to apt-get -f install for fix deps # can't use APTOPTIONS with empty install args epm_install_names -f # repeat install for get correct status sudocmd dpkg $DPKGOPTIONS -i $@ return ;; yum-rpm|dnf-rpm) __epm_check_if_try_install_deb $@ && return sudocmd rpm -Uvh $force $nodeps $@ && return # if run with --nodeps, do not fallback on hi level __epm_check_if_rpm_already_installed $@ && return [ -n "$nodeps" ] && return YUMOPTIONS=--nogpgcheck # use install_names ;; zypper-rpm) __epm_check_if_try_install_deb $@ && return sudocmd rpm -Uvh $force $nodeps $@ && return local RES=$? __epm_check_if_rpm_already_installed $@ && return # if run with --nodeps, do not fallback on hi level [ -n "$nodeps" ] && return $RES ZYPPEROPTIONS=$(__use_zypper_no_gpg_checks) # use install_names ;; urpm-rpm) __epm_check_if_try_install_deb $@ && return sudocmd rpm -Uvh $force $nodeps $@ && return local RES=$? __epm_check_if_rpm_already_installed $@ && return # if run with --nodeps, do not fallback on hi level [ -n "$nodeps" ] && return $RES URPMOPTIONS=--no-verify-rpm # use install_names ;; pkgsrc) sudocmd pkg_add $@ return ;; pkgng) local PKGTYPE="$(get_package_type $@)" case "$PKGTYPE" in tbz) sudocmd pkg_add $@ ;; *) sudocmd pkg add $@ ;; esac return ;; android) sudocmd pm install $@ return ;; emerge) load_helper epm-install-emerge sudocmd epm_install_emerge $@ return ;; pacman) sudocmd pacman -U --noconfirm $force $nodeps $@ && return local RES=$? [ -n "$nodeps" ] && return $RES sudocmd pacman -U $force $@ return ;; slackpkg) # FIXME: check for full package name # FIXME: broken status when use batch and default answer __separate_sudocmd_foreach "/sbin/installpkg" "/sbin/upgradepkg" $@ return ;; esac # other systems can install file package via ordinary command epm_install_names "$@" } epm_print_install_command() { case $PMTYPE in apt-rpm|yum-rpm|urpm-rpm|zypper-rpm|dnf-rpm) echo "rpm -Uvh --force $nodeps $@" ;; apt-dpkg|aptitude-dpkg) echo "dpkg -i $@" ;; pkgsrc) echo "pkg_add $@" ;; pkgng) echo "pkg add $@" ;; emerge) # need be placed in /usr/portage/packages/somewhere echo "emerge --usepkg $@" ;; pacman) echo "pacman -U --noconfirm --force $nodeps $@" ;; slackpkg) echo "/sbin/installpkg $@" ;; npackd) echo "npackdcl add --package=$@" ;; ipkg) echo "ipkg install $@" ;; android) echo "pm install $@" ;; aptcyg) echo "apt-cyg install $@" ;; tce) echo "tce-load -wi $@" ;; xbps) echo "xbps-install -y $@" ;; homebrew) # FIXME: sudo and quote echo "brew install $@" ;; *) fatal "Have no suitable appropriate install command for $PMTYPE" ;; esac } epm_install() { if [ -n "$show_command_only" ] ; then epm_print_install_command $pkg_filenames return fi if [ -n "$direct" ] ; then __handle_direct_install fi # if possible, it will put pkg_urls into pkg_files or pkg_names if [ -n "$pkg_urls" ] ; then load_helper epm-download __handle_pkg_urls_to_install fi [ -z "$pkg_files$pkg_names" ] && info "Skip empty install list" && return 22 local names="$(echo $pkg_names | filter_out_installed_packages)" local files="$(echo $pkg_files | filter_out_installed_packages)" [ -z "$files$names" ] && info "Skip empty install list" && return 22 if [ -z "$files" ] && [ -z "$direct" ] ; then # it is useful for first time running update_repo_if_needed fi epm_install_names $names || return epm_install_files $files local RETVAL=$? # TODO: reinvent [ -n "$to_remove_pkg_files" ] && rm -fv $to_remove_pkg_files return $RETVAL }