Skip to content

Commit 20da75b

Browse files
committed
Re-work config file reading and writing
1 parent 2e6a603 commit 20da75b

16 files changed

Lines changed: 411 additions & 196 deletions

includes/cmdline.sh

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -606,14 +606,14 @@ run_command() {
606606
)
607607

608608
CommandConfigVar+=(
609-
["--theme-shadows"]="shadow"
610-
["--theme-no-shadows"]="shadow"
611-
["--theme-scrollbar"]="scrollbar"
612-
["--theme-no-scrollbar"]="scrollbar"
613-
["--theme-lines"]="line_characters"
614-
["--theme-no-lines"]="line_characters"
615-
["--theme-borders"]="borders"
616-
["--theme-no-borders"]="borders"
609+
["--theme-shadows"]="ui.shadow"
610+
["--theme-no-shadows"]="ui.shadow"
611+
["--theme-scrollbar"]="ui.scrollbar"
612+
["--theme-no-scrollbar"]="ui.scrollbar"
613+
["--theme-lines"]="ui.line_characters"
614+
["--theme-no-lines"]="ui.line_characters"
615+
["--theme-borders"]="ui.borders"
616+
["--theme-no-borders"]="ui.borders"
617617
)
618618

619619
CommandConfigValue=(
@@ -939,7 +939,7 @@ run_command() {
939939
notice \
940940
"${Notice}"
941941
fi
942-
set_toml_val "${APPLICATION_TOML_FILE}" "ui.${ConfigVar}" "${ConfigValue}" || result=$?
942+
run_script 'config_set' "${ConfigVar}" "${ConfigValue}" || result=$?
943943
if use_dialog_box; then
944944
run_script 'menu_dialog_example' "${Title}" "${CURRENT_COMMANDLINE}"
945945
fi

includes/misc_functions.sh

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,92 @@ get_toml_val() {
444444
return 0
445445
fi
446446
done < "${file}"
447+
448+
# Key or section not found
449+
return 1
450+
}
451+
452+
get_ini_val() {
453+
# get_ini_val VarFile VarName
454+
local ConfigFile=${1-}
455+
local VarName=${2-}
456+
457+
if [[ -z ${VarName} || -z ${ConfigFile} || ! -f ${ConfigFile} ]]; then
458+
# VarName or ConfigFile empty strings, or ConfigFile does not exist, return
459+
return 1
460+
fi
461+
462+
local Line
463+
local Val=""
464+
local Found=false
465+
while IFS= read -r Line || [[ -n ${Line} ]]; do
466+
# Skip comments and empty lines
467+
[[ ${Line} =~ ^[[:space:]]*# ]] && continue
468+
[[ -z ${Line} ]] && continue
469+
470+
# Check if line contains Key=Value
471+
if [[ ${Line} =~ ^[[:space:]]*${VarName}[[:space:]]*= ]]; then
472+
# Extract Key and Value
473+
local Key="${Line%%=*}"
474+
local Value="${Line#*=}"
475+
476+
# Trim whitespace from Key
477+
Key="${Key#"${Key%%[![:space:]]*}"}"
478+
Key="${Key%"${Key##*[![:space:]]}"}"
479+
480+
# Check if this is the requested key
481+
if [[ ${Key} == "${VarName}" ]]; then
482+
Val="${Value}"
483+
Found=true
484+
# Keep reading to get the last occurrence (tail -1 behavior)
485+
fi
486+
fi
487+
done < "${ConfigFile}"
488+
489+
if [[ ${Found} == false ]]; then
490+
# Key was not found in the config file
491+
return 1
492+
fi
493+
494+
# Trim leading whitespace
495+
Val="${Val#"${Val%%[![:space:]]*}"}"
496+
# Trim trailing whitespace
497+
Val="${Val%"${Val##*[![:space:]]}"}"
498+
499+
# Strip single quotes if present on both ends
500+
if [[ ${Val} == \'*\' ]]; then
501+
Val="${Val#\'}"
502+
Val="${Val%\'}"
503+
# Strip double quotes if present on both ends
504+
elif [[ ${Val} == \"*\" ]]; then
505+
Val="${Val#\"}"
506+
Val="${Val%\"}"
507+
fi
508+
509+
printf '%s\n' "${Val}"
447510
return 0
448511
}
449512

513+
get_ini_val_string() {
514+
get_ini_val "$@"
515+
}
516+
517+
get_ini_val_bool() {
518+
# get_ini_val_bool FILE KEY
519+
# Returns the value of KEY in FILE, normalized to "true" or "false".
520+
local file=${1-}
521+
local key=${2-}
522+
523+
local Value
524+
if Value="$(get_ini_val "${file}" "${key}")"; then
525+
string_to_bool "${Value}"
526+
return 0
527+
fi
528+
529+
# Key not found
530+
return 1
531+
}
532+
450533
set_toml_val() {
451534
# set_toml_val FILE SECTION.KEY VALUE
452535
# Creates or updates KEY = "VALUE" within [SECTION] in FILE.
@@ -525,7 +608,14 @@ get_toml_val_string() {
525608
# Returns the value of KEY within [SECTION] in FILE.
526609
local file=${1-}
527610
local section_key="${2-}"
528-
get_toml_val "${file}" "${section_key}"
611+
local Value
612+
if Value="$(get_toml_val "${file}" "${section_key}")"; then
613+
printf '%s\n' "${Value}"
614+
return 0
615+
fi
616+
617+
# Key or section not found
618+
return 1
529619
}
530620

531621
set_toml_val_string() {
@@ -555,7 +645,14 @@ get_toml_val_bool() {
555645
local file=${1-}
556646
local section_key="${2-}"
557647

558-
string_to_bool "$(get_toml_val "${file}" "${section_key}")"
648+
local Value
649+
if Value="$(get_toml_val "${file}" "${section_key}")"; then
650+
string_to_bool "${Value}"
651+
return 0
652+
fi
653+
654+
# Key or section not found
655+
return 1
559656
}
560657

561658
set_toml_val_bool() {
@@ -575,7 +672,14 @@ get_toml_val_int() {
575672
local file=${1-}
576673
local section_key="${2-}"
577674

578-
string_to_int "$(get_toml_val "${file}" "${section_key}")"
675+
local Value
676+
if Value="$(get_toml_val "${file}" "${section_key}")"; then
677+
string_to_int "${Value}"
678+
return 0
679+
fi
680+
681+
# Key or section not found
682+
return 1
579683
}
580684

581685
set_toml_val_int() {

scripts/apply_config.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ apply_config() {
66
run_script 'config_create'
77

88
#shellcheck disable=SC2034 # (warning): LITERAL_CONFIG_FOLDER appears unused. Verify use (or export if used externally).
9-
LITERAL_CONFIG_FOLDER="$(get_toml_val_string "${APPLICATION_TOML_FILE}" "paths.config_folder")"
9+
LITERAL_CONFIG_FOLDER="$(run_script 'config_get' paths.config_folder)"
1010
#shellcheck disable=SC2034 # (warning): LITERAL_COMPOSE_FOLDER appears unused. Verify use (or export if used externally).
11-
LITERAL_COMPOSE_FOLDER="$(get_toml_val_string "${APPLICATION_TOML_FILE}" "paths.compose_folder")"
11+
LITERAL_COMPOSE_FOLDER="$(run_script 'config_get' paths.compose_folder)"
1212
set_global_variables
1313
run_script 'config_theme'
1414
run_script 'config_package_manager'

scripts/config_create.sh

Lines changed: 42 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ set -Eeuo pipefail
33
IFS=$'\n\t'
44

55
config_create() {
6-
76
# Early return if the TOML config already exists
87
if [[ -f ${APPLICATION_TOML_FILE} ]]; then
98
return 0
@@ -20,23 +19,32 @@ config_create() {
2019

2120
local ComposeFolderFound=false
2221
# Handle legacy config files
23-
if [[ -f ${SCRIPTPATH}/${APPLICATION_INI_NAME} || -f ${SCRIPTPATH}/menu.ini || -f ${XDG_CONFIG_HOME}/${APPLICATION_INI_NAME} ]]; then
24-
for LegacyIniFile in "${XDG_CONFIG_HOME}/${APPLICATION_INI_NAME}" "${SCRIPTPATH}/${APPLICATION_INI_NAME}" "${SCRIPTPATH}/menu.ini"; do
25-
if [[ -f ${LegacyIniFile} ]]; then
26-
if [[ ${LegacyIniFile} == "${APPLICATION_INI_FILE}" ]]; then
27-
continue
28-
fi
29-
notice "Renaming '{{|File|}}${LegacyIniFile}{{[-]}}' to '{{|File|}}${APPLICATION_INI_FILE}{{[-]}}'."
30-
mv "${LegacyIniFile}" "${APPLICATION_INI_FILE}" ||
31-
fatal \
32-
"Failed to rename old config file." \
33-
"Failing command: {{|FailingCommand|}}mv \"${LegacyIniFile}\" \"${APPLICATION_INI_FILE}\""
34-
break
22+
local -a LegacyIniFiles=(
23+
"${XDG_CONFIG_HOME}/${APPLICATION_INI_NAME}"
24+
"${SCRIPTPATH}/${APPLICATION_INI_NAME}"
25+
"${SCRIPTPATH}/menu.ini"
26+
)
27+
local LegacyIniFile=""
28+
for CheckLegacyIniFile in "${LegacyIniFiles[@]}"; do
29+
if [[ -f ${CheckLegacyIniFile} ]]; then
30+
if [[ ${CheckLegacyIniFile} == "${APPLICATION_INI_FILE}" ]]; then
31+
continue
3532
fi
36-
done
33+
LegacyIniFile="${CheckLegacyIniFile}"
34+
fi
35+
done
36+
if [[ -n ${LegacyIniFile} ]]; then
37+
local Heading="Configuration options in old config file '{{|File|}}${LegacyIniFile}{{[-]}}':"
38+
notice ""
39+
notice "$(run_script 'config_show' "${LegacyIniFile}" "${Heading}")"
40+
notice ""
41+
notice "Renaming '{{|File|}}${LegacyIniFile}{{[-]}}' to '{{|File|}}${APPLICATION_INI_FILE}{{[-]}}'."
42+
mv "${LegacyIniFile}" "${APPLICATION_INI_FILE}" ||
43+
fatal \
44+
"Failed to rename old config file." \
45+
"Failing command: {{|FailingCommand|}}mv \"${LegacyIniFile}\" \"${APPLICATION_INI_FILE}\""
3746
run_script 'set_permissions' "${APPLICATION_INI_FILE}"
3847
fi
39-
4048
if [[ -f ${APPLICATION_INI_FILE} ]]; then
4149
# Migrate from INI to TOML
4250
notice "Migrating '{{|File|}}${APPLICATION_INI_FILE}{{[-]}}' to '{{|File|}}${APPLICATION_TOML_FILE}{{[-]}}'."
@@ -47,65 +55,26 @@ config_create() {
4755
"Failing command: {{|FailingCommand|}}cp \"${DEFAULT_TOML_FILE}\" \"${APPLICATION_TOML_FILE}\""
4856
run_script 'set_permissions' "${APPLICATION_TOML_FILE}"
4957

50-
local -A TOMLtoINIMap_strings=(
51-
["paths.config_folder"]="ConfigFolder"
52-
["ui.theme"]="Theme"
53-
["pm.package_manager"]="PackageManager"
58+
local -a ConfigOptions=(
59+
"paths.config_folder"
60+
"ui.theme"
61+
"pm.package_manager"
62+
"ui.scrollbar"
63+
"ui.shadow"
64+
"ui.borders"
65+
"ui.line_characters"
5466
)
5567

56-
local -A TOMLtoINIMap_booleans=(
57-
["ui.scrollbar"]="Scrollbar:Scrollbars"
58-
["ui.shadow"]="Shadow:Shadows"
59-
)
60-
61-
if run_script 'env_var_exists' ComposeFolder "${APPLICATION_INI_FILE}"; then
62-
set_toml_val_string \
63-
"${APPLICATION_TOML_FILE}" \
64-
paths.compose_folder \
65-
"$(run_script 'config_get' ComposeFolder "${APPLICATION_INI_FILE}")"
68+
local Value
69+
if Value=$(run_script 'config_get' paths.compose_folder "${APPLICATION_INI_FILE}"); then
70+
run_script 'config_set' paths.compose_folder "${Value}"
6671
ComposeFolderFound=true
6772
fi
6873

69-
for Key in "${!TOMLtoINIMap_strings[@]}"; do
70-
if run_script 'env_var_exists' "${TOMLtoINIMap_strings["${Key}"]}" "${APPLICATION_INI_FILE}"; then
71-
set_toml_val_string \
72-
"${APPLICATION_TOML_FILE}" \
73-
"${Key}" \
74-
"$(run_script 'config_get' "${TOMLtoINIMap_strings["${Key}"]}" "${APPLICATION_INI_FILE}")"
75-
fi
76-
done
77-
78-
# Migrate LineCharacters to ui.borders if Borders doesn't exist (old INI settings)
79-
if run_script 'env_var_exists' Borders "${APPLICATION_INI_FILE}"; then
80-
set_toml_val_bool \
81-
"${APPLICATION_TOML_FILE}" \
82-
ui.borders \
83-
"$(run_script 'config_get' Borders "${APPLICATION_INI_FILE}")"
84-
if run_script 'env_var_exists' LineCharacters "${APPLICATION_INI_FILE}"; then
85-
set_toml_val_bool \
86-
"${APPLICATION_TOML_FILE}" \
87-
ui.line_characters \
88-
"$(run_script 'config_get' LineCharacters "${APPLICATION_INI_FILE}")"
74+
for Key in "${ConfigOptions[@]}"; do
75+
if Value=$(run_script 'config_get' "${Key}" "${APPLICATION_INI_FILE}"); then
76+
run_script 'config_set' "${Key}" "${Value}"
8977
fi
90-
elif run_script 'env_var_exists' LineCharacters "${APPLICATION_INI_FILE}"; then
91-
set_toml_val_bool \
92-
"${APPLICATION_TOML_FILE}" \
93-
ui.borders \
94-
"$(run_script 'config_get' LineCharacters "${APPLICATION_INI_FILE}")"
95-
fi
96-
97-
for Key in "${!TOMLtoINIMap_booleans[@]}"; do
98-
local VarList
99-
VarList="${TOMLtoINIMap_booleans["${Key}"]}"
100-
for Val in ${VarList//:/ }; do
101-
if run_script 'env_var_exists' "${Val}" "${APPLICATION_INI_FILE}"; then
102-
set_toml_val_bool \
103-
"${APPLICATION_TOML_FILE}" \
104-
"${Key}" \
105-
"$(run_script 'config_get' "${Val}" "${APPLICATION_INI_FILE}")"
106-
break
107-
fi
108-
done
10978
done
11079
else
11180
# Fresh install: copy the default TOML file
@@ -129,7 +98,7 @@ config_create() {
12998
detect_compose_folder() {
13099
# Check for a legacy compose folder and update ComposeFolder if needed
131100
local ConfigFolder
132-
ConfigFolder="$(get_toml_val_string "${APPLICATION_TOML_FILE}" paths.config_folder)"
101+
ConfigFolder="$(run_script 'config_get' paths.config_folder)"
133102

134103
local -a ExpandVarList=(
135104
ScriptFolder "${SCRIPTPATH}"
@@ -154,7 +123,7 @@ detect_compose_folder() {
154123
fi
155124

156125
local DefaultComposeFolder
157-
DefaultComposeFolder="$(get_toml_val_string "${APPLICATION_TOML_FILE}" paths.compose_folder)"
126+
DefaultComposeFolder="$(run_script 'config_get' paths.compose_folder)"
158127
local ExpandedDefaultComposeFolder
159128
ExpandedDefaultComposeFolder="$(expand_vars "${DefaultComposeFolder}" "${ExpandVarList[@]}")"
160129

@@ -169,14 +138,15 @@ detect_compose_folder() {
169138
notice \
170139
"Chose the Legacy compose folder location:" \
171140
" '{{|Folder|}}${ExpandedLegacyComposeFolder}{{[-]}}'"
172-
set_toml_val_string "${APPLICATION_TOML_FILE}" paths.compose_folder "${LegacyComposeFolder}"
141+
run_script 'config_set' paths.compose_folder "${LegacyComposeFolder}"
173142
else
174143
notice \
175144
"Chose the Default compose folder location:" \
176145
" '{{|Folder|}}${ExpandedDefaultComposeFolder}{{[-]}}'"
146+
run_script 'config_set' paths.compose_folder "${DefaultComposeFolder}"
177147
fi
178148
elif [[ ${LegacyHasFiles} == true ]]; then
179-
set_toml_val_string "${APPLICATION_TOML_FILE}" paths.compose_folder "${LegacyComposeFolder}"
149+
run_script 'config_set' paths.compose_folder "${LegacyComposeFolder}"
180150
fi
181151
}
182152

0 commit comments

Comments
 (0)