OSDN Git Service

[fix] : Exit when reading the configuration file fails
[alterlinux/alterlinux.git] / tools / pkglist.sh
index fc7aa83..4991a72 100755 (executable)
@@ -3,16 +3,17 @@
 set -e
 
 script_path="$( cd -P "$( dirname "$(readlink -f "$0")" )" && cd .. && pwd )"
-share_dir="${script_path}/channels/share"
-extra_dir="${script_path}/channels/share-extra"
+module_dir="${script_path}/modules"
+modules=()
 
 boot_splash=false
-aur=false
 pkgdir_name="packages"
-extra=false
 line=false
 debug=false
 memtest86=false
+nocolor=false
+
+additional_exclude_pkg=()
 
 arch=""
 channel_dir=""
@@ -21,7 +22,7 @@ locale_name=""
 
 
 _help() {
-    echo "usage ${0} [options] [command]"
+    echo "usage ${0} [options] [module 1] [module 2]..."
     echo
     echo "Get a list of packages to install on that channel"
     echo
@@ -30,7 +31,7 @@ _help() {
     echo "    -b | --boot-splash        Enable boot splash"
     echo "    -c | --channel [dir]      Specify the channel directory"
     echo "    -d | --debug              Enable debug message"
-    echo "    -e | --extra              Include extra packages"
+    echo "    -e | --exclude [pkgs]     List of packages to be additionally excluded"
     echo "    -k | --kernel [kernel]    Specify the kernel"
     echo "    -l | --locale [locale]    Specify the locale"
     echo "    -m | --memtest86          Enable memtest86 package"
@@ -39,38 +40,43 @@ _help() {
     echo "         --line               Line break the output"
 }
 
-# Usage: getclm <number>
-# 標準入力から値を受けとり、引数で指定された列を抽出します。
-getclm() {
-    echo "$(cat -)" | cut -d " " -f "${1}"
-}
+# 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 "${@//"{}"/${module}}"; done; }
 
 # Message functions
+msg_common(){
+    local _args=(-s "5" -a "pkglist.sh")
+    [[ "${nocolor}" = true ]] && _args+=("--nocolor")
+    "${script_path}/tools/msg.sh" "${_args[@]}" "${@}"
+}
+
 msg_error() {
-    "${script_path}/tools/msg.sh" -s "5" -a "pkglist.sh" -l "Error" -r "red" error "${1}"
+    msg_common -l "Error" -r "red" -p "stderr" error "${1}" &
 }
 
 msg_info() {
-    "${script_path}/tools/msg.sh" -s "5" -a "pkglist.sh" -l "Info" -r "green" error "${1}"
+    msg_common -l "Info" -r "green" -p "stderr" info "${1}" &
 }
 
 msg_debug() {
     if [[ "${debug}" = true ]]; then
-        "${script_path}/tools/msg.sh" -s "5" -a "pkglist.sh" -l "Debug" -r "magenta" error "${1}"
+        msg_common -l "Debug" -r "magenta" -p "stderr" debug "${1}" &
     fi
 }
 
 
 # Parse options
-ARGUMENT="${@}"
-opt_short="a:bc:dek:l:mh"
-opt_long="arch:,boot-splash,channel:,debug,extra,kernel:,locale:,memtest86,aur,help,line"
-if ! OPT=$(getopt -o ${opt_short} -l ${opt_long} -- ${ARGUMENT}); then
+ARGUMENT=("${@}")
+OPTS="a:bc:de:k:l:mh"
+OPTL="arch:,boot-splash,channel:,debug,exclude:,kernel:,locale:,memtest86,aur,help,line,nocolor"
+if ! OPT=$(getopt -o ${OPTS} -l ${OPTL} -- "${ARGUMENT[@]}"); then
     exit 1
 fi
 
 eval set -- "${OPT}"
-unset OPT opt_short opt_long
+unset OPT OPTS OPTL ARGUMENT
 
 while true; do
     case "${1}" in
@@ -90,9 +96,9 @@ while true; do
             debug=true
             shift 1
             ;;
-        -e | --extra)
-            extra=true
-            shift 1
+        -e | --exclude)
+            IFS=" " read -r -a additional_exclude_pkg <<< "${2}"
+            shift 2
             ;;
         -k | --kernel)
             kernel="${2}"
@@ -107,7 +113,7 @@ while true; do
             shift 1
             ;;
         --aur)
-            aur=true
+            pkgdir_name="packages_aur"
             shift 1
             ;;
         --line)
@@ -118,6 +124,10 @@ while true; do
             _help
             exit 0
             ;;
+        --nocolor)
+            nocolor=true
+            shift 1
+            ;;
         --)
             shift 1
             break
@@ -126,100 +136,74 @@ while true; do
     esac
 done
 
+for module in "${@}"; do
+    if "${script_path}/tools/module.sh" check "${module}"; then
+        modules=("${@}")
+    else
+        msg_debug "Module ${module} was not found"
+    fi
+done
 
-if [[ -z "${arch}" ]]; then
+if [[ -z "${arch}" ]] || [[ "${arch}" = "" ]]; then
     msg_error "Architecture not specified"
     exit 1
-elif [[ -z "${channel_dir}" ]]; then
+elif [[ -z "${channel_dir}" ]] || [[ "${channel_dir}" = "" ]]; then
     msg_error "Channel directory not specified"
     exit 1
-elif [[ -z "${kernel}" ]]; then
+elif [[ -z "${kernel}" ]] || [[ "${kernel}" = "" ]]; then
     msg_error "kernel not specified"
     exit 1
-elif [[ -z "${locale_name}" ]]; then
+elif [[ -z "${locale_name}" ]] || [[ "${locale_name}" = "" ]]; then
     msg_error "Locale not specified"
     exit 1
 fi
 
-
-if [[ "${aur}" = true ]]; then
-    pkgdir_name="packages_aur"
-else
-    pkgdir_name="packages"
-fi
-
 set +e
 
+get_filelist(){
+    if [[ -d "${1}" ]]; then
+        find "${1}" -mindepth 1 -name "*.${arch}" -type f -or -type l 2> /dev/null
+    fi
+}
 
 #-- Detect package list to load --#
 # Add the files for each channel to the list of files to read.
-_loadfilelist=(
-    #-- share packages --#
-    $(ls ${share_dir}/${pkgdir_name}.${arch}/*.${arch} 2> /dev/null)
-
-    # lang
-    "${share_dir}/${pkgdir_name}.${arch}/lang/${locale_name}.${arch}"
-
-    # kernel
-    "${share_dir}/${pkgdir_name}.${arch}/kernel/${kernel}.${arch}"
+#readarray -t _loadfilelist < <(ls ${channel_dir}/${pkgdir_name}.${arch}/*.${arch} 2> /dev/null)
+readarray -t _loadfilelist < <(get_filelist "${channel_dir}/${pkgdir_name}.${arch}")
 
-    #-- channel packages --#
-    $(ls ${channel_dir}/${pkgdir_name}.${arch}/*.${arch} 2> /dev/null)
-
-    # lang
+_loadfilelist+=(
     "${channel_dir}/${pkgdir_name}.${arch}/lang/${locale_name}.${arch}"
-
-    # kernel
     "${channel_dir}/${pkgdir_name}.${arch}/kernel/${kernel}.${arch}"
 )
 
+# module package list
+for_module '_loadfilelist+=($(ls ${module_dir}/{}/${pkgdir_name}.${arch}/*.${arch} 2> /dev/null))'
+for_module '_loadfilelist+=(${module_dir}/{}/${pkgdir_name}.${arch}/lang/${locale_name}.${arch})'
+for_module '_loadfilelist+=(${module_dir}/{}/${pkgdir_name}.${arch}/kernel/${kernel}.${arch})'
+
 # Plymouth package list
 if [[ "${boot_splash}" = true ]]; then
-    _loadfilelist+=(
-        $(ls ${share_dir}/${pkgdir_name}.${arch}/plymouth/*.${arch} 2> /dev/null)
-        $(ls ${channel_dir}/${pkgdir_name}.${arch}/plymouth/*.${arch} 2> /dev/null)
-    )
-
-    if [[ "${extra}" = true ]]; then
-        _loadfilelist+=(
-            $(ls ${extra_dir}/${pkgdir_name}.${arch}/plymouth/*.${arch} 2> /dev/null)
-        )
-    fi
-fi
-
-# share-extra package list
-if [[ "${extra}" = true ]]; then
-    _loadfilelist+=(
-        $(ls ${extra_dir}/${pkgdir_name}.${arch}/*.${arch} 2> /dev/null)
-
-        # lang
-        "${extra_dir}/${pkgdir_name}.${arch}/lang/${locale_name}.${arch}"
-
-        # kernel
-        "${extra_dir}/${pkgdir_name}.${arch}/kernel/${kernel}.${arch}"
-    )
+    #readarray -t -O "${#_loadfilelist[@]}" _loadfilelist < <(ls ${channel_dir}/${pkgdir_name}.${arch}/plymouth/*.${arch} 2> /dev/null)
+    readarray -t -O "${#_loadfilelist[@]}" _loadfilelist < <(get_filelist "${channel_dir}/${pkgdir_name}.${arch}/plymouth")
+    for_module '_loadfilelist+=($(ls ${module_dir}/{}/${pkgdir_name}.${arch}/plymouth/*.${arch} 2> /dev/null))'
 fi
 
 # memtest86 package list
 if [[ "${memtest86}" = true ]]; then
-    _loadfilelist+=(
-        $(ls ${share_dir}/${pkgdir_name}.${arch}/memtest86/*.${arch} 2> /dev/null)
-        $(ls ${channel_dir}/${pkgdir_name}.${arch}/memtest86/*.${arch} 2> /dev/null)
-    )
-
-    if [[ "${extra}" = true ]]; then
-        _loadfilelist+=(
-            $(ls ${extra_dir}/${pkgdir_name}.${arch}/memtest86/*.${arch} 2> /dev/null)
-        )
-    fi
+    #readarray -t -O "${#_loadfilelist[@]}" _loadfilelist < <(ls ${channel_dir}/${pkgdir_name}.${arch}/memtest86/*.${arch} 2> /dev/null)
+    readarray -t -O "${#_loadfilelist[@]}" _loadfilelist < <(get_filelist "${channel_dir}/${pkgdir_name}.${arch}/memtest86")
+
+    for_module '_loadfilelist+=($(ls ${module_dir}/{}/${pkgdir_name}.${arch}/memtest86/*.${arch} 2> /dev/null))'
 fi
 
 #-- Read package list --#
 # Read the file and remove comments starting with # and add it to the list of packages to install.
-for _file in ${_loadfilelist[@]}; do
+_pkglist=()
+for _file in "${_loadfilelist[@]}"; do
     if [[ -f "${_file}" ]]; then
         msg_debug "Loaded package file ${_file}"
-        _pkglist=( ${_pkglist[@]} "$(grep -h -v ^'#' ${_file})" )
+        #_pkglist=( ${_pkglist[@]} "$(grep -h -v ^'#' ${_file})" )
+        readarray -t -O "${#_pkglist[@]}" _pkglist < <(grep -h -v ^'#' "${_file}")
     else
         msg_debug "The file was not found ${_file}"
     fi
@@ -227,55 +211,44 @@ done
 
 #-- Read exclude list --#
 # Exclude packages from the share exclusion list
-_excludefile=(
-    "${share_dir}/packages.${arch}/exclude"
-    "${share_dir}/packages_aur.${arch}/exclude"
-
-    "${channel_dir}/packages.${arch}/exclude"
-    "${channel_dir}/packages_aur.${arch}/exclude"
-)
+_excludefile=("${channel_dir}/packages.${arch}/exclude" "${channel_dir}/packages_aur.${arch}/exclude")
+for_module '_excludefile+=("${module_dir}/{}/packages.${arch}/exclude" "${module_dir}/{}/packages_aur.${arch}/exclude")'
 
-if [[ "${extra}" = true ]];then
-    _excludefile+=(
-        "${extra_dir}/packages.${arch}/exclude"
-        "${extra_dir}/packages_aur.${arch}/exclude"
-    )
-fi
-
-for _file in ${_excludefile[@]}; do
+for _file in "${_excludefile[@]}"; do
     if [[ -f "${_file}" ]]; then
-        _excludelist+=($(grep -h -v ^'#' "${_file}") )
+        #_excludelist+=($(grep -h -v ^'#' "${_file}") )
+        readarray -t -O "${#_excludelist[@]}" _excludelist < <(grep -h -v ^'#' "${_file}")
     fi
 done
 
+#-- additional_exclude_pkg のパッケージを_excludelistに追加 --#
+if (( "${#additional_exclude_pkg[@]}" >= 1 )); then
+    _excludelist+=("${additional_exclude_pkg[@]}")
+    msg_debug "Additional excluded packages: ${additional_exclude_pkg[*]}"
+fi
+
+#-- パッケージリストをソートし重複を削除 --#
+#_pkglist=($(printf "%s\n" "${_pkglist[@]}" | sort | uniq | tr "\n" " "))
+readarray -t _pkglist < <(printf "%s\n" "${_pkglist[@]}" | sort | uniq | grep -v ^$)
+
 #-- excludeに記述されたパッケージを除外 --#
-# _pkglistを_subpkglistにコピーしexcludeのパッケージを除外し再代入
-_subpkglist=(${_pkglist[@]})
-unset _pkglist
-for _pkg in ${_subpkglist[@]}; do
-    # もし変数_pkgの値が配列_excludelistに含まれていなかったらpkglistに追加する
-    if [[ ! $(printf '%s\n' "${_excludelist[@]}" | grep -qx "${_pkg}"; echo -n ${?} ) = 0 ]]; then
-        _pkglist+=("${_pkg}")
-    fi
+for _pkg in "${_excludelist[@]}"; do
+    #_pkglist=($(printf "%s\n" "${_pkglist[@]}" | grep -xv "${_pkg}" | tr "\n" " "))
+    readarray -t _pkglist < <(printf "%s\n" "${_pkglist[@]}" | grep -xv "${_pkg}")
 done
-unset _subpkglist
 
 #-- excludeされたパッケージを表示 --#
-if [[ -n "${_excludelist[*]}" ]]; then
+if (( "${#_excludelist[@]}" >= 1 )); then
     msg_debug "The following packages have been removed from the installation list."
     msg_debug "Excluded packages: ${_excludelist[*]}"
+else
+    msg_debug "No packages are excluded."
 fi
 
-# Sort the list of packages in abc order.
-_pkglist=($(printf "%s\n" "${_pkglist[@]}" | sort | perl -pe 's/\n/ /g'))
-
-# 重複してるものを削除
-_pkglist=($(printf "%s\n" "${_pkglist[@]}" | uniq))
+wait
 
-OLD_IFS="${IFS}"
 if [[ "${line}" = true ]]; then
-    IFS=$'\n'
+    printf "%s\n" "${_pkglist[@]}"
+else
+    echo "${_pkglist[*]}" >&1
 fi
-
-echo "${_pkglist[*]}" >&1
-IFS="${OLD_IFS}"