OSDN Git Service

[update] : Added --depend
[alterlinux/alterlinux.git] / build.sh
index 510fa26..07f42e1 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -11,7 +11,7 @@
 # The main script that runs the build
 #
 
-set -eu
+set -Eeu
 
 # Internal config
 # Do not change these values.
@@ -27,12 +27,16 @@ pkglist_args=()
 makepkg_script_args=()
 modules=()
 DEFAULT_ARGUMENT=""
+ARGUMENT=("${@}")
 alteriso_version="3.1"
+norepopkg=()
+legacy_mode=false
+rerun=false
 
 # Load config file
 [[ ! -f "${defaultconfig}" ]] && "${tools_dir}/msg.sh" -a 'build.sh' error "${defaultconfig} was not found." && exit 1
 for config in "${defaultconfig}" "${script_path}/custom.conf"; do
-    [[ -f "${config}" ]] && source "${config}"
+    [[ -f "${config}" ]] && source "${config}" && loaded_files+=("${config}")
 done
 
 umask 0022
@@ -40,8 +44,7 @@ umask 0022
 # Message common function
 # msg_common [type] [-n] [string]
 msg_common(){
-    local _msg_opts=("-a" "build.sh") _type="${1}"
-    shift 1
+    local _msg_opts=("-a" "build.sh") _type="${1}" && shift 1
     [[ "${1}" = "-n" ]] && _msg_opts+=("-o" "-n") && shift 1
     [[ "${msgdebug}" = true ]] && _msg_opts+=("-x")
     [[ "${nocolor}"  = true ]] && _msg_opts+=("-n")
@@ -60,8 +63,7 @@ msg_warn() { msg_common warn "${@}"; }
 # Show an debug message
 # ${1}: message string
 msg_debug() { 
-    [[ "${debug}" = true ]] && msg_common debug "${@}"
-    return 0
+    [[ "${debug}" = true ]] && msg_common debug "${@}" || return 0
 }
 
 # Show an ERROR message then exit with status
@@ -69,7 +71,7 @@ msg_debug() {
 # ${2}: exit code number (with 0 does not exit)
 msg_error() {
     msg_common error "${1}"
-    [[ -n "${2:-}" ]] && exit "${2}"
+    [[ -n "${2:-""}" ]] && exit "${2}" || return 0
 }
 
 
@@ -89,46 +91,39 @@ _usage () {
     echo " General options:"
     echo "    -b | --boot-splash           Enable boot splash"
     echo "    -e | --cleanup | --cleaning  Enable post-build cleaning"
-    echo "         --tarball               Build rootfs in tar.xz format"
+    echo "    -r |  --tarball               Build rootfs in tar.xz format"
     echo "    -h | --help                  This help message and exit"
     echo
     echo "    -a | --arch <arch>           Set iso architecture"
-    echo "                                  Default: ${arch}"
     echo "    -c | --comp-type <comp_type> Set SquashFS compression type (gzip, lzma, lzo, xz, zstd)"
-    echo "                                  Default: ${sfs_comp}"
     echo "    -g | --gpgkey <key>          Set gpg key"
-    echo "                                  Default: ${gpg_key}"
     echo "    -l | --lang <lang>           Specifies the default language for the live environment"
-    echo "                                  Default: ${locale_name}"
-    echo "    -k | --kernel <kernel>       Set special kernel type.See below for available kernels"
-    echo "                                  Default: ${defaultkernel}"
+    echo "    -k | --kernel <kernel>       Set special kernel type. See below for available kernels"
     echo "    -o | --out <out_dir>         Set the output directory"
-    echo "                                  Default: ${out_dir}"
     echo "    -p | --password <password>   Set a live user password"
-    echo "                                  Default: ${password}"
     echo "    -t | --comp-opts <options>   Set compressor-specific options."
-    echo "                                  Default: empty"
     echo "    -u | --user <username>       Set user name"
-    echo "                                  Default: ${username}"
     echo "    -w | --work <work_dir>       Set the working directory"
-    echo "                                  Default: ${work_dir}"
     echo
 
-    local blank="33" _arch _dirname _type
-
+    local blank="29" _arch _dirname _type _output _first
     for _type in "locale" "kernel"; do
         echo " ${_type} for each architecture:"
         for _arch in $(find "${script_path}/system/" -maxdepth 1 -mindepth 1 -name "${_type}-*" -print0 | xargs -I{} -0 basename {} | sed "s|${_type}-||g"); do
-            echo -n "    ${_arch}$(echo_blank "$(( "${blank}" - 4 - "${#_arch}" ))")"
-            "${tools_dir}/${_type}.sh" -a "${_arch}" show
+            echo "    ${_arch}$(echo_blank "$(( "${blank}" - "${#_arch}" ))")$("${tools_dir}/${_type}.sh" -a "${_arch}" show)"
         done
         echo
     done
 
     echo " Channel:"
-    for _dirname in $(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -d -b -n show); do
-        echo -ne "    ${_dirname%.add}$(echo_blank "$(( "${blank}" - 3 - "$(echo "${_dirname%.add}" | wc -m)" ))")"
-        "${tools_dir}/channel.sh" --version "${alteriso_version}" --nocheck desc "${_dirname%.add}"
+    for _dirname in $(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -d -b -n --line show | sed "s|.add$||g"); do
+        readarray -t _output < <("${tools_dir}/channel.sh" --version "${alteriso_version}" --nocheck desc "${_dirname}")
+        _first=true
+        echo -n "    ${_dirname}"
+        for _out in "${_output[@]}"; do
+            "${_first}" && echo -e "    $(echo_blank "$(( "${blank}" - 4 - "${#_dirname}" ))")${_out}" || echo -e "    $(echo_blank "$(( "${blank}" + 5 - "${#_dirname}" ))")${_out}"
+            _first=false
+        done
     done
 
     echo
@@ -136,7 +131,8 @@ _usage () {
     echo "    -d | --debug                 Enable debug messages"
     echo "    -x | --bash-debug            Enable bash debug mode(set -xv)"
     echo "         --channellist           Output the channel list and exit"
-    echo "         --gitversion            Add Git commit hash to image file version"
+    echo "         --config                Load additional config file"
+    echo "         --[no]gitversion        Add Git commit hash to image file version"
     echo "         --logpath <file>        Set log file path (use with --log)"
     echo "         --[no]log               (No) log ;re-run script with tee"
     echo "         --msgdebug              Enables output debugging"
@@ -144,14 +140,18 @@ _usage () {
     echo "         --nocolor               No output colored output"
     echo "         --[no]confirm           (No) check the settings before building"
     echo "         --nochkver              No check the version of the channel"
-    echo "         --nodebug               No debug message"
+    echo "         --nodebug               Disable all debug messages"
     echo "         --noefi                 No efi boot (Use only for debugging)"
     echo "         --noloopmod             No check and load kernel module automatically"
-    echo "         --nodepend              No check package dependencies before building"
+    echo "         --[no]depend            (No) check package dependencies before building"
     echo "         --noiso                 No build iso image (Use with --tarball)"
+    echo "         --nosigcheck            No pacman signature check"
     echo "         --pacman-debug          Enable pacman debug mode"
     echo "         --normwork              No remove working dir"
     echo "         --nopkgbuild            Ignore PKGBUILD (Use only for debugging)"
+    echo "         --tar-type <comp_type>  Set compression type (gzip, lzma, lzo, xz, zstd)"
+    echo "         --tar-opts <option>     Set tar command argument (Use with --tarball)"
+    echo "         --add-module <module>   Load additional modules (Separated by \",\")"
     echo
     echo " Many packages are installed from AUR, so specifying --noaur can cause problems."
     echo
@@ -159,7 +159,7 @@ _usage () {
 }
 
 # Unmount helper Usage: _umount <target>
-_umount() { if mountpoint -q "${1}"; then umount -lf "${1}"; fi; }
+_umount() { mountpoint -q "${1}" && umount -lf "${1}"; return 0; }
 
 # Mount helper Usage: _mount <source> <target>
 _mount() { ! mountpoint -q "${2}" && [[ -f "${1}" ]] && [[ -d "${2}" ]] && mount "${1}" "${2}"; return 0; }
@@ -168,6 +168,7 @@ _mount() { ! mountpoint -q "${2}" && [[ -f "${1}" ]] && [[ -d "${2}" ]] && mount
 umount_work () {
     local _args=("${build_dir}")
     [[ "${debug}" = true ]] && _args=("-d" "${_args[@]}")
+    [[ "${nocolor}" = true ]] && _args+=("--nocolor")
     "${tools_dir}/umount.sh" "${_args[@]}"
 }
 
@@ -180,13 +181,13 @@ mount_airootfs () {
 
 # Helper function to run make_*() only one time.
 run_once() {
-    set -eu
     if [[ ! -e "${lockfile_dir}/build.${1}" ]]; then
+        umount_work
         msg_debug "Running ${1} ..."
         mount_airootfs
         eval "${@}"
         mkdir -p "${lockfile_dir}"; touch "${lockfile_dir}/build.${1}"
-        umount_work
+        
     else
         msg_debug "Skipped because ${1} has already been executed."
     fi
@@ -224,10 +225,7 @@ show_channel_list() {
 
 # Execute command for each module. It will be executed with {} replaced with the module name.
 # for_module <command>
-for_module(){
-    local module
-    for module in "${modules[@]}"; do eval "$(echo "${@}" | sed "s|{}|${module}|g")"; done
-}
+for_module(){ local module && for module in "${modules[@]}"; do eval "${@//"{}"/${module}}"; done; }
 
 # pacstrapを実行
 _pacstrap(){
@@ -249,7 +247,7 @@ _run_with_pacmanconf(){
 # コマンドをchrootで実行する
 _chroot_run() {
     msg_debug "Run command in chroot\nCommand: ${*}"
-    eval -- arch-chroot "${airootfs_dir}" "${@}"
+    arch-chroot "${airootfs_dir}" "${@}" || return "${?}"
 }
 
 _cleanup_common () {
@@ -300,8 +298,8 @@ check_bool() {
     local _value _variable
     for _variable in "${@}"; do
         msg_debug -n "Checking ${_variable}..."
-        eval ': ${'${_variable}':=""}'
-        _value="$(eval echo '$'${_variable})"
+        eval ": \${${_variable}:=''}"
+        _value="$(eval echo "\$${_variable}")"
         if [[ ! -v "${1}" ]] || [[ "${_value}"  = "" ]]; then
             [[ "${debug}" = true ]] && echo ; msg_error "The variable name ${_variable} is empty." "1"
         elif [[ ! "${_value}" = "true" ]] && [[ ! "${_value}" = "false" ]]; then
@@ -313,7 +311,7 @@ check_bool() {
 }
 
 _run_cleansh(){
-    bash $([[ "${bash_debug}" = true ]] && echo -n "-x" ) "${tools_dir}/clean.sh" -o -w "$(realpath "${build_dir}")" "$([[ "${debug}" = true ]] && printf "%s" "-d")" "$([[ "${noconfirm}" = true ]] && printf "%s" "-n")"
+    bash "$([[ "${bash_debug}" = true ]] && echo -n "-x" || echo -n "+x")" "${tools_dir}/clean.sh" -o -w "$(realpath "${build_dir}")" "$([[ "${debug}" = true ]] && printf "%s" "-d")" "$([[ "${noconfirm}" = true ]] && printf "%s" "-n")" "$([[ "${nocolor}" = true ]] && printf "%s" "--nocolor")"
 }
 
 
@@ -323,9 +321,7 @@ prepare_env() {
     if [[ "${nodepend}" = false ]]; then
         local _check_failed=false _pkg _result=0
         msg_info "Checking dependencies ..."
-        if ! pacman -Qq pyalpm > /dev/null 2>&1; then
-            msg_error "pyalpm is not installed." 1
-        fi   
+        ! pacman -Qq pyalpm > /dev/null 2>&1 && msg_error "pyalpm is not installed." 1
         for _pkg in "${dependence[@]}"; do
             eval "${tools_dir}/package.py" "${_pkg}" "$( [[ "${debug}" = false ]] && echo "> /dev/null")" || _result="${?}"
             if (( _result == 3 )) || (( _result == 4 )); then
@@ -339,7 +335,7 @@ prepare_env() {
     # Load loop kernel module
     if [[ "${noloopmod}" = false ]]; then
         [[ ! -d "/usr/lib/modules/$(uname -r)" ]] && msg_error "The currently running kernel module could not be found.\nProbably the system kernel has been updated.\nReboot your system to run the latest kernel." "1"
-        [[ -z "$(lsmod | getclm 1 | grep -x "loop")" ]] && modprobe loop
+        lsmod | getclm 1 | grep -qx "loop" || modprobe loop
     fi
 
     # Check work dir
@@ -362,11 +358,18 @@ prepare_env() {
         [[ "${normwork}" = false ]] && echo && _run_cleansh
         exit "${status}"
     }
-    trap '_trap_remove_work' 1 2 3 15
+    trap '_trap_remove_work' HUP INT QUIT TERM
 
     return 0
 }
 
+# Error message
+error_exit_trap(){
+    local _exit="${?}" _line="${1}" && shift 1
+    msg_error "An exception error occurred in the function"
+    msg_error "Exit Code: ${_exit}\nLine: ${_line}\nArgument: ${ARGUMENT[*]}"
+    exit "${_exit}"
+}
 
 # Show settings.
 show_settings() {
@@ -381,12 +384,14 @@ show_settings() {
     msg_info "The compression method of squashfs is ${sfs_comp}."
     msg_info "Use the ${channel_name%.add} channel."
     msg_info "Build with architecture ${arch}."
+    (( "${#additional_exclude_pkg[@]}" != 0 )) && msg_info "Excluded packages: ${additional_exclude_pkg[*]}"
     if [[ "${noconfirm}" = false ]]; then
         echo -e "\nPress Enter to continue or Ctrl + C to cancel."
-        read
+        read -r
     fi
-    trap 1 2 3 15
-    trap 'umount_trap' 1 2 3 15
+    trap HUP INT QUIT TERM
+    trap 'umount_trap' HUP INT QUIT TERM
+    trap 'error_exit_trap $LINENO' ERR
 
     return 0
 }
@@ -394,40 +399,41 @@ show_settings() {
 
 # Preparation for build
 prepare_build() {
+    # Debug mode
+    [[ "${bash_debug}" = true ]] && set -x -v
+
     # Show alteriso version
-    if [[ -d "${script_path}/.git" ]]; then
-        cd  "${script_path}"
-        msg_debug "The version of alteriso is $(git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g')."
-        cd "${OLDPWD}"
-    fi
+    [[ -n "${gitrev-""}" ]] && msg_debug "The version of alteriso is ${gitrev}"
 
     # Load configs
     load_config "${channel_dir}/config.any" "${channel_dir}/config.${arch}"
 
-    # Debug mode
-    if [[ "${bash_debug}" = true ]]; then
-        set -x -v
-    fi
+    # Additional modules
+    modules+=("${additional_modules[@]}")
 
     # Legacy mode
     if [[ "$(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" ver "${channel_name}")" = "3.0" ]]; then
         msg_warn "The module cannot be used because it works with Alter ISO3.0 compatibility."
-        if [[ ! -z "${include_extra+SET}" ]]; then
-            if [[ "${include_extra}" = true ]]; then
-                modules=("base" "share" "share-extra" "zsh-powerline")
-            else
-                modules=("base" "share")
-            fi
-        fi
+        modules=("legacy")
+        legacy_mode=true
+        [[ "${include_extra-"unset"}" = true ]] && modules=("legacy-extra")
     fi
 
-    local module_check
+    # Load presets
+    local _modules=() module_check
+    for_module '[[ -f "${preset_dir}/{}" ]] && readarray -t -O "${#_modules[@]}" _modules < <(grep -h -v ^'#' "${preset_dir}/{}") || _modules+=("{}")'
+    modules=("${_modules[@]}")
+    unset _modules
+
+    # Check modules
     module_check(){
         msg_debug "Checking ${1} module ..."
         bash "${tools_dir}/module.sh" check "${1}" || msg_error "Module ${1} is not available." "1";
     }
-    modules=($(printf "%s\n" "${modules[@]}" | awk '!a[$0]++'))
+    readarray -t modules < <(printf "%s\n" "${modules[@]}" | awk '!a[$0]++')
     for_module "module_check {}"
+
+    # Load modules
     for_module load_config "${module_dir}/{}/config.any" "${module_dir}/{}/config.${arch}"
     msg_debug "Loaded modules: ${modules[*]}"
     ! printf "%s\n" "${modules[@]}" | grep -x "share" >/dev/null 2>&1 && msg_warn "The share module is not loaded."
@@ -444,11 +450,21 @@ prepare_build() {
     [[ "${customized_password}" = false ]] && password="${defaultpassword}"
 
     # gitversion
+    [[ ! -d "${script_path}/.git" ]] && [[ "${gitversion}" = true ]] && msg_error "There is no git directory. You need to use git clone to use this feature." "1"
     [[ "${gitversion}" = true ]] && iso_version="${iso_version}-${gitrev}"
 
-    # Generate iso file name.
+    # Generate tar file name
+    tar_ext=""
+    case "${tar_comp}" in
+        "gzip" ) tar_ext="gz"                        ;;
+        "zstd" ) tar_ext="zst"                       ;;
+        "xz" | "lzo" | "lzma") tar_ext="${tar_comp}" ;;
+    esac
+
+    # Generate iso file name
     local _channel_name="${channel_name%.add}-${locale_version}" 
     iso_filename="${iso_name}-${_channel_name}-${iso_version}-${arch}.iso"
+    tar_filename="${iso_filename%.iso}.tar.${tar_ext}"
     [[ "${nochname}" = true ]] && iso_filename="${iso_name}-${iso_version}-${arch}.iso"
     msg_debug "Iso filename is ${iso_filename}"
 
@@ -457,27 +473,24 @@ prepare_build() {
 
     # Check architecture for each channel
     local _exit=0
-    bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -a ${arch} -n -b check "${channel_name}" || _exit="${?}"
-    if (( "${_exit}" != 0 )) && (( "${_exit}" != 1 )); then
-        msg_error "${channel_name} channel does not support current architecture (${arch})." "1"
-    fi
+    bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -a "${arch}" -n -b check "${channel_name}" || _exit="${?}"
+    ( (( "${_exit}" != 0 )) && (( "${_exit}" != 1 )) ) && msg_error "${channel_name} channel does not support current architecture (${arch})." "1"
 
     # Run with tee
     if [[ ! "${logging}" = false ]]; then
         [[ "${customized_logpath}" = false ]] && logging="${out_dir}/${iso_filename%.iso}.log"
         mkdir -p "$(dirname "${logging}")" && touch "${logging}"
-        msg_warn "Re-run sudo ${0} ${ARGUMENT[*]} --nodepend --nolog --nocolor 2>&1 | tee ${logging}"
-        sudo "${0}" "${ARGUMENT[@]}" --nolog --nocolor --nodepend 2>&1 | tee "${logging}"
+        msg_warn "Re-run sudo ${0} ${ARGUMENT[*]} --nodepend --nolog --nocolor --rerun 2>&1 | tee ${logging}"
+        sudo "${0}" "${ARGUMENT[@]}" --nolog --nocolor --nodepend --rerun 2>&1 | tee "${logging}"
         exit "${?}"
-    else
-        unset ARGUMENT
     fi
 
     # Set argument of pkglist.sh
-    pkglist_args=("-a" "${arch}" "-k" "${kernel}" "-c" "${channel_dir}" "-l" "${locale_name}")
+    pkglist_args=("-a" "${arch}" "-k" "${kernel}" "-c" "${channel_dir}" "-l" "${locale_name}" --line)
     [[ "${boot_splash}"              = true ]] && pkglist_args+=("-b")
     [[ "${debug}"                    = true ]] && pkglist_args+=("-d")
     [[ "${memtest86}"                = true ]] && pkglist_args+=("-m")
+    [[ "${nocolor}"                  = true ]] && pkglist_args+=("--nocolor")
     (( "${#additional_exclude_pkg[@]}" >= 1 )) && pkglist_args+=("-e" "${additional_exclude_pkg[*]}")
     pkglist_args+=("${modules[@]}")
 
@@ -535,20 +548,37 @@ make_basefs() {
 # Additional packages (airootfs)
 make_packages_repo() {
     msg_debug "pkglist.sh ${pkglist_args[*]}"
-    local _pkglist=($("${tools_dir}/pkglist.sh" "${pkglist_args[@]}"))
+    readarray -t _pkglist_install < <("${tools_dir}/pkglist.sh" "${pkglist_args[@]}")
+
+    # Package check
+    if [[ "${legacy_mode}" = true ]]; then
+        readarray -t _pkglist < <("${tools_dir}/pkglist.sh" "${pkglist_args[@]}")
+        readarray -t repopkgs < <(pacman-conf -c "${build_pacman_conf}" -l | xargs -I{} pacman -Sql --config "${build_pacman_conf}" --color=never {} && pacman -Sg)
+        local _pkg
+        for _pkg in "${_pkglist[@]}"; do
+            msg_info "Checking ${_pkg}..."
+            if printf "%s\n" "${repopkgs[@]}" | grep -qx "${_pkg}"; then
+                _pkglist_install+=("${_pkg}")
+            else
+                msg_info "${_pkg} was not found. Install it with yay from AUR"
+                norepopkg+=("${_pkg}")
+            fi
+        done
+    fi
 
     # Create a list of packages to be finally installed as packages.list directly under the working directory.
     echo -e "# The list of packages that is installed in live cd.\n#\n" > "${build_dir}/packages.list"
-    printf "%s\n" "${_pkglist[@]}" >> "${build_dir}/packages.list"
+    printf "%s\n" "${_pkglist_install[@]}" >> "${build_dir}/packages.list"
 
     # Install packages on airootfs
-    _pacstrap "${_pkglist[@]}"
+    _pacstrap "${_pkglist_install[@]}"
 
     return 0
 }
 
 make_packages_aur() {
-    local _pkglist_aur=($("${tools_dir}/pkglist.sh" --aur "${pkglist_args[@]}"))
+    readarray -t _pkglist_aur < <("${tools_dir}/pkglist.sh" --aur "${pkglist_args[@]}")
+    _pkglist_aur=("${_pkglist_aur[@]}" "${norepopkg[@]}")
 
     # Create a list of packages to be finally installed as packages.list directly under the working directory.
     echo -e "\n# AUR packages.\n#\n" >> "${build_dir}/packages.list"
@@ -556,6 +586,7 @@ make_packages_aur() {
 
     # prepare for yay
     cp -rf --preserve=mode "${script_path}/system/aur.sh" "${airootfs_dir}/root/aur.sh"
+    _pacstrap --asdeps --needed "go" # --asdepsをつけているのでaur.shで削除される --neededをつけているので明示的にインストールされている場合削除されない
 
     # Run aur script
     _run_with_pacmanconf _chroot_run "bash" "/root/aur.sh" "${makepkg_script_args[@]}" "${_pkglist_aur[@]}"
@@ -632,10 +663,10 @@ make_customize_airootfs() {
     # -k changed in AlterISO3 from passing kernel name to passing kernel configuration.
 
     # Generate options of customize_airootfs.sh.
-    _airootfs_script_options="-p '${password}' -k '${kernel} ${kernel_filename} ${kernel_mkinitcpio_profile}' -u '${username}' -o '${os_name}' -i '${install_dir}' -s '${usershell}' -a '${arch}' -g '${locale_gen_name}' -l '${locale_name}' -z '${locale_time}' -t ${theme_name}"
-    [[ "${boot_splash}" = true ]] && _airootfs_script_options="${_airootfs_script_options} -b"
-    [[ "${debug}" = true       ]] && _airootfs_script_options="${_airootfs_script_options} -d"
-    [[ "${bash_debug}" = true  ]] && _airootfs_script_options="${_airootfs_script_options} -x"
+    _airootfs_script_options=(-p "${password}" -k "${kernel} ${kernel_filename} ${kernel_mkinitcpio_profile}" -u "${username}" -o "${os_name}" -i "${install_dir}" -s "${usershell}" -a "${arch}" -g "${locale_gen_name}" -l "${locale_name}" -z "${locale_time}" -t "${theme_name}")
+    [[ "${boot_splash}" = true ]] && _airootfs_script_options+=("-b")
+    [[ "${debug}" = true       ]] && _airootfs_script_options+=("-d")
+    [[ "${bash_debug}" = true  ]] && _airootfs_script_options+=("-x")
 
     _main_script="root/customize_airootfs.sh"
 
@@ -649,7 +680,7 @@ make_customize_airootfs() {
     # Create script
     for _script in "${_script_list[@]}"; do
         if [[ -f "${_script}" ]]; then
-            echo -e "\n$(cat "${_script}")" >> "${airootfs_dir}/${_main_script}"
+            (echo -e "\n#--$(basename "${_script}")--#\n" && cat "${_script}")  >> "${airootfs_dir}/${_main_script}"
             remove "${_script}"
         else
             msg_debug "${_script} was not found."
@@ -657,8 +688,8 @@ make_customize_airootfs() {
     done
 
     chmod 755 "${airootfs_dir}/${_main_script}"
-    cp "${airootfs_dir}/${_main_script}" "${build_dir}/$(basename ${_main_script})"
-    _chroot_run "${_main_script} ${_airootfs_script_options}"
+    cp "${airootfs_dir}/${_main_script}" "${build_dir}/$(basename "${_main_script}")"
+    _chroot_run "${_main_script}" "${_airootfs_script_options[@]}"
     remove "${airootfs_dir}/${_main_script}"
 
     # /root permission https://github.com/archlinux/archiso/commit/d39e2ba41bf556674501062742190c29ee11cd59
@@ -677,20 +708,19 @@ make_setup_mkinitcpio() {
         cp "${script_path}/system/initcpio/install/${_hook}" "${airootfs_dir}/etc/initcpio/install"
     done
 
+    sed -i "s|%COWSPACE%|${cowspace}|g" "${airootfs_dir}/etc/initcpio/hooks/archiso"
     sed -i "s|/usr/lib/initcpio/|/etc/initcpio/|g" "${airootfs_dir}/etc/initcpio/install/archiso_shutdown"
     cp "${script_path}/system/initcpio/install/archiso_kms" "${airootfs_dir}/etc/initcpio/install"
-    cp "${script_path}/system/initcpio/archiso_shutdown" "${airootfs_dir}/etc/initcpio"
-    if [[ "${boot_splash}" = true ]]; then
-        cp "${script_path}/mkinitcpio/mkinitcpio-archiso-plymouth.conf" "${airootfs_dir}/etc/mkinitcpio-archiso.conf"
-    else
-        cp "${script_path}/mkinitcpio/mkinitcpio-archiso.conf" "${airootfs_dir}/etc/mkinitcpio-archiso.conf"
-    fi
+    cp "${script_path}/system/initcpio/script/archiso_shutdown" "${airootfs_dir}/etc/initcpio"
+    cp "${script_path}/mkinitcpio/mkinitcpio-archiso.conf" "${airootfs_dir}/etc/mkinitcpio-archiso.conf"
+    [[ "${boot_splash}" = true ]] && cp "${script_path}/mkinitcpio/mkinitcpio-archiso-plymouth.conf" "${airootfs_dir}/etc/mkinitcpio-archiso.conf"
+
     if [[ "${gpg_key}" ]]; then
       gpg --export "${gpg_key}" >"${build_dir}/gpgkey"
       exec 17<>"${build_dir}/gpgkey"
     fi
 
-    _chroot_run "mkinitcpio -c /etc/mkinitcpio-archiso.conf -k /boot/${kernel_filename} -g /boot/archiso.img"
+    _chroot_run mkinitcpio -c "/etc/mkinitcpio-archiso.conf" -k "/boot/${kernel_filename}" -g "/boot/archiso.img"
 
     [[ "${gpg_key}" ]] && exec 17<&-
     
@@ -739,9 +769,7 @@ make_syslinux() {
     # 一時ディレクトリに設定ファイルをコピー
     mkdir -p "${build_dir}/syslinux/"
     cp -a "${script_path}/syslinux/"* "${build_dir}/syslinux/"
-    if [[ -d "${channel_dir}/syslinux" ]] && [[ "${customized_syslinux}" = true ]]; then
-        cp -af "${channel_dir}/syslinux"* "${build_dir}/syslinux/"
-    fi
+    [[ -d "${channel_dir}/syslinux" ]] && [[ "${customized_syslinux}" = true ]] && cp -af "${channel_dir}/syslinux"* "${build_dir}/syslinux/"
 
     # copy all syslinux config to work dir
     for _cfg in "${build_dir}/syslinux/"*.cfg; do
@@ -753,13 +781,10 @@ make_syslinux() {
     done
 
     # Replace the SYSLINUX configuration file with or without boot splash.
-    local _use_config_name _no_use_config_name _pxe_or_sys
+    local _use_config_name="nosplash" _no_use_config_name="splash" _pxe_or_sys
     if [[ "${boot_splash}" = true ]]; then
         _use_config_name=splash
         _no_use_config_name=nosplash
-    else
-        _use_config_name=nosplash
-        _no_use_config_name=splash
     fi
     for _pxe_or_sys in "sys" "pxe"; do
         remove "${isofs_dir}/syslinux/archiso_${_pxe_or_sys}_${_no_use_config_name}.cfg"
@@ -767,17 +792,14 @@ make_syslinux() {
     done
 
     # Set syslinux wallpaper
-    if [[ -f "${channel_dir}/splash.png" ]]; then
-        cp "${channel_dir}/splash.png" "${isofs_dir}/syslinux"
-    else
-        cp "${script_path}/syslinux/splash.png" "${isofs_dir}/syslinux"
-    fi
+    cp "${script_path}/syslinux/splash.png" "${isofs_dir}/syslinux"
+    [[ -f "${channel_dir}/splash.png" ]] && cp -f "${channel_dir}/splash.png" "${isofs_dir}/syslinux"
 
     # remove config
     local _remove_config
     function _remove_config() {
         remove "${isofs_dir}/syslinux/${1}"
-        sed -i "s|$(cat "${isofs_dir}/syslinux/archiso_sys_load.cfg" | grep "${1}")||g" "${isofs_dir}/syslinux/archiso_sys_load.cfg" 
+        sed -i "s|$(grep "${1}" "${isofs_dir}/syslinux/archiso_sys_load.cfg")||g" "${isofs_dir}/syslinux/archiso_sys_load.cfg" 
     }
 
     [[ "${norescue_entry}" = true  ]] && _remove_config archiso_sys_rescue.cfg
@@ -812,25 +834,18 @@ make_isolinux() {
 
 # Prepare /EFI
 make_efi() {
-    install -d -m 0755 -- "${isofs_dir}/EFI/boot"
+    local _bootfile _use_config_name="nosplash" _efi_config_list=() _efi_config
+    [[ "${boot_splash}" = true ]] && _use_config_name="splash"
+    _bootfile="$(basename "$(ls "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-boot"*".efi" )")"
 
-    local _bootfile="$(basename "$(ls "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-boot"*".efi" )")"
+    install -d -m 0755 -- "${isofs_dir}/EFI/boot"
     install -m 0644 -- "${airootfs_dir}/usr/lib/systemd/boot/efi/${_bootfile}" "${isofs_dir}/EFI/boot/${_bootfile#systemd-}"
 
-    local _use_config_name="nosplash"
-    if [[ "${boot_splash}" = true ]]; then
-        _use_config_name="splash"
-    fi
-
     install -d -m 0755 -- "${isofs_dir}/loader/entries"
     sed "s|%ARCH%|${arch}|g;" "${script_path}/efiboot/${_use_config_name}/loader.conf" > "${isofs_dir}/loader/loader.conf"
 
-    local _efi_config_list=() _efi_config
-    _efi_config_list+=($(ls "${script_path}/efiboot/${_use_config_name}/archiso-usb"*".conf" | grep -v "rescue"))
-
-    if [[ "${norescue_entry}" = false ]]; then
-        _efi_config_list+=($(ls "${script_path}/efiboot/${_use_config_name}/archiso-usb"*".conf" | grep -v "rescue"))
-    fi
+    readarray -t _efi_config_list < <(find "${script_path}/efiboot/${_use_config_name}/" -mindepth 1 -maxdepth 1 -type f -name "archiso-usb*.conf" -printf "%f\n" | grep -v "rescue")
+    [[ "${norescue_entry}" = false ]] && readarray -t _efi_config_list < <(find "${script_path}/efiboot/${_use_config_name}/" -mindepth 1 -maxdepth 1 -type f  -name "archiso-usb*.conf" -printf "%f\n")
 
     for _efi_config in "${_efi_config_list[@]}"; do
         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
@@ -838,7 +853,7 @@ make_efi() {
             s|%KERNEL_FILENAME%|${kernel_filename}|g;
             s|%ARCH%|${arch}|g;
             s|%INSTALL_DIR%|${install_dir}|g" \
-        "${_efi_config}" > "${isofs_dir}/loader/entries/$(basename "${_efi_config}" | sed "s|usb|${arch}|g")"
+        "${script_path}/efiboot/${_use_config_name}/${_efi_config}" > "${isofs_dir}/loader/entries/$(basename "${_efi_config}" | sed "s|usb|${arch}|g")"
     done
 
     # edk2-shell based UEFI shell
@@ -867,35 +882,27 @@ make_efiboot() {
     mkdir -p "${build_dir}/efiboot"
     mount "${build_dir}/efiboot.img" "${build_dir}/efiboot"
 
-    mkdir -p "${build_dir}/efiboot/EFI/alteriso/${arch}"
+    mkdir -p "${build_dir}/efiboot/EFI/alteriso/${arch}" "${build_dir}/efiboot/EFI/boot" "${build_dir}/efiboot/loader/entries"
     cp "${isofs_dir}/${install_dir}/boot/${arch}/${kernel_filename}" "${build_dir}/efiboot/EFI/alteriso/${arch}/${kernel_filename}.efi"
     cp "${isofs_dir}/${install_dir}/boot/${arch}/archiso.img" "${build_dir}/efiboot/EFI/alteriso/${arch}/archiso.img"
 
-    local _ucode_image
+    local _ucode_image _efi_config _use_config_name="nosplash" _bootfile
     for _ucode_image in "${airootfs_dir}/boot/"{intel-uc.img,intel-ucode.img,amd-uc.img,amd-ucode.img,early_ucode.cpio,microcode.cpio}; do
         [[ -e "${_ucode_image}" ]] && cp "${_ucode_image}" "${build_dir}/efiboot/EFI/alteriso/"
     done
 
-    mkdir -p "${build_dir}/efiboot/EFI/boot"
-
     cp "${airootfs_dir}/usr/share/efitools/efi/HashTool.efi" "${build_dir}/efiboot/EFI/boot/"
 
-    local _bootfile="$(basename "$(ls "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-boot"*".efi" )")"
+    _bootfile="$(basename "$(ls "${airootfs_dir}/usr/lib/systemd/boot/efi/systemd-boot"*".efi" )")"
     cp "${airootfs_dir}/usr/lib/systemd/boot/efi/${_bootfile}" "${build_dir}/efiboot/EFI/boot/${_bootfile#systemd-}"
 
-    local _use_config_name="nosplash"
     [[ "${boot_splash}" = true ]] && _use_config_name="splash"
-
-    mkdir -p "${build_dir}/efiboot/loader/entries"
     sed "s|%ARCH%|${arch}|g;" "${script_path}/efiboot/${_use_config_name}/loader.conf" > "${build_dir}/efiboot/loader/loader.conf"
 
     find "${isofs_dir}/loader/entries/" -maxdepth 1 -mindepth 1 -name "uefi-shell*" -type f -printf "%p\0" | xargs -0 -I{} cp {} "${build_dir}/efiboot/loader/entries/"
 
-    local _efi_config _efi_config_list=($(ls "${script_path}/efiboot/${_use_config_name}/archiso-cd"*".conf"))
-
-    if [[ "${norescue_entry}" = false ]]; then
-        _efi_config_list=($(printf "%s\n" "${_efi_config_list[@]}" | grep -v "rescue"))
-    fi
+    readarray -t _efi_config_list < <(find "${script_path}/efiboot/${_use_config_name}/" -mindepth 1 -maxdepth 1 -type f -name "archiso-cd*.conf" -printf "%f\n" | grep -v "rescue")
+    [[ "${norescue_entry}" = false ]] && readarray -t _efi_config_list < <(find "${script_path}/efiboot/${_use_config_name}/" -mindepth 1 -maxdepth 1 -type f  -name "archiso-cd*.conf" -printf "%f\n")
 
     for _efi_config in "${_efi_config_list[@]}"; do
         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
@@ -903,7 +910,7 @@ make_efiboot() {
             s|%KERNEL_FILENAME%|${kernel_filename}|g;
             s|%ARCH%|${arch}|g;
             s|%INSTALL_DIR%|${install_dir}|g" \
-        "${_efi_config}" > "${build_dir}/efiboot/loader/entries/$(basename "${_efi_config}" | sed "s|cd|${arch}|g")"
+        "${script_path}/efiboot/${_use_config_name}/${_efi_config}" > "${build_dir}/efiboot/loader/entries/$(basename "${_efi_config}" | sed "s|cd|${arch}|g")"
     done
 
     find "${isofs_dir}/EFI" -maxdepth 1 -mindepth 1 -name "shell*.efi" -printf "%p\0" | xargs -0 -I{} cp {} "${build_dir}/efiboot/EFI/"
@@ -915,36 +922,34 @@ make_efiboot() {
 # Compress tarball
 make_tarball() {
     # backup airootfs.img for tarball
+    msg_debug "Tarball filename is ${tar_filename}"
     msg_info "Copying airootfs.img ..."
     cp "${airootfs_dir}.img" "${airootfs_dir}.img.org"
 
     # Run script
     mount_airootfs
-    if [[ -f "${airootfs_dir}/root/optimize_for_tarball.sh" ]]; then
-        _chroot_run "bash /root/optimize_for_tarball.sh -u ${username}"
-    fi
-
+    [[ -f "${airootfs_dir}/root/optimize_for_tarball.sh" ]] && _chroot_run "bash /root/optimize_for_tarball.sh -u ${username}"
     _cleanup_common
     _chroot_run "mkinitcpio -P"
-
     remove "${airootfs_dir}/root/optimize_for_tarball.sh"
 
+    # make
+    tar_comp_opt+=("--${tar_comp}")
     mkdir -p "${out_dir}"
     msg_info "Creating tarball..."
-    local tar_path="$(realpath ${out_dir})/${iso_filename%.iso}.tar.xz"
     cd -- "${airootfs_dir}"
-    tar -v -J -p -c -f "${tar_path}" ./*
+    msg_debug "Run tar -c -v -p -f \"${out_dir}/${tar_filename}\" ${tar_comp_opt[*]} ./*"
+    tar -c -v -p -f "${out_dir}/${tar_filename}" "${tar_comp_opt[@]}" ./*
     cd -- "${OLDPWD}"
 
-    _mkchecksum "${tar_path}"
-    msg_info "Done! | $(ls -sh ${tar_path})"
+    # checksum
+    _mkchecksum "${out_dir}/${tar_filename}"
+    msg_info "Done! | $(ls -sh "${out_dir}/${tar_filename}")"
 
     remove "${airootfs_dir}.img"
     mv "${airootfs_dir}.img.org" "${airootfs_dir}.img"
 
-    if [[ "${noiso}" = true ]]; then
-        msg_info "The password for the live user and root is ${password}."
-    fi
+    [[ "${noiso}" = true ]] && msg_info "The password for the live user and root is ${password}."
     
     return 0
 }
@@ -995,7 +1000,7 @@ make_alteriso_info(){
         local _info_file="${isofs_dir}/alteriso-info" _version="${iso_version}"
         remove "${_info_file}"; touch "${_info_file}"
         [[ -d "${script_path}/.git" ]] && [[ "${gitversion}" = false ]] && _version="${iso_version}-${gitrev}"
-        "${tools_dir}/alteriso-info.sh" -a "${arch}" -b "${boot_splash}" -c "${channel_name%.add}" -d "${iso_publisher}" -k "${kernel}" -o "${os_name}" -p "${password}" -u "${username}" -v "${_version}" > "${_info_file}"
+        "${tools_dir}/alteriso-info.sh" -a "${arch}" -b "${boot_splash}" -c "${channel_name%.add}" -d "${iso_publisher}" -k "${kernel}" -o "${os_name}" -p "${password}" -u "${username}" -v "${_version}" -m "$(printf "%s," "${modules[@]}")" > "${_info_file}"
     fi
 
     return 0
@@ -1005,9 +1010,9 @@ make_alteriso_info(){
 make_overisofs() {
     local _over_isofs_list _isofs
     _over_isofs_list=("${channel_dir}/over_isofs.any""${channel_dir}/over_isofs.${arch}")
-    for_module '_over_isofs_list+=("${module_dir}/{}/over_isofs.any""${module_dir}/{}/over_isofs.${arch}")'
+    for_module '_over_isofs_list+=("${module_dir}/{}/over_isofs.any" "${module_dir}/{}/over_isofs.${arch}")'
     for _isofs in "${_over_isofs_list[@]}"; do
-        [[ -d "${_isofs}" ]] && cp -af "${_isofs}"/* "${isofs_dir}"
+        [[ -d "${_isofs}" ]] && [[ -n "$(find "${_isofs}" -mindepth 1 -maxdepth 2)" ]] &&  cp -af "${_isofs}"/* "${isofs_dir}"
     done
 
     return 0
@@ -1017,9 +1022,7 @@ make_overisofs() {
 make_iso() {
     local _iso_efi_boot_args=()
     # If exists, add an EFI "El Torito" boot image (FAT filesystem) to ISO-9660 image.
-    if [[ -f "${build_dir}/efiboot.img" ]]; then
-        _iso_efi_boot_args=(-append_partition 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B "${build_dir}/efiboot.img" -appended_part_as_gpt -eltorito-alt-boot -e --interval:appended_partition_2:all:: -no-emul-boot -isohybrid-gpt-basdat)
-    fi
+    [[ -f "${build_dir}/efiboot.img" ]] && _iso_efi_boot_args=(-append_partition 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B "${build_dir}/efiboot.img" -appended_part_as_gpt -eltorito-alt-boot -e --interval:appended_partition_2:all:: -no-emul-boot -isohybrid-gpt-basdat)
 
     mkdir -p -- "${out_dir}"
     msg_info "Creating ISO image..."
@@ -1036,7 +1039,7 @@ make_iso() {
         -eltorito-boot syslinux/isolinux.bin \
         -eltorito-catalog syslinux/boot.cat \
         -no-emul-boot -boot-load-size 4 -boot-info-table \
-        -isohybrid-mbr ${build_dir}/iso/syslinux/isohdpfx.bin \
+        -isohybrid-mbr "${build_dir}/iso/syslinux/isohdpfx.bin" \
         "${_iso_efi_boot_args[@]}" \
         -output "${out_dir}/${iso_filename}" \
         "${build_dir}/iso/"
@@ -1050,27 +1053,17 @@ make_iso() {
 
 
 # Parse options
-ARGUMENT=("${@}" ${DEFAULT_ARGUMENT})
-OPTS=("a:" "b" "c:" "d" "e" "g:" "h" "j" "k:" "l:" "o:" "p:" "r" "t:" "u:" "w:" "x")
-OPTL=("arch:" "boot-splash" "comp-type:" "debug" "cleaning" "cleanup" "gpgkey:" "help" "lang:" "japanese" "kernel:" "out:" "password:" "comp-opts:" "user:" "work:" "bash-debug" "nocolor" "noconfirm" "nodepend" "gitversion" "msgdebug" "noloopmod" "tarball" "noiso" "noaur" "nochkver" "channellist" "config:" "noefi" "nodebug" "nosigcheck" "normwork" "log" "logpath:" "nolog" "nopkgbuild" "pacman-debug" "confirm")
-if ! OPT=$(getopt -o "$(printf "%s," "${OPTS[@]}")" -l "$(printf "%s," "${OPTL[@]}")" --  "${ARGUMENT[@]}"); then
-    exit 1
-fi
+ARGUMENT=("${DEFAULT_ARGUMENT[@]}" "${@}") OPTS=("a:" "b" "c:" "d" "e" "g:" "h" "j" "k:" "l:" "o:" "p:" "r" "t:" "u:" "w:" "x") OPTL=("arch:" "boot-splash" "comp-type:" "debug" "cleaning" "cleanup" "gpgkey:" "help" "lang:" "japanese" "kernel:" "out:" "password:" "comp-opts:" "user:" "work:" "bash-debug" "nocolor" "noconfirm" "nodepend" "gitversion" "msgdebug" "noloopmod" "tarball" "noiso" "noaur" "nochkver" "channellist" "config:" "noefi" "nodebug" "nosigcheck" "normwork" "log" "logpath:" "nolog" "nopkgbuild" "pacman-debug" "confirm" "tar-type:" "tar-opts:" "add-module:" "nogitversion" "cowspace:" "rerun" "depend")
+GETOPT=(-o "$(printf "%s," "${OPTS[@]}")" -l "$(printf "%s," "${OPTL[@]}")" -- "${ARGUMENT[@]}")
+getopt -Q "${GETOPT[@]}" || exit 1 # 引数エラー判定
+readarray -t OPT < <(getopt "${GETOPT[@]}") # 配列に代入
 
-eval set -- "${OPT}"
-msg_debug "Argument: ${OPT}"
-unset OPT OPTS OPTL DEFAULT_ARGUMENT
+eval set -- "${OPT[@]}"
+msg_debug "Argument: ${OPT[*]}"
+unset OPT OPTS OPTL DEFAULT_ARGUMENT GETOPT
 
 while true; do
     case "${1}" in
-        -a | --arch)
-            arch="${2}"
-            shift 2
-            ;;
-        -b | --boot-splash)
-            boot_splash=true
-            shift 1
-            ;;
         -c | --comp-type)
             case "${2}" in
                 "gzip" | "lzma" | "lzo" | "lz4" | "xz" | "zstd") sfs_comp="${2}" ;;
@@ -1078,22 +1071,6 @@ while true; do
             esac
             shift 2
             ;;
-        -d | --debug)
-            debug=true
-            shift 1
-            ;;
-        -e | --cleaning | --cleanup)
-            cleaning=true
-            shift 1
-            ;;
-        -g | --gpgkey)
-            gpg_key="${2}"
-            shift 2
-            ;;
-        -h | --help)
-            _usage
-            exit 0
-            ;;
         -j | --japanese)
             msg_error "This option is obsolete in AlterISO 3. To use Japanese, use \"-l ja\"." "1"
             ;;
@@ -1102,143 +1079,89 @@ while true; do
             kernel="${2}"
             shift 2
             ;;
-        -l | --lang)
-            locale_name="${2}"
-            shift 2
-            ;;
-        -o | --out)
-            out_dir="${2}"
-            shift 2
-            ;;
         -p | --password)
             customized_password=true
             password="${2}"
             shift 2
             ;;
-        -r | --tarball)
-            tarball=true
-            shift 1
-            ;;
         -t | --comp-opts)
             if [[ "${2}" = "reset" ]]; then
                 sfs_comp_opt=()
             else
-                sfs_comp_opt=(${2})
+                IFS=" " read -r -a sfs_comp_opt <<< "${2}"
             fi
             shift 2
             ;;
         -u | --user)
             customized_username=true
-            username="$(echo -n "${2}" | sed 's/ //g' |tr '[A-Z]' '[a-z]')"
-            shift 2
-            ;;
-        -w | --work)
-            work_dir="${2}"
+            username="$(echo -n "${2}" | sed 's/ //g' | tr '[:upper:]' '[:lower:]')"
             shift 2
             ;;
-        -x | --bash-debug)
-            debug=true
-            bash_debug=true
-            shift 1
-            ;;
-        --noconfirm)
-            noconfirm=true
-            shift 1
-            ;;
-        --confirm)
-            noconfirm=false
-            shift 1
-            ;;
-        --nodepend)
-            nodepend=true
-            shift 1
-            ;;
-        --nocolor)
-            nocolor=true
-            shift 1
-            ;;
-        --gitversion)
-            if [[ -d "${script_path}/.git" ]]; then
-                gitversion=true
-            else
-                msg_error "There is no git directory. You need to use git clone to use this feature." "1"
-            fi
-            shift 1
-            ;;
-        --msgdebug)
-            msgdebug=true;
-            shift 1
-            ;;
-        --noloopmod)
-            noloopmod=true
-            shift 1
-            ;;
-        --noiso)
-            noiso=true
-            shift 1
-            ;;
-        --noaur)
-            noaur=true
-            shift 1
-            ;;
-        --nochkver)
-            nochkver=true
-            shift 1
-            ;;
         --nodebug)
             debug=false
             msgdebug=false
             bash_debug=false
             shift 1
             ;;
-        --noefi)
-            noefi=true
-            shift 1
-            ;;
-        --channellist)
-            show_channel_list
-            exit 0
-            ;;
-        --config)
-            source "${2}"
-            shift 2
-            ;;
-        --pacman-debug)
-            pacman_debug=true
-            shift 1
-            ;;
-        --nosigcheck)
-            nosigcheck=true
-            shift 1
-            ;;
-        --normwork)
-            normwork=true
-            shift 1
-            ;;
-        --log)
-            logging=true
-            shift 1
-            ;;
         --logpath)
             logging="${2}"
             customized_logpath=true
             shift 2
             ;;
-        --nolog)
-            logging=false
-            shift 1
+        --tar-type)
+            case "${2}" in
+                "gzip" | "lzma" | "lzo" | "lz4" | "xz" | "zstd") tar_comp="${2}" ;;
+                *) msg_error "Invaild compressors '${2}'" '1' ;;
+            esac
+            shift 2
             ;;
-        --nopkgbuild)
-            nopkgbuild=true
-            shift 1
+        --tar-opts)
+            IFS=" " read -r -a tar_comp_opt <<< "${2}"
+            shift 2
             ;;
-        --)
-            shift
-            break
+        --add-module)
+            readarray -t -O "${#additional_modules[@]}" additional_modules < <(echo "${2}" | tr "," "\n")
+            msg_debug "Added modules: ${additional_modules[*]}"
+            shift 2
             ;;
+        -g | --gpgkey               ) gpg_key="${2}"     && shift 2 ;;
+        -h | --help                 ) _usage 0                      ;;
+        -a | --arch                 ) arch="${2}"        && shift 2 ;;
+        -d | --debug                ) debug=true         && shift 1 ;;
+        -e | --cleaning | --cleanup ) cleaning=true      && shift 1 ;;
+        -b | --boot-splash          ) boot_splash=true   && shift 1 ;;
+        -l | --lang                 ) locale_name="${2}" && shift 2 ;;
+        -o | --out                  ) out_dir="${2}"     && shift 2 ;;
+        -r | --tarball              ) tarball=true       && shift 1 ;;
+        -w | --work                 ) work_dir="${2}"    && shift 2 ;;
+        -x | --bash-debug           ) bash_debug=true    && shift 1 ;;
+        --gitversion                ) gitversion=true    && shift 1 ;;
+        --noconfirm                 ) noconfirm=true     && shift 1 ;;
+        --confirm                   ) noconfirm=false    && shift 1 ;;
+        --nodepend                  ) nodepend=true      && shift 1 ;;
+        --nocolor                   ) nocolor=true       && shift 1 ;;
+        --msgdebug                  ) msgdebug=true      && shift 1 ;;
+        --noloopmod                 ) noloopmod=true     && shift 1 ;;
+        --noiso                     ) noiso=true         && shift 1 ;;
+        --noaur                     ) noaur=true         && shift 1 ;;
+        --nochkver                  ) nochkver=true      && shift 1 ;;
+        --noefi                     ) noefi=true         && shift 1 ;;
+        --channellist               ) show_channel_list  && exit 0  ;;
+        --config                    ) source "${2}"      ;  shift 2 ;;
+        --pacman-debug              ) pacman_debug=true  && shift 1 ;;
+        --nosigcheck                ) nosigcheck=true    && shift 1 ;;
+        --normwork                  ) normwork=true      && shift 1 ;;
+        --log                       ) logging=true       && shift 1 ;;
+        --nolog                     ) logging=false      && shift 1 ;;
+        --nopkgbuild                ) nopkgbuild=true    && shift 1 ;;
+        --nogitversion              ) gitversion=false   && shift 1 ;;
+        --cowspace                  ) cowspace="${2}"    && shift 2 ;;
+        --rerun                     ) rerun=true         && shift 1 ;;
+        --depend                    ) nodepend=false      && shift 1 ;;
+        --                          ) shift 1            && break   ;;
         *)
-            msg_error "Invalid argument '${1}'"
-            _usage 1
+            msg_error "Argument exception error '${1}'"
+            msg_error "Please report this error to the developer." 1
             ;;
     esac
 done
@@ -1247,7 +1170,7 @@ done
 if (( ! "${EUID}" == 0 )); then
     msg_warn "This script must be run as root." >&2
     msg_warn "Re-run 'sudo ${0} ${ARGUMENT[*]}'"
-    sudo "${0}" "${ARGUMENT[@]}"
+    sudo "${0}" "${ARGUMENT[@]}" --rerun
     exit "${?}"
 fi
 
@@ -1260,7 +1183,7 @@ msg_debug "Use the default configuration file (${defaultconfig})."
 
 # Check for a valid channel name
 if [[ -n "${1+SET}" ]]; then
-    case "$(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -n check "${1}"; printf "${?}")" in
+    case "$(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" -n check "${1}"; printf "%d" "${?}")" in
         "2")
             msg_error "Invalid channel ${1}" "1"
             ;;
@@ -1278,17 +1201,13 @@ else
 fi
 
 # Set vars
-work_dir="$(realpath "${work_dir}")"
-build_dir="${work_dir}/build/${arch}"
-cache_dir="${work_dir}/cache/${arch}"
-airootfs_dir="${build_dir}/airootfs"
-isofs_dir="${build_dir}/iso"
-lockfile_dir="${build_dir}/lockfile"
-gitrev="$(cd "${script_path}"; git rev-parse --short HEAD)"
+build_dir="${work_dir}/build/${arch}" cache_dir="${work_dir}/cache/${arch}" airootfs_dir="${build_dir}/airootfs" isofs_dir="${build_dir}/iso" lockfile_dir="${build_dir}/lockfile" gitrev="$(cd "${script_path}"; git rev-parse --short HEAD)" preset_dir="${script_path}/presets"
 
 # Create dir
-for _dir in "${build_dir}" "${cache_dir}" "${airootfs_dir}" "${isofs_dir}" "${lockfile_dir}"; do
-    mkdir -p "${_dir}"
+for _dir in build_dir cache_dir airootfs_dir isofs_dir lockfile_dir out_dir; do
+    mkdir -p "$(eval "echo \$${_dir}")"
+    msg_debug "${_dir} is $(realpath "$(eval "echo \$${_dir}")")"
+    eval "${_dir}=\"$(realpath "$(eval "echo \$${_dir}")")\""
 done
 
 # Set for special channels
@@ -1311,8 +1230,6 @@ if [[ ! "$(bash "${tools_dir}/channel.sh" --version "${alteriso_version}" ver "$
     fi
 fi
 
-set -eu
-
 prepare_env
 prepare_build
 show_settings