OSDN Git Service

[fix] : Fixed default entry name
[alterlinux/alterlinux.git] / tools / wizard.sh
1 #!/usr/bin/env bash
2 set -e
3
4 :<< TEXT
5 変数や関数の命名規則について
6
7 << グローバル >>
8 グローバル変数: Var_Global_[変数名]
9 グローバル関数: Function_Global_[関数名]
10
11 [ Function_Global_Main_ask_questions内で使用する関数のみ ]
12 グローバル関数: Function_Global_Ask_[設定される変数名]
13
14 [ wizard.sh用の変数 ]
15 オプション用: Var_Global_Wizard_Option_
16 実行環境設定: Var_Global_Wizard_Env_
17
18 << ローカル >>
19 ローカル変数: Var_Local_[変数名]
20 ローカル関数: Var_Local_[関数名]
21 TEXT
22
23
24 Var_Global_Wizard_Option_nobuild=false
25 script_path="$( cd -P "$( dirname "$(readlink -f "$0")" )" && cd .. && pwd )"
26 Var_Global_Wizard_Env_script_path="${script_path}"
27
28 Var_Global_Wizard_Env_machine_arch="$(uname -m)"
29 Var_Global_Wizard_Option_build_arch="${Var_Global_Wizard_Env_machine_arch}"
30
31 # Pacman configuration file used only when checking packages.
32 Var_Global_Wizard_Env_pacman_conf="${Var_Global_Wizard_Env_script_path}/system/pacman-${Var_Global_Wizard_Env_machine_arch}.conf"
33
34 # 言語(en or jp)
35 #Var_Global_Wizard_Option_language="jp"
36 Var_Global_Wizard_Option_language="en"
37 Var_Global_Wizard_Option_skip_language=false
38
39
40
41 # メッセージを表示する
42 # msg [日本語] [英語]
43 msg() {
44     if [[ ${Var_Global_Wizard_Option_language} = "jp" ]]; then
45         echo "${1}"
46     else
47         echo "${2}"
48     fi
49 }
50 msg_error() {
51     if [[ ${Var_Global_Wizard_Option_language} = "jp" ]]; then
52         echo "${1}" >&2
53     else
54         echo "${1}" >&2
55     fi
56 }
57 msg_n() {
58     if [[ ${Var_Global_Wizard_Option_language} = "jp" ]]; then
59         echo -n "${1}"
60     else
61         echo -n "${2}"
62     fi
63 }
64
65
66 # Usage: getclm <number>
67 # 標準入力から値を受けとり、引数で指定された列を抽出します。
68 getclm() { cut -d " " -f "${1}"; }
69
70 # 使い方
71 Function_Global_help() {
72     echo "usage ${0} [options]"
73     echo
74     echo " General options:"
75     echo "    -a          Specify the architecture"
76     echo "    -e          English"
77     echo "    -j          Japanese"
78     echo "    -n          Enable simulation mode"
79     echo "    -x          Enable bash debug"
80     echo "    -h          This help message"
81 }
82
83 while getopts 'a:xnjeh' arg; do
84     case "${arg}" in
85         n)
86             Var_Global_Wizard_Option_nobuild=true
87             msg \
88                 "シミュレーションモードを有効化しました" "Enabled simulation mode"
89             ;;
90         x)
91             set -x
92             msg "デバッグモードを有効化しました" "Debug mode enabled"
93             ;;
94         e)
95             Var_Global_Wizard_Option_language="en"
96             echo "English is set"
97             Var_Global_Wizard_Option_skip_language=true
98             ;;
99         j)
100             Var_Global_Wizard_Option_language="jp"
101             echo "日本語が設定されました"
102             Var_Global_Wizard_Option_skip_language=true
103             ;;
104         h)
105             Function_Global_help
106             exit 0
107             ;;
108         a)
109             Var_Global_Wizard_Option_build_arch="${OPTARG}"
110             ;;
111         *)
112             _help
113             exit 1
114             ;;
115     esac
116 done
117
118 Function_Global_Main_wizard_language () {
119     if [[ "${Var_Global_Wizard_Option_skip_language}" = false ]]; then
120         echo "このウィザードでどちらの言語を使用しますか?"
121         echo "この質問はウィザード内のみの設定であり、ビルドへの影響はありません。"
122         echo
123         echo "Which language would you like to use for this wizard?"
124         echo "This question is a wizard-only setting and does not affect the build."
125         echo
126         echo "1: 英語 English"
127         echo "2: 日本語 Japanese"
128         echo
129         echo -n ": "
130         read -r Var_Global_Wizard_Option_language
131
132         case "${Var_Global_Wizard_Option_language}" in
133             "1" | "英語"   | "English"  | "en") Var_Global_Wizard_Option_language=en ;;
134             "2" | "日本語" | "Japanese" | "ja") Var_Global_Wizard_Option_language=jp ;;
135             *                                ) Function_Global_Main_wizard_language ;;
136         esac
137     fi
138 }
139
140 Function_Global_Main_check_required_files () {
141     local Var_Local_file_list Var_Local_file Var_Local_error=false
142     Var_Local_file_list=(
143         "build.sh"
144         "tools/keyring.sh"
145         "tools/clean.sh"
146         "tools/channel.sh"
147         "tools/module.sh"
148         "tools/locale.sh"
149         "tools/kernel.sh"
150         "tools/pkglist.sh"
151         "tools/alteriso-info.sh"
152         "tools/package.py"
153         "tools/msg.sh"
154         "system/kernel-i686"
155         "system/kernel-x86_64"
156         "system/locale-i686"
157         "system/locale-x86_64"
158         "system/pacman-i686.conf"
159         "system/pacman-x86_64.conf"
160         "default.conf"
161     )
162
163     for Var_Local_file in "${Var_Local_file_list[@]}"; do
164         if [[ ! -f "${Var_Global_Wizard_Env_script_path}/${Var_Local_file}" ]]; then
165             msg_error "${Var_Local_file}が見つかりませんでした。" "${Var_Local_file} was not found."
166             Var_Local_error=true
167         fi
168     done
169     if [[ "${Var_Local_error}" = true ]]; then
170         exit 1
171     fi
172 }
173
174 Function_Global_Main_load_default_config () {
175     source "${Var_Global_Wizard_Env_script_path}/default.conf"
176 }
177
178 Function_Global_Main_check_yay(){
179     if ! pacman -Qq yay > /dev/null 2>&1; then
180         msg_error "yayが見つかりませんでした" "yay was not found."
181         exit 1
182     fi
183 }
184
185 Function_Global_Main_install_dependent_packages () {
186     #local pkg installed_pkg installed_ver check_pkg
187     local Function_Local_checkpkg Var_Local_package
188
189     msg "データベースの更新をしています..." "Updating package datebase..."
190     sudo pacman -Sy --config "${Var_Global_Wizard_Env_pacman_conf}"
191
192     Function_Local_checkpkg () {
193         local Var_Local_package Var_Local_installed_package Var_Local_installed_version
194         readarray -t Var_Local_installed_package < <(pacman -Q | getclm 1)
195         readarray -t Var_Local_installed_version < <(pacman -Q | getclm 2)
196         for Var_Local_package in $(seq 0 $(( "${#Var_Local_installed_package[@]}" - 1 ))); do
197             if [[ "${Var_Local_installed_package[${Var_Local_package}]}" = "${1}" ]]; then
198                 [[ "${Var_Local_installed_version[${Var_Local_package}]}" = "$(pacman -Sp --print-format '%v' --config "${Var_Global_Wizard_Env_pacman_conf}" "${1}")" ]] && return 0 || return 1
199             fi
200         done
201         return 1
202     }
203     echo
204     for Var_Local_package in "${dependence[@]}"; do
205         msg "依存パッケージ ${Var_Local_package} を確認しています..." "Checking dependency package ${Var_Local_package} ..."
206         if Function_Local_checkpkg "${Var_Local_package}"; then
207             Var_Global_missing_packages+=("${Var_Local_package}")
208         fi
209     done
210     if [[ -n "${Var_Global_missing_packages[*]}" ]]; then
211         yay -S --needed --config "${Var_Global_Wizard_Env_pacman_conf}" "${Var_Global_missing_packages[@]}"
212     fi
213     echo
214 }
215
216 Function_Global_Main_guide_to_the_web () {
217     if [[ "${Var_Global_Wizard_Option_language}"  = "jp" ]]; then
218         msg "wizard.sh ではビルドオプションの生成以外にもパッケージのインストールやキーリングのインストールなど様々なことを行います。"
219         msg "もし既に環境が構築されておりそれらの操作が必要ない場合は、以下のサイトによるジェネレータも使用することができます。"
220         msg "http://hayao.fascode.net/alteriso-options-generator/"
221         echo
222     fi
223 }
224
225 Function_Global_Main_run_keyring.sh () {
226     local Var_Local_input_yes_or_no
227     msg_n "Alter Linuxの鍵を追加しますか?(y/N): " "Are you sure you want to add the Alter Linux key? (y/N):"
228     read -r Var_Local_input_yes_or_no
229     if ${Var_Global_Wizard_Option_nobuild}; then
230         msg \
231             "${Var_Local_input_yes_or_no}が入力されました。シミュレーションモードが有効化されているためスキップします。" \
232             "You have entered ${Var_Local_input_yes_or_no}. Simulation mode is enabled and will be skipped."
233     else
234         case "${Var_Local_input_yes_or_no}" in
235             "y" | "Y" | "yes" | "Yes" | "YES" ) sudo "${Var_Global_Wizard_Env_script_path}/keyring.sh" --alter-add   ;;
236             "n" | "N" | "no"  | "No"  | "NO"  ) return 0                                       ;;
237             *                                 ) Function_Global_Main_run_keyring.sh            ;;
238         esac
239     fi
240 }
241
242
243 Function_Global_Main_remove_dependent_packages () {
244     if [[ -n "${Var_Global_missing_packages[*]}" ]]; then
245         sudo pacman -Rsn --config "${Var_Global_Wizard_Env_pacman_conf}" "${Var_Global_missing_packages[@]}"
246     fi
247 }
248
249
250 Function_Global_Ask_build_arch() {
251     msg \
252         "アーキテクチャを選択して下さい " \
253         "Please select an architecture."
254     msg \
255         "注意:このウィザードでは正式にサポートされているアーキテクチャのみ選択可能です。" \
256         "Note: Only officially supported architectures can be selected in this wizard."
257     echo
258     echo "1: x86_64 (64bit)"
259     echo "2: i686 (32bit)"
260     echo -n ": "
261
262     read -r Var_Global_Wizard_Option_build_arch
263
264     case "${Var_Global_Wizard_Option_build_arch}" in
265         1 | "x86_64" ) Var_Global_Wizard_Option_build_arch="x86_64" ;;
266         2 | "i686"   ) Var_Global_Wizard_Option_build_arch="i686"   ;;
267         *            ) Function_Global_Ask_build_arch               ;;
268     esac
269     return 0
270 }
271
272 Function_Global_Ask_plymouth () {
273     local Var_Local_input_yes_or_no
274     msg_n "Plymouthを有効化しますか?[no](y/N) : " "Do you want to enable Plymouth? [no] (y/N) : "
275     read -r Var_Local_input_yes_or_no
276     case "${Var_Local_input_yes_or_no}" in
277         "y" | "Y" | "yes" | "Yes" | "YES" ) Var_Global_Build_plymouth=true   ;;
278         "n" | "N" | "no"  | "No"  | "NO"  ) Var_Global_Build_plymouth=false  ;;
279         *                                 ) Function_Global_Ask_plymouth ;;
280     esac
281 }
282
283 # この関数はAlterISO2以前を想定したものです。現在はコメントアウトされて実行されません。
284 Function_Global_Ask_japanese () {
285     local Var_Local_input_yes_or_no
286     msg_n "日本語を有効化しますか?[no](y/N) : " "Do you want to activate Japanese? [no] (y/N) : "
287     read -r Var_Local_input_yes_or_no
288     case "${Var_Local_input_yes_or_no}" in
289         "y" | "Y" | "yes" | "Yes" | "YES" ) Var_Global_Build_japanese=true   ;;
290         "n" | "N" | "no"  | "No"  | "NO"  ) Var_Global_Build_japanese=false  ;;
291         *                                 ) Function_Global_Ask_japanese ;;
292     esac
293 }
294
295 # Function_Global_Ask_japaneseの代わりにFunction_Global_Ask_localeを使用して下さい。
296 Function_Global_Ask_locale() {
297     msg \
298         "ビルドする言語を以下の番号から選択して下さい " \
299         "Please select the language to build from the following numbers"
300
301     local Var_Local_locale_list Var_Local_locale Var_Local_count=1 Var_Local_input_locale
302     #Var_Local_locale_list=($("${Var_Global_Wizard_Env_script_path}/tools/locale.sh" -a "${Var_Global_Wizard_Option_build_arch}" show))
303     readarray -t Var_Local_locale_list < <("${Var_Global_Wizard_Env_script_path}/tools/locale.sh" -a "${Var_Global_Wizard_Option_build_arch}" show)
304     for Var_Local_locale in "${Var_Local_locale_list[@]}"; do
305         (
306             local locale_name locale_gen_name locale_version locale_time locale_fullname
307             eval "$("${Var_Global_Wizard_Env_script_path}/tools/locale.sh" -a "${Var_Global_Wizard_Option_build_arch}" get "${Var_Local_locale}" )"
308             echo -n "$(printf %02d "${Var_Local_count}")    ${locale_name}"
309             for Var_Local_int in $( seq 1 $(( 10 - ${#kernel} )) ); do echo -ne " "; done
310             echo -ne "(${locale_fullname})\n"
311         )
312         Var_Local_count=$(( Var_Local_count + 1 ))
313     done
314     echo -n ": "
315     read -r Var_Local_input_locale
316
317     set +e
318     expr "${Var_Local_input_locale}" + 1 >/dev/null 2>&1
319     if [[ "${?}" -lt 2 ]]; then
320         set -e
321         # 数字である
322         Var_Local_input_locale=$(( Var_Local_input_locale - 1 ))
323         if [[ -z "${Var_Local_locale_list[${Var_Local_input_locale}]}" ]]; then
324             Function_Global_Ask_locale
325             return 0
326         else
327             Var_Global_Build_locale="${Var_Local_locale_list[${Var_Local_input_locale}]}"
328             
329         fi
330     else
331         set -e
332         # 数字ではない
333         # 配列に含まれるかどうか判定
334         if [[ ! $(printf '%s\n' "${Var_Local_locale_list[@]}" | grep -qx "${Var_Local_input_locale}"; echo -n ${?} ) -eq 0 ]]; then
335             Function_Global_Ask_locale
336             return 0
337         else
338             Var_Global_Build_locale="${Var_Local_input_locale}"
339         fi
340     fi
341 }
342
343
344 Function_Global_Ask_comp_type () {
345     local Var_Local_input_comp_type
346     msg \
347         "圧縮方式を以下の番号から選択してください " \
348         "Please select the compression method from the following numbers"
349     echo
350     echo "1: gzip (default)"
351     echo "2: lzma"
352     echo "3: lzo"
353     echo "4: lz4"
354     echo "5: xz"
355     echo "6: zstd"
356     echo -n ": "
357     read -r Var_Local_input_comp_type
358     case "${Var_Local_input_comp_type}" in
359         "1" | "gzip" ) Var_Global_Build_comp_type="gzip" ;;
360         "2" | "lzma" ) Var_Global_Build_comp_type="lzma" ;;
361         "3" | "lzo"  ) Var_Global_Build_comp_type="lzo"  ;;
362         "4" | "lz4"  ) Var_Global_Build_comp_type="lz4"  ;;
363         "5" | "xz"   ) Var_Global_Build_comp_type="xz"   ;;
364         "6" | "zstd" ) Var_Global_Build_comp_type="zstd" ;;
365         *            ) Function_Global_Ask_comp_type     ;;
366     esac
367     return 0
368 }
369
370
371 Function_Global_Ask_comp_option () {
372     comp_option=""
373     local Function_Local_comp_option
374     case "${Var_Global_Build_comp_type}" in
375         "gzip")
376             Function_Local_comp_option() {
377                 local Var_Local_gzip_level Var_Local_gzip_window
378                 local Function_Local_gzip_level Function_Local_gzip_window
379
380                 Function_Local_gzip_level () {
381                     msg_n "gzipの圧縮レベルを入力してください。 (1~22) : " "Enter the gzip compression level.  (1~22) : "
382                     read -r Var_Local_gzip_level
383                     if ! [[ ${Var_Local_gzip_level} -lt 23 && ${Var_Local_gzip_level} -ge 1 ]]; then
384                         Function_Local_gzip_level
385                         return 0
386                     fi
387                 }
388                 Function_Local_gzip_window () {
389                     msg_n \
390                         "gzipのウィンドウサイズを入力してください。 (1~15) : " \
391                         "Please enter the gzip window size. (1~15) : "
392
393                     read -r Var_Local_gzip_window
394                     if ! [[ ${Var_Local_gzip_window} -lt 15 && ${Var_Local_gzip_window} -ge 1 ]]; then
395                         Function_Local_gzip_window
396                         return 0
397                     fi
398                 }
399                 Function_Local_gzip_level
400                 Function_Local_gzip_window
401                 comp_option="-Xcompression-level ${Var_Local_gzip_level} -Xwindow-size ${Var_Local_gzip_window}"
402             }
403             ;;
404         "lz4")
405             Function_Local_comp_option () {
406                 local Var_Local_lz4_high_comp
407                 msg_n \
408                     "高圧縮モードを有効化しますか? (y/N) : " \
409                     "Do you want to enable high compression mode? (y/N) : "
410                 read -r Var_Local_lz4_high_comp
411                 case "${Var_Local_lz4_high_comp}" in
412                     "y" | "Y" | "yes" | "Yes" | "YES" ) comp_option="-Xhc"         ;;
413                     "n" | "N" | "no"  | "No"  | "NO"  ) :                          ;;
414                     *                                 ) Function_Local_comp_option ;;
415                 esac
416             }
417             ;;
418         "zstd")
419             Function_Local_comp_option () {
420                 local Var_Local_zstd_level
421                 msg_n \
422                     "zstdの圧縮レベルを入力してください。 (1~22) : " \
423                     "Enter the zstd compression level. (1~22) : "
424                 read -r Var_Local_zstd_level
425                 if [[ ${Var_Local_zstd_level} -lt 23 && ${Var_Local_zstd_level} -ge 1 ]]; then
426                     comp_option="-Xcompression-level ${Var_Local_zstd_level}"
427                 else
428                     Function_Local_comp_option
429                 fi
430             }
431             ;;
432         "lzo")
433             Function_Local_comp_option () {
434                 local Function_Local_lzo_algorithm Var_Local_lzo_algorithm
435                 Function_Local_lzo_algorithm () {
436                     msg \
437                         "lzoの圧縮アルゴリズムを以下の番号から選択して下さい" \
438                         "Select the lzo compression algorithm from the numbers below"
439                     msg \
440                         "よく理解していない場合はlzo1x_999を選択して下さい" \
441                         "Choose lzo1x_999 if you are not familiar with it"
442                     echo
443                     echo "1: lzo1x_1"
444                     echo "2: lzo1x_1_11"
445                     echo "3: lzo1x_1_12"
446                     echo "4: lzo1x_1_15"
447                     echo "5: lzo1x_999"
448                     echo -n ": "
449                     read -r Var_Local_lzo_algorithm
450                     case "${Var_Local_lzo_algorithm}" in
451                         "1" | "lzo1x_1")
452                             Var_Local_lzo_algorithm="lzo1x_1"
453                             ;;
454                         "2" | "lzo1x_1_11")
455                             Var_Local_lzo_algorithm="lzo1x_1_11"
456                             ;;
457                         "3" | "lzo1x_1_12")
458                             Var_Local_lzo_algorithm="lzo1x_1_12"
459                             ;;
460                         "4" | "lzo1x_1_15")
461                             Var_Local_lzo_algorithm="lzo1x_1_15"
462                             ;;
463                         "5" | "lzo1x_999")
464                             Var_Local_lzo_algorithm="lzo1x_999"
465                             ;;
466                         *)
467                             Function_Local_lzo_algorithm
468                             return 0
469                             ;;
470                     esac
471                 }
472                 Function_Local_lzo_algorithm
473                 if [[ "${Var_Local_lzo_algorithm}" = "lzo1x_999" ]]; then                
474                     local Function_Local_lzo_level Var_Local_lzo_level
475                     Function_Local_lzo_level () {
476                         msg_n "lzoの圧縮レベルを入力してください。 (1~9) : " "Enter the gzip compression level.  (1~9) : "
477                         read -r Var_Local_lzo_level
478                         if ! [[ ${Var_Local_lzo_level} -lt 10 && ${Var_Local_lzo_level} -ge 1 ]]; then
479                             Function_Local_lzo_level
480                             return 0
481                         fi
482                     }
483                     Function_Local_lzo_level
484                     comp_option="-Xalgorithm lzo1x_999 -Xcompression-level ${Var_Local_lzo_level}"
485                 else
486                     comp_option="-Xalgorithm ${Var_Local_lzo_algorithm}"
487                 fi
488             }
489             ;;
490         "xz")
491             Function_Local_comp_option () {
492                 msg_error \
493                     "現在${Var_Global_Build_comp_type}の詳細設定ウィザードがサポートされていません。" \
494                     "The ${Var_Global_Build_comp_type} Advanced Wizard is not currently supported."
495             }
496             ;;
497         "lzma" | *)
498             Function_Local_comp_option () {
499                 :
500             }
501             ;;
502     esac
503
504     Function_Local_comp_option
505 }
506
507
508 Function_Global_Ask_username () {
509     msg_n "ユーザー名を入力してください : " "Please enter your username : "
510     read -r Var_Global_Build_username
511     if [[ -z "${Var_Global_Build_username}" ]]; then
512         Function_Global_Ask_username
513         return 0
514     fi
515     return 0
516 }
517
518
519 Function_Global_Ask_password () {
520     local Var_Local_password Var_Local_password_confirm
521
522     msg_n "パスワードを入力してください : " "Please enter your password : "
523     read -r -s Var_Local_password
524     echo
525     msg_n "もう一度入力して下さい : " "Type it again : "
526     read -r -s Var_Local_password_confirm
527     if [[ ! "${Var_Local_password}" = "${Var_Local_password_confirm}" ]]; then
528         echo
529         msg_error "同じパスワードが入力されませんでした。" "You did not enter the same password."
530         Function_Global_Ask_password
531     elif [[ -z "${Var_Local_password}" || -z "${Var_Local_password_confirm}" ]]; then
532         echo
533         msg_error "パスワードを入力してください。" "Please enter your password."
534         Function_Global_Ask_password
535     fi
536     Var_Global_Build_password="${Var_Local_password}"
537     echo
538     return 0
539 }
540
541
542 Function_Global_Ask_kernel () {
543     msg \
544         "使用するカーネルを以下の番号から選択してください" \
545         "Please select the kernel to use from the following numbers"
546
547     #カーネルの一覧を取得
548     local Var_Local_kernel_list
549     #Var_Local_kernel_list=($("${Var_Global_Wizard_Env_script_path}/tools/kernel.sh" -a "${Var_Global_Wizard_Option_build_arch}" show))
550     readarray -t Var_Local_kernel_list < <("${Var_Global_Wizard_Env_script_path}/tools/kernel.sh" -a "${Var_Global_Wizard_Option_build_arch}" show)
551
552     #選択肢の生成
553     local Var_Local_kernel Var_Local_count=1 Var_Local_int
554     for Var_Local_kernel in "${Var_Local_kernel_list[@]}"; do
555         (
556             local kernel kernel_filename kernel_mkinitcpio_profile
557             eval "$("${Var_Global_Wizard_Env_script_path}/tools/kernel.sh" -a "${Var_Global_Wizard_Option_build_arch}" get "${Var_Local_kernel}" )"
558             echo -n "$(printf %02d "${Var_Local_count}")    ${kernel}"
559             for Var_Local_int in $( seq 1 $(( 19 - ${#kernel} )) ); do echo -ne " "; done
560             echo -ne "(${kernel_filename})\n"
561         )
562         Var_Local_count=$(( Var_Local_count + 1 ))
563     done
564
565     # 質問する
566     echo -n ": "
567     local Var_Local_input_kernel
568     read -r Var_Local_input_kernel
569
570     # 回答を解析する
571     # 数字かどうか判定する
572     set +e
573     expr "${Var_Local_input_kernel}" + 1 >/dev/null 2>&1
574     if [[ ${?} -lt 2 ]]; then
575         set -e
576         # 数字である
577         Var_Local_input_kernel=$(( Var_Local_input_kernel - 1 ))
578         if [[ -z "${Var_Local_kernel_list[${Var_Local_input_kernel}]}" ]]; then
579             Function_Global_Ask_kernel
580             return 0
581         else
582             Var_Global_Build_kernel="${Var_Local_kernel_list[${Var_Local_input_kernel}]}"
583             
584         fi
585     else
586         set -e
587         # 数字ではない
588         # 配列に含まれるかどうか判定
589         if [[ ! $(printf '%s\n' "${Var_Local_kernel_list[@]}" | grep -qx "${Var_Local_input_kernel}"; echo -n ${?} ) -eq 0 ]]; then
590             Function_Global_Ask_kernel
591             return 0
592         else
593             Var_Global_Build_kernel="${Var_Local_input_kernel}"
594         fi
595     fi
596 }
597
598
599 # チャンネルの指定
600 Function_Global_Ask_channel () {
601     # チャンネルの一覧を取得
602     local Var_Local_int Var_Local_count=1 Var_Local_channel Var_Local_channel_list Var_Local_description Var_Local_channel_dir Var_Local_index
603     #Var_Local_channel_list=($("${Var_Global_Wizard_Env_script_path}/tools/channel.sh" --nobuiltin show))
604     #Var_Local_channel_dir=($("${Var_Global_Wizard_Env_script_path}/tools/channel.sh" --dirname --nobuiltin show))
605
606     readarray -t Var_Local_channel_list < <("${Var_Global_Wizard_Env_script_path}/tools/channel.sh" --nobuiltin show)
607     readarray -t Var_Local_channel_dir  < <("${Var_Global_Wizard_Env_script_path}/tools/channel.sh" --dirname --nobuiltin show)
608
609     msg "チャンネルを以下の番号から選択してください。" "Select a channel from the numbers below."
610     # 選択肢を生成
611     for Var_Local_channel in "${Var_Local_channel_list[@]}"; do
612         if [[ -f "${Var_Global_Wizard_Env_script_path}/channels/${Var_Local_channel_dir[$(( Var_Local_count - 1 ))]}/description.txt" ]]; then
613             Var_Local_description=$(cat "${Var_Global_Wizard_Env_script_path}/channels/${Var_Local_channel_dir[$(( Var_Local_count - 1 ))]}/description.txt")
614         else
615             if [[ "${Var_Global_Wizard_Option_language}"  = "jp" ]]; then
616                 Var_Local_description="このチャンネルにはdescription.txtがありません。"
617             else
618                 Var_Local_description="This channel does not have a description.txt."
619             fi
620         fi
621         echo -ne "$(printf %02d "${Var_Local_count}")    ${Var_Local_channel}"
622         for Var_Local_int in $( seq 1 $(( 19 - ${#Var_Local_channel} )) ); do echo -ne " "; done
623         echo -ne "${Var_Local_description}\n"
624         Var_Local_count="$(( Var_Local_count + 1 ))"
625     done
626     echo -n ":"
627     read -r Var_Global_Build_channel
628
629     # 入力された値が数字かどうか判定する
630     set +e
631     expr "${Var_Global_Build_channel}" + 1 >/dev/null 2>&1
632     if (( ${?} == 0 )); then
633         set -e
634         # 数字である
635         Var_Global_Build_channel=$(( Var_Global_Build_channel - 1))
636         if [[ -z "${Var_Local_channel_list[${Var_Global_Build_channel}]}" ]]; then
637             Function_Global_Ask_channel
638             return 0
639         else
640             Var_Global_Build_channel="${Var_Local_channel_list[${Var_Global_Build_channel}]}"
641         fi
642     else
643         set -e
644         # 数字ではない
645         if [[ ! $(printf '%s\n' "${Var_Local_channel_list[@]}" | grep -qx "${Var_Global_Build_channel}"; echo -n ${?} ) -eq 0 ]]; then
646             Function_Global_Ask_channel
647             return 0
648         fi
649     fi
650
651     echo "${Var_Global_Build_channel}"
652
653     return 0
654 }
655
656
657 # イメージファイルの所有者
658 Function_Global_Ask_owner () {
659     local Function_Local_check_user
660     Function_Local_check_user () {
661         [[ -z "${1+SET}" ]] && return 2
662         getent passwd "${1}" > /dev/null && return 0 || return 1
663     }
664
665     msg_n "イメージファイルの所有者を入力してください。: " "Enter the owner of the image file.: "
666     read -r Var_Global_iso_owner
667     if Function_Local_check_user "${Var_Global_iso_owner}"; then
668         echo "ユーザーが存在しません。"
669         Function_Global_Ask_owner
670         return 0
671     elif  [[ -z "${Var_Global_iso_owner}" ]]; then
672         echo "ユーザー名を入力して下さい。"
673         Function_Global_Ask_owner
674         return 0
675     elif [[ "${Var_Global_iso_owner}" = "root" ]]; then
676         echo "所有者の変更を行いません。"
677         return 0
678     fi
679 }
680
681
682 # イメージファイルの作成先
683 Function_Global_Ask_out_dir () {
684     msg "イメージファイルの作成先を入力して下さい。" "Enter the destination to create the image file."
685     msg "デフォルトは ${Var_Global_Wizard_Env_script_path}/out です。" "The default is ${Var_Global_Wizard_Env_script_path}/out."
686     echo -n ": "
687     read -r out_dir
688     if [[ -z "${out_dir}" ]]; then
689         out_dir="${Var_Global_Wizard_Env_script_path}/out"
690     else
691         if [[ ! -d "${out_dir}" ]]; then
692             msg_error \
693                 "存在しているディレクトリを指定して下さい。" \
694                 "Please specify the existing directory."
695             Function_Global_Ask_out_dir
696             return 0
697         elif [[ "${out_dir}" = "/" ]] || [[ "${out_dir}" = "/home" ]]; then
698             msg_error \
699                 "そのディレクトリは使用できません。" \
700                 "The directory is unavailable."
701             Function_Global_Ask_out_dir
702             return 0
703         fi
704     fi
705 }
706
707 Function_Global_Ask_tarball () {
708     local Var_Local_input_yes_or_no
709     msg_n "tarballをビルドしますか?[no](y/N) : " "Build a tarball? [no] (y/N) : "
710     read -r Var_Local_input_yes_or_no
711     case "${Var_Local_input_yes_or_no}" in
712         "y" | "Y" | "yes" | "Yes" | "YES" ) Var_Global_Build_tarball=true   ;;
713         "n" | "N" | "no"  | "No"  | "NO"  ) Var_Global_Build_tarball=false  ;;
714         *                                 ) Function_Global_Ask_tarball ;;
715     esac
716 }
717
718
719 # 最終的なbuild.shのオプションを生成
720 Function_Global_Main_create_argument () {
721     Var_Global_Build_argument=("--noconfirm" "-a" "${Var_Global_Wizard_Option_build_arch}")
722
723     #[[ "${Var_Global_Build_japanese}" = true ]] && Var_Global_Build_argument+=("-l ja")
724     [[ -n "${Var_Global_Build_locale}"       ]] && Var_Global_Build_argument+=("-l" "${Var_Global_Build_locale}")
725     [[ "${Var_Global_Build_plymouth}" = true ]] && Var_Global_Build_argument+=("-b")
726     [[ -n "${Var_Global_Build_comp_type}"    ]] && Var_Global_Build_argument+=("-c ${Var_Global_Build_comp_type}")
727     [[ -n "${comp_option}"                   ]] && Var_Global_Build_argument+=("-t" "${comp_option}")
728     [[ -n "${Var_Global_Build_kernel}"       ]] && Var_Global_Build_argument+=("-k" "${Var_Global_Build_kernel}")
729     [[ -n "${Var_Global_Build_username}"     ]] && Var_Global_Build_argument+=("-u" "${Var_Global_Build_username}")
730     [[ -n "${Var_Global_Build_password}"     ]] && Var_Global_Build_argument+=("-p" "${Var_Global_Build_password}")
731     [[ -n "${out_dir}"                       ]] && Var_Global_Build_argument+=("-o" "${out_dir}")
732     [[ "${Var_Global_Build_tarball}" = true  ]] && Var_Global_Build_argument+=("--tarball")
733     #argument="--noconfirm -a ${Var_Global_Wizard_Option_build_arch} ${argument} ${Var_Global_Build_channel}"
734     Var_Global_Build_argument+=("${Var_Global_Build_channel}")
735 }
736
737
738 # ビルド設定の確認
739 Function_Global_Ask_Confirm () {
740     msg "以下の設定でビルドを開始します。" "Start the build with the following settings."
741     echo
742     #[[ -n "${Var_Global_Build_japanese}"           ]] && echo "           Japanese : ${Var_Global_Build_japanese}"
743     [[ -n "${Var_Global_Build_locale}"             ]] && echo "           Language : ${Var_Global_Build_locale}"
744     [[ -n "${Var_Global_Wizard_Option_build_arch}" ]] && echo "       Architecture : ${Var_Global_Wizard_Option_build_arch}"
745     [[ -n "${Var_Global_Build_plymouth}"           ]] && echo "           Plymouth : ${Var_Global_Build_plymouth}"
746     [[ -n "${Var_Global_Build_kernel}"             ]] && echo "             kernel : ${Var_Global_Build_kernel}"
747     [[ -n "${Var_Global_Build_comp_type}"          ]] && echo " Compression method : ${Var_Global_Build_comp_type}"
748     [[ -n "${comp_option}"                         ]] && echo "Compression options : ${comp_option}"
749     [[ -n "${Var_Global_Build_username}"           ]] && echo "           Username : ${Var_Global_Build_username}"
750     [[ -n "${Var_Global_Build_password}"           ]] && echo "           Password : ${Var_Global_Build_password}"
751     [[ -n "${Var_Global_Build_channel}"            ]] && echo "            Channel : ${Var_Global_Build_channel}"
752     echo
753     msg_n \
754         "この設定で続行します。よろしいですか? (y/N) : " \
755         "Continue with this setting. Is it OK? (y/N) : "
756     local Var_Local_input_yes_or_no
757     read -r Var_Local_input_yes_or_no
758     case "${Var_Local_input_yes_or_no}" in
759         "y" | "Y" | "yes" | "Yes" | "YES" ) :         ;;
760         "n" | "N" | "no"  | "No"  | "NO"  ) exit 0    ;;
761         *                                 ) Function_Global_Ask_Confirm ;;
762     esac
763 }
764
765 Function_Global_Main_run_build.sh () {
766     if [[ "${Var_Global_Wizard_Option_nobuild}" = true ]]; then
767         echo "${argument}"
768     else
769         # build.shの引数を表示(デバッグ用)
770         # echo ${argument}
771
772         work_dir="${Var_Global_Wizard_Env_script_path}/work"
773         sudo bash "${Var_Global_Wizard_Env_script_path}/build.sh" "${Var_Global_Build_argument[@]}"
774         
775     fi
776 }
777
778
779 Function_Global_Main_run_clean.sh() {
780     sudo "${Var_Global_Wizard_Env_script_path}/tools/clean.sh -w ${work_dir}"
781 }
782
783
784 Function_Global_Main_set_iso_permission() {
785     if [[ -n "${Var_Global_iso_owner}" ]]; then
786         chown -R "${Var_Global_iso_owner}" "${out_dir}"
787         chmod -R 750 "${out_dir}"
788     fi
789 }
790
791 # 上の質問の関数を実行
792 Function_Global_Main_ask_questions () {
793     Function_Global_Ask_build_arch
794     Function_Global_Ask_plymouth
795     Function_Global_Ask_kernel
796     Function_Global_Ask_comp_type
797     Function_Global_Ask_comp_option
798     Function_Global_Ask_username
799     Function_Global_Ask_password
800     # Function_Global_Ask_japanese この関数はAlterISO2以前を想定されたものです。
801     Function_Global_Ask_locale
802     Function_Global_Ask_channel
803     Function_Global_Ask_tarball
804
805     # これらのディレクトリやファイルの所有権変更は現在無効化されています
806     # Function_Global_Ask_owner
807     # Function_Global_Ask_out_dir
808
809     Function_Global_Ask_Confirm
810 }
811
812 Function_Global_Prebuild() {
813     Function_Global_Main_wizard_language
814     Function_Global_Main_check_required_files
815     #Function_Global_Main_check_yay
816     Function_Global_Main_load_default_config
817     Function_Global_Main_install_dependent_packages
818     Function_Global_Main_guide_to_the_web
819     Function_Global_Main_run_keyring.sh
820     Function_Global_Main_ask_questions
821     Function_Global_Main_create_argument
822 }
823
824 Function_Global_Build() {
825     Function_Global_Main_run_build.sh
826 }
827
828 Function_Global_PostBuild() {
829     Function_Global_Main_remove_dependent_packages
830     Function_Global_Main_run_clean.sh
831     Function_Global_Main_set_iso_permission
832 }
833
834 Function_Global_Run() {
835     Function_Global_Prebuild
836     Function_Global_Build
837     Function_Global_PostBuild
838 }
839
840 Function_Global_Run