mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-11 06:56:58 +02:00
Two warnings, SC2034 and SC2178, pop up very often with the references - shellcheck handles them poorly and produces a ton of bogus warnings about them. Silence the warnings and drop most of the "shellcheck disable" clauses.
271 lines
7.1 KiB
Bash
Executable File
271 lines
7.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
##
|
|
## Prints profile information in form of an inheritance tree and/or
|
|
## evaluation order.
|
|
##
|
|
## Parameters:
|
|
## -h: this help
|
|
## -ni: no inheritance tree
|
|
## -ne: no evaluation order
|
|
## -nh: no headers
|
|
##
|
|
## Environment variables:
|
|
## ROOT
|
|
##
|
|
|
|
set -euo pipefail
|
|
|
|
source "$(dirname "${BASH_SOURCE[0]}")/util.sh"
|
|
|
|
: "${ROOT:=/}"
|
|
|
|
print_inheritance_tree=x
|
|
print_evaluation_order=x
|
|
print_headers=x
|
|
|
|
while [[ ${#} -gt 0 ]]; do
|
|
case ${1} in
|
|
-h)
|
|
print_help
|
|
exit 0
|
|
;;
|
|
-ni)
|
|
print_inheritance_tree=
|
|
;;
|
|
-ne)
|
|
print_evaluation_order=
|
|
;;
|
|
-nh)
|
|
print_headers=
|
|
;;
|
|
*)
|
|
fail "unknown flag ${1}"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
all_repo_names=()
|
|
read -a all_repo_names -r < <(portageq get_repos "${ROOT}")
|
|
|
|
declare -A repo_data repo_data_r
|
|
# name to path
|
|
repo_data=()
|
|
# path to name
|
|
repo_data_r=()
|
|
|
|
for repo_name in "${all_repo_names[@]}"; do
|
|
repo_path=$(portageq get_repo_path "${ROOT}" "${repo_name}")
|
|
repo_path=$(realpath "${repo_path}")
|
|
repo_data["${repo_name}"]="${repo_path}"
|
|
repo_data_r["${repo_path}"]="${repo_name}"
|
|
done
|
|
|
|
unset all_repo_names
|
|
|
|
function get_repo_from_profile_path() {
|
|
local path
|
|
path=${1}; shift
|
|
local -n repo_dir_ref=${1}; shift
|
|
|
|
repo_dir_ref="${path%/profiles/*}"
|
|
}
|
|
|
|
function repo_path_to_name() {
|
|
local path
|
|
path=${1}; shift
|
|
local -n name_ref=${1}; shift
|
|
|
|
name_ref=${repo_data_r["${path}"]:-'<unknown>'}
|
|
}
|
|
|
|
function repeat_string() {
|
|
local str ntimes out_str_var_name
|
|
str=${1}; shift
|
|
ntimes=${1}; shift
|
|
out_str_var_name=${1}; shift
|
|
local -n out_str_ref="${out_str_var_name}"
|
|
|
|
if [[ ${ntimes} -eq 0 ]]; then
|
|
out_str_ref=""
|
|
return 0
|
|
elif [[ ${ntimes} -eq 1 ]]; then
|
|
out_str_ref="${str}"
|
|
return 0
|
|
fi
|
|
local add_one
|
|
add_one=$((ntimes % 2))
|
|
repeat_string "${str}${str}" $((ntimes / 2)) "${out_str_var_name}"
|
|
if [[ add_one -gt 0 ]]; then
|
|
out_str_ref+="${str}"
|
|
fi
|
|
}
|
|
|
|
function process_profile() {
|
|
local repo_name profile_path
|
|
repo_name=${1}; shift
|
|
profile_path=${1}; shift
|
|
local -n children_ref=${1}; shift
|
|
|
|
local parent_file line pp_new_repo_name new_profile_path pp_new_repo_path
|
|
local -a children
|
|
|
|
parent_file="${profile_path}/parent"
|
|
children=()
|
|
if [[ -e ${parent_file} ]]; then
|
|
while read -r line; do
|
|
if [[ ${line} = *:* ]]; then
|
|
pp_new_repo_name=${line%%:*}
|
|
if [[ -z ${pp_new_repo_name} ]]; then
|
|
pp_new_repo_name=${repo_name}
|
|
fi
|
|
pp_new_repo_path=${repo_data["${pp_new_repo_name}"]}
|
|
new_profile_path="${pp_new_repo_path}/profiles/${line#*:}"
|
|
children+=( "${pp_new_repo_name}" "${new_profile_path}" )
|
|
elif [[ ${line} = /* ]]; then
|
|
pp_new_repo_path=
|
|
get_repo_from_profile_path "${line}" pp_new_repo_path
|
|
pp_new_repo_name=
|
|
repo_path_to_name "${pp_new_repo_path}" pp_new_repo_name
|
|
children+=( "${pp_new_repo_name}" "${line}" )
|
|
else
|
|
pp_new_repo_path=$(realpath "${profile_path}/${line}")
|
|
children+=( "${repo_name}" "${pp_new_repo_path}" )
|
|
fi
|
|
done <"${parent_file}"
|
|
fi
|
|
|
|
children_ref=( "${children[@]}" )
|
|
}
|
|
|
|
function get_profile_name() {
|
|
local repo_name profile_path
|
|
repo_name="${1}"; shift
|
|
profile_path="${1}"; shift
|
|
local -n profile_name_ref=${1}; shift
|
|
|
|
local repo_path profile_name
|
|
repo_path=${repo_data["${repo_name}"]}
|
|
profile_name=${profile_path#"${repo_path}/profiles/"}
|
|
|
|
profile_name_ref="${profile_name}"
|
|
}
|
|
|
|
make_profile_path="${ROOT%/}/etc/portage/make.profile"
|
|
top_profile_dir_path=$(realpath "${make_profile_path}")
|
|
top_repo_path=
|
|
get_repo_from_profile_path "${top_profile_dir_path}" top_repo_path
|
|
top_repo_name=
|
|
repo_path_to_name "${top_repo_path}" top_repo_name
|
|
|
|
if [[ -n ${print_inheritance_tree} ]]; then
|
|
|
|
set -- '0' "${top_repo_name}" "${top_profile_dir_path}"
|
|
|
|
profile_tree=()
|
|
|
|
while [[ ${#} -gt 2 ]]; do
|
|
indent=${1}; shift
|
|
repo_name=${1}; shift
|
|
profile_path=${1}; shift
|
|
|
|
lines=
|
|
fork=
|
|
if [[ ${indent} -gt 0 ]]; then
|
|
if [[ ${indent} -gt 1 ]]; then
|
|
repeat_string '| ' $((indent - 1)) lines
|
|
fi
|
|
fork='+-'
|
|
fi
|
|
g_profile_name=
|
|
get_profile_name "${repo_name}" "${profile_path}" g_profile_name
|
|
profile_tree+=( "${lines}${fork}${repo_name}:${g_profile_name}" )
|
|
g_profile_children=()
|
|
|
|
process_profile "${repo_name}" "${profile_path}" g_profile_children
|
|
|
|
new_profiles=()
|
|
new_indent=$((indent + 1))
|
|
pc_idx=0
|
|
while [[ $((pc_idx + 1)) -lt "${#g_profile_children[@]}" ]]; do
|
|
new_repo_name=${g_profile_children["${pc_idx}"]}
|
|
new_profile_path=${g_profile_children[$((pc_idx + 1))]}
|
|
new_profiles+=( "${new_indent}" "${new_repo_name}" "${new_profile_path}" )
|
|
pc_idx=$((pc_idx + 2))
|
|
done
|
|
|
|
set -- "${new_profiles[@]}" "${@}"
|
|
done
|
|
|
|
if [[ -n ${print_headers} ]]; then
|
|
echo
|
|
echo 'profile inheritance tree:'
|
|
echo
|
|
fi
|
|
for line in "${profile_tree[@]}"; do
|
|
echo "${line}"
|
|
done
|
|
|
|
fi
|
|
|
|
if [[ -n ${print_evaluation_order} ]]; then
|
|
|
|
set -- "${top_repo_name}" "${top_profile_dir_path}" '0'
|
|
|
|
profile_eval=()
|
|
|
|
while [[ ${#} -gt 2 ]]; do
|
|
repo_name=${1}; shift
|
|
profile_path=${1}; shift
|
|
num_parents=${1}; shift
|
|
# each parent is a repo name and profile path, so two items for each parent
|
|
num_parent_items=$((num_parents * 2))
|
|
parents=( "${@:1:${num_parent_items}}" )
|
|
shift "${num_parent_items}"
|
|
g_profile_children=()
|
|
|
|
process_profile "${repo_name}" "${profile_path}" g_profile_children
|
|
|
|
new_args=()
|
|
if [[ ${#g_profile_children[@]} -eq 0 ]]; then
|
|
to_evaluate=( "${repo_name}" "${profile_path}" "${parents[@]}" )
|
|
te_idx=0
|
|
while [[ $((te_idx + 1)) -lt "${#to_evaluate[@]}" ]]; do
|
|
new_repo_name=${to_evaluate["${te_idx}"]}
|
|
new_profile_path=${to_evaluate[$((te_idx + 1))]}
|
|
g_new_profile_name=
|
|
get_profile_name "${new_repo_name}" "${new_profile_path}" g_new_profile_name
|
|
profile_eval+=( "${new_repo_name}:${g_new_profile_name}" )
|
|
te_idx=$((te_idx + 2))
|
|
done
|
|
else
|
|
last_idx=$(( ${#g_profile_children[@]} - 2 ))
|
|
pc_idx=0
|
|
while [[ $((pc_idx + 1)) -lt "${#g_profile_children[@]}" ]]; do
|
|
new_repo_name=${g_profile_children["${pc_idx}"]}
|
|
new_profile_path=${g_profile_children[$((pc_idx + 1))]}
|
|
new_args+=( "${new_repo_name}" "${new_profile_path}" )
|
|
if [[ pc_idx -eq last_idx ]]; then
|
|
new_args+=( $((num_parents + 1)) "${repo_name}" "${profile_path}" "${parents[@]}" )
|
|
else
|
|
new_args+=( 0 )
|
|
fi
|
|
pc_idx=$((pc_idx + 2))
|
|
done
|
|
fi
|
|
|
|
set -- "${new_args[@]}" "${@}"
|
|
done
|
|
|
|
if [[ -n ${print_headers} ]]; then
|
|
echo
|
|
echo 'profile evaluation order:'
|
|
echo
|
|
fi
|
|
for line in "${profile_eval[@]}"; do
|
|
echo "${line}"
|
|
done
|
|
|
|
fi
|