#!/usr/bin/env bash # # __ # /\ \__ # __ _____\ \ ,_\ _____ __ ___ # /'__`\ /\ '__`\ \ \//\ '__`\ /'__`\ /'___\ #/\ \L\.\\ \ \L\ \ \ \\ \ \L\ /\ \L\.\_/\ \__/ #\ \__/.\_\ \ ,__/\ \__\ \ ,__\ \__/.\_\ \____\ # \/__/\/_/\ \ \/ \/__/\ \ \/ \/__/\/_/\/____/ # \ \_\ \ \_\ # \/_/ \/_/ # a pacman wrapper with syntax based on debian's apt # (c) 2019-2020 Fascode Network. # License: Do What The Fuck You Want To Public License # maintained by Yamada Hayao # Enter the path to the AUR helper you want to use here. # If it is empty, the corresponding AUR helper will be searched automatically. #AURHELPER= set -e # APTPAC Version APTPAC_VERSION="3.3.0" # Initilize List PACMAN_PACKAGE_FILE=() PACMAN_PACKAGE=() DEB_PACKAGE_FILE=() # PACMAN Config HELPERS=( "/usr/bin/yay" "/usr/bin/paru" "/usr/bin/yaourt" "/usr/bin/aurman" "/usr/bin/pikaur" "/usr/bin/pacaur" "/usr/bin/aura" "/usr/bin/wfa" ) PACMAN_OPTIONS=() DEFAULT_PACMAN_COMMAND="/usr/bin/pacman" PACMAN_COMMAND="${DEFAULT_PACMAN_COMMAND}" PACMAN_CONFIG="/etc/pacman.conf" # APTPAC Config DEBTAP_WORK="/tmp/aptpac-debtap" DEBUG=false RUN_WITH_SUDO=false DIRECT_PACMAN=false AUTOREMOVE=false INSTALL=false _msg_error () { echo -e "${@}" >&2 } _msg_warn () { echo -e "${@}" >&2 } _msg_debug () { if "${DEBUG}"; then echo -e "${@}" >&1 fi } # List option INSTALLED_PKGLIST=false _usage () { echo "usage ${0} [options] [command] [packages]" echo echo " apt commands:" echo " install Install the specified package" echo " remove Remove the specified package" echo " purge Permanently remove the package" echo " update Update package database" echo " upgrade | full-upgrade Update packages" echo " edit-sources Edit config file of pacman" echo " search Search for a package" echo " autoremove Remove unnecessary packages" echo " clean Remove the package cache" echo " list Display a list of packages" echo " show | showpkg Display the package records" echo " rdepends Display the dependencies" echo echo " apt options:" echo " -y | --yes | --assume-yes Do not check" echo " -d | --download-only Only download the package" echo " -c | --config-file Config file for pacman" echo " -h | --help Display this help" echo " -v | --version Display the version of aptpac and pacman" echo " --auto-remove | --autoremove Remove unnecessary packages with other command" echo " --purge Delete the entire configuration file" echo echo " pacapt options:" echo " --aur-helper Specifies the command to use as the AUR helper" echo " Ignored if pacapt is run as root" echo " Specify AUR helper that supports common command line options with pacman" echo " --pflags Pass arguments to pacman" echo echo " Notes:" echo " - aptpac supports not only above options but also options of pacman" echo " - If you specify the deb file, you can install using debtap" } _exit () { exit "${1}" } _version () { cat << EOF aptpac ${APTPAC_VERSION} - A pacman wrapper with syntax based on debian's apt License: Do What The Fuck You Want To Public License (c) 2019-2020 Fascode Network. Yamada Hayao EOF echo pacman --version } ADD_OPTION () { _msg_debug "Added pacman option '${*}'" PACMAN_OPTIONS+=("${@}") } _sudo(){ if "${RUN_WITH_SUDO}"; then _msg_debug "Run sudo ${*}" eval sudo "${@}" else _msg_debug "Run ${*}" eval "${@}" fi } _pacman(){ _sudo "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" --config "${PACMAN_CONFIG}" "${@}" } _run_detect_aur_helper(){ if [[ ! "${UID}" = 0 ]]; then if [[ -z "${AURHELPER+SET}" ]]; then for AURHELPER in "${HELPERS[@]}"; do if [[ -f "${AURHELPER}" ]]; then PACMAN_COMMAND="${AURHELPER}" break elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then PACMAN_COMMAND="$(basename "${AURHELPER}")" break fi done else if [[ -f "${AURHELPER}" ]]; then PACMAN_COMMAND="${AURHELPER}" elif hash "$(basename "${AURHELPER}")" 2> /dev/null; then PACMAN_COMMAND="$(basename "${AURHELPER}")" else _msg_error "${AURHELPER} is not installed" exit 1 fi fi fi } _run_aur_message(){ if [[ ! "${PACMAN_COMMAND}" = "${DEFAULT_PACMAN_COMMAND}" ]] && [[ ! "$(basename "${PACMAN_COMMAND}")" = "$(basename "${DEFAULT_PACMAN_COMMAND}")" ]]; then _msg_debug "Use AUR helper ${PACMAN_COMMAND}" else RUN_WITH_SUDO=true fi } _run_autoremove(){ if "${AUTOREMOVE}"; then if [[ -n $(${PACMAN_COMMAND} -Qttdq) ]]; then "${PACMAN_COMMAND}" -Qttdq | _sudo "${PACMAN_COMMAND}" -Rsc --config "${PACMAN_CONFIG}" - else echo "No packages to remove" exit 0 fi fi } _run_distinguish_package(){ local pkg for pkg in "${PACKAGE[@]}"; do if [[ ! -f "${pkg}" ]]; then PACMAN_PACKAGE+=("${pkg}") elif [[ "$(file -b --mime-type "${pkg}" 2> /dev/null)" = "application/vnd.debian.binary-package" ]]; then DEB_PACKAGE_FILE+=("${pkg}") else PACMAN_PACKAGE_FILE+=("${pkg}") fi done } _run_pacman(){ if [[ "${INSTALL}" = true ]]; then _pacman -S "${PACMAN_PACKAGE[@]}" else _pacman "${PACMAN_PACKAGE[@]}" fi } _run_debtap(){ _msg_warn "It is not recommended to install deb package" _msg_warn "The package conversion is not perfect and can lead to errors in some cases" if (( "${#DEB_PACKAGE_FILE[@]}" != 0 )) && ! hash "debtap"; then _msg_error "debtap was not found" exit 1 fi if [[ -z "$(find "/var/cache/pkgfile" -maxdepth 1 -mindepth 1 -name "*.files" 2> /dev/null)" ]] || [[ -z "$(find "/var/cache/debtap" -maxdepth 1 -mindepth 1 -name "*-packages" 2> /dev/null)" ]] || [[ -z "$(find "/var/cache/debtap" -maxdepth 1 -mindepth 1 -name "*-files" 2> /dev/null)" ]]; then _msg_debug "Updating debtap datebase" sudo debtap -u fi ( sudo mkdir -p "${DEBTAP_WORK}" local pkg work for pkg in "${DEB_PACKAGE_FILE[@]}"; do work="${DEBTAP_WORK}/$(basename "${pkg}")/" file="${work}/$(basename "${pkg}")" _msg_debug "Work dir: ${work}" _msg_debug "Deb file:${work}" sudo mkdir -p "${work}" sudo cp "${pkg}" "${file}" cd "${work}" sudo debtap --Quiet "${file}" while read -r archpkg; do _msg_debug "Install ${archpkg} with pacman" _pacman -U "${archpkg}" done < <(find "${work}" -maxdepth 1 -mindepth 1 -type f -name "*.pkg.tar.*") done ) } # Argument analysis and processing set +e PACAPT_ARGUMENTS=("${@}") _opt_short="ydfc:hvVDFQRSTU" _opt_long="yes,assume-yes,download-only,fix-broken,purse,installed,debug,help,version,config-file:,auto-remove,autoremove,aur-helper:,pflags:" OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- "${@}" 2> /dev/null) set -e #if [[ ${?} != 0 ]]; then # exit 1 #fi eval set -- "${OPT}" #echo "Argument is \"${OPT}\"" unset OPT _opt_short _opt_long while true; do case "${1}" in -y | --yes | --assume-yes) ADD_OPTION "--noconfirm" shift 1 ;; -d | --download-only) ADD_OPTION "-w" shift 1 ;; -f | --fix-broken) shift 1 ;; -c | --config-file) PACMAN_CONFIG="${2}" shift 2 ;; --purge) ADD_OPTION "-n" shift 1 ;; --installed) INSTALLED_PKGLIST=true shift 1 ;; --debug) DEBUG=true shift 1 ;; -h | --help) _usage shift 1 exit 0 ;; -v | --version) _version shift 1 exit 0 ;; --autoremove | --auto-remove) AUTOREMOVE=true shift 1 ;; --aur-helper) if [[ ! "${UID}" = 0 ]] && [[ -f "${2}" ]]; then PACMAN_COMMAND="${2}" elif [[ "${UID}" = 0 ]]; then _msg_warn "The specified AUR helper is not used because pacapt is running on the root." elif hash "$(basename "${2}")" 2> /dev/null; then PACMAN_COMMAND="$(basename "${2}")" else _msg_error "${2} is not installed" exit 1 fi shift 2 ;; --pflags) # shellcheck disable=SC2086 ADD_OPTION ${2} shift 2 ;; -V | -D | -F | -Q | -R | -S | -T | -U) DIRECT_PACMAN=true ADD_OPTION "${PACAPT_ARGUMENTS[@]}" break ;; --) shift 1 break ;; *) _msg_error "Invalid argument '${1}'" _help exit 1 ;; esac done if [[ "${DIRECT_PACMAN}" = false ]]; then if [[ $# -lt 1 ]]; then _msg_error "No command specified" _usage _exit 1 fi COMMAND="${1,,}" shift 1 PACKAGE=("${@}") case "${COMMAND}" in install) #ADD_OPTION "-S" INSTALL=true ;; remove) ADD_OPTION "-Rsc" ;; purge) ADD_OPTION "-Rsnc" ;; update) ADD_OPTION "-Syy" ;; upgrade) ADD_OPTION "-Syu" ;; search) ADD_OPTION "-Ss" ;; full-upgrade) ADD_OPTION "-Syu" ;; clean) ADD_OPTION "-Sccc" ;; dist-upgrade) ADD_OPTION "-Syu" ;; edit-sources) if [[ -n "${EDITOR}" ]]; then sudo "${EDITOR}" "${PACMAN_CONFIG}" else sudo nano "${PACMAN_CONFIG}" fi _exit 0 ;; huawei) # shellcheck disable=SC1091 if [[ "$(source "/etc/locale.conf" 2> /dev/null; echo -n "${LANG}")" = "ja_JP.UTF-8" ]]; then echo "(ง •ᴗ•)ว ⁾⁾ファーウェイでウェイウェイ" _exit 0 else _msg_error "Invalid command '${COMMAND}'" _exit 1 fi ;; moo) echo " (__) " echo " (oo) " echo " /------\/ " echo " / | || " echo " * /\---/\ " echo " ~~ ~~ " echo "....\"Have you mooed today?\"..." exit 0 ;; autoremove) if [[ -n "$(${PACMAN_COMMAND} -Qttdq)" ]]; then ADD_OPTION "-Rsc" while read -r pkg; do PACKAGE+=("${pkg}") done < <(${PACMAN_COMMAND} -Qttdq) else echo "No packages to remove" exit 0 fi ;; list) if [[ "${INSTALLED_PKGLIST}" = true ]]; then ADD_OPTION "-Q | grep" else ADD_OPTION "-Ss" fi ;; show | showpkg) for pkg in "${PACKAGE[@]}"; do if pacman -Qq "${pkg}" 2> /dev/null 1>&2; then "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" -Qi --config "${PACMAN_CONFIG}" "${pkg}" else "${PACMAN_COMMAND}" "${PACMAN_OPTIONS[@]}" -Si --config "${PACMAN_CONFIG}" "${pkg}" fi done unset pkg _exit 0 ;; rdepends) ADD_OPTION "-Sii" ;; help) _usage exit 0 ;; *) _msg_error "Invalid command '${COMMAND}'" _exit 1 ;; esac fi _run_detect_aur_helper _run_aur_message _run_distinguish_package _run_pacman if [[ "${INSTALL}" = true ]]; then _run_debtap fi _run_autoremove