OSDN Git Service

[fix] : Fixed translation at line break
[alterlinux/wfa.git] / wfa
1 #!/usr/bin/env bash
2
3 set -eu
4
5
6 ######################################################################################
7 # ここから翻訳データ
8
9 declare -A ja_JP=(
10     ["Undefined operation"]="未定義のオペレーションです"
11     ["only one operation may be used at a time"]="一度に使用できるオペレーションは1つだけです"
12     ["Failed to set the argument of %s"]="%sの引数の設定に失敗しました"
13     ["Setting that command is not currently supported"]="そのコマンドの設定は現在サポートされていません"
14     ["Install dependent packages..."]="依存パッケージをインストールします..."
15     ["No package with an exact name match was found"]="完全に一致する名前のパッケージが見つかりませんでした"
16     ["Select a package %s with an exact name match"]="名前が完全に一致するパッケージ %s を選択します"
17     ["Download PKGBUILD of %s"]="%s のPKGBUILDをダウンロード"
18     ["Get PKGBUILD from %s"]="%sからPKGBUILDを取得します"
19     ["PKGBUILD has already been downloaded"]="PKGBUILDは既にダウンロードされています"
20     ["Do you want to overwrite and download? [n] :"]="上書きダウンロードしますか? [n] :"
21     ["Unpacking the tarball of PKGBUILD ..."]="PKGBUILDを展開しています ..."
22
23     ["This is a feature that has not been implemented yet"]="まだ実装されていない機能です"
24 )
25 ######################################################################################
26 # ここからデフォルト設定の定義
27
28 #-- wfa configs --#
29 wfa_version="0.1"
30 wfa_name="WFA"
31 wfa_command="wfa"
32
33 #-- options (int) --#
34 option_y_count=0
35
36 #-- options (str) --#
37 aururl="https://aur.archlinux.org/"
38 operation="none"
39
40 #-- options (bool) --#
41 bash_debug=false
42 debug=false
43 force_aur=false
44 msgdebug=false
45 nocolor=false
46 noconfirm=false
47 nodeps=false
48 nomakepkgconf=false
49 sync_search=false
50 sync_upgrade=false
51
52 #-- makepkg --#
53 # 実行ファイル
54 makepkg_command="/usr/bin/makepkg" 
55 # 設定ファイル
56 makepkg_config="/etc/makepkg.conf"
57 # 引数
58 makepkg_args=""
59
60 #-- pacman --#
61 # 実行ファイル
62 pacman_command="/usr/bin/pacman"
63 # 設定ファイル
64 pacman_config="/etc/pacman.conf"
65 # 引数
66 pacman_args=""
67
68 #-- git --#
69 # 実行ファイル
70 git_command="/usr/bin/git"
71 # 引数
72 git_args=""
73
74 #-- gpg --#
75 # 実行ファイル
76 gpg_command="/usr/bin/gpg"
77 # 引数
78 gpg_args=""
79
80 #-- sudo --#
81 # 実行ファイル
82 sudo_command="/usr/bin/sudo"
83 # 引数
84 sudo_args=""
85
86
87
88 ######################################################################################
89 # ここからメッセージ関連の関数定義
90
91
92 # メッセージ出力の制御
93 # https://github.com/FascodeNet/alterlinux/blob/dev/tools/msg.sh の変数名にアンダーバーを追加し関数化
94 msg() {
95     local OPTIND OPTARG arg
96
97     local _appname="msg.sh"
98     local _bash_debug=false
99     local _nocolor=false
100     local _echo_opts=""
101     local _message=""
102     local _msg_type="info"
103     local _msg_label=""
104     local _label_space="7"
105     local _adjust_chr=" "
106     local _customized_label=false
107     local _customized_label_color=false
108     local _nolabel=false
109     local _noappname=false
110     local _noadjust=false
111     local _output="stdout"
112
113     _help() {
114         echo "usage ${0} [option] [type] [message]"
115         echo
116         echo "Display a message with a colored app name and message type label"
117         echo
118         echo " General type:"
119         echo "    info                      General message"
120         echo "    warn                      Warning message"
121         echo "    error                     Error message"
122         echo "    debug                     Debug message"
123         echo
124         echo " General options:"
125         echo "    -a [name]                 Specify the app name"
126         echo "    -c [character]            Specify the character to adjust the label"
127         echo "    -l [label]                Specify the label."
128         echo "    -n | --nocolor            No output colored output"
129         echo "    -o [option]               Specify echo options"
130         echo "    -r [color]                Specify the color of label"
131         echo "    -s [number]               Specifies the label space."
132         echo "    -x | --bash-debug         Enables output bash debugging"
133         echo "    -h | --help               This help message"
134         echo
135         echo "         --nolabel            Do not output label"
136         echo "         --noappname          Do not output app name"
137         echo "         --noadjust           Do not adjust the width of the label"
138     }
139
140     while getopts "a:c:l:no:r:s:xh-:" arg; do
141         case ${arg} in
142                 a) 
143                     _appname="${OPTARG}"
144                     ;;
145                 c) 
146                     _adjust_chr="${OPTARG}"
147                     ;;
148                 l) 
149                     _customized_label=true
150                     _msg_label="${OPTARG}"
151                     ;;
152                 n)
153                     _nocolor=true
154                     ;;
155                 o)
156                     _echo_opts="${OPTARG}"
157                     ;;
158                 r)
159                     _customized_label_color=true
160                     case ${OPTARG} in
161                         "black")
162                             _labelcolor="30"
163                             ;;
164                         "red")
165                             _labelcolor="31"
166                             ;;
167                         "green")
168                             _labelcolor="32"
169                             ;;
170                         "yellow")
171                             _labelcolor="33"
172                             ;;
173                         "blue")
174                             _labelcolor="34"
175                             ;;
176                         "magenta")
177                             _labelcolor="35"
178                             ;;
179                         "cyan")
180                             _labelcolor="36"
181                             ;;
182                         "white")
183                             _labelcolor="37"
184                             ;;
185                         *)
186                             return 1
187                             ;;
188                     esac
189                     ;;
190                 s)
191                     _label_space="${OPTARG}"
192                     ;;
193                 x)
194                     _bash_debug=true
195                     set -xv
196                     ;;
197                 h)
198                     _help
199                     shift 1
200                     exit 0
201                     ;;
202                 -)
203                     case "${OPTARG}" in
204                         "nocolor")
205                             _nocolor=true
206                             ;;
207                         "bash-debug")
208                             _bash_debug=true
209                             set -xv
210                             ;;
211                         "help") 
212                             _help
213                             exit 0
214                             ;;
215                         "nolabel")
216                             _nolabel=true
217                             ;;
218                         "noappname")
219                             _noappname=true
220                             ;;
221                         "noadjust")
222                             _noadjust=true 
223                             ;;
224                         *)
225                             _help
226                             exit 1
227                             ;;
228                     esac
229         esac
230     done
231
232     shift $((OPTIND - 1))
233
234     # Color echo
235     #
236     # Text Color
237     # 30 => Black
238     # 31 => Red
239     # 32 => Green
240     # 33 => Yellow
241     # 34 => Blue
242     # 35 => Magenta
243     # 36 => Cyan
244     # 37 => White
245     #
246     # Background color
247     # 40 => Black
248     # 41 => Red
249     # 42 => Green
250     # 43 => Yellow
251     # 44 => Blue
252     # 45 => Magenta
253     # 46 => Cyan
254     # 47 => White
255     #
256     # Text decoration
257     # You can specify multiple decorations with ;.
258     # 0 => All attributs off (ノーマル)
259     # 1 => Bold on (太字)
260     # 4 => Underscore (下線)
261     # 5 => Blink on (点滅)
262     # 7 => Reverse video on (色反転)
263     # 8 => Concealed on
264
265     case ${1} in
266         "info")
267             _msg_type="type"
268             _output="stdout"
269             [[ "${_customized_label_color}" = false ]] && _labelcolor="32"
270             [[ "${_customized_label}"       = false ]] && _msg_label="Info"
271             shift 1
272             ;;
273         "warn")
274             _msg_type="warn"
275             _output="stdout"
276             [[ "${_customized_label_color}" = false ]] && _labelcolor="33"
277             [[ "${_customized_label}"       = false ]] && _msg_label="Warning"
278             shift 1
279             ;;
280         "debug")
281             _msg_type="debug"
282             _output="stdout"
283             [[ "${_customized_label_color}" = false ]] && _labelcolor="35"
284             [[ "${_customized_label}"       = false ]] && _msg_label="Debug"
285             shift 1
286             ;;
287         "error")
288             _msg_type="error"
289             _output="stderr"
290             [[ "${_customized_label_color}" = false ]] && _labelcolor="31"
291             [[ "${_customized_label}"       = false ]] && _msg_label="Error"
292             shift 1
293             ;;
294         "")
295             echo "Please specify the message type" >&2
296             exit 1
297             ;;
298         *)
299             echo "Unknown message type" >&2
300             exit 1
301             ;;
302     esac
303
304     _word_count="${#_msg_label}"
305     _message="${@}"
306
307     echo_type() {
308         local __time
309         if [[ "${_nolabel}" = false ]]; then
310             if [[ "${_noadjust}" = false ]]; then
311                 for __time in $( seq 1 $(( ${_label_space} - ${_word_count})) ); do
312                     echo -ne "${_adjust_chr}"
313                 done
314             fi
315             if [[ "${_nocolor}" = false ]]; then
316                 echo -ne "\e[$([[ -v _backcolor ]] && echo -n "${_backcolor}"; [[ -v _labelcolor ]] && echo -n ";${_labelcolor}"; [[ -v _decotypes ]] && echo -n ";${_decotypes}")m${_msg_label}\e[m "
317             else
318                 echo -ne "${_msg_label} "
319             fi
320         fi
321     }
322
323     echo_appname() {
324         if [[ "${_noappname}" = false ]]; then
325             if [[ "${_nocolor}" = false ]]; then
326                 echo -ne "\e[36m[${_appname}]\e[m "
327             else
328                 echo -ne "[${_appname}] "
329             fi
330         fi
331     }
332
333     for _count in $(seq "1" "$(echo -ne "${_message}\n" | wc -l)"); do
334         _echo_message=$(echo -ne "${_message}\n" |head -n "${_count}" | tail -n 1 )
335         _full_message="$(echo_appname)$(echo_type)${_echo_message}"
336         case "${_output}" in
337             "stdout")
338                 echo ${_echo_opts} "${_full_message}" >&1
339                 ;;
340             "stderr")
341                 echo ${_echo_opts} "${_full_message}" >&2
342                 ;;
343             *)
344                 echo ${_echo_opts} "${_full_message}" > ${_output}
345                 ;;
346         esac
347     done
348 }
349
350 # テキストの翻訳
351 #set -xv
352 translate() {
353     local _msg_translate
354     _msg_translate() {
355         local _get_text
356         local _locale="$(echo "${LANG}" | cut -d "." -f 1)"
357
358         _get_text() {
359             set +eu
360             local _translated_text="$(eval echo '$'{${_locale}[\"${*}\"]})"
361             set -eu
362             if [[ -z "${_translated_text}" ]]; then
363                 echo "${*}"
364             else
365                 echo "${_translated_text}"
366             fi
367         }
368
369         local _text _fulltext=() _main
370
371         if declare -p "${_locale}" 2> /dev/null 1>/dev/null; then
372             _main="$(_get_text ${1})"
373         else
374             _main="${1}"
375         fi
376         shift 1
377         echo "$(printf "${_main}" ${@})"
378     }
379     _msg_translate "${@}"
380 }
381
382
383
384 # Show an INFO message
385 # $1: message string
386 msg_info() {
387     if [[ "${msgdebug}" = false ]]; then
388         set +xv
389     fi
390     local _msg_opts="-a ${wfa_name}"
391     if [[ "${1}" = "-n" ]]; then
392         _msg_opts="${_msg_opts} -o -n"
393         shift 1
394     fi
395     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
396     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
397     msg ${_msg_opts} info "$(translate "${@}")"
398     if [[ "${bash_debug}" = true ]]; then
399         set -xv
400     fi
401 }
402
403 # Show an Warning message
404 # $1: message string
405 msg_warn() {
406     if [[ "${msgdebug}" = false ]]; then
407         set +xv
408     fi
409     local _msg_opts="-a ${wfa_name}"
410     if [[ "${1}" = "-n" ]]; then
411         _msg_opts="${_msg_opts} -o -n"
412         shift 1
413     fi
414     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
415     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
416     msg ${_msg_opts} warn "$(translate "${@}")"
417     if [[ "${bash_debug}" = true ]]; then
418         set -xv
419     fi
420 }
421
422 # Show an debug message
423 # $1: message string
424 msg_debug() {
425     if [[ "${msgdebug}" = false ]]; then
426         set +xv
427     fi
428     if [[ "${debug}" = true ]]; then
429         local _msg_opts="-a ${wfa_name}"
430         if [[ "${1}" = "-n" ]]; then
431             _msg_opts="${_msg_opts} -o -n"
432             shift 1
433         fi
434         [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
435         [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
436         msg ${_msg_opts} debug "$(translate "${@}")"
437     fi
438     if [[ "${bash_debug}" = true ]]; then
439         set -xv
440     fi
441 }
442
443 # Show an ERROR message then exit with status
444 # $1: message string
445 # $2: exit code number (with 0 does not exit)
446 msg_error() {
447     if [[ "${msgdebug}" = false ]]; then
448         set +xv
449     fi
450     local _msg_opts="-a ${wfa_name}"
451     if [[ "${1}" = "-n" ]]; then
452         _msg_opts="${_msg_opts} -o -n"
453         shift 1
454     fi
455     [[ "${msgdebug}" = true ]] && _msg_opts="${_msg_opts} -x"
456     [[ "${nocolor}"  = true ]] && _msg_opts="${_msg_opts} -n"
457     msg ${_msg_opts} error "$(translate "${@}")"
458     if [[ "${bash_debug}" = true ]]; then
459         set -xv
460     fi
461 }
462
463 ######################################################################################
464 # ここから実際の処理開始
465 # ここから下のメッセージは翻訳可能です
466
467 # rm helper
468 # Delete the file if it exists.
469 # For directories, rm -rf is used.
470 # If the file does not exist, skip it.
471 # remove <file> <file> ...
472 remove() {
473     local _list=($(echo "$@")) _file
474     for _file in "${_list[@]}"; do
475         msg_debug "Removing ${_file}"
476         if [[ -f "${_file}" ]]; then    
477             rm -f "${_file}"
478         elif [[ -d "${_file}" ]]; then
479             rm -rf "${_file}"
480         fi
481     done
482 }
483
484 usage (){
485     local _pacman_help=false
486
487     local _wfa_usage
488     _wfa_usage() {
489         echo "Usage:"
490         echo "${wfa_command}"
491         echo "${wfa_command} <operation> [...]"
492         echo
493         echo "operations:"
494         echo "    ${wfa_command} {-h --help}"
495         echo "    ${wfa_command} {-V --version}"
496        #echo "    ${wfa_command} {-D --database}    <options> <package(s)>"
497        #echo "    ${wfa_command} {-F --files}       [options] [package(s)]"
498         echo "    ${wfa_command} {-Q --query}       [options] [package(s)]"
499         echo "    ${wfa_command} {-R --remove}      [options] <package(s)>"
500         echo "    ${wfa_command} {-S --sync}        [options] [package(s)]"
501        #echo "    ${wfa_command} {-T --deptest}     [options] [package(s)]"
502        #echo "    ${wfa_command} {-U --upgrade}     [options] <file(s)>"
503        #echo
504        #echo "New operations:"
505        #echo "    ${wfa_command} {-P --show}        [options]"
506        #echo "    ${wfa_command} {-G --getpkgbuild} [package(s)]"
507         echo
508         echo "New options:"
509         echo "       --repo             Assume targets are from the repositories"
510         echo "    -a --aur              Assume targets are from the AUR"
511         echo
512         echo "Permanent configuration options:"
513         echo "    --aururl      <url>   Set an alternative AUR URL"
514         echo "    --makepkg     <file>  makepkg command to use"
515         echo "    --mflags      <flags> Pass arguments to makepkg"
516         echo "    --pacman      <file>  pacman command to use"
517         echo "    --git         <file>  git command to use"
518         echo "    --gitflags    <flags> Pass arguments to git"
519         echo "    --gpg         <file>  gpg command to use"
520         echo "    --gpgflags    <flags> Pass arguments to gpg"
521         echo "    --config      <file>  pacman.conf file to use"
522         echo "    --makepkgconf <file>  makepkg.conf file to use"
523         echo "    --nomakepkgconf       Use the default makepkg.conf"
524         echo
525     }
526
527     local _wfa_usage_sync
528     _wfa_usage_sync() {
529         echo "usage:  ${wfa_command} {-S --sync} [options] [package(s)]"
530         echo "options:"
531         echo "  -b, --dbpath <path>  set an alternate database location"
532         echo "      --config <path>  set an alternate configuration file"
533         echo "      --noconfirm      do not ask for any confirmation"
534
535     }
536
537     if [[ "${operation}" = "none" ]]; then
538         _wfa_usage
539     elif [[ "${_pacman_help}" = true ]]; then
540         "${pacman_command}" -h --${operation}
541     elif [[ "$(type -t "_wfa_usage_${operation}" )" = "function" ]]; then
542         _wfa_usage_${operation}
543     else
544         msg_error "Undefined operation"
545         exit 1
546     fi
547 }
548
549 set_operation() {
550     if [[ "${operation}" = "none" ]]; then
551         operation="${1}"
552         add_args pacman "--${operation}"
553     else
554         msg_error "only one operation may be used at a time"
555         exit 1
556     fi
557 }
558
559 run_sudo() {
560     if (( ${UID} == 0 )); then
561         ${@}
562     else
563         sudo ${@}
564     fi
565 }
566
567 run_pacman() {
568     run_sudo "${pacman_command}" ${@}
569 }
570
571 # pacmanの引数を追加する
572 # https://github.com/FascodeNet/aptpac/blob/master/aptpac のADD_OPTION関数を参考
573 # Usage: add_args [pacman/makepkg] <args1> <args2>...
574 add_args() {
575     local _target="${1}"
576     local _args_array
577     shift 1
578
579     case "${_target}" in
580         "makepkg")
581             _args_array=(${makepkg_args})
582             _args_array+=(${@})
583             makepkg_args=${_args_array[@]}
584             msg_debug "makepkg ARGS: ${makepkg_args}"
585             ;;
586
587         "pacman")
588             _args_array=(${pacman_args})
589             _args_array+=(${@})
590             pacman_args=${_args_array[@]}
591             msg_debug "pacman ARGS: ${pacman_args}"
592             ;;
593         "git")
594             _args_array=(${mpg_args})
595             _args_array+=(${@})
596             git_args=${_args_array[@]}
597             msg_debug "git ARGS: ${git_args}"
598             ;;
599         "gpg")
600             _args_array=(${gpg_args})
601             _args_array+=(${@})
602             gpg_args=${_args_array[@]}
603             msg_debug "gpg ARGS: ${gpg_args}"
604             ;;
605         "sudo")
606             _args_array=(${sudo_args})
607             _args_array+=(${@})
608             sudo_args=${_args_array[@]}
609             msg_debug "sudo ARGS: ${sudo_args}"
610             ;;
611         *)
612             msg_error "Failed to set the argument of %s" "${_target}"
613             msg_error "Setting that command is not currently supported"
614             exit 1
615             ;;
616     esac
617 }
618
619 # 引数で指定されたパッケージがAUR以外の場所に存在しない場合にのみ正常終了します(AURのパッケージの場合に正常終了)
620 check_aur_package() {
621     local _package="${1}"
622     # 参考: https://qiita.com/Hayao0819/items/a8740a17301fafa2fdab
623     if [[ -z "$(pacman -Ssq "${_package}" 2>/dev/null | grep -o ".*${_package}$")" ]]; then
624         #AUR以外のリポジトリに存在しない
625         return 0
626     else
627         return 1
628     fi
629 }
630
631
632 # 引数で指定されたパッケージが既にインストールされている場合は正常終了します。
633 check_installed_package() {
634     local _package="${1}"
635     if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1; then
636         return 0
637     else
638         return 1
639     fi
640 }
641
642 get_cache_dir() {
643     local _user_config_dir
644     if [[ -v XDG_CONFIG_HOME ]]; then
645         _user_config_dir="${XDG_CONFIG_HOME}"
646     else
647         _use_config_dir="${HOME}/.config"
648     fi
649     if [[ -f "${_use_config_dir}/user-dirs.dirs" ]]; then
650         source "${_use_config_dir}/user-dirs.dirs"
651     fi
652     if [[ -v XDG_CACHE_HOME ]]; then
653         echo -n "${XDG_CACHE_HOME}"
654         return 0
655     else
656         echo -n "${HOME}/.cache"
657         return 0
658     fi
659 }
660
661 # Usage: get_srcinfo_data <path> <var>
662 # 参考: https://qiita.com/withelmo/items/b0e1ffba639dd3ae18c0
663 get_srcinfo_data() {
664     local _srcinfo="${1}" _ver="${2}"
665     local _srcinfo_json=$(python << EOF
666 from srcinfo.parse import parse_srcinfo; import json
667 text = """
668 $(cat ${1})
669 """
670 parsed, errors = parse_srcinfo(text)
671 print(json.dumps(parsed))
672 EOF
673 )
674     echo "${_srcinfo_json}" | jq -rc "${2}" | tr '\n' ' '
675 }
676
677
678 # AURからパッケージをビルドしてインストールします
679 # 現在1つのパッケージしか指定できません
680 install_aur_package() {
681     local _package="${1}"
682
683     # Create cache dir
684     if [[ ! -v wfa_cache_dir ]]; then
685         wfa_cache_dir="$(get_cache_dir)/wfa"
686     fi
687     mkdir -p "${wfa_cache_dir}/archive"
688     mkdir -p "${wfa_cache_dir}/build/${_package}"
689
690     # AurJsonから値を取得
691     local _aur_json=$(curl -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name&arg=${_package}" | jq -r)
692     if (( "$(echo "${_aur_json}" | jq -r ".resultcount")" == 0 )); then
693         msg_error "Could not find all required packages:\n      ${_package}"
694         exit 1
695     fi
696
697     local _found_packages="$(echo "${_aur_json}" | jq -r --tab '.results[].Name')"
698     #msg_debug "Found package: $(echo ${_found_packages} | tr '\n' ' ')"
699
700     if [[ -n "$(echo "${_found_packages}" | grep -x "${_package}" )" ]]; then
701         msg_debug "Select a package %s with an exact name match" "${_package}"
702     else
703         msg_error "No package with an exact name match was found"
704         exit 1
705     fi
706
707     # PKGBUILDをダウンロード
708     msg_info "Download PKGBUILD of %s" "${_package}"
709     _aur_json=$(echo "${_aur_json}" | jq -r ".results[] | select(.Name == \"${_package}\")" )
710     local _aur_snapshot_url="${aururl%/}$(echo "${_aur_json}" | jq -r ".URLPath")"
711     local _aur_version="$(echo "${_aur_json}" | jq -r ".Version")"
712     msg_debug "Get PKGBUILD from %s" "${_aur_snapshot_url}"
713
714     local _pkgbuild_archive_path="${wfa_cache_dir}/archive/${_package}-${_aur_version}"
715     local _download_pkgbuild=true
716     if [[ -f "${_pkgbuild_archive_path}" ]]; then
717         msg_warn "PKGBUILD has already been downloaded"
718         msg_warn -n "Do you want to overwrite and download? [n] :"
719         local _yes_or_no
720         if [[ "${noconfirm}" = true ]]; then
721             echo
722             _yes_or_no="No"
723         else
724             read _yes_or_no
725         fi
726         case "${_yes_or_no}" in
727             "y" | "Y" | "yes" | "Yes" | "YES" ) _download_pkgbuild=true  ;;
728             *                                 ) _download_pkgbuild=false ;;
729         esac
730     fi
731     if [[ "${_download_pkgbuild}" = true ]]; then
732         remove "${_pkgbuild_archive_path}"
733         curl -L -C - -f -o "${_pkgbuild_archive_path}" "${_aur_snapshot_url}"
734     fi
735
736     # PKGBUILDを展開
737     msg_info "Unpacking the tarball of PKGBUILD ..."  #ここまで翻訳
738     tar -xv -f "${_pkgbuild_archive_path}" -C "${wfa_cache_dir}/build/" > /dev/null 2>&1
739
740     # .SRCINFOを解析
741     local _build_dir="${wfa_cache_dir}/build/${_package}"
742     if [[ ! -f "${_build_dir}/.SRCINFO" ]]; then
743         msg_warn ".SRCINFO was not found.\nGenerate it using makepkg."
744         (
745             cd "${_build_dir}"
746             "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
747         )
748     fi
749
750     local _makedepends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".makedepends[]?")"
751     local _depends="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".depends[]?")"
752     local _conflicts="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".conflicts[]?")"
753     msg_debug "makedepends: ${_makedepends}"
754     msg_debug "depends: ${_depends}"
755     msg_debug "conflicts: ${_conflicts}"
756
757
758     # 衝突を確認
759     local _pkg _conflicts_found=false
760     for _pkg in ${_conflicts[@]}; do
761         if "${pacman_command}" -Qq "${_pkg}" > /dev/null 2>&1 ; then
762             _conflicts_found=true
763             msg_error "${_package} is colliding with ${_pkg}"
764         fi
765     done
766     if "${pacman_command}" -Qq "${_package}" > /dev/null 2>&1 &&  [[ ! "$("${pacman_command}" -Qq "${_package}" 2> /dev/null)" = "${_package}" ]]; then
767         msg_error "${_package} is colliding with $("${pacman_command}" -Qq "${_package}")"
768         _conflicts_found=true
769     fi
770     if [[ "${_conflicts_found}" = true ]]; then
771         msg_error "A conflict was found."
772         exit 1
773     fi
774
775
776     # 依存パッケージをインストール
777     if [[ "${nodeps}" = false ]]; then
778         msg_info "Install dependent packages..."
779         local _force_aur="${force_aur}"
780         force_aur=false
781         install_package "${_depends}"
782         force_aur="${_force_aur}"
783         unset _force_aur
784     fi
785
786     # ビルド準備
787     # srcdirの確認
788     if [[ -d "${_build_dir}/src" ]]; then
789         msg_info "Found ${_build_dir}/src"
790         msg_info "Packages to cleanBuild? [n] :"
791         local _yes_or_no
792         unset _yes_or_no
793         if [[ "${noconfirm}" = true ]]; then
794             echo
795             _yes_or_no="No"
796         else
797             read _yes_or_no
798         fi
799         case "${_yes_or_no}" in
800             "y" | "Y" | "yes" | "Yes" | "YES" ) add_args makepkg "--clean" ;;
801         esac
802     fi
803
804
805     # ビルド
806     add_args "makepkg" "-sf"
807     (
808         cd "${_build_dir}"
809         "${makepkg_command}" "${makepkg_args}"
810     )
811
812
813     # ビルド後のパッケージ一覧を生成
814     (
815         cd "${_build_dir}"
816         "${makepkg_command}" --printsrcinfo > "${_build_dir}/.SRCINFO"
817     )
818     local _pkgnames=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".packages | keys[]" | sed 's/ //g'))
819     local _pkgver="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgver" | sed 's/ //g')"
820     local _pkgrel="$(get_srcinfo_data "${_build_dir}/.SRCINFO" ".pkgrel" | sed 's/ //g')"
821     local _arch_array=($(get_srcinfo_data "${_build_dir}/.SRCINFO" ".arch[]"))
822     local _arch _pkgname
823     if [[ "${_arch_array[*]}" = "any" ]]; then
824         _arch="any"
825     else
826         _arch="$(uname -m)"
827     fi
828     local _PKGEXT=$(
829         source "${makepkg_config}"
830         echo "${PKGEXT}"
831     )
832     local _pkgfilelist=()
833     for _pkgname in ${_pkgnames[@]}; do
834         _pkgfilelist+=("${_build_dir}/${_pkgname}-${_pkgver}-${_pkgrel}-${_arch}${_PKGEXT}")
835     done
836
837     # インストール
838     run_pacman -U --noconfirm ${_pkgfilelist[@]}
839 }
840
841 # AURのパッケージを検索
842 search_aur_package() {
843     local _package="${1}"
844     local _aur_json=$(curl -sL "https://aur.archlinux.org/rpc/?v=5&type=search&by=name-desc&arg=${_package}" | jq -r )
845     local _found_result_count="$(echo "${_aur_json}" | jq -r ".resultcount")"
846     if (( "${_found_result_count}" == 0 )); then
847         msg_error "Could not find all required packages:\n      ${_package}"
848         exit 1
849     fi
850     _aur_json=$(echo "${_aur_json}" | jq -r ".results[]")
851
852     #echo ${_aur_json} 
853
854     local _found_pkgname=($(echo "${_aur_json}" | jq -r ".Name" ))
855
856
857
858
859     local  _found_package __pkgver __popularity __vote __pkgdesc
860     for _found_package in ${_found_pkgname[@]}; do
861         _found_json="$(echo ${_aur_json} | jq "select(.Name == \"${_found_package}\")")"
862         __pkgver="$(echo "${_found_json}" | jq -r ".Version" )"
863         __popularity="$(echo "${_found_json}" | jq -r ".Popularity" )"
864         __vote="$(echo "${_found_json}" | jq -r ".NumVotes" )"
865         __pkgdesc="$(echo "${_found_json}" | jq -r ".Description" )"
866     
867         echo "aur/${_found_package} ${__pkgver} (+${__vote} ${__popularity})"
868         echo "    ${__pkgdesc}"
869         unset __pkgver __popularity __vote __pkgdesc _found_json
870     done
871 }
872
873 # バージョンを表示して終了
874 operation_version() {
875     # Pyalpmからlibalpmの値を取得
876     # 参考: https://pyalpm.readthedocs.io/en/latest/pyalpm/pyalpm.html
877     local _libalpm_version="$(python3 -c 'import pyalpm; print(pyalpm.alpmversion())')"
878     local _pacman_version="$("${pacman_command}" -Q pacman | cut -d ' ' -f 2)"
879     echo "wfa v${wfa_version} - pacman v${_pacman_version} - libalpm v${_libalpm_version}"
880 }
881
882 operation_remove() {
883     run_pacman ${pacman_args} "${specified_packages[@]}"
884 }
885
886 # Usage: install_package <package1> <package2>...
887 install_package() {
888     local _package
889     for _package in ${@}; do
890         if ! check_installed_package "${_package}"; then
891             if ! check_aur_package "${_package}"; then
892                 # 公式パッケージなのでpacmanでそのままインストール
893                 run_pacman ${pacman_args} "${_package}"
894             else
895                 # AUR上のパッケージの場合の処理
896                 install_aur_package "${_package}"
897                 #msg_error "Getting the AUR package has not been implemented yet.
898                 #exit 1
899             fi
900         fi
901     done
902 }
903
904 upgrade_aur_package() {
905     msg_error "This is a feature that has not been implemented yet"
906 }
907
908 operation_sync(){
909     local _package
910     if [[ "${sync_search}" = true ]]; then
911         for _package in ${specified_packages[@]}; do
912             search_aur_package "${_package}"
913         done
914         "${pacman_command}" ${pacman_args} ${specified_packages[@]}
915     else
916         if [[ "${sync_upgrade}" = true ]]; then
917             upgrade_aur_package
918             run_pacman ${pacman_args} --sysupgrade
919         fi
920         for _package in ${specified_packages[@]}; do
921             if ! check_aur_package "${_package}" && [[ "${force_aur}" = false ]]; then
922                 # 公式パッケージなのでpacmanでそのままインストール
923                 run_pacman ${pacman_args} "${_package}"
924             else
925                 # AUR上のパッケージの場合の処理
926                 install_aur_package "${_package}"
927                 #msg_error "Getting the AUR package has not been implemented yet."
928                 #exit 1
929             fi
930         done
931     fi
932 }
933
934
935 # Parse options
936 ARGUMENT="${@}"
937 _opt_short="QRShVdb:aysu"
938 _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"
939
940 OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- ${ARGUMENT})
941 [[ ${?} != 0 ]] && exit 1
942 unset _opt_short _opt_long
943
944 eval set -- "${OPT}"
945 msg_debug "Argument: ${OPT}"
946
947 while :; do
948     case ${1} in
949         -Q | --query)
950             set_operation "query"
951             shift 1
952             ;;
953         -R | --remove)
954             set_operation "remove"
955             shift 1
956             ;;
957         -S | --sync)
958             set_operation "sync"
959             shift 1
960             ;;
961         -V | --version)
962             set_operation "version"
963             shift 1
964             ;;
965         --)
966             shift
967             break
968             ;;
969         *)
970             shift 1
971             ;;
972     esac
973 done
974
975 eval set -- "${OPT}"
976
977 while :; do
978     case ${1} in
979         -a | --aur)
980             force_aur=true
981             msg_debug "Assume targets are from the AUR"
982             shift 1
983             ;;
984         --debug)
985             debug=true
986             add_args pacman "--debug"
987             shift 1
988             ;;
989         -d | --nodeps)
990             nodeps=true
991             add_args pacman "--nodeps"
992             shift 1
993             ;;
994         -b | --dbpath)
995             add_args pacman "--dbpath '${2}'"
996             shift 2
997             ;;
998         -y | --refresh)
999             option_y_count=$(( option_y_count + 1 ))
1000             shift 1
1001             ;;
1002         -s | --search)
1003             add_args pacman "--search"
1004             sync_search=true
1005             shift 1
1006             ;;
1007         -u | --sysupgrade)
1008             sync_upgrade=true
1009             shift 1
1010             ;;
1011         --aururl)
1012             aururl="${2}"
1013             shift 2
1014             ;;
1015         --noconfirm)
1016             add_args pacman "--noconfirm"
1017             noconfirm=true
1018             shift 1
1019             ;;
1020         --config)
1021             pacman_config="${2}"
1022             add_args pacman "--config \"${2}\""
1023             shift 2
1024             ;;
1025         --makepkg)
1026             makepkg_command="${2}"
1027             shift 2
1028             ;;
1029         --mflags)
1030             makepkg_args="${2}"
1031             shift 2
1032             ;;
1033         --pacman)
1034             pacman_command="${2}"
1035             shift 2
1036             ;;
1037         --git)
1038             git_command="${2}"
1039             shift 2
1040             ;;
1041         --gitflags)
1042             git_args="${2}"
1043             shift 2
1044             ;;
1045         --makepkgconfig)
1046             if [[ "${nomakepkgconf}" = false ]]; then
1047                 makepkg_config="${2}"
1048             else
1049                 msg_warn "--nomakepkgconf is specified.\n--makepkgconf has been ignored."
1050             fi
1051             shift 2
1052             ;;
1053         --nomakepkgconf)
1054             makepkg_config="/etc/makepkg.conf"
1055             nomakepkgconf=true
1056             shift 1
1057         ;;
1058         --bash-debug)
1059             bash_debug=true
1060             set -xv
1061             shift 1
1062             ;;
1063         --msg-debug)
1064             msgdebug=true
1065             shift 1
1066             ;;
1067         -h | --help)
1068             usage
1069             shift 1
1070             exit 0
1071             ;;
1072         --)
1073             shift
1074             break
1075             ;;
1076         *)
1077             shift 1
1078             ;;
1079     esac
1080 done
1081
1082 specified_packages=(${@})
1083
1084 # Run database update
1085 if (( "${option_y_count}" == 1 )); then
1086     run_pacman -Sy
1087 elif (( "${option_y_count}" >= 2 )); then
1088     run_pacman -Syy
1089 fi
1090
1091 case "${operation}" in
1092     "version")
1093         operation_version
1094         ;;
1095     "sync")
1096         operation_sync
1097         ;;
1098     "remove")
1099         operation_remove
1100         ;;
1101     "none")
1102         exit 0
1103         ;;
1104     *)
1105         msg_error "Undefined operation"
1106         exit 1
1107         ;;
1108 esac