Skip to content

Commit

Permalink
ci(srcinfo.sh): reduce overhead usage, repair search (#6866)
Browse files Browse the repository at this point in the history
See pacstall/pacstall#1308

---------

Co-authored-by: ook37 <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 12, 2025
1 parent 40094c0 commit b1e60e9
Showing 1 changed file with 67 additions and 233 deletions.
300 changes: 67 additions & 233 deletions scripts/srcinfo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -304,57 +304,34 @@ function srcinfo._contains() {
# @description Create array based on input
#
# @example
# srcinfo._create_array pkgbase var_name var_prefix
# srcinfo._create_array base var_name
#
# @arg $1 string (optional) The pkgbase of the section
# @arg $1 string The pkgbase of the section
# @arg $2 string The variable name
# @arg $3 string (optional) The variable prefix
#
# @stdout Name of array created.
function srcinfo._create_array() {
local pkgbase="${1}" var_name="${2}" var_pref="${3}"
if [[ -n ${pkgbase} ]]; then
pkgbase="${pkgbase//./_}" var_name="${var_name//./_}"
if ! [[ -v "${var_pref}_${pkgbase}_array_${var_name}" ]]; then
declare -ag "${var_pref}_${pkgbase}_array_${var_name}"
fi
echo "${var_pref}_${pkgbase}_array_${var_name}"
else
if ! [[ -v "${var_pref}_array_${var_name}" ]]; then
declare -ag "${var_pref}_array_${var_name}"
fi
echo "${var_pref}_array_${var_name}"
local base="${1}" var_name="${2}"
base="${base//./_}" var_name="${var_name//./_}"
if ! [[ -v "srcinfo_${base}_array_${var_name}" ]]; then
declare -ag "srcinfo_${base}_array_${var_name}"
fi
}

# @description Promote array to variable
#
# @example
# foo=('bar')
# srcinfo._promote_to_variable foo
#
# @arg $1 string Name of array to promote
function srcinfo._promote_to_variable() {
local var_name="${1}" key value
key="${var_name}"
value="${!var_name[0]}"
declare -g "${key}=${value}"
echo "srcinfo_${base}_array_${var_name}"
}

function srcinfo.parse() {
# We need this for trimming whitespace without external tools.
# shellcheck disable=SC2064
trap "$(shopt -p extglob)" RETURN
shopt -s extglob
local srcinfo_file var_prefix locbase temp_array ref total_list loop part i part_two split_up suffix
srcinfo_file="${1:?No .SRCINFO passed to srcinfo.parse}"
var_prefix="${2:?Variable prefix not passed to srcinfo.parse}"
srcinfo.cleanup "${var_prefix}"
[[ ! -s ${srcinfo_file} ]] && return 5
while IFS= read -r line; do
srcinfo.cleanup
local srcfile locbase temp_array ref total_list loop part i suffix
srcfile="${1:?No .SRCINFO passed to srcinfo.parse}"
[[ ! -s ${srcfile} ]] && return 5
mapfile -t srcinfo_data < "${srcfile}"
for line in "${srcinfo_data[@]}"; do
# Skip blank lines
[[ -z ${line} ]] && continue
[[ ${line} =~ ^\s*#.* ]] && continue
[[ -z ${line} || ${line} =~ ^\s*#.* ]] && continue
# Trim leading whitespace.
line="${line##+([[:space:]])}"
declare -A temp_line
Expand All @@ -372,10 +349,10 @@ function srcinfo.parse() {
# Do we have pkgbase first?
if [[ ${temp_line[key]} == "pkgbase" ]]; then
locbase="pkgbase_${temp_line[value]//-/_}"
export globase="${temp_line[value]//./_}"
globase="${temp_line[value]//./_}"
else
locbase="${temp_line[value]//-/_}"
export globase="temporary_pacstall_pkgbase"
globase="temporary_pacstall_pkgbase"
fi
elif [[ ${temp_line[key]} == *"pkgname" ]]; then
# Bash can't have dashes in variable names
Expand All @@ -385,162 +362,38 @@ function srcinfo.parse() {
# So the strategy is to create arrays of every key and at the end,
# we can promote array.len() == 1 to variables instead. After that we
# can work back upwards.
temp_array="$(srcinfo._create_array "${locbase}" "${temp_line[key]}" "${var_prefix}")"
temp_array="$(srcinfo._create_array "${locbase}" "${temp_line[key]}" "srcinfo")"
declare -n ref="${temp_array}"
ref+=("${temp_line[value]}")
if [[ ${locbase} == "pkgbase_"* ]] || ! srcinfo._contains total_list "${temp_array}"; then
if ! srcinfo._contains total_list "${temp_array}"; then
total_list+=("${temp_array}")
fi
done < "${srcinfo_file}"
declare -Ag "${var_prefix}_access"
done
unset srcinfo_data
declare -Ag "srcinfo_access"
for loop in "${total_list[@]}"; do
declare -n part="${loop}"
# Are we at a new pkgname (pkgbase)?
if [[ ${loop} == *@(pkgname|pkgbase) ]]; then
declare -n var_name="${var_prefix}_access"
[[ ${loop} == "${var_prefix}_pkgbase"* ]] && global="pkgbase_"
declare -n var_name="srcinfo_access"
[[ ${loop} == "srcinfo_pkgbase"* ]] && global="pkgbase_"
for i in "${!part[@]}"; do
suffix="${global}${part[${i}]//-/_}"
suffix="${suffix//./_}"
# Create our inner part
declare -ga "${var_prefix}_${suffix}"
declare -ga "srcinfo_${suffix}"
# Declare that relationship
var_name["${var_prefix}_${suffix}"]="${var_prefix}_${suffix}"
var_name["srcinfo_${suffix}"]="srcinfo_${suffix}"
done
unset global
fi
done
for part_two in "${total_list[@]}"; do
# Now we need to go and check every loop over, and parse it out so we get something like ("prefix", "key"), so we can then work with that.
# But first actually we should promote single element arrays to variables
declare -n referoo="${part_two}"
if (("${#referoo[@]}" == 1)); then
srcinfo._promote_to_variable "${part_two}"
fi
mapfile -t split_up <<< "${part_two/_array_/$'\n'}"
declare -n addarr="${split_up[0]}"
unset "${split_up[1]}"
# So now we need to check if the thing we're trying to insert is a variable,
# or an array.
if srcinfo.is_array "${part_two}"; then
declare -ga "${part_two}"
# shellcheck disable=SC2004
addarr[${split_up[1]}]="${part_two}"
else
# shellcheck disable=SC2034,SC2004
addarr[${split_up[1]}]="${!part_two}"
fi
done
}

function srcinfo.cleanup() {
local var_prefix="${1:?No var_prefix passed to srcinfo.cleanup}" i z
local main_loop_template="${var_prefix}_access" compg
declare -n main_loop="${main_loop_template}"
for i in "${main_loop[@]}"; do
declare -n cleaner="${i}"
for z in "${cleaner[@]}"; do
unset "${var_prefix}_array_${z}"
done
unset cleaner
done
unset "${var_prefix}_access" globase global
# So now lets clean the stragglers that we can't reasonably infer
mapfile -t compg < <(compgen -v)
for i in "${compg[@]}"; do
if [[ ${i} == "${var_prefix}_"* ]]; then
unset -v "${i}"
fi
done
}

# @description Reformat numbered associative array to indexed
#
# @example
# srcinfo_depends_vala_panel_appmenu_xfce_git=(["vala-panel-appmenu-valapanel-git-0"]="gtk3")
# srcinfo.reformat_assoc_arr "srcinfo_depends_vala_panel_appmenu_xfce_git" "eviler"
#
# converts to `srcinfo_depends_vala_panel_appmenu_valapanel_git=([0]="gtk3")`
#
# @arg $1 string Associative array to reformat
# @arg $2 string Ref string of indexed array to append conversion to (can be anything)
function srcinfo.reformat_assoc_arr() {
local pfx base ida new pfs in_name="${1}"
local -n in_arr="${in_name}" app="${2}"
IFS='_' read -r -a pfs <<< "${in_name}"
for pfx in "${!in_arr[@]}"; do
base="${pfx%-*}" ida="${pfx##*-}" new="${base//-/_}"
new="${new//./_}"
app+=("$(printf "%s[%s]=\"%s\"\n" "${pfs[0]}_${pfs[1]}_${new}" "${ida}" "${in_arr[${pfx}]}")")
done
}

# @description Parse a specific variable from .SRCINFO
#
# @example
#
# srcinfo.print_var .SRCINFO source
# @arg $1 string .SRCINFO file path
# @arg $2 string Variable or Array to print
function srcinfo.print_var() {
local srcinfo_file="${1}" found="${2}" var_prefix="srcinfo" pkgbase output var name idx evil eviler e printed
local -n bases="${var_prefix}_access"
srcinfo.parse "${srcinfo_file}" "${var_prefix}"
if [[ ${found} == "pkgbase" ]]; then
if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then
pkgbase="${globase}"
declare -p pkgbase
return 0
else
return 3
fi
fi
for var in "${bases[@]}"; do
var="${var//./_}"
declare -n output="${var}_array_${found}"
declare -n name="${var}_array_pkgname"
if [[ -n ${output[*]} ]]; then
for idx in "${!output[@]}"; do
if ((${#bases[@]} > 1)); then
# shellcheck disable=SC2076
if [[ ${var} =~ "pkgbase_${globase//-/_}" ]]; then
evil+=("$(printf "${var_prefix}_${found}_${globase//-/_}[\"${globase}-pkgbase-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")")
else
evil+=("$(printf "${var_prefix}_${found}_${globase//-/_}[\"${name}-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")")
fi
else
evil+=("$(printf "${var_prefix}_${found}_${name//-/_}[\"${name}-%d\"]=\"%s\"\n" "${idx}" "${output[${idx}]}")")
fi
done
fi
done
if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then
unset "${var_prefix}_${found}_${globase//-/_}"
declare -Ag "${var_prefix}_${found}_${globase//-/_}"
else
unset "${var_prefix}_${found}_${name//-/_}"
declare -Ag "${var_prefix}_${found}_${name//-/_}"
fi
# shellcheck disable=SC2294
eval "${evil[@]}"
if [[ -n ${globase} && ${globase} != "temporary_pacstall_pkgbase" ]]; then
srcinfo.reformat_assoc_arr "${var_prefix}_${found}_${globase//-/_}" "eviler"
unset "${var_prefix}_${found}_${globase//-/_}"
# shellcheck disable=SC2294
eval "${eviler[@]}"
else
srcinfo.reformat_assoc_arr "${var_prefix}_${found}_${name//-/_}" "eviler"
unset "${var_prefix}_${found}_${name//-/_}"
# shellcheck disable=SC2294
eval "${eviler[@]}"
fi
for e in "${eviler[@]}"; do
if ! srcinfo._contains printed "${e%\[*}"; then
printed+=("${e%\[*}")
declare -p "${e%\[*}"
fi
unset "${e%\[*}"
done
local compg
mapfile -t compg < <(compgen -v "srcinfo_")
unset "${compg[@]}" srcinfo_access globase global 2> /dev/null
}

# @description Output a specific variable from .SRCINFO
Expand All @@ -553,46 +406,22 @@ function srcinfo.print_var() {
# @arg $2 string Variable or Array to search
# @arg $3 string Package name or base to get output for
function srcinfo.match_pkg() {
local declares d bases b guy match out srcfile="${1}" search="${2}" pkg="${3}"
local srcinfo_file="${1}" search="${2}" pkg="${3}" pkgbase output var
local -n bases="srcinfo_access"
pkg="${pkg//./_}"
if [[ ${pkg} == "pkgbase:"* || ${search} == "pkgbase" ]]; then
pkg="${pkg/pkgbase:/}"
match="srcinfo_${search%%_*}_${pkg//-/_}_pkgbase"
else
match="srcinfo_${search%%_*}_${pkg//-/_}"
fi
mapfile -t declares < <(srcinfo.print_var "${srcfile}" "${search}" | awk '{sub(/^declare -a |^declare -- |^declare -x /, ""); print}')
[[ ${search} == "pkgbase" && -z ${declares[*]} ]] \
&& mapfile -t declares < <(srcinfo.print_var "${srcfile}" "pkgname" | awk '{sub(/^declare -a |^declare -- |^declare -x /, ""); print}')
for d in "${declares[@]}"; do
if [[ ${d%=\(*} =~ = ]]; then
declare -- "${d}"
bases+=("${d%=*}")
else
declare -a "${d}"
bases+=("${d%=\(*}")
fi
done
for b in "${bases[@]}"; do
guy="${b}[@]"
if [[ -z ${pkg} ]]; then
if [[ ${search} == "pkgname" || ${search} == "pkgbase" ]]; then
if [[ -n ${pkgbase} ]]; then
out="${pkgbase/\"/}"
out="${out/\"/}"
printf '%s\n' "pkgbase:${out}"
continue
fi
printf '%s\n' "${!guy}"
continue
else
printf '%s\n' "${guy}"
continue
pkg="${pkg//:/_}"
pkg="${pkg//-/_}"
srcinfo.parse "${srcinfo_file}"
for var in "${bases[@]}"; do
var="${var//./_}"
declare -n output="${var}_array_${search}"
if [[ -n ${output[*]} ]]; then
if [[ ${search} == "pkgbase" ]]; then
echo "pkgbase:${output[0]}"
elif [[ ${search} == "pkgname" || ${var}_array_${search} == "srcinfo_${pkg}_array_${search}" ]]; then
printf '%s\n' "${output[@]}"
fi
fi
if [[ ${b} == "${match}" ]]; then
printf '%s\n' "${!guy}"
fi
done
}

Expand Down Expand Up @@ -663,45 +492,50 @@ function srcinfo.list_search() {
function print_pkgbase_and_pkgname() {
if (pkgbase != "") {
print pkgbase, pkgbase_desc
if (pkgname != "") {
desc = (pkgname_desc != "" ? pkgname_desc : pkgbase_desc)
print pkgbase ":" pkgname, desc
for (i in pkgnames) {
desc = (pkgname_descs[i] != "" ? pkgname_descs[i] : pkgbase_desc)
print pkgbase ":" pkgnames[i], desc
}
}
}
/^---$/ {
if (pkgbase != "" && (pkgbase ~ kw || tolower(pkgbase_desc) ~ kw)) {
print_pkgbase_and_pkgname()
found = 1
} else if (pkgname != "" && (pkgname ~ kw || tolower(pkgname_desc) ~ kw)) {
print_pkgbase_and_pkgname()
found = 1
if (pkgbase != "") {
if (pkgbase ~ kw || tolower(pkgbase_desc) ~ kw || kw == "") {
print_pkgbase_and_pkgname()
found = 1
} else {
for (i in pkgnames) {
desc = (pkgname_descs[i] != "" ? pkgname_descs[i] : pkgbase_desc)
if (pkgnames[i] ~ kw || tolower(desc) ~ kw) {
print pkgbase ":" pkgnames[i], desc
found = 1
}
}
}
}
pkgname = ""; pkgbase = ""; pkgbase_desc = ""; pkgname_desc = ""; next
pkgbase = ""; pkgbase_desc = ""; delete pkgnames; delete pkgname_descs
next
}
/^[[:space:]]*pkgbase[[:space:]]*=/ {
pkgbase = $2
pkgbase_desc = ""
}
/^[[:space:]]*pkgname[[:space:]]*=/ {
if (pkgname != "") {
desc = (pkgname_desc != "" ? pkgname_desc : pkgbase_desc)
if (pkgname ~ kw || tolower(desc) ~ kw) {
print pkgbase ":" pkgname, desc
found = 1
}
}
pkgname = $2
pkgname_desc = ""
# Add pkgname to array
pkgnames[length(pkgnames) + 1] = $2
pkgname_descs[length(pkgnames)] = ""
}
/^[[:space:]]*pkgdesc[[:space:]]*=/ {
if (pkgname == "") {
if (length(pkgnames) == 0) {
pkgbase_desc = $2
} else {
pkgname_desc = $2
pkgname_descs[length(pkgnames)] = $2
}
}
END {
if (pkgbase != "") {
print_pkgbase_and_pkgname()
}
if (!found) {
print "No matching packages found"
}
Expand Down

0 comments on commit b1e60e9

Please sign in to comment.