OSDN Git Service

[fix] : Fixed blank output
[alterlinux/wfa.git] / wfa
1 #!/usr/bin/env bash
2 #
3 # 1. Author info
4 #
5 # Yamada Hayao
6 # Twitter: @Hayao0819
7 # Email  : hayao@fascode.net
8 #
9 # (c) 2019-2020 Fascode Network.
10 #
11 # 2. Overview
12
13 # Wfa is a multilingual AUR helper written in bash that is being developed to replace yaourt
14 #
15 # 3. License
16
17 #        DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
18 #                    Version 2, December 2004 
19 #
20 # Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> 
21 #
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. 
25 #
26 #            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
27 #   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 
28 #
29 #  0. You just DO WHAT THE FUCK YOU WANT TO.
30 #
31 #
32
33 set -eu
34
35
36 ######################################################################################
37 # ここから翻訳データ
38 # 翻訳はBashの連想配列を使用して行います
39 # 連想配列名は echo "${LANG}" | cut -d "." -f 1 の実行結果の値です
40
41
42 # 日本語
43 declare -A ja_JP=(
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
70     ["(Orphaned)"]="(メンテナ不在)"
71     ["[Installed]"]="[インストール済み]"
72     ["This is a feature that has not been implemented yet"]="まだ実装されていない機能です"
73
74     ["Please make a contract with me and become a Puella Magi !"]="僕と契約して魔法少女になってよ! "
75 )
76
77
78 # English
79 # 翻訳データが存在しない場合はデフォルトメッセージ(英語)が出力されます
80 # そのため英語の翻訳データは必要ありません
81 declare -A en_US=()
82 declare -A C=()
83
84 ######################################################################################
85 # ここからデフォルト設定の定義
86
87 #-- wfa configs --#
88 wfa_version="0.1"
89 wfa_name="WFA"
90 wfa_command="wfa"
91 wfa_path="$(dirname "$(realpath "${0}")")/$(basename "${0}")"
92
93 #-- options (int) --#
94 option_y_count=0
95 sync_clean_count=0
96
97 #-- options (str) --#
98 arch="$(uname -m)"
99 aururl="https://aur.archlinux.org/"
100 operation="none"
101
102 #-- options (bool) --#
103 bash_debug=false
104 debug=false
105 force_aur=false
106 msgdebug=false
107 nocolor=false
108 noconfirm=false
109 nodeps=false
110 nomakepkgconf=false
111 sync_search=false
112 sync_upgrade=false
113 quiet=false
114
115 #-- makepkg --#
116 # 実行ファイル
117 makepkg_command="/usr/bin/makepkg" 
118 # 設定ファイル
119 makepkg_config="/etc/makepkg.conf"
120 # 引数
121 makepkg_args=""
122
123 #-- pacman --#
124 # 実行ファイル
125 pacman_command="/usr/bin/pacman"
126 # 設定ファイル
127 pacman_config="/etc/pacman.conf"
128 # 引数
129 pacman_args=""
130
131 #-- git --#
132 # 実行ファイル
133 git_command="/usr/bin/git"
134 # 引数
135 git_args=""
136
137 #-- gpg --#
138 # 実行ファイル
139 gpg_command="/usr/bin/gpg"
140 # 引数
141 gpg_args=""
142
143 #-- sudo --#
144 # 実行ファイル
145 sudo_command="/usr/bin/sudo"
146 # 引数
147 sudo_args=""
148
149 #-- curl --#
150 # 実行ファイル
151 curl_command="/usr/bin/curl"
152 # 引数
153 curl_args=""
154
155
156 ######################################################################################
157 # ここからメッセージ関連の関数定義
158
159
160 # メッセージ出力の制御
161 # https://github.com/FascodeNet/alterlinux/blob/dev/tools/msg.sh の変数名にアンダーバーを追加し関数化
162 msg() {
163     local OPTIND OPTARG arg
164
165     local _appname="msg.sh"
166     local _bash_debug=false
167     local _nocolor=false
168     local _echo_opts=""
169     local _message=""
170     local _msg_type="info"
171     local _msg_label=""
172     local _label_space="7"
173     local _adjust_chr=" "
174     local _customized_label=false
175     local _customized_label_color=false
176     local _nolabel=false
177     local _noappname=false
178     local _noadjust=false
179     local _output="stdout"
180
181     _help() {
182         echo "usage msg [option] [type] [message]"
183         echo
184         echo "Display a message with a colored app name and message type label"
185         echo
186         echo " General type:"
187         echo "    info                      General message"
188         echo "    warn                      Warning message"
189         echo "    error                     Error message"
190         echo "    debug                     Debug message"
191         echo
192         echo " General options:"
193         echo "    -a [name]                 Specify the app name"
194         echo "    -c [character]            Specify the character to adjust the label"
195         echo "    -l [label]                Specify the label."
196         echo "    -n | --nocolor            No output colored output"
197         echo "    -o [option]               Specify echo options"
198         echo "    -r [color]                Specify the color of label"
199         echo "    -s [number]               Specifies the label space."
200         echo "    -x | --bash-debug         Enables output bash debugging"
201         echo "    -h | --help               This help message"
202         echo
203         echo "         --nolabel            Do not output label"
204         echo "         --noappname          Do not output app name"
205         echo "         --noadjust           Do not adjust the width of the label"
206     }
207
208     while getopts "a:c:l:no:r:s:xh-:" arg; do
209         case ${arg} in
210                 a) 
211                     _appname="${OPTARG}"
212                     ;;
213                 c) 
214                     _adjust_chr="${OPTARG}"
215                     ;;
216                 l) 
217                     _customized_label=true
218                     _msg_label="${OPTARG}"
219                     ;;
220                 n)
221                     _nocolor=true
222                     ;;
223                 o)
224                     _echo_opts="${OPTARG}"
225                     ;;
226                 r)
227                     _customized_label_color=true
228                     case ${OPTARG} in
229                         "black")
230                             _labelcolor="30"
231                             ;;
232                         "red")
233                             _labelcolor="31"
234                             ;;
235                         "green")
236                             _labelcolor="32"
237                             ;;
238                         "yellow")
239                             _labelcolor="33"
240                             ;;
241                         "blue")
242                             _labelcolor="34"
243                             ;;
244                         "magenta")
245                             _labelcolor="35"
246                             ;;
247                         "cyan")
248                             _labelcolor="36"
249                             ;;
250                         "white")
251                             _labelcolor="37"
252                             ;;
253                         *)
254                             return 1
255                             ;;
256                     esac
257                     ;;
258                 s)
259                     _label_space="${OPTARG}"
260                     ;;
261                 x)
262                     _bash_debug=true
263                     set -xv
264                     ;;
265                 h)
266                     _help
267                     shift 1
268                     exit 0
269                     ;;
270                 -)
271                     case "${OPTARG}" in
272                         "nocolor")
273                             _nocolor=true
274                             ;;
275                         "bash-debug")
276                             _bash_debug=true
277                             set -xv
278                             ;;
279                         "help") 
280                             _help
281                             exit 0
282                             ;;
283                         "nolabel")
284                             _nolabel=true
285                             ;;
286                         "noappname")
287                             _noappname=true
288                             ;;
289                         "noadjust")
290                             _noadjust=true 
291                             ;;
292                         *)
293                             _help
294                             exit 1
295                             ;;
296                     esac
297         esac
298     done
299
300     shift $((OPTIND - 1))
301
302     # Color echo
303     #
304     # Text Color
305     # 30 => Black
306     # 31 => Red
307     # 32 => Green
308     # 33 => Yellow
309     # 34 => Blue
310     # 35 => Magenta
311     # 36 => Cyan
312     # 37 => White
313     #
314     # Background color
315     # 40 => Black
316     # 41 => Red
317     # 42 => Green
318     # 43 => Yellow
319     # 44 => Blue
320     # 45 => Magenta
321     # 46 => Cyan
322     # 47 => White
323     #
324     # Text decoration
325     # You can specify multiple decorations with ;.
326     # 0 => All attributs off (ノーマル)
327     # 1 => Bold on (太字)
328     # 4 => Underscore (下線)
329     # 5 => Blink on (点滅)
330     # 7 => Reverse video on (色反転)
331     # 8 => Concealed on
332
333     case ${1} in
334         "info")
335             _msg_type="type"
336             _output="stdout"
337             [[ "${_customized_label_color}" = false ]] && _labelcolor="32"
338             [[ "${_customized_label}"       = false ]] && _msg_label="Info"
339             shift 1
340             ;;
341         "warn")
342             _msg_type="warn"
343             _output="stdout"
344             [[ "${_customized_label_color}" = false ]] && _labelcolor="33"
345             [[ "${_customized_label}"       = false ]] && _msg_label="Warning"
346             shift 1
347             ;;
348         "debug")
349             _msg_type="debug"
350             _output="stdout"
351             [[ "${_customized_label_color}" = false ]] && _labelcolor="35"
352             [[ "${_customized_label}"       = false ]] && _msg_label="Debug"
353             shift 1
354             ;;
355         "error")
356             _msg_type="error"
357             _output="stderr"
358             [[ "${_customized_label_color}" = false ]] && _labelcolor="31"
359             [[ "${_customized_label}"       = false ]] && _msg_label="Error"
360             shift 1
361             ;;
362         "")
363             echo "Please specify the message type" >&2
364             exit 1
365             ;;
366         *)
367             echo "Unknown message type" >&2
368             exit 1
369             ;;
370     esac
371
372     _word_count="${#_msg_label}"
373     _message="${@}"
374
375     echo_type() {
376         local __time
377         if [[ "${_nolabel}" = false ]]; then
378             if [[ "${_noadjust}" = false ]]; then
379                 for __time in $( seq 1 $(( ${_label_space} - ${_word_count})) ); do
380                     echo -ne "${_adjust_chr}"
381                 done
382             fi
383             if [[ "${_nocolor}" = false ]]; then
384                 echo -ne "\e[$([[ -v _backcolor ]] && echo -n "${_backcolor}"; [[ -v _labelcolor ]] && echo -n ";${_labelcolor}"; [[ -v _decotypes ]] && echo -n ";${_decotypes}")m${_msg_label}\e[m "
385             else
386                 echo -ne "${_msg_label} "
387             fi
388         fi
389     }
390
391     echo_appname() {
392         if [[ "${_noappname}" = false ]]; then
393             if [[ "${_nocolor}" = false ]]; then
394                 echo -ne "\e[36m[${_appname}]\e[m "
395             else
396                 echo -ne "[${_appname}] "
397             fi
398         fi
399     }
400
401     for _count in $(seq "1" "$(echo -ne "${_message}\n" | wc -l)"); do
402         _echo_message=$(echo -ne "${_message}\n" |head -n "${_count}" | tail -n 1 )
403         _full_message="$(echo_appname)$(echo_type)${_echo_message}"
404         case "${_output}" in
405             "stdout")
406                 echo ${_echo_opts} "${_full_message}" >&1
407                 ;;
408             "stderr")
409                 echo ${_echo_opts} "${_full_message}" >&2
410                 ;;
411             *)
412                 echo ${_echo_opts} "${_full_message}" > ${_output}
413                 ;;
414         esac
415     done
416 }
417
418 # テキストの翻訳
419 #set -xv
420 translate() {
421     local _msg_translate
422     _msg_translate() {
423         local _get_text
424         local _locale="$(echo "${LANG}" | cut -d "." -f 1)"
425
426         _get_text() {
427             set +eu
428             if [[ -z "${*}" ]]; then
429                 return 1
430             fi
431             local _translated_text="$(eval echo '$'{${_locale}[\"${*}\"]})"
432             set -eu
433             if [[ -z "${_translated_text}" ]]; then
434                 if [[ ! "${_locale}" = "C" ]] && [[ ! "${_locale}" = "en_US" ]]; then
435                     echo "$(text -nc cyan "[WFA]") $(text -nc yellow "Warning")   (No translation data was found)" 1>&2
436                 fi
437                 echo "${*}"
438             else
439                 echo "${_translated_text}"
440             fi
441         }
442
443         local _text _fulltext=() _main
444
445         if declare -p "${_locale}" 2> /dev/null 1>/dev/null; then
446             _main="$(_get_text ${1})"
447         else
448             _main="${1}"
449         fi
450         shift 1
451         echo "$(printf "${_main}" "${@}")"
452     }
453     _msg_translate "${@}"
454 }
455
456
457
458 # Show an INFO message
459 # $1: message string
460 msg_info() {
461     if [[ "${msgdebug}" = false ]]; then
462         set +xv
463     fi
464     local _msg_opts="-a ${wfa_name}"
465     if [[ "${1}" = "-n" ]]; then
466         _msg_opts="${_msg_opts} -o -n"
467         shift 1
468     fi
469     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
470     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
471     msg ${_msg_opts} info "$(translate "${@}")"
472     if [[ "${bash_debug}" = true ]]; then
473         set -xv
474     fi
475 }
476
477 # Show an Warning message
478 # $1: message string
479 msg_warn() {
480     if [[ "${msgdebug}" = false ]]; then
481         set +xv
482     fi
483     local _msg_opts="-a ${wfa_name}"
484     if [[ "${1}" = "-n" ]]; then
485         _msg_opts="${_msg_opts} -o -n"
486         shift 1
487     fi
488     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
489     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
490     msg ${_msg_opts} warn "$(translate "${@}")"
491     if [[ "${bash_debug}" = true ]]; then
492         set -xv
493     fi
494 }
495
496 # Show an debug message
497 # $1: message string
498 msg_debug() {
499     if [[ "${msgdebug}" = false ]]; then
500         set +xv
501     fi
502     if [[ "${debug}" = true ]]; then
503         local _msg_opts="-a ${wfa_name}"
504         if [[ "${1}" = "-n" ]]; then
505             _msg_opts="${_msg_opts} -o -n"
506             shift 1
507         fi
508         [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
509         [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
510         msg ${_msg_opts} debug "$(translate "${@}")"
511     fi
512     if [[ "${bash_debug}" = true ]]; then
513         set -xv
514     fi
515 }
516
517 # Show an ERROR message then exit with status
518 # $1: message string
519 # $2: exit code number (with 0 does not exit)
520 msg_error() {
521     if [[ "${msgdebug}" = false ]]; then
522         set +xv
523     fi
524     local _msg_opts="-a ${wfa_name}"
525     if [[ "${1}" = "-n" ]]; then
526         _msg_opts="${_msg_opts} -o -n"
527         shift 1
528     fi
529     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
530     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
531     msg ${_msg_opts} error "$(translate "${@}")"
532     if [[ "${bash_debug}" = true ]]; then
533         set -xv
534     fi
535 }
536
537 # 使い方
538 # text [-b/-c color/-n/-f/-l/]
539 text() {
540     local OPTIND OPTARG arg _textcolor _decotypes="" _message _notranslate=false
541     while getopts "c:bnfl" arg; do
542         case ${arg} in
543             c)
544                 case "${OPTARG}" in
545                     "black")
546                         _textcolor="30"
547                         ;;
548                     "red")
549                         _textcolor="31"
550                         ;;
551                     "green")
552                         _textcolor="32"
553                         ;;
554                     "yellow")
555                         _textcolor="33"
556                         ;;
557                     "blue")
558                         _textcolor="34"
559                         ;;
560                     "magenta")
561                         _textcolor="35"
562                         ;;
563                     "cyan")
564                         _textcolor="36"
565                         ;;
566                     "white")
567                         _textcolor="37"
568                         ;;
569                     *)
570                         return 1
571                         ;;
572                 esac
573                 ;;
574             b)
575                 _decotypes="${_decotypes};1"
576                 ;;
577             f)
578                 _decotypes="${_decotypes};5"
579                 ;;
580             l)
581                 _decotypes="${_decotypes};4"
582                 ;;
583             n)
584                 _notranslate=true
585                 ;;
586         esac
587     done
588     shift $((OPTIND - 1))
589
590     _message="${@}"
591     if [[ "${_notranslate}" = false ]]; then
592         _message="$(translate "${@}")"
593     fi
594     if [[ "${nocolor}" = true ]]; then
595         echo -ne "${@}"
596     else
597         echo -ne "\e[$([[ -v _textcolor ]] && echo -n ";${_textcolor}"; [[ -v _decotypes ]] && echo -n "${_decotypes}")m${_message}\e[m"
598     fi
599 }
600
601 ######################################################################################
602 # ここから実際の処理開始
603 # ここから下のメッセージは翻訳可能です
604
605 # rm helper
606 # Delete the file if it exists.
607 # For directories, rm -rf is used.
608 # If the file does not exist, skip it.
609 # remove <file> <file> ...
610 remove() {
611     local _list=($(echo "$@")) _file
612     for _file in "${_list[@]}"; do
613         msg_debug "Removing ${_file}"
614         if [[ -f "${_file}" ]]; then    
615             rm -f "${_file}"
616         elif [[ -d "${_file}" ]]; then
617             rm -rf "${_file}"
618         fi
619     done
620 }
621
622 usage (){
623     local _pacman_help=false
624
625     local _wfa_usage
626     _wfa_usage() {
627         echo "Usage:"
628         echo "${wfa_command}"
629         echo "${wfa_command} <operation> [...]"
630         echo
631         echo "operations:"
632         echo "    ${wfa_command} {-h --help}"
633         echo "    ${wfa_command} {-A --vote}"
634         echo "    ${wfa_command} {-V --version}"
635        #echo "    ${wfa_command} {-D --database}    <options> <package(s)>"
636        #echo "    ${wfa_command} {-F --files}       [options] [package(s)]"
637         echo "    ${wfa_command} {-Q --query}       [options] [package(s)]"
638         echo "    ${wfa_command} {-R --remove}      [options] <package(s)>"
639         echo "    ${wfa_command} {-S --sync}        [options] [package(s)]"
640        #echo "    ${wfa_command} {-T --deptest}     [options] [package(s)]"
641        #echo "    ${wfa_command} {-U --upgrade}     [options] <file(s)>"
642        #echo
643        #echo "New operations:"
644        #echo "    ${wfa_command} {-P --show}        [options]"
645        #echo "    ${wfa_command} {-G --getpkgbuild} [package(s)]"
646         echo
647         echo "New options:"
648         echo "       --repo             Assume targets are from the repositories"
649         echo "    -a --aur              Assume targets are from the AUR"
650         echo
651         echo "Permanent configuration options:"
652         echo "    --aururl      <url>   Set an alternative AUR URL"
653         echo "    --makepkg     <file>  makepkg command to use"
654         echo "    --mflags      <flags> Pass arguments to makepkg"
655         echo "    --pacman      <file>  pacman command to use"
656         echo "    --git         <file>  git command to use"
657         echo "    --gitflags    <flags> Pass arguments to git"
658         echo "    --gpg         <file>  gpg command to use"
659         echo "    --gpgflags    <flags> Pass arguments to gpg"
660         echo "    --config      <file>  pacman.conf file to use"
661         echo "    --makepkgconf <file>  makepkg.conf file to use"
662         echo "    --nomakepkgconf       Use the default makepkg.conf"
663         echo
664         echo "wfa specific options:"
665         echo "    -c --clean            Remove unneeded dependencies"
666         echo
667         echo "This program is an alpha version that is not yet stable"
668         echo "If you find a bug, please share it on GitHub"
669         echo "https://github.com/hayao0819/wfa/issues"
670         echo
671     }
672
673     local _wfa_usage_sync
674     _wfa_usage_sync() {
675         echo "usage:  ${wfa_command} {-S --sync} [options] [package(s)]"
676         echo "options:"
677         echo "  -b, --dbpath <path>  set an alternate database location"
678         echo "  -c, --clean          remove old packages from cache directory (-cc for all)"
679         echo "  -d, --nodeps         skip dependency version checks (-dd to skip all checks)"
680         echo "  -s, --search <regex> search remote repositories for matching strings"
681         echo "  -u, --sysupgrade     upgrade installed packages (-uu enables downgrades)"
682         echo "  -y, --refresh        download fresh package databases from the server"
683         echo "                       (-yy to force a refresh even if up to date)"
684         echo "      --arch <arch>    set an alternate architecture"
685         echo "      --color <when>   colorize the output"
686         echo "      --config <path>  set an alternate configuration file"
687         echo "      --confirm        always ask for confirmation"
688         echo "      --debug          display debug messages"
689         echo "      --disable-download-timeout"
690         echo "                       use relaxed timeouts for download"
691         echo "      --noconfirm      do not ask for any confirmation"
692
693     }
694
695     local _wfa_usage_remove
696     _wfa_usage_remove() {
697         echo "usage:  ${wfa_command} {-R --remove} [options] <package(s)>"
698         echo "options:"
699         echo "  -b, --dbpath <path>  set an alternate database location"
700         echo "  -d, --nodeps         skip dependency version checks (-dd to skip all checks)"
701         echo "  -u, --unneeded       remove unneeded packages"
702         echo "      --arch <arch>    set an alternate architecture"
703         echo "      --color <when>   colorize the output"
704         echo "      --config <path>  set an alternate configuration file"
705         echo "      --confirm        always ask for confirmation"
706         echo "      --debug          display debug messages"
707         echo "      --disable-download-timeout"
708         echo "                       use relaxed timeouts for download"
709         echo "      --noconfirm      do not ask for any confirmation"
710     }
711
712     if [[ "${operation}" = "none" ]]; then
713         _wfa_usage
714     elif [[ "${_pacman_help}" = true ]]; then
715         "${pacman_command}" -h --${operation}
716     elif [[ "$(type -t "_wfa_usage_${operation}" )" = "function" ]]; then
717         _wfa_usage_${operation}
718     else
719         msg_error "Help for this operation is not implemented"
720         exit 1
721     fi
722 }
723
724 set_operation() {
725     if [[ "${operation}" = "none" ]]; then
726         operation="${1}"
727         add_args pacman "--${operation}"
728     else
729         msg_error "only one operation may be used at a time"
730         exit 1
731     fi
732 }
733
734 run_sudo() {
735     if (( ${UID} == 0 )); then
736         ${@}
737     else
738         sudo ${@}
739     fi
740 }
741
742 run_pacman() {
743     run_sudo "${pacman_command}" ${@}
744 }
745
746 wfa() {
747     "${wfa_path}" ${@}
748 }
749
750 # pacmanの引数を追加する
751 # https://github.com/FascodeNet/aptpac/blob/master/aptpac のADD_OPTION関数を参考
752 # Usage: add_args [pacman/makepkg/git/gpg/sudo/curl] <args1> <args2>...
753 add_args() {
754     local _target="${1}"
755     local _args_array
756     shift 1
757
758     case "${_target}" in
759         "makepkg")
760             _args_array=(${makepkg_args})
761             _args_array+=(${@})
762             makepkg_args=${_args_array[@]}
763             msg_debug "makepkg ARGS: ${makepkg_args}"
764             ;;
765
766         "pacman")
767             _args_array=(${pacman_args})
768             _args_array+=(${@})
769             pacman_args=${_args_array[@]}
770             msg_debug "pacman ARGS: ${pacman_args}"
771             ;;
772         "git")
773             _args_array=(${mpg_args})
774             _args_array+=(${@})
775             git_args=${_args_array[@]}
776             msg_debug "git ARGS: ${git_args}"
777             ;;
778         "gpg")
779             _args_array=(${gpg_args})
780             _args_array+=(${@})
781             gpg_args=${_args_array[@]}
782             msg_debug "gpg ARGS: ${gpg_args}"
783             ;;
784         "sudo")
785             _args_array=(${sudo_args})
786             _args_array+=(${@})
787             sudo_args=${_args_array[@]}
788             msg_debug "sudo ARGS: ${sudo_args}"
789             ;;
790         "curl")
791             _args_array=(${curl_args})
792             _args_array+="${@}"
793             curl_args=${_args_array[@]}
794             msg_debug "curl ARGS: ${curl_args}"
795             ;;
796         *)
797             msg_error "Failed to set the argument of %s" "${_target}"
798             msg_error "Setting that command is not currently supported"
799             exit 1
800             ;;
801     esac
802 }
803
804 # 引数で指定されたパッケージがAUR以外の場所に存在しない場合にのみ正常終了します(AURのパッケージの場合に正常終了)
805 check_aur_package() {
806     local _package="${1}"
807     # 参考: https://qiita.com/Hayao0819/items/a8740a17301fafa2fdab
808     if [[ -z "$(pacman -Ssq "${_package}" 2>/dev/null | grep -o ".*${_package}$")" ]]; then
809         #AUR以外のリポジトリに存在しない
810         return 0
811     else
812         return 1
813     fi
814 }
815
816
817 # 引数で指定されたパッケージが既にインストールされている場合は正常終了します。
818 check_installed_package() {
819     local _package="${1}"
820     if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1; then
821         return 0
822     else
823         return 1
824     fi
825 }
826
827 # ~/.cacheに相当するディレクトリを返します
828 get_cache_dir() {
829     local _user_config_dir _cache_dir
830     if [[ -v XDG_CONFIG_HOME ]]; then
831         _user_config_dir="${XDG_CONFIG_HOME}"
832     else
833         _use_config_dir="${HOME}/.config"
834     fi
835     if [[ -f "${_use_config_dir}/user-dirs.dirs" ]]; then
836         source "${_use_config_dir}/user-dirs.dirs"
837     fi
838     if [[ -v XDG_CACHE_HOME ]]; then
839         _cache_dir="${XDG_CACHE_HOME}"
840     else
841         _cache_dir="${HOME}/.cache"
842     fi
843     echo -n "${_cache_dir}"
844 }
845
846 # Usage: get_srcinfo_data <path> <var>
847 # 参考: https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
848 get_srcinfo_data() {
849     local _srcinfo="${1}" _ver="${2}"
850     local _srcinfo_json=$(python << EOF
851 from srcinfo.parse import parse_srcinfo; import json
852 text = """
853 $(cat ${1})
854 """
855 parsed, errors = parse_srcinfo(text)
856 print(json.dumps(parsed))
857 EOF
858 )
859     echo "${_srcinfo_json}" | jq -rc "${2}" | tr '\n' ' '
860 }
861
862
863 # AURからパッケージをビルドしてインストールします
864 # 現在1つのパッケージしか指定できません
865 install_aur_package() {
866     local _package="${1}"
867
868     # Create cache dir
869     if [[ ! -v wfa_cache_dir ]]; then
870         wfa_cache_dir="$(get_cache_dir)/wfa"
871     fi
872     mkdir -p "${wfa_cache_dir}/archive"
873     mkdir -p "${wfa_cache_dir}/build/${_package}"
874
875     # AurJsonから値を取得
876     msg_info "Searching in AUR ..."
877     local _aur_json=$("${curl_command}" ${curl_args} -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name&arg=${_package}" | jq -r)
878     if (( "$(echo "${_aur_json}" | jq -r ".resultcount")" == 0 )); then
879         msg_error "Could not find all required packages: %s" "${_package}"
880         exit 1
881     fi
882
883     local _found_packages="$(echo "${_aur_json}" | jq -r --tab '.results[].Name')"
884     #msg_debug "Found package: $(echo ${_found_packages} | tr '\n' ' ')"
885
886     if [[ -n "$(echo "${_found_packages}" | grep -x "${_package}" )" ]]; then
887         msg_debug "Select a package %s with an exact name match" "${_package}"
888     else
889         msg_error "No package with an exact name match was found"
890         exit 1
891     fi
892
893     # PKGBUILDをダウンロード
894     msg_info "Download PKGBUILD of %s" "${_package}"
895     _aur_json=$(echo "${_aur_json}" | jq -r ".results[] | select(.Name == \"${_package}\")" )
896     local _aur_snapshot_url="${aururl%/}$(echo "${_aur_json}" | jq -r ".URLPath")"
897     local _aur_version="$(echo "${_aur_json}" | jq -r ".Version")"
898     msg_debug "Get PKGBUILD from %s" "${_aur_snapshot_url}"
899
900     local _pkgbuild_archive_path="${wfa_cache_dir}/archive/${_package}-${_aur_version}"
901     local _download_pkgbuild=true
902     if [[ -f "${_pkgbuild_archive_path}" ]]; then
903         msg_warn "PKGBUILD has already been downloaded"
904         msg_warn -n "Do you want to overwrite and download? [n] :"
905         local _yes_or_no
906         if [[ "${noconfirm}" = true ]]; then
907             echo
908             _yes_or_no="No"
909         else
910             read _yes_or_no
911         fi
912         case "${_yes_or_no}" in
913             "y" | "Y" | "yes" | "Yes" | "YES" ) _download_pkgbuild=true  ;;
914             *                                 ) _download_pkgbuild=false ;;
915         esac
916     fi
917     if [[ "${_download_pkgbuild}" = true ]]; then
918         remove "${_pkgbuild_archive_path}"
919         "${curl_command}"  ${curl_args} -L -C - -f -o "${_pkgbuild_archive_path}" "${_aur_snapshot_url}"
920     fi
921
922     # PKGBUILDを展開
923     msg_info "Unpacking the tarball of PKGBUILD ..."
924     tar -xv -f "${_pkgbuild_archive_path}" -C "${wfa_cache_dir}/build/" > /dev/null 2>&1
925
926     # .SRCINFOを解析
927     local _build_dir="${wfa_cache_dir}/build/${_package}"
928     if [[ ! -f "${_build_dir}/.SRCINFO" ]]; then
929         msg_warn ".SRCINFO was not found.\nGenerating it using makepkg"
930         (
931             cd "${_build_dir}"
932             "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
933         )
934     fi
935
936     local _makedepends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".makedepends[]?")"
937     local _depends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".depends[]?")"
938     local _conflicts="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".conflicts[]?")"
939     msg_debug "makedepends: %s" "${_makedepends}"
940     msg_debug "depends: %s" "${_depends}"
941     msg_debug "conflicts: %s " "${_conflicts}"
942
943
944     # 衝突を確認
945     local _pkg _conflicts_found=false
946     for _pkg in ${_conflicts[@]}; do
947         if "${pacman_command}" -Qq "${_pkg}" > /dev/null 2>&1 ; then
948             _conflicts_found=true
949             msg_error "${_package} is colliding with ${_pkg}"
950         fi
951     done
952     if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1 &&  [[ ! "$("${pacman_command}" -Qq "${_package}" 2> /dev/null)" = "${_package}" ]]; then
953         msg_error "${_package} is colliding with $("${pacman_command}" -Qq "${_package}")"
954         _conflicts_found=true
955     fi
956     if [[ "${_conflicts_found}" = true ]]; then
957         msg_error "Conflict(s) was found"
958         exit 1
959     fi
960
961
962     # 依存パッケージをインストール
963     if [[ "${nodeps}" = false ]]; then
964         msg_info "Install dependent packages..."
965         local _force_aur="${force_aur}"
966         force_aur=false
967         install_package "${_depends}"
968         force_aur="${_force_aur}"
969         unset _force_aur
970     fi
971
972     # ビルド準備
973     # srcdirの確認
974     if [[ -d "${_build_dir}/src" ]]; then
975         msg_info "Found %s" "${_build_dir}/src"
976         msg_info -n "Packages to cleanBuild? [n] :"
977         local _yes_or_no
978         unset _yes_or_no
979         if [[ "${noconfirm}" = true ]]; then
980             echo
981             _yes_or_no="No"
982         else
983             read _yes_or_no
984         fi
985         case "${_yes_or_no}" in
986             "y" | "Y" | "yes" | "Yes" | "YES" ) add_args makepkg "--clean" ;;
987         esac
988     fi
989
990
991     # ビルド
992     add_args "makepkg" "-sf"
993     (
994         cd "${_build_dir}"
995         "${makepkg_command}" "${makepkg_args}"
996     )
997
998
999     # ビルド後のパッケージ一覧を生成
1000     (
1001         cd "${_build_dir}"
1002         "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
1003     )
1004     local _pkgnames=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".packages | keys[]"))
1005     local _pkgver="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgver" | sed 's/ //g')"
1006     local _pkgrel="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgrel" | sed 's/ //g')"
1007     local _arch_array=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".arch[]"))
1008     local _arch _pkgname
1009     if [[ "${_arch_array[*]}" = "any" ]]; then
1010         _arch="any"
1011     else
1012         _arch="${arch}"
1013     fi
1014     local _PKGEXT=$(
1015         source "${makepkg_config}"
1016         echo "${PKGEXT}"
1017     )
1018     local _pkgfilelist=()
1019     for _pkgname in ${_pkgnames[@]}; do
1020         _pkgfilelist+=("${_build_dir}/${_pkgname}-${_pkgver}-${_pkgrel}-${_arch}${_PKGEXT}")
1021     done
1022
1023     # インストール
1024     run_pacman -U --noconfirm ${_pkgfilelist[@]}
1025 }
1026
1027 # AURのパッケージを検索
1028 search_aur_package() {
1029     local _package="${1}"
1030     #msg_info "Searching in AUR ..."
1031     local _aur_json=$("${curl_command}" ${curl_args} -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name-desc&arg=${_package}" | jq -r )
1032     local _found_result_count="$(echo "${_aur_json}" | jq -r ".resultcount")"
1033     if (( "${_found_result_count}" == 0 )); then
1034         msg_error "Could not find all required packages: %s" "${_package}"
1035         exit 1
1036     fi
1037     _aur_json=$(echo "${_aur_json}" | jq -r ".results[]")
1038
1039     local _found_pkgname=($(echo "${_aur_json}" | jq -r ".Name" ))
1040
1041     if [[ "${quiet}" = true ]]; then
1042         local _IFS="${IFS}"
1043         IFS=$'\n'
1044         echo "${_found_pkgname[*]}"
1045         IFS="${_IFS}"
1046     else
1047         local  _found_package __pkgver __popularity __vote __pkgdesc __orphaned __installed __output_text=()
1048         for _found_package in ${_found_pkgname[@]}; do
1049             __orphaned=false
1050             __installed=false
1051             _found_json="$(echo ${_aur_json} | jq "select(.Name == \"${_found_package}\")")"
1052
1053             #echo "${_found_json}"
1054             __pkgver="$(echo "${_found_json}" | jq -r ".Version" )"
1055             __popularity="$(echo "${_found_json}" | jq -r ".Popularity" )"
1056             __vote="$(echo "${_found_json}" | jq -r ".NumVotes" )"
1057             __pkgdesc="$(echo "${_found_json}" | jq -r ".Description" )"
1058
1059             # 人気度の少数2位以下を四捨五入
1060             # 参考: http://www.rivhiro-weather.com/knowledge/?p=536
1061             msg_debug "Row popularity: %s" "${__popularity}"
1062             __popularity="$(printf "%g\n" "${__popularity}" | awk '{printf("%4.2f", $1)}')"
1063
1064             # 孤児判定
1065             #参考: https://www.366service.com/jp/qa/7c95f46e5236039134ff5b862ae2cd13
1066             if ! echo "${_found_json}" | jq -r --exit-status ".Maintainer" 1> /dev/null 2> /dev/null ; then
1067                 __orphaned=true
1068             fi
1069
1070             # インストール済み判定
1071             if check_installed_package "${_found_package}"; then
1072                 __installed=true
1073             fi
1074
1075             __output_text+=(
1076                 "$(text -c blue -b "aur")/$(text -b "${_found_package}") $(text -c cyan "${__pkgver}") (+$(text -b "${__vote} ${__popularity}"))"
1077             )
1078             
1079             if [[ "${__orphaned}" = true ]]; then
1080                 __output_text+=("$(text -bc red "(Orphaned)")")
1081             fi
1082
1083             if [[ "${__installed}" = true ]]; then
1084                 __output_text+=("$(text -bc cyan "[Installed]")")
1085             fi
1086             echo "${__output_text[*]}"
1087             echo "    ${__pkgdesc}"
1088             unset __pkgver __popularity __vote __pkgdesc _found_json __orphaned __installed __output_text
1089         done
1090     fi
1091 }
1092
1093 # バージョンを表示して終了
1094 operation_version() {
1095     # Pyalpmからlibalpmの値を取得
1096     # 参考: https://pyalpm.readthedocs.io/en/latest/pyalpm/pyalpm.html
1097     local _libalpm_version="$(python3 -c 'import pyalpm; print(pyalpm.alpmversion())')"
1098     local _pacman_version="$("${pacman_command}" -Q pacman | cut -d ' ' -f 2)"
1099     echo "wfa v${wfa_version} - pacman v${_pacman_version} - libalpm v${_libalpm_version}"
1100 }
1101
1102 operation_remove() {
1103     run_pacman ${pacman_args} "${specified_packages[@]}"
1104 }
1105
1106 # Usage: install_package <package1> <package2>...
1107 install_package() {
1108     local _package _repo_packages=() _aur_packages=()
1109     for _package in ${@}; do
1110         if ! check_installed_package "${_package}"; then
1111             if ! check_aur_package "${_package}"; then
1112                 # 公式パッケージなのでpacmanでそのままインストール
1113                 _repo_packages+=("${_package}")
1114             else
1115                 # AUR上のパッケージの場合の処理
1116                 _aur_packages+=("${_package}")
1117             fi
1118         fi
1119     done
1120
1121     if (( "${#_repo_packages[@]}" > 0 )); then
1122         run_pacman --asdeps ${pacman_args} "${_repo_packages[@]}"
1123     fi
1124
1125     if (( "${#_aur_packages[@]}" > 0 )); then
1126         unset _package
1127         for _package in ${_aur_packages[@]}; do
1128             install_aur_package "${_package}"
1129         done
1130     fi
1131 }
1132
1133 upgrade_aur_package() {
1134     #ここまで翻訳
1135     msg_error "This is a feature that has not been implemented yet"
1136 }
1137
1138 operation_sync(){
1139     local _package
1140     if (( "${sync_clean_count}" >= 1 )); then
1141         remove "$(get_cache_dir)/wfa"
1142         run_pacman ${pacman_args} $(
1143             local _count
1144             for _count in $(seq 1 ${sync_clean_count}); do
1145                 echo -n "-c "
1146             done
1147         )
1148     fi
1149
1150
1151     if [[ "${sync_search}" = true ]]; then
1152         for _package in ${specified_packages[@]}; do
1153             search_aur_package "${_package}"
1154         done
1155         "${pacman_command}" ${pacman_args} ${specified_packages[@]} || :
1156     else
1157         if [[ "${sync_upgrade}" = true ]]; then
1158             upgrade_aur_package
1159             run_pacman ${pacman_args} --sysupgrade
1160         fi
1161         for _package in ${specified_packages[@]}; do
1162             if ! check_aur_package "${_package}" && [[ "${force_aur}" = false ]]; then
1163                 # 公式パッケージなのでpacmanでそのままインストール
1164                 run_pacman ${pacman_args} "${_package}"
1165             else
1166                 # AUR上のパッケージの場合の処理
1167                 install_aur_package "${_package}"
1168                 #msg_error "Getting the AUR package has not been implemented yet."
1169                 #exit 1
1170             fi
1171         done
1172     fi
1173 }
1174
1175
1176 operation_vote() {
1177
1178     # aurvoteの確認
1179     if ! type aurvote 1> /dev/null 2> /dev/null; then
1180         msg_error "There is no aurvote"
1181         msg_error "Please install with %s" "\"wfa -S aurvote\""
1182         exit 1
1183     fi
1184
1185     local _package _aur_json _found_result_count _pkgver _before_popularity _before_vote
1186     for _package in ${specified_packages[@]}; do
1187
1188         # 存在するパッケージか確認
1189         _aur_json=$("${curl_command}" ${curl_args} -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name-desc&arg=${_package}" | jq -r)
1190         _found_result_count="$(echo "${_aur_json}" | jq -r ".resultcount")"
1191         _aur_json=$(echo "${_aur_json}" | jq -r ".results[] | select(.Name == \"${_package}\")")
1192         if (( "${_found_result_count}" == 0 )) || [[ -z "${_aur_json}" ]]; then
1193             msg_error "Package not found on AUR: %s" "${_package}"
1194             exit 1
1195         fi
1196
1197         # jsonから値を取り出して整形
1198         _pkgver="$(echo "${_aur_json}" | jq -r ".Version" )"
1199         _before_popularity="$(printf "%g\n" "$(echo "${_aur_json}" | jq -r ".Popularity" )" | awk '{printf("%4.2f", $1)}')"
1200         _before_vote="$(echo "${_aur_json}" | jq -r ".NumVotes" )"
1201
1202         # 投票を操作
1203         if [[ "$(aurvote --check "${_package}")" = "not voted" ]]; then
1204             msg_info "Voted for %s" "${_package}"
1205             aurvote --vote "${_package}" 1> /dev/null
1206         else
1207             msg_info "Unvoted for %s" "${_package}"
1208             aurvote --unvote "${_package}" 1> /dev/null
1209         fi
1210
1211         # 投票後の値を取得
1212         _aur_json=$("${curl_command}" ${curl_args} -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name-desc&arg=${_package}" | jq -r ".results[] | select(.Name == \"${_package}\")")
1213         _after_popularity="$(printf "%g\n" "$(echo "${_aur_json}" | jq -r ".Popularity" )" | awk '{printf("%4.2f", $1)}')"
1214         _after_vote="$(echo "${_aur_json}" | jq -r ".NumVotes" )"
1215
1216         # 結果を出力
1217         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}")"
1218     done
1219 }
1220
1221 unavailable_in_this_operation() {
1222     msg_error "This option is not available in the current operation"
1223     exit 1
1224 }
1225
1226 # オペレーションを実行します
1227 run_operation() {
1228     local _operation="${1}"
1229     msg_debug "Operation: ${_operation}"
1230
1231     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"
1232     msg_warn ""
1233     msg_warn ""
1234
1235     operation_${_operation}
1236 }
1237
1238 # Parse options
1239 ARGUMENT="${@}"
1240 _opt_short="AQRShVdb:aysucq"
1241 _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"
1242
1243 OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- ${ARGUMENT})
1244 [[ ${?} != 0 ]] && exit 1
1245 unset _opt_short _opt_long
1246
1247 eval set -- "${OPT}"
1248 msg_debug "Argument: ${OPT}"
1249
1250 while :; do
1251     case ${1} in
1252         -A | --vote)
1253             set_operation "vote"
1254             shift 1
1255             ;;
1256         -Q | --query)
1257             set_operation "query"
1258             shift 1
1259             ;;
1260         -R | --remove)
1261             set_operation "remove"
1262             shift 1
1263             ;;
1264         -S | --sync)
1265             set_operation "sync"
1266             shift 1
1267             ;;
1268         -V | --version)
1269             set_operation "version"
1270             shift 1
1271             ;;
1272         --)
1273             shift
1274             break
1275             ;;
1276         *)
1277             shift 1
1278             ;;
1279     esac
1280 done
1281
1282 eval set -- "${OPT}"
1283
1284 while :; do
1285     case ${1} in
1286         -a | --aur)
1287             force_aur=true
1288             msg_debug "Assume targets are from the AUR"
1289             shift 1
1290             ;;
1291         --debug)
1292             debug=true
1293             add_args pacman "--debug"
1294             shift 1
1295             ;;
1296         -d | --nodeps)
1297             nodeps=true
1298             add_args pacman "--nodeps"
1299             shift 1
1300             ;;
1301         -b | --dbpath)
1302             add_args pacman "--dbpath '${2}'"
1303             shift 2
1304             ;;
1305         -y | --refresh)
1306             option_y_count=$(( option_y_count + 1 ))
1307             shift 1
1308             ;;
1309         -s | --search)
1310             add_args pacman "--search"
1311             sync_search=true
1312             shift 1
1313             ;;
1314         -u | --sysupgrade | --unneeded)
1315             case "${1}" in
1316                 --sysupgrade)
1317                     if [[ "${operation}" = "sync" ]]; then
1318                         sync_upgrade=true
1319                     else
1320                         unavailable_in_this_operation
1321                     fi
1322                     ;;
1323                 --unneeded)
1324                     if [[ "${operation}" = "remove" ]]; then
1325                         add_args pacman "--unneeded"
1326                     else
1327                         unavailable_in_this_operation
1328                     fi
1329                     ;;
1330                 -u)
1331                     case "${operation}" in
1332                         "sync")
1333                             sync_upgrade=true
1334                             ;;
1335                         "remove")
1336                             add_args pacman "--unneeded"
1337                             ;;
1338                         "none")
1339                             :
1340                             ;;
1341                         *)
1342                             unavailable_in_this_operation
1343                             ;;
1344                     esac
1345                     ;;
1346             esac
1347             shift 1
1348             ;;
1349         -c | --clean)
1350             sync_clean_count=$(( sync_clean_count + 1 ))
1351             shift 1
1352             ;;
1353         -q | --quiet)
1354             quiet=true
1355             add_args pacman "--quiet"
1356             shift 1
1357             ;;
1358         --arch)
1359             arch="${2}"
1360             add_args pacman "--arch ${2}"
1361             shift 2
1362             ;;
1363         --aururl)
1364             aururl="${2}"
1365             shift 2
1366             ;;
1367         --noconfirm)
1368             add_args pacman "--noconfirm"
1369             noconfirm=true
1370             shift 1
1371             ;;
1372         --config)
1373             pacman_config="${2}"
1374             add_args pacman "--config ${2}"
1375             shift 2
1376             ;;
1377         --makepkg)
1378             makepkg_command="${2}"
1379             shift 2
1380             ;;
1381         --mflags)
1382             #makepkg_args="${2}"
1383             add_args makepkg "${2}"
1384             shift 2
1385             ;;
1386         --pacman)
1387             pacman_command="${2}"
1388             shift 2
1389             ;;
1390         --git)
1391             git_command="${2}"
1392             shift 2
1393             ;;
1394         --gitflags)
1395             #git_args="${2}"
1396             add_args git "${2}"
1397             shift 2
1398             ;;
1399         --makepkgconfig)
1400             if [[ "${nomakepkgconf}" = false ]]; then
1401                 makepkg_config="${2}"
1402             else
1403                 msg_warn "--nomakepkgconf is specified.\n--makepkgconf has been ignored."
1404             fi
1405             shift 2
1406             ;;
1407         --nomakepkgconf)
1408             makepkg_config="/etc/makepkg.conf"
1409             nomakepkgconf=true
1410             shift 1
1411         ;;
1412         --bash-debug)
1413             bash_debug=true
1414             set -xv
1415             shift 1
1416             ;;
1417         --msg-debug)
1418             msgdebug=true
1419             shift 1
1420             ;;
1421         --color)
1422             case "${2}" in
1423                 "never")
1424                     nocolor=true
1425                     add_args pacman "--color never"
1426                     ;;
1427                 "always")
1428                     nocolor=false
1429                     add_args pacman "--color always"
1430                     ;;
1431                 "auto")
1432                     msg_error "auto is not currently supported."
1433                     add_args pacman "--color auto"
1434                     ;;
1435             esac
1436             ;;
1437         --nocolor)
1438             nocolor=true
1439             add_args pacman "--color never"
1440             shift 1
1441             ;;
1442         --confirm)
1443             noconfirm=false
1444             shift 1
1445             ;;
1446         --disable-download-timeout)
1447             add_args curl "--max-time 0"
1448             add_args pacman "--disable-download-timeout"
1449             shift 1
1450             ;;
1451         --curl)
1452             curl_command="${2}"
1453             shift 2
1454             ;;
1455         --curlflags)
1456             add_args curl "${2}"
1457             shift 2
1458             ;;
1459         --puella)
1460             text -flb "Please make a contract with me and become a Puella Magi !"
1461             echo
1462             shift 1
1463             exit 0
1464             ;;
1465         -h | --help)
1466             usage
1467             shift 1
1468             exit 0
1469             ;;
1470         --)
1471             shift
1472             break
1473             ;;
1474         *)
1475             shift 1
1476             ;;
1477     esac
1478 done
1479
1480 specified_packages=(${@})
1481
1482 # Run database update
1483 if (( "${option_y_count}" == 1 )); then
1484     run_pacman -Sy
1485 elif (( "${option_y_count}" >= 2 )); then
1486     run_pacman -Syy
1487 fi
1488
1489 # set_operationで設定された操作を実行
1490 case "${operation}" in
1491     "version" | "sync" | "remove" | "vote")
1492         run_operation "${operation}"
1493         ;;
1494     "none")
1495         exit 0
1496         ;;
1497     *)
1498         msg_error "Undefined operation"
1499         exit 1
1500         ;;
1501 esac