set -eu
-msgdebug=false
-nocolor=false
-debug=false
-pacman_args=""
+######################################################################################
+
+#-- wfa configs --#
+wfa_version="0.1"
+wfa_name="WFA"
+wfa_command="wfa"
+
+#-- options (int) --#
+option_y_count=0
+
+#-- options (str) --#
+aururl="https://aur.archlinux.org/"
operation="none"
+
+#-- options (bool) --#
+bash_debug=false
+debug=false
force_aur=false
+msgdebug=false
+nocolor=false
noconfirm=false
+nodeps=false
+nomakepkgconf=false
+
+#-- makepkg --#
+# 実行ファイル
+makepkg_command="/usr/bin/makepkg"
+# 設定ファイル
+makepkg_config="/etc/makepkg.conf"
+# 引数
+makepkg_args=""
+
+#-- pacman --#
+# 実行ファイル
+pacman_command="/usr/bin/pacman"
+# 設定ファイル
+pacman_config="/etc/pacman.conf"
+# 引数
+pacman_args=""
+
+#-- git --#
+# 実行ファイル
+git_command="/usr/bin/git"
+# 引数
+git_args=""
+
+#-- gpg --#
+# 実行ファイル
+gpg_command="/usr/bin/gpg"
+# 引数
+gpg_args=""
+
+#-- sudo --#
+# 実行ファイル
+sudo_command="/usr/bin/sudo"
+# 引数
+sudo_args=""
+
+
+######################################################################################
-wfa_version="0.1"
-aururl="https://aur.archlinux.org/"
# メッセージ出力の制御
# https://github.com/FascodeNet/alterlinux/blob/dev/tools/msg.sh の変数名にアンダーバーを追加し関数化
# Show an INFO message
# $1: message string
msg_info() {
- local _msg_opts="-a WFA"
+ if [[ "${msgdebug}" = false ]]; then
+ set +xv
+ fi
+ local _msg_opts="-a ${wfa_name}"
if [[ "${1}" = "-n" ]]; then
_msg_opts="${_msg_opts} -o -n"
shift 1
[[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
[[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
msg ${_msg_opts} info "${1}"
+ if [[ "${bash_debug}" = true ]]; then
+ set -xv
+ fi
}
# Show an Warning message
# $1: message string
msg_warn() {
- local _msg_opts="-a WFA"
+ if [[ "${msgdebug}" = false ]]; then
+ set +xv
+ fi
+ local _msg_opts="-a ${wfa_name}"
if [[ "${1}" = "-n" ]]; then
_msg_opts="${_msg_opts} -o -n"
shift 1
[[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
[[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
msg ${_msg_opts} warn "${1}"
+ if [[ "${bash_debug}" = true ]]; then
+ set -xv
+ fi
}
# Show an debug message
# $1: message string
msg_debug() {
+ if [[ "${msgdebug}" = false ]]; then
+ set +xv
+ fi
if [[ "${debug}" = true ]]; then
- local _msg_opts="-a WFA"
+ local _msg_opts="-a ${wfa_name}"
if [[ "${1}" = "-n" ]]; then
_msg_opts="${_msg_opts} -o -n"
shift 1
[[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
msg ${_msg_opts} debug "${1}"
fi
+ if [[ "${bash_debug}" = true ]]; then
+ set -xv
+ fi
}
# Show an ERROR message then exit with status
# $1: message string
# $2: exit code number (with 0 does not exit)
msg_error() {
- local _msg_opts="-a WFA"
+ if [[ "${msgdebug}" = false ]]; then
+ set +xv
+ fi
+ local _msg_opts="-a ${wfa_name}"
if [[ "${1}" = "-n" ]]; then
_msg_opts="${_msg_opts} -o -n"
shift 1
if [[ -n "${2:-}" ]]; then
exit ${2}
fi
+ if [[ "${bash_debug}" = true ]]; then
+ set -xv
+ fi
}
# rm helper
}
usage (){
+ local _pacman_help=false
+
local _wfa_usage
_wfa_usage() {
echo "Usage:"
- echo "wfa"
- echo "wfa <operation> [...]"
+ echo "${wfa_command}"
+ echo "${wfa_command} <operation> [...]"
echo
echo "operations:"
- echo "wfa {-h --help}"
- echo "wfa {-V --version}"
- #echo "wfa {-D --database} <options> <package(s)>"
- #echo "wfa {-F --files} [options] [package(s)]"
- echo "wfa {-Q --query} [options] [package(s)]"
- echo "wfa {-R --remove} [options] <package(s)>"
- echo "wfa {-S --sync} [options] [package(s)]"
- #echo "wfa {-T --deptest} [options] [package(s)]"
- #echo "wfa {-U --upgrade} [options] <file(s)>"
+ echo " ${wfa_command} {-h --help}"
+ echo " ${wfa_command} {-V --version}"
+ #echo " ${wfa_command} {-D --database} <options> <package(s)>"
+ #echo " ${wfa_command} {-F --files} [options] [package(s)]"
+ echo " ${wfa_command} {-Q --query} [options] [package(s)]"
+ echo " ${wfa_command} {-R --remove} [options] <package(s)>"
+ echo " ${wfa_command} {-S --sync} [options] [package(s)]"
+ #echo " ${wfa_command} {-T --deptest} [options] [package(s)]"
+ #echo " ${wfa_command} {-U --upgrade} [options] <file(s)>"
+ #echo
+ #echo "New operations:"
+ #echo " ${wfa_command} {-P --show} [options]"
+ #echo " ${wfa_command} {-G --getpkgbuild} [package(s)]"
+ echo
+ echo "New options:"
+ echo " --repo Assume targets are from the repositories"
+ echo " -a --aur Assume targets are from the AUR"
+ echo
+ echo "Permanent configuration options:"
+ echo " --aururl <url> Set an alternative AUR URL"
+ echo " --makepkg <file> makepkg command to use"
+ echo " --mflags <flags> Pass arguments to makepkg"
+ echo " --pacman <file> pacman command to use"
+ echo " --git <file> git command to use"
+ echo " --gitflags <flags> Pass arguments to git"
+ echo " --gpg <file> gpg command to use"
+ echo " --gpgflags <flags> Pass arguments to gpg"
+ echo " --config <file> pacman.conf file to use"
+ echo " --makepkgconf <file> makepkg.conf file to use"
+ echo " --nomakepkgconf Use the default makepkg.conf"
+ echo
+ }
+
+ local _wfa_usage_sync
+ _wfa_usage_sync() {
+ echo "usage: ${wfa_command} {-S --sync} [options] [package(s)]"
+ echo "options:"
+ echo " -b, --dbpath <path> set an alternate database location"
+ echo " --config <path> set an alternate configuration file"
+ echo " --noconfirm do not ask for any confirmation"
+
}
if [[ "${operation}" = "none" ]]; then
_wfa_usage
+ elif [[ "${_pacman_help}" = true ]]; then
+ "${pacman_command}" -h --${operation}
+ elif [[ "$(type -t "_wfa_usage_${operation}" )" = "function" ]]; then
+ _wfa_usage_${operation}
else
- pacman -h --${operation}
+ msg_error "Undefined operation." 1
fi
}
set_operation() {
if [[ "${operation}" = "none" ]]; then
operation="${1}"
- add_pacman_args "--${operation}"
+ add_args pacman "--${operation}"
else
msg_error "only one operation may be used at a time" 1
fi
}
run_pacman() {
- run_sudo pacman ${pacman_args} ${@}
+ run_sudo "${pacman_command}" ${@}
}
# pacmanの引数を追加する
# https://github.com/FascodeNet/aptpac/blob/master/aptpac のADD_OPTION関数を参考
-add_pacman_args() {
- local _pacman_args_array=(${pacman_args})
- _pacman_args_array+=(${@})
- pacman_args=${_pacman_args_array[@]}
- msg_debug "PACMAN ARGS: ${pacman_args}"
+# Usage: add_args [pacman/makepkg] <args1> <args2>...
+add_args() {
+ local _target="${1}"
+ local _args_array
+ shift 1
+
+ case "${_target}" in
+ "makepkg")
+ _args_array=(${makepkg_args})
+ _args_array+=(${@})
+ makepkg_args=${_args_array[@]}
+ msg_debug "makepkg ARGS: ${makepkg_args}"
+ ;;
+
+ "pacman")
+ _args_array=(${pacman_args})
+ _args_array+=(${@})
+ pacman_args=${_args_array[@]}
+ msg_debug "pacman ARGS: ${pacman_args}"
+ ;;
+ "git")
+ _args_array=(${mpg_args})
+ _args_array+=(${@})
+ git_args=${_args_array[@]}
+ msg_debug "git ARGS: ${git_args}"
+ ;;
+ "gpg")
+ _args_array=(${gpg_args})
+ _args_array+=(${@})
+ gpg_args=${_args_array[@]}
+ msg_debug "gpg ARGS: ${gpg_args}"
+ ;;
+ "sudo")
+ _args_array=(${sudo_args})
+ _args_array+=(${@})
+ sudo_args=${_args_array[@]}
+ msg_debug "sudo ARGS: ${sudo_args}"
+ ;;
+ *)
+ msg_error "Failed to set the argument of ${_target}\nSetting that command is not currently supported." 1
+ ;;
+ esac
}
# 引数で指定されたパッケージがAUR以外の場所に存在しない場合にのみ正常終了します(AURのパッケージの場合に正常終了)
check_aur_package() {
local _package="${1}"
# 参考: https://qiita.com/Hayao0819/items/a8740a17301fafa2fdab
- if [[ -z "$(pacman -Fq "${_package}" 2>/dev/null | grep -o ".*${_package}$")" ]]; then
+ if [[ -z "$(pacman -Ssq "${_package}" 2>/dev/null | grep -o ".*${_package}$")" ]]; then
#AUR以外のリポジトリに存在しない
return 0
else
}
+# 引数で指定されたパッケージが既にインストールされている場合は正常終了します。
+check_installed_package() {
+ local _package="${1}"
+ if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1; then
+ return 0
+ else
+ return 1
+ fi
+}
+
get_cache_dir() {
local _user_config_dir
if [[ -v XDG_CONFIG_HOME ]]; then
}
# Usage: get_srcinfo_data <path> <var>
-: << "DISABLED"
+# 参考: https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
get_srcinfo_data() {
local _srcinfo="${1}" _ver="${2}"
local _srcinfo_json=$(python << EOF
parsed, errors = parse_srcinfo(text)
print(json.dumps(parsed))
EOF
- )
- echo "${_srcinfo_json}" | jq -r .${2}
-}
-DISABLED
-
-get_srcinfo_data() {
- local _srcinfo="${1}"
- local _var="${2}"
- local _pkg _output
- if [[ ! -f "${_srcinfo}" ]]; then
- msg_error ".SRCINFO does not exist."
- fi
- for _pkg in $(cat "${_srcinfo}" | grep "${_var} = " | cut -d ' ' -f "3"); do
- _output+=(${_pkg})
- done
- echo -n "${_output[@]}"
+)
+ echo "${_srcinfo_json}" | jq -rc "${2}" | tr '\n' ' '
}
fi
# PKGBUILDを展開
- tar -xv -f "${_pkgbuild_archive_path}" -C "${wfa_cache_dir}/build/"
+ msg_info "Unpacking the tarball of PKGBUILD ..."
+ tar -xv -f "${_pkgbuild_archive_path}" -C "${wfa_cache_dir}/build/" > /dev/null 2>&1
# .SRCINFOを解析
local _build_dir="${wfa_cache_dir}/build/${_package}"
if [[ ! -f "${_build_dir}/.SRCINFO" ]]; then
msg_warn ".SRCINFO was not found.\nGenerate it using makepkg."
- makepkg -p "${_build_dir}/PKGBUILD" --printsrcinfo > "${_build_dir}/.SRCINFO"
+ (
+ cd "${_build_dir}"
+ "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
+ )
fi
- local _makedepends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" "makedepends")"
- local _depends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" "depends")"
- local _conflicts="$(get_srcinfo_data "${_build_dir}/.SRCINFO" "conflicts")"
+ local _makedepends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".makedepends[]?")"
+ local _depends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".depends[]?")"
+ local _conflicts="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".conflicts[]?")"
msg_debug "makedepends: ${_makedepends}"
msg_debug "depends: ${_depends}"
msg_debug "conflicts: ${_conflicts}"
# 衝突を確認
local _pkg _conflicts_found=false
for _pkg in ${_conflicts[@]}; do
- if pacman -Qq "${_pkg}" 2>/dev/null 1>&2 ; then
+ if "${pacman_command}" -Qq "${_pkg}" > /dev/null 2>&1 ; then
_conflicts_found=true
msg_error "${_package} is colliding with ${_pkg}"
fi
done
- if pacman -Qq "${_package}" 2>/dev/null 1>&2; then
- msg_error "${_package} is colliding with $(pacman -Qq "${_package}")"
+ if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1 && [[ ! "$("${pacman_command}" -Qq "${_package}" 2> /dev/null)" = "${_package}" ]]; then
+ msg_error "${_package} is colliding with $("${pacman_command}" -Qq "${_package}")"
_conflicts_found=true
fi
if [[ "${_conflicts_found}" = true ]]; then
# 依存パッケージをインストール
- msg_info "Install dependent packages..."
- install_package "${_makedepends}" "${_depends}"
+ if [[ "${nodeps}" = false ]]; then
+ msg_info "Install dependent packages..."
+ local _force_aur="${force_aur}"
+ force_aur=false
+ install_package "${_depends}"
+ force_aur="${_force_aur}"
+ unset _force_aur
+ fi
+ # ビルド準備
+ # srcdirの確認
+ if [[ -d "${_build_dir}/src" ]]; then
+ msg_info "Found ${_build_dir}/src"
+ msg_info "Packages to cleanBuild? [n] :"
+ local _yes_or_no
+ unset _yes_or_no
+ if [[ "${noconfirm}" = true ]]; then
+ echo
+ _yes_or_no="No"
+ else
+ read _yes_or_no
+ fi
+ case "${_yes_or_no}" in
+ "y" | "Y" | "yes" | "Yes" | "YES" ) add_args makepkg "--clean" ;;
+ esac
+ fi
+
+
+ # ビルド
+ add_args "makepkg" "-sf"
+ (
+ cd "${_build_dir}"
+ "${makepkg_command}" "${makepkg_args}"
+ )
+ # ビルド後のパッケージ一覧を生成
+ (
+ cd "${_build_dir}"
+ "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
+ )
+ local _pkgnames=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".packages | keys[]" | sed 's/ //g'))
+ local _pkgver="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgver" | sed 's/ //g')"
+ local _pkgrel="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgrel" | sed 's/ //g')"
+ local _arch_array=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".arch[]"))
+ local _arch _pkgname
+ if [[ "${_arch_array[*]}" = "any" ]]; then
+ _arch="any"
+ else
+ _arch="$(uname -m)"
+ fi
+ local _PKGEXT=$(
+ source "${makepkg_config}"
+ echo "${PKGEXT}"
+ )
+ local _pkgfilelist=()
+ for _pkgname in ${_pkgnames[@]}; do
+ _pkgfilelist+=("${_build_dir}/${_pkgname}-${_pkgver}-${_pkgrel}-${_arch}${_PKGEXT}")
+ done
+
+ # インストール
+ run_pacman -U --noconfirm ${_pkgfilelist[@]}
}
# バージョンを表示して終了
# Pyalpmからlibalpmの値を取得
# 参考: https://pyalpm.readthedocs.io/en/latest/pyalpm/pyalpm.html
local _libalpm_version="$(python3 -c 'import pyalpm; print(pyalpm.alpmversion())')"
- local _pacman_version="$(pacman -Q pacman | cut -d ' ' -f 2)"
+ local _pacman_version="$("${pacman_command}" -Q pacman | cut -d ' ' -f 2)"
echo "wfa v${wfa_version} - pacman v${_pacman_version} - libalpm v${_libalpm_version}"
}
operation_remove() {
- run_pacman "${specified_packages[@]}"
+ run_pacman ${pacman_args} "${specified_packages[@]}"
}
# Usage: install_package <package1> <package2>...
install_package() {
local _package
for _package in ${@}; do
+ if ! check_installed_package "${_package}"; then
+ if ! check_aur_package "${_package}"; then
+ # 公式パッケージなのでpacmanでそのままインストール
+ run_pacman ${pacman_args} "${_package}"
+ else
+ # AUR上のパッケージの場合の処理
+ install_aur_package "${_package}"
+ #msg_error "Getting the AUR package has not been implemented yet." 1
+ fi
+ fi
+ done
+}
+
+operation_sync(){
+ local _package
+ for _package in ${specified_packages[@]}; do
if ! check_aur_package "${_package}" && [[ "${force_aur}" = false ]]; then
# 公式パッケージなのでpacmanでそのままインストール
- run_pacman "${_package}"
+ run_pacman ${pacman_args} "${_package}"
else
# AUR上のパッケージの場合の処理
install_aur_package "${_package}"
done
}
-operation_sync(){
- install_package "${specified_packages[@]}"
-}
-
# Parse options
ARGUMENT="${@}"
-_opt_short="QRShVdb:a"
-_opt_long="query,remove,sync,help,version,debug,dbpath:,aururl,aur,noconfirm"
+_opt_short="QRShVdb:ay"
+_opt_long="query,remove,sync,help,version,debug,dbpath:,aururl,aur,noconfirm,config:,makepkg:,mflags:,pacman:,git:,gitflags:,gpg:,gpgflags:,makepkgconf:,nomakepkgconf,nodeps,refresh,bash-debug"
OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- ${ARGUMENT})
[[ ${?} != 0 ]] && exit 1
msg_debug "Assume targets are from the AUR"
shift 1
;;
- -d | --debug)
+ --debug)
debug=true
- add_pacman_args "--debug"
+ add_args pacman "--debug"
+ shift 1
+ ;;
+ -d | --nodeps)
+ nodeps=true
+ add_args pacman "--nodeps"
shift 1
;;
-b | --dbpath)
- add_pacman_args "--dbpath '${2}'"
+ add_args pacman "--dbpath '${2}'"
shift 2
;;
+ -y | --refresh)
+ option_y_count=$(( option_y_count + 1 ))
+ shift 1
+ ;;
--aururl)
aururl="${2}"
shift 2
;;
--noconfirm)
- add_pacman_args "--noconfirm"
+ add_args pacman "--noconfirm"
noconfirm=true
shift 1
;;
+ --config)
+ pacman_config="${2}"
+ add_args pacman "--config \"${2}\""
+ shift 2
+ ;;
+ --makepkg)
+ makepkg_command="${2}"
+ shift 2
+ ;;
+ --mflags)
+ makepkg_args="${2}"
+ shift 2
+ ;;
+ --pacman)
+ pacman_command="${2}"
+ shift 2
+ ;;
+ --git)
+ git_command="${2}"
+ shift 2
+ ;;
+ --gitflags)
+ git_args="${2}"
+ shift 2
+ ;;
+ --makepkgconfig)
+ if [[ "${nomakepkgconf}" = false ]]; then
+ makepkg_config="${2}"
+ else
+ msg_warn "--nomakepkgconf is specified.\n--makepkgconf has been ignored."
+ fi
+ shift 2
+ ;;
+ --nomakepkgconf)
+ makepkg_config="/etc/makepkg.conf"
+ nomakepkgconf=true
+ shift 1
+ ;;
+ --bash-debug)
+ bash_debug=true
+ set -xv
+ shift 1
+ ;;
-h | --help)
usage
shift 1
specified_packages=(${@})
+# Run database update
+if (( "${option_y_count}" == 1 )); then
+ run_pacman -Sy
+elif (( "${option_y_count}" >= 2 )); then
+ run_pacman -Syy
+fi
+
case "${operation}" in
"version")
operation_version