7 # Email : hayao@fascode.net
9 # (c) 2019-2020 Fascode Network.
13 # Wfa is a multilingual AUR helper written in bash that is being developed to replace yaourt
17 # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
18 # Version 2, December 2004
20 # Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
22 # Everyone is permitted to copy and distribute verbatim or modified
23 # copies of this license document, and changing it is allowed as long
24 # as the name is changed.
26 # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
27 # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
29 # 0. You just DO WHAT THE FUCK YOU WANT TO.
36 ######################################################################################
38 # 翻訳はBashの連想配列を使用して行います
39 # 連想配列名は echo "${LANG}" | cut -d "." -f 1 の実行結果の値です
44 ["Undefined operation"]="未定義のオペレーションです"
45 ["only one operation may be used at a time"]="一度に使用できるオペレーションは1つだけです"
46 ["Failed to set the argument of %s"]="%sの引数の設定に失敗しました"
47 ["Setting that command is not currently supported"]="そのコマンドの設定は現在サポートされていません"
48 ["Searching in AUR ..."]="AUR内を検索しています..."
49 ["No package with an exact name match was found"]="完全に一致する名前のパッケージが見つかりませんでした"
50 ["Select a package %s with an exact name match"]="名前が完全に一致するパッケージ %s を選択します"
51 ["Download PKGBUILD of %s"]="%s のPKGBUILDをダウンロード"
52 ["Get PKGBUILD from %s"]="%sからPKGBUILDを取得します"
53 ["PKGBUILD has already been downloaded"]="PKGBUILDは既にダウンロードされています"
54 ["Do you want to overwrite and download? [n] :"]="上書きダウンロードしますか? [n] :"
55 ["Unpacking the tarball of PKGBUILD ..."]="PKGBUILDを展開しています ..."
56 [".SRCINFO was not found.\nGenerating it using makepkg"]=".SCRINFOが見つかりませんでした。makepkgを使用して生成しています"
57 ["Conflict(s) was found"]="衝突が見つかりました"
58 ["Install dependent packages..."]="依存パッケージをインストールします..."
59 ["Found %s"]="%s を見つけました"
60 ["Packages to cleanBuild? [n] :"]="パッケージをクリーンビルドしますか? [n] :"
61 ["Could not find all required packages: %s"]="必要なすべてのパッケージが見つかりませんでした: %s"
62 ["This is a feature that has not been implemented yet"]="まだ実装されていない機能です"
63 ["Package not found on AUR: %s"]="パッケージがAUR上から見つかりませんでした: "
64 ["There is no aurvote"]="aurvote が見つかりませんでした"
65 ["Please install with %s"]="%s でインストールしてください"
66 ["Voted for %s"]="%s に投票しました"
67 ["Unvoted for %s"]="%s の投票を解除しました"
68 ["Help for this operation is not implemented"]="このオペレーションのヘルプは実装されていません"
69 ["(Orphaned)"]="(メンテナ不在)"
70 ["[Installed]"]="[インストール済み]"
71 ["This is a feature that has not been implemented yet"]="まだ実装されていない機能です"
72 ["Operation: %s"]="オペレーション: %s"
73 ["Raw popularity: %s"]="人気度の正確な値: %s"
74 ["This program is an alpha version that is not yet stable\nIf you find a bug, please share it on GitHub\nhttps://github.com/hayao0819/wfa/issues"]="このプログラムはまだ安定しないアルファ版です\nもしバグを見つけたらGitHub上で共有してください\nhttps://github.com/hayao0819/wfa/issues"
75 ["Please make a contract with me and become a Puella Magi !"]="僕と契約して魔法少女になってよ! "
80 # 翻訳データが存在しない場合はデフォルトメッセージ(英語)が出力されます
81 # そのため英語の翻訳データは必要ありません
85 ######################################################################################
92 wfa_path="$(dirname "$(realpath "${0}")")/$(basename "${0}")"
100 aururl="https://aur.archlinux.org/"
103 #-- options (bool) --#
118 makepkg_command="/usr/bin/makepkg"
120 makepkg_config="/etc/makepkg.conf"
126 pacman_command="/usr/bin/pacman"
128 pacman_config="/etc/pacman.conf"
134 git_command="/usr/bin/git"
140 gpg_command="/usr/bin/gpg"
146 sudo_command="/usr/bin/sudo"
152 curl_command="/usr/bin/curl"
157 ######################################################################################
162 if [[ "${msgdebug}" = true ]]; then
170 if [[ "${bash_debug}" = true ]]; then
178 # https://github.com/FascodeNet/alterlinux/blob/dev/tools/msg.sh の変数名にアンダーバーを追加し関数化
180 local OPTIND OPTARG arg
182 local _appname="msg.sh"
183 local _bash_debug=false
187 local _msg_type="info"
189 local _label_space="7"
190 local _adjust_chr=" "
191 local _customized_label=false
192 local _customized_label_color=false
194 local _noappname=false
195 local _noadjust=false
196 local _output="stdout"
199 echo "usage msg [option] [type] [message]"
201 echo "Display a message with a colored app name and message type label"
203 echo " General type:"
204 echo " info General message"
205 echo " warn Warning message"
206 echo " error Error message"
207 echo " debug Debug message"
209 echo " General options:"
210 echo " -a [name] Specify the app name"
211 echo " -c [character] Specify the character to adjust the label"
212 echo " -l [label] Specify the label."
213 echo " -n | --nocolor No output colored output"
214 echo " -o [option] Specify echo options"
215 echo " -r [color] Specify the color of label"
216 echo " -s [number] Specifies the label space."
217 echo " -x | --bash-debug Enables output bash debugging"
218 echo " -h | --help This help message"
220 echo " --nolabel Do not output label"
221 echo " --noappname Do not output app name"
222 echo " --noadjust Do not adjust the width of the label"
225 while getopts "a:c:l:no:r:s:xh-:" arg; do
231 _adjust_chr="${OPTARG}"
234 _customized_label=true
235 _msg_label="${OPTARG}"
241 _echo_opts="${OPTARG}"
244 _customized_label_color=true
276 _label_space="${OPTARG}"
317 shift $((OPTIND - 1))
342 # You can specify multiple decorations with ;.
343 # 0 => All attributs off (ノーマル)
345 # 4 => Underscore (下線)
347 # 7 => Reverse video on (色反転)
354 [[ "${_customized_label_color}" = false ]] && _labelcolor="32"
355 [[ "${_customized_label}" = false ]] && _msg_label="Info"
361 [[ "${_customized_label_color}" = false ]] && _labelcolor="33"
362 [[ "${_customized_label}" = false ]] && _msg_label="Warning"
368 [[ "${_customized_label_color}" = false ]] && _labelcolor="35"
369 [[ "${_customized_label}" = false ]] && _msg_label="Debug"
375 [[ "${_customized_label_color}" = false ]] && _labelcolor="31"
376 [[ "${_customized_label}" = false ]] && _msg_label="Error"
380 echo "Please specify the message type" >&2
384 echo "Unknown message type" >&2
389 _word_count="${#_msg_label}"
394 if [[ "${_nolabel}" = false ]]; then
395 if [[ "${_noadjust}" = false ]]; then
396 for __time in $( seq 1 $(( ${_label_space} - ${_word_count})) ); do
397 echo -ne "${_adjust_chr}"
400 if [[ "${_nocolor}" = false ]]; then
401 echo -ne "\e[$([[ -v _backcolor ]] && echo -n "${_backcolor}"; [[ -v _labelcolor ]] && echo -n ";${_labelcolor}"; [[ -v _decotypes ]] && echo -n ";${_decotypes}")m${_msg_label}\e[m "
403 echo -ne "${_msg_label} "
409 if [[ "${_noappname}" = false ]]; then
410 if [[ "${_nocolor}" = false ]]; then
411 echo -ne "\e[36m[${_appname}]\e[m "
413 echo -ne "[${_appname}] "
418 for _count in $(seq "1" "$(echo -ne "${_message}\n" | wc -l)"); do
419 _echo_message=$(echo -ne "${_message}\n" |head -n "${_count}" | tail -n 1 )
420 _full_message="$(echo_appname)$(echo_type)${_echo_message}"
423 echo ${_echo_opts} "${_full_message}" >&1
426 echo ${_echo_opts} "${_full_message}" >&2
429 echo ${_echo_opts} "${_full_message}" > ${_output}
440 local _locale="$(echo "${LANG}" | cut -d "." -f 1)"
444 if [[ -z "${*}" ]]; then
447 local _translated_text="$(eval echo '$'{${_locale}[\"${*}\"]})"
449 if [[ -z "${_translated_text}" ]]; then
450 if [[ ! "${_locale}" = "C" ]] && [[ ! "${_locale}" = "en_US" ]]; then
451 echo "$(text -nc cyan "[WFA]") $(text -nc yellow "Warning") No translation data was found (${*})" 1>&2
455 echo "${_translated_text}"
459 local _text _fulltext=() _main
461 if declare -p "${_locale}" 2> /dev/null 1>/dev/null; then
462 _main="$(_get_text ${1})"
467 echo "$(printf "${_main}" "${@}")"
469 _msg_translate "${@}"
474 # Show an INFO message
478 local _msg_opts="-a ${wfa_name}"
479 if [[ "${1}" = "-n" ]]; then
480 _msg_opts="${_msg_opts} -o -n"
483 [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
484 [[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
485 msg ${_msg_opts} info "$(translate "${@}")"
489 # Show an Warning message
493 local _msg_opts="-a ${wfa_name}"
494 if [[ "${1}" = "-n" ]]; then
495 _msg_opts="${_msg_opts} -o -n"
498 [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
499 [[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
500 msg ${_msg_opts} warn "$(translate "${@}")"
504 # Show an debug message
508 if [[ "${debug}" = true ]]; then
509 local _msg_opts="-a ${wfa_name}"
510 if [[ "${1}" = "-n" ]]; then
511 _msg_opts="${_msg_opts} -o -n"
514 [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
515 [[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
516 msg ${_msg_opts} debug "$(translate "${@}")"
521 # Show an ERROR message then exit with status
523 # $2: exit code number (with 0 does not exit)
526 local _msg_opts="-a ${wfa_name}"
527 if [[ "${1}" = "-n" ]]; then
528 _msg_opts="${_msg_opts} -o -n"
531 [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
532 [[ "${nocolor}" = true ]] && _msg_opts="${_msg_opts} -n"
533 msg ${_msg_opts} error "$(translate "${@}")"
538 # text [-b/-c color/-n/-f/-l/]
541 local OPTIND OPTARG arg _textcolor _decotypes="" _message _notranslate=false
542 while getopts "c:bnfl" arg; do
576 _decotypes="${_decotypes};1"
579 _decotypes="${_decotypes};5"
582 _decotypes="${_decotypes};4"
589 shift $((OPTIND - 1))
592 if [[ "${_notranslate}" = false ]]; then
593 _message="$(translate "${@}")"
595 if [[ "${nocolor}" = true ]]; then
598 echo -ne "\e[$([[ -v _textcolor ]] && echo -n ";${_textcolor}"; [[ -v _decotypes ]] && echo -n "${_decotypes}")m${_message}\e[m"
604 ######################################################################################
609 # Delete the file if it exists.
610 # For directories, rm -rf is used.
611 # If the file does not exist, skip it.
612 # remove <file> <file> ...
614 local _list=($(echo "$@")) _file
615 for _file in "${_list[@]}"; do
616 msg_debug "Removing ${_file}"
617 if [[ -f "${_file}" ]]; then
619 elif [[ -d "${_file}" ]]; then
626 local _pacman_help=false
631 echo "${wfa_command}"
632 echo "${wfa_command} <operation> [...]"
635 echo " ${wfa_command} {-h --help}"
636 echo " ${wfa_command} {-A --vote}"
637 echo " ${wfa_command} {-V --version}"
638 #echo " ${wfa_command} {-D --database} <options> <package(s)>"
639 #echo " ${wfa_command} {-F --files} [options] [package(s)]"
640 echo " ${wfa_command} {-Q --query} [options] [package(s)]"
641 echo " ${wfa_command} {-R --remove} [options] <package(s)>"
642 echo " ${wfa_command} {-S --sync} [options] [package(s)]"
643 #echo " ${wfa_command} {-T --deptest} [options] [package(s)]"
644 #echo " ${wfa_command} {-U --upgrade} [options] <file(s)>"
646 #echo "New operations:"
647 #echo " ${wfa_command} {-P --show} [options]"
648 #echo " ${wfa_command} {-G --getpkgbuild} [package(s)]"
651 echo " --repo Assume targets are from the repositories"
652 echo " -a --aur Assume targets are from the AUR"
654 echo "Permanent configuration options:"
655 echo " --aururl <url> Set an alternative AUR URL"
656 echo " --makepkg <file> makepkg command to use"
657 echo " --mflags <flags> Pass arguments to makepkg"
658 echo " --pacman <file> pacman command to use"
659 echo " --git <file> git command to use"
660 echo " --gitflags <flags> Pass arguments to git"
661 echo " --gpg <file> gpg command to use"
662 echo " --gpgflags <flags> Pass arguments to gpg"
663 echo " --config <file> pacman.conf file to use"
664 echo " --makepkgconf <file> makepkg.conf file to use"
665 echo " --nomakepkgconf Use the default makepkg.conf"
667 echo "wfa specific options:"
668 echo " -c --clean Remove unneeded dependencies"
670 echo "This program is an alpha version that is not yet stable"
671 echo "If you find a bug, please share it on GitHub"
672 echo "https://github.com/hayao0819/wfa/issues"
676 local _wfa_usage_sync
678 echo "usage: ${wfa_command} {-S --sync} [options] [package(s)]"
680 echo " -b, --dbpath <path> set an alternate database location"
681 echo " -c, --clean remove old packages from cache directory (-cc for all)"
682 echo " -d, --nodeps skip dependency version checks (-dd to skip all checks)"
683 echo " -s, --search <regex> search remote repositories for matching strings"
684 echo " -u, --sysupgrade upgrade installed packages (-uu enables downgrades)"
685 echo " -y, --refresh download fresh package databases from the server"
686 echo " (-yy to force a refresh even if up to date)"
687 echo " --arch <arch> set an alternate architecture"
688 echo " --color <when> colorize the output"
689 echo " --config <path> set an alternate configuration file"
690 echo " --confirm always ask for confirmation"
691 echo " --debug display debug messages"
692 echo " --disable-download-timeout"
693 echo " use relaxed timeouts for download"
694 echo " --noconfirm do not ask for any confirmation"
698 local _wfa_usage_remove
699 _wfa_usage_remove() {
700 echo "usage: ${wfa_command} {-R --remove} [options] <package(s)>"
702 echo " -b, --dbpath <path> set an alternate database location"
703 echo " -d, --nodeps skip dependency version checks (-dd to skip all checks)"
704 echo " -u, --unneeded remove unneeded packages"
705 echo " --arch <arch> set an alternate architecture"
706 echo " --color <when> colorize the output"
707 echo " --config <path> set an alternate configuration file"
708 echo " --confirm always ask for confirmation"
709 echo " --debug display debug messages"
710 echo " --disable-download-timeout"
711 echo " use relaxed timeouts for download"
712 echo " --noconfirm do not ask for any confirmation"
715 if [[ "${operation}" = "none" ]]; then
717 elif [[ "${_pacman_help}" = true ]]; then
718 "${pacman_command}" -h --${operation}
719 elif [[ "$(type -t "_wfa_usage_${operation}" )" = "function" ]]; then
720 _wfa_usage_${operation}
722 msg_error "Help for this operation is not implemented"
728 if [[ "${operation}" = "none" ]]; then
730 add_args pacman "--${operation}"
732 msg_error "only one operation may be used at a time"
738 if (( ${UID} == 0 )); then
746 run_sudo "${pacman_command}" ${@}
754 # https://github.com/FascodeNet/aptpac/blob/master/aptpac のADD_OPTION関数を参考
755 # Usage: add_args [pacman/makepkg/git/gpg/sudo/curl] <args1> <args2>...
763 _args_array=(${makepkg_args})
765 makepkg_args=${_args_array[@]}
766 msg_debug "makepkg ARGS: ${makepkg_args}"
770 _args_array=(${pacman_args})
772 pacman_args=${_args_array[@]}
773 msg_debug "pacman ARGS: ${pacman_args}"
776 _args_array=(${mpg_args})
778 git_args=${_args_array[@]}
779 msg_debug "git ARGS: ${git_args}"
782 _args_array=(${gpg_args})
784 gpg_args=${_args_array[@]}
785 msg_debug "gpg ARGS: ${gpg_args}"
788 _args_array=(${sudo_args})
790 sudo_args=${_args_array[@]}
791 msg_debug "sudo ARGS: ${sudo_args}"
794 _args_array=(${curl_args})
796 curl_args=${_args_array[@]}
797 msg_debug "curl ARGS: ${curl_args}"
800 msg_error "Failed to set the argument of %s" "${_target}"
801 msg_error "Setting that command is not currently supported"
807 # 引数で指定されたパッケージがAUR以外の場所に存在しない場合にのみ正常終了します(AURのパッケージの場合に正常終了)
808 check_aur_package() {
809 local _package="${1}"
810 # 参考: https://qiita.com/Hayao0819/items/a8740a17301fafa2fdab
811 if [[ -z "$(pacman -Ssq "${_package}" 2>/dev/null | grep -o ".*${_package}$")" ]]; then
820 # 引数で指定されたパッケージが既にインストールされている場合は正常終了します。
821 check_installed_package() {
822 local _package="${1}"
823 if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1; then
830 # ~/.cacheに相当するディレクトリを返します
832 local _user_config_dir _cache_dir
833 if [[ -v XDG_CONFIG_HOME ]]; then
834 _user_config_dir="${XDG_CONFIG_HOME}"
836 _use_config_dir="${HOME}/.config"
838 if [[ -f "${_use_config_dir}/user-dirs.dirs" ]]; then
839 source "${_use_config_dir}/user-dirs.dirs"
841 if [[ -v XDG_CACHE_HOME ]]; then
842 _cache_dir="${XDG_CACHE_HOME}"
844 _cache_dir="${HOME}/.cache"
846 echo -n "${_cache_dir}"
849 # Usage: get_srcinfo_data <path> <var>
850 # 参考: https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
852 local _srcinfo="${1}" _ver="${2}"
853 local _srcinfo_json=$(python << EOF
854 from srcinfo.parse import parse_srcinfo; import json
858 parsed, errors = parse_srcinfo(text)
859 print(json.dumps(parsed))
862 echo "${_srcinfo_json}" | jq -rc "${2}" | tr '\n' ' '
866 local _package="${1}"
867 local _aur_json=$("${curl_command}" ${curl_args} -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name&arg=${_package}" | jq -r)
868 if (( "$(echo "${_aur_json}" | jq -r ".resultcount")" != 0 )); then
869 echo "${_aur_json}" | jq -r ".results[]"
874 # AURからパッケージをビルドしてインストールします
875 # 現在1つのパッケージしか指定できません
876 install_aur_package() {
877 local _package="${1}"
880 if [[ ! -v wfa_cache_dir ]]; then
881 wfa_cache_dir="$(get_cache_dir)/wfa"
883 mkdir -p "${wfa_cache_dir}/archive"
884 mkdir -p "${wfa_cache_dir}/build/${_package}"
887 msg_info "Searching in AUR ..."
888 local _aur_json="$(get_aur_json "${_package}")"
889 if [[ -z "${_aur_json}" ]]; then
890 msg_error "Could not find all required packages: %s" "${_package}"
893 local _found_packages="$(echo "${_aur_json}" | jq -r --tab '.Name')"
894 #msg_debug "Found package: $(echo ${_found_packages} | tr '\n' ' ')"
896 if [[ -n "$(echo "${_found_packages}" | grep -x "${_package}" )" ]]; then
897 msg_debug "Select a package %s with an exact name match" "${_package}"
899 msg_error "No package with an exact name match was found"
904 msg_info "Download PKGBUILD of %s" "${_package}"
905 _aur_json=$(echo "${_aur_json}" | jq -r "select(.Name == \"${_package}\")" )
906 local _aur_snapshot_url="${aururl%/}$(echo "${_aur_json}" | jq -r ".URLPath")"
907 local _aur_version="$(echo "${_aur_json}" | jq -r ".Version")"
908 msg_debug "Get PKGBUILD from %s" "${_aur_snapshot_url}"
910 local _pkgbuild_archive_path="${wfa_cache_dir}/archive/${_package}-${_aur_version}"
911 local _download_pkgbuild=true
912 if [[ -f "${_pkgbuild_archive_path}" ]]; then
913 msg_warn "PKGBUILD has already been downloaded"
914 msg_warn -n "Do you want to overwrite and download? [n] :"
916 if [[ "${noconfirm}" = true ]]; then
922 case "${_yes_or_no}" in
923 "y" | "Y" | "yes" | "Yes" | "YES" ) _download_pkgbuild=true ;;
924 * ) _download_pkgbuild=false ;;
927 if [[ "${_download_pkgbuild}" = true ]]; then
928 remove "${_pkgbuild_archive_path}"
929 "${curl_command}" ${curl_args} -L -C - -f -o "${_pkgbuild_archive_path}" "${_aur_snapshot_url}"
933 msg_info "Unpacking the tarball of PKGBUILD ..."
934 tar -xv -f "${_pkgbuild_archive_path}" -C "${wfa_cache_dir}/build/" > /dev/null 2>&1
937 local _build_dir="${wfa_cache_dir}/build/${_package}"
938 if [[ ! -f "${_build_dir}/.SRCINFO" ]]; then
939 msg_warn ".SRCINFO was not found.\nGenerating it using makepkg"
942 "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
946 local _makedepends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".makedepends[]?")"
947 local _depends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".depends[]?")"
948 local _conflicts="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".conflicts[]?")"
949 msg_debug "makedepends: %s" "${_makedepends}"
950 msg_debug "depends: %s" "${_depends}"
951 msg_debug "conflicts: %s " "${_conflicts}"
955 local _pkg _conflicts_found=false
956 for _pkg in ${_conflicts[@]}; do
957 if "${pacman_command}" -Qq "${_pkg}" > /dev/null 2>&1 ; then
958 _conflicts_found=true
959 msg_error "${_package} is colliding with ${_pkg}"
962 if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1 && [[ ! "$("${pacman_command}" -Qq "${_package}" 2> /dev/null)" = "${_package}" ]]; then
963 msg_error "${_package} is colliding with $("${pacman_command}" -Qq "${_package}")"
964 _conflicts_found=true
966 if [[ "${_conflicts_found}" = true ]]; then
967 msg_error "Conflict(s) was found"
973 if [[ "${nodeps}" = false ]]; then
974 msg_info "Install dependent packages..."
975 local _force_aur="${force_aur}"
977 install_package "${_depends}"
978 force_aur="${_force_aur}"
984 if [[ -d "${_build_dir}/src" ]]; then
985 msg_info "Found %s" "${_build_dir}/src"
986 msg_info -n "Packages to cleanBuild? [n] :"
989 if [[ "${noconfirm}" = true ]]; then
995 case "${_yes_or_no}" in
996 "y" | "Y" | "yes" | "Yes" | "YES" ) add_args makepkg "--clean" ;;
1002 add_args "makepkg" "-sf"
1005 "${makepkg_command}" "${makepkg_args}"
1012 "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
1014 local _pkgnames=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".packages | keys[]"))
1015 local _pkgver="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgver" | sed 's/ //g')"
1016 local _pkgrel="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgrel" | sed 's/ //g')"
1017 local _arch_array=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".arch[]"))
1018 local _arch _pkgname
1019 if [[ "${_arch_array[*]}" = "any" ]]; then
1025 source "${makepkg_config}"
1028 local _pkgfilelist=()
1029 for _pkgname in ${_pkgnames[@]}; do
1030 _pkgfilelist+=("${_build_dir}/${_pkgname}-${_pkgver}-${_pkgrel}-${_arch}${_PKGEXT}")
1034 run_pacman -U --noconfirm ${_pkgfilelist[@]}
1038 search_aur_package() {
1039 local _package="${1}"
1040 local _aur_json="$(get_aur_json "${_package}")"
1041 if [[ -z "${_aur_json}" ]]; then
1042 msg_error "Could not find all required packages: %s" "${_package}"
1045 local _found_pkgname=($(echo "${_aur_json}" | jq -r ".Name" ))
1047 if [[ "${quiet}" = true ]]; then
1050 echo "${_found_pkgname[*]}"
1053 local _found_package __pkgver __popularity __vote __pkgdesc __orphaned __installed __output_text=()
1054 for _found_package in ${_found_pkgname[@]}; do
1057 _found_json="$(echo ${_aur_json} | jq "select(.Name == \"${_found_package}\")")"
1059 #echo "${_found_json}"
1060 __pkgver="$(echo "${_found_json}" | jq -r ".Version" )"
1061 __popularity="$(echo "${_found_json}" | jq -r ".Popularity" )"
1062 __vote="$(echo "${_found_json}" | jq -r ".NumVotes" )"
1063 __pkgdesc="$(echo "${_found_json}" | jq -r ".Description" )"
1066 # 参考: http://www.rivhiro-weather.com/knowledge/?p=536
1067 msg_debug "Raw popularity: %s" "${__popularity}"
1068 __popularity="$(printf "%g\n" "${__popularity}" | awk '{printf("%4.2f", $1)}')"
1071 #参考: https://www.366service.com/jp/qa/7c95f46e5236039134ff5b862ae2cd13
1072 if ! echo "${_found_json}" | jq -r --exit-status ".Maintainer" 1> /dev/null 2> /dev/null ; then
1077 if check_installed_package "${_found_package}"; then
1082 "$(text -n -c blue -b "aur")/$(text -n -b "${_found_package}") $(text -n -c cyan "${__pkgver}") (+$(text -n -b "${__vote} ${__popularity}"))"
1085 if [[ "${__orphaned}" = true ]]; then
1086 __output_text+=("$(text -bc red "(Orphaned)")")
1089 if [[ "${__installed}" = true ]]; then
1090 __output_text+=("$(text -bc cyan "[Installed]")")
1092 echo "${__output_text[*]}"
1093 echo " ${__pkgdesc}"
1094 unset __pkgver __popularity __vote __pkgdesc _found_json __orphaned __installed __output_text
1100 operation_version() {
1101 # Pyalpmからlibalpmの値を取得
1102 # 参考: https://pyalpm.readthedocs.io/en/latest/pyalpm/pyalpm.html
1103 local _libalpm_version="$(python3 -c 'import pyalpm; print(pyalpm.alpmversion())')"
1104 local _pacman_version="$("${pacman_command}" -Q pacman | cut -d ' ' -f 2)"
1105 echo "wfa v${wfa_version} - pacman v${_pacman_version} - libalpm v${_libalpm_version}"
1108 operation_remove() {
1109 local _package _not_found=false
1110 for _package in ${specified_packages[@]}; do
1111 if ! check_installed_package "${_package}"; then
1112 msg_error "target not found: %s" "${_package}"
1116 if [[ "${_not_found}" = true ]]; then
1119 run_pacman ${pacman_args} "${specified_packages[@]}"
1123 # Usage: install_package <package1> <package2>...
1125 local _package _repo_packages=() _aur_packages=()
1126 for _package in ${@}; do
1127 if ! check_installed_package "${_package}"; then
1128 if ! check_aur_package "${_package}"; then
1129 # 公式パッケージなのでpacmanでそのままインストール
1130 _repo_packages+=("${_package}")
1133 _aur_packages+=("${_package}")
1138 if (( "${#_repo_packages[@]}" > 0 )); then
1139 run_pacman --asdeps ${pacman_args} "${_repo_packages[@]}"
1142 if (( "${#_aur_packages[@]}" > 0 )); then
1144 for _package in ${_aur_packages[@]}; do
1145 install_aur_package "${_package}"
1150 upgrade_aur_package() {
1152 msg_error "This is a feature that has not been implemented yet"
1157 if (( "${sync_clean_count}" >= 1 )); then
1158 remove "$(get_cache_dir)/wfa"
1159 run_pacman ${pacman_args} $(
1161 for _count in $(seq 1 ${sync_clean_count}); do
1168 if [[ "${sync_search}" = true ]]; then
1169 for _package in ${specified_packages[@]}; do
1170 search_aur_package "${_package}"
1172 "${pacman_command}" ${pacman_args} ${specified_packages[@]} || :
1174 if [[ "${sync_upgrade}" = true ]]; then
1176 run_pacman ${pacman_args} --sysupgrade
1178 for _package in ${specified_packages[@]}; do
1179 if ! check_aur_package "${_package}" && [[ "${force_aur}" = false ]]; then
1180 # 公式パッケージなのでpacmanでそのままインストール
1181 run_pacman ${pacman_args} "${_package}"
1184 install_aur_package "${_package}"
1185 #msg_error "Getting the AUR package has not been implemented yet."
1196 if ! type aurvote 1> /dev/null 2> /dev/null; then
1197 msg_error "There is no aurvote"
1198 msg_error "Please install with %s" "\"wfa -S aurvote\""
1202 local _package _aur_json _found_result_count _pkgver _before_popularity _before_vote
1203 for _package in ${specified_packages[@]}; do
1206 local _aur_json="$(get_aur_json "${_package}")"
1207 if [[ -z "${_aur_json}" ]]; then
1208 msg_error "Could not find all required packages: %s" "${_package}"
1211 _aur_json=$(echo "${_aur_json}" | jq -r "select(.Name == \"${_package}\")")
1214 _pkgver="$(echo "${_aur_json}" | jq -r ".Version" )"
1215 _before_popularity="$(printf "%g\n" "$(echo "${_aur_json}" | jq -r ".Popularity" )" | awk '{printf("%4.2f", $1)}')"
1216 _before_vote="$(echo "${_aur_json}" | jq -r ".NumVotes" )"
1219 if [[ "$(aurvote --check "${_package}")" = "not voted" ]]; then
1220 msg_info "Voted for %s" "${_package}"
1221 aurvote --vote "${_package}" 1> /dev/null
1223 msg_info "Unvoted for %s" "${_package}"
1224 aurvote --unvote "${_package}" 1> /dev/null
1228 _aur_json=$(get_aur_json | jq -r "select(.Name == \"${_package}\")")
1229 _after_popularity="$(printf "%g\n" "$(echo "${_aur_json}" | jq -r ".Popularity" )" | awk '{printf("%4.2f", $1)}')"
1230 _after_vote="$(echo "${_aur_json}" | jq -r ".NumVotes" )"
1233 msg_info "%s %s (+%s) → (+%s)" "$(text -b "${_package}")" "$(text -c cyan "${_pkgver}")" "$(text -b "${_before_vote} ${_before_popularity}")" "$(text -b "${_after_vote} ${_after_popularity}")"
1237 unavailable_in_this_operation() {
1238 msg_error "This option is not available in the current operation"
1244 local _operation="${1}"
1245 msg_debug "Operation: %s" "${_operation}"
1246 if [[ "${quiet}" = false ]]; then
1247 msg_warn "This program is an alpha version that is not yet stable\nIf you find a bug, please share it on GitHub\nhttps://github.com/hayao0819/wfa/issues"
1250 operation_${_operation}
1255 _opt_short="AQRShVdb:aysucqn"
1256 _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,msg-debug,sysupgrade,color:,nocolor,clean,quiet,arch:,confirm,disable-download-timeout,curl:,curlflags:,unneeded,puella,wfa-debug,cascade"
1258 OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- ${ARGUMENT})
1259 [[ ${?} != 0 ]] && exit 1
1260 unset _opt_short _opt_long
1262 eval set -- "${OPT}"
1263 msg_debug "Argument: ${OPT}"
1268 set_operation "vote"
1272 set_operation "query"
1276 set_operation "remove"
1280 set_operation "sync"
1284 set_operation "version"
1297 eval set -- "${OPT}"
1303 msg_debug "Assume targets are from the AUR"
1308 add_args pacman "--debug"
1313 add_args pacman "--nodeps"
1317 add_args pacman "--dbpath '${2}'"
1321 option_y_count=$(( option_y_count + 1 ))
1324 -s | --search | --recursive)
1327 if [[ "${operation}" = "sync" ]]; then
1328 add_args pacman "--search"
1331 unavailable_in_this_operation
1335 if [[ "${operation}" = "remove" ]]; then
1336 add_args pacman "--recursive"
1338 unavailable_in_this_operation
1342 case "${operation}" in
1344 add_args pacman "--search"
1348 add_args pacman "--recursive"
1351 unavailable_in_this_operation
1358 -u | --sysupgrade | --unneeded)
1361 if [[ "${operation}" = "sync" ]]; then
1364 unavailable_in_this_operation
1368 if [[ "${operation}" = "remove" ]]; then
1369 add_args pacman "--unneeded"
1371 unavailable_in_this_operation
1375 case "${operation}" in
1380 add_args pacman "--unneeded"
1386 unavailable_in_this_operation
1393 -c | --clean | --cascade)
1396 if [[ "${operation}" = "sync" ]]; then
1397 sync_clean_count=$(( sync_clean_count + 1 ))
1399 unavailable_in_this_operation
1403 if [[ "${operation}" = "remove" ]]; then
1404 add_args pacman "--cascade"
1406 unavailable_in_this_operation
1410 case "${operation}" in
1412 sync_clean_count=$(( sync_clean_count + 1 ))
1415 add_args pacman "--cascade"
1418 unavailable_in_this_operation
1427 add_args pacman "--quiet"
1431 add_args pacman "--nosave"
1436 add_args pacman "--arch ${2}"
1444 add_args pacman "--noconfirm"
1449 pacman_config="${2}"
1450 add_args pacman "--config ${2}"
1454 makepkg_command="${2}"
1458 #makepkg_args="${2}"
1459 add_args makepkg "${2}"
1463 pacman_command="${2}"
1476 if [[ "${nomakepkgconf}" = false ]]; then
1477 makepkg_config="${2}"
1479 msg_warn "--nomakepkgconf is specified.\n--makepkgconf has been ignored."
1484 makepkg_config="/etc/makepkg.conf"
1501 add_args pacman "--color never"
1505 add_args pacman "--color always"
1508 msg_error "auto is not currently supported."
1509 add_args pacman "--color auto"
1515 add_args pacman "--color never"
1522 --disable-download-timeout)
1523 add_args curl "--max-time 0"
1524 add_args pacman "--disable-download-timeout"
1532 add_args curl "${2}"
1536 text -flb "Please make a contract with me and become a Puella Magi !"
1560 specified_packages=(${@})
1562 # Run database update
1563 if (( "${option_y_count}" == 1 )); then
1565 elif (( "${option_y_count}" >= 2 )); then
1569 # set_operationで設定された操作を実行
1570 case "${operation}" in
1571 "version" | "sync" | "remove" | "vote")
1572 run_operation "${operation}"
1578 msg_error "Undefined operation"