bsdconfig: rework packages selection TUI

Rework the packages TUI, do that the index caching is now done with
dialog --gauge (tested with cdialog and bsddialog).
With pkg we can know in avance the number of packages making it
possible to have a real gauge.

The cache of the index is now a file that can be sourced, meaning it
is not anymore an index like file, but a post process one, simplifying
the code.

Each menu is now built calling directly pkg rquery with just the
informations required to build the menu instead of parsing an indexfile

install all the awk index processing into a separate file to ease
reading and debuggung
This commit is contained in:
Baptiste Daroussin
2023-10-10 08:56:36 +02:00
parent 826d144679
commit 6d3c0798cc
4 changed files with 133 additions and 117 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
FILESDIR= ${SHAREDIR}/bsdconfig/packages
FILES= categories.subr index.subr musthavepkg.subr packages.subr
FILES= categories.subr index.awk index.subr musthavepkg.subr packages.subr
.include <bsd.prog.mk>
@@ -0,0 +1,98 @@
function _asorti(src, dest)
{
k = nitems = 0
# Copy src indices to dest and calculate array length
for (i in src) dest[++nitems] = i
# Sort the array of indices (dest) using insertion sort method
for (i = 1; i <= nitems; k = i++)
{
idx = dest[i]
while ((k > 0) && (dest[k] > idx))
{
dest[k+1] = dest[k]
k--
}
dest[k+1] = idx
}
return nitems
}
function print_category(category, npkgs, desc)
{
cat = category
# Accent the category if the first page has been
# cached (also acting as a visitation indicator)
if ( ENVIRON["_index_page_" varcat "_1"] )
cat = cat "*"
printf "'\''%s'\'' '\''%s " packages "'\'' '\''%s'\''\n",
cat, npkgs, desc >>tmpfile
}
BEGIN{
cnt=0
div=int(npkg / 100)
last=0
prefix = ""
}
{
cnt+=1
i = int(cnt / div)
if (i > last) {
last = i
print "XXX"
print i
print msg
print "XXX"
fflush("/dev/stdout");
}
varpkg = $1
gsub("[^" valid_chars "]", "_", varpkg)
print "_categories_" varpkg "=\"" $7 "\"" >> tmpfile
split($7, pkg_categories, /[[:space:]]+/)
for (pkg_category in pkg_categories)
categories[pkg_categories[pkg_category]]++
print "_rundeps_" varpkg "=\"" $9 "\"" >> tmpfile
}
END {
n = _asorti(categories, categories_sorted)
# Produce package counts for each category
for (i = 1; i <= n; i++)
{
cat = varcat = categories_sorted[i]
npkgs = categories[cat]
gsub("[^" valid_chars "]", "_", varcat)
print "_npkgs_" varcat "=\"" npkgs "\"" >>tmpfile
}
#
# Create menu list and generate list of categories at same time
print "CATEGORY_MENU_LIST=\"" >>tmpfile
print_category(msg_all, npkg, msg_all_desc)
category_list = ""
for (i = 1; i <= n; i++)
{
cat = varcat = categories_sorted[i]
npkgs = categories[cat]
cur_prefix = tolower(substr(cat, 1, 1))
if ( prefix != cur_prefix )
prefix = cur_prefix
else
cat = " " cat
gsub("[^" valid_chars "]", "_", varcat)
desc = ENVIRON["_category_" varcat]
if ( ! desc ) desc = default_desc
print_category(cat, npkgs, desc)
category_list = category_list " " cat
}
print "\"" >>tmpfile
# Produce the list of categories (calculated in above block)
sub(/^ /, "", category_list)
print "PACKAGE_CATEGORIES=\"" category_list "\"" >> tmpfile
print "_npkgs=\""npkg"\"" >>tmpfile
print "EOF"
}
+24 -114
View File
@@ -146,7 +146,7 @@ f_index_initialize()
# one populate the environment from the on-disk
# cache and provide success exit status.
#
if [ "$digest" = "$__sqlite_digest" ]; then
if [ "$digest" = "#$__sqlite_digest" ]; then
cat
exit $SUCCESS
else
@@ -171,24 +171,27 @@ f_index_initialize()
# If we reach this point, we need to generate the data from scratch
#
eval "$__var_to_set"='$( pkg rquery -I | (
exec 2<&1; dpv -ko /dev/stderr >&$TERMINAL_STDOUT_PASSTHRU \
-b "$DIALOG_BACKTITLE" \
-- "$msg_generating_index_from_pkg_database"
) | sort )'
#
# Attempt to create the persistent on-disk cache
#
# Create a new temporary file to write to
local __tmpfile
if f_eval_catch -dk __tmpfile $__funcname mktemp \
'mktemp -t "%s"' "$pgm"
then
'mktemp -t "%s"' "$pgm"; then
local _npkg
# Write the temporary file contents
echo "$__sqlite_digest" > "$__tmpfile"
debug= f_getvar "$__var_to_set" >> "$__tmpfile"
echo "#$__sqlite_digest" > "$__tmpfile"
f_eval_catch -k _npkg $__funcname pkg \
"pkg stat -r | awk '%s'" '/Packages available/ { print $3 }'
pkg rquery -I | awk -v npkg=$_npkg \
-v msg="$msg_generating_index_from_pkg_database" \
-v tmpfile="$__tmpfile" \
-v valid_chars="$VALID_VARNAME_CHARS" \
-v default_desc="$msg_no_description_provided" \
-v packages="$msg_packages" \
-v msg_all="$msg_all" \
-v msg_all_desc="$msg_all_desc" \
-F "|" \
-f $BSDCFG_SHARE/packages/index.awk | \
$DIALOG --backtitle "$DIALOG_BACKTITLE" \
--gauge "$msg_generating_index_from_pkg_database" 0 0
# Finally, move the temporary file into place
case "$PACKAGES_INDEX_CACHEFILE" in
@@ -197,10 +200,13 @@ f_index_initialize()
esac
f_eval_catch -d $__funcname mv 'mv -f "%s" "%s"' \
"$__tmpfile" "$PACKAGES_INDEX_CACHEFILE"
else
return $FAILURE
fi
if ! f_index_read "$__var_to_set"; then
f_show_err "$msg_io_or_format_error_on_index_file"
f_show_err \
"$msg_io_or_format_error_on_index_file"
return $FAILURE
fi
@@ -234,98 +240,7 @@ f_index_read()
export VALID_VARNAME_CHARS
export msg_packages
eval "$( debug= f_getvar "$var_to_get" | awk -F'|' '
function _asorti(src, dest)
{
k = nitems = 0
# Copy src indices to dest and calculate array length
for (i in src) dest[++nitems] = i
# Sort the array of indices (dest) using insertion sort method
for (i = 1; i <= nitems; k = i++)
{
idx = dest[i]
while ((k > 0) && (dest[k] > idx))
{
dest[k+1] = dest[k]
k--
}
dest[k+1] = idx
}
return nitems
}
function print_category(category, npkgs, desc)
{
cat = category
# Accent the category if the first page has been
# cached (also acting as a visitation indicator)
if ( ENVIRON["_index_page_" varcat "_1"] )
cat = cat "*"
printf "'\''%s'\'' '\''%s " packages "'\'' '\''%s'\''\n",
cat, npkgs, desc
}
BEGIN {
valid_chars = ENVIRON["VALID_VARNAME_CHARS"]
default_desc = ENVIRON["msg_no_description_provided"]
packages = ENVIRON["msg_packages"]
tpkgs = 0
prefix = ""
}
{
tpkgs++
varpkg = $1
gsub("[^" valid_chars "]", "_", varpkg)
print "_categories_" varpkg "=\"" $7 "\""
split($7, pkg_categories, /[[:space:]]+/)
for (pkg_category in pkg_categories)
categories[pkg_categories[pkg_category]]++
print "_rundeps_" varpkg "=\"" $9 "\""
}
END {
print "_npkgs=" tpkgs # For convenience, total package count
n = _asorti(categories, categories_sorted)
# Produce package counts for each category
for (i = 1; i <= n; i++)
{
cat = varcat = categories_sorted[i]
npkgs = categories[cat]
gsub("[^" valid_chars "]", "_", varcat)
print "_npkgs_" varcat "=\"" npkgs "\""
}
# Create menu list and generate list of categories at same time
print "CATEGORY_MENU_LIST=\""
print_category(ENVIRON["msg_all"], tpkgs,
ENVIRON["msg_all_desc"])
category_list = ""
for (i = 1; i <= n; i++)
{
cat = varcat = categories_sorted[i]
npkgs = categories[cat]
cur_prefix = tolower(substr(cat, 1, 1))
if ( prefix != cur_prefix )
prefix = cur_prefix
else
cat = " " cat
gsub("[^" valid_chars "]", "_", varcat)
desc = ENVIRON["_category_" varcat]
if ( ! desc ) desc = default_desc
print_category(cat, npkgs, desc)
category_list = category_list " " cat
}
print "\""
# Produce the list of categories (calculated in above block)
sub(/^ /, "", category_list)
print "PACKAGE_CATEGORIES=\"" category_list "\""
}' | ( exec 2<&1; dpv -ko /dev/stderr >&$TERMINAL_STDOUT_PASSTHRU \
-b "$DIALOG_BACKTITLE" -- "$msg_reading_package_index_data"
) )" # End-Quote
. $PACKAGES_INDEX_CACHEFILE
}
# f_index_extract_pages $var_to_get $var_basename $pagesize [$category]
@@ -342,19 +257,14 @@ f_index_read()
f_index_extract_pages()
{
local var_to_get="${1:-PACKAGE_INDEX}" var_basename="$2" pagesize="$3"
local category="$4" # Optional
eval "$(
debug= f_getvar "$var_to_get" | awk -F'|' \
-v cat="$category" \
-v pagesize="$pagesize" \
-v var_basename="$var_basename" \
-v i18n_all="$msg_all" '
-v var_basename="$var_basename" ' \
BEGIN { n = page = 0 }
/'\''/{ gsub(/'\''/, "'\''\\'\'\''") }
{
if ( cat !~ "(^$|^" i18n_all "$)" && $7 !~ \
"(^|[[:space:]])" cat "([[:space:]]|$)" ) next
starting_new_page = (n++ == (pagesize * page))
if ( starting_new_page )
printf "%s%s", ( n > 1 ? "'\''\n" : "" ),
@@ -378,6 +378,7 @@ f_package_index_get_page()
#
f_package_menu_select()
{
local __funcname=f_package_menu_deselect
local category="$1" page="${2:-1}"
local prompt= # Calculated below
local menu_list # Calculated below
@@ -424,8 +425,15 @@ f_package_menu_select()
next_page="$next_page*"
fi
local index_page
f_package_index_get_page "$category" $page index_page
local index_page __index
if [ "$category" = "$msg_all" ]; then
f_eval_catch -k __index $__funcname pkg \
"pkg rquery -a '%s'" "%n|%o||%c"
else
f_eval_catch -k __index $__funcname pkg \
"pkg rquery -g '%s' '%s/\*'" "%n|%o||%c" "$category"
fi
f_package_index_get_page "$category" $page index_page __index
menu_list="
${add_prev:+'> $previous_page' '' ${SHOW_DESC:+''}}