[fix] ynh_read_var_in_file with endline

This commit is contained in:
ljf 2021-09-05 16:08:23 +02:00
parent 4c9fcdc9e4
commit 1207b54de6
2 changed files with 77 additions and 38 deletions

View file

@ -507,6 +507,7 @@ ynh_replace_vars () {
# #
# Requires YunoHost version 4.3 or higher. # Requires YunoHost version 4.3 or higher.
ynh_read_var_in_file() { ynh_read_var_in_file() {
set +o xtrace
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=fk local legacy_args=fk
local -A args_array=( [f]=file= [k]=key= ) local -A args_array=( [f]=file= [k]=key= )
@ -514,18 +515,43 @@ ynh_read_var_in_file() {
local key local key
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
set +o xtrace
local filename="$(basename -- "$file")"
local ext="${filename##*.}"
local endline=',;'
local assign="=>|:|="
local comments="#"
local string="\"'"
if [[ "yaml yml toml ini env" =~ *"$ext"* ]]; then
endline='#'
fi
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
comments="//"
fi
local list='\[\s*['$string']?\w+['$string']?\]'
local var_part='^\s*(?:(const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
var_part+="[$string]?${key}[$string]?"
var_part+='\s*\]?\s*'
var_part+="(?:$assign)"
var_part+='\s*'
local var_part='^[ \t]*\$?(\w*\[)?[ \t]*["'"']?${key}['"'"]?[ \t]*\]?[ \t]*[:=]>?[ \t]*' # Extract the part after assignation sign
local expression_with_comment="$(grep -i -o -P $var_part'\K.*$' ${file} || echo YNH_NULL | head -n1)"
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
echo YNH_NULL
return 0
fi
local crazy_value="$(grep -i -o -P '^[ \t]*\$?(\w*\[)?[ \t]*["'"']?${key}['"'"]?[ \t]*\]?[ \t]*[:=]>?[ \t]*\K.*(?=[ \t,\n;]*$)' ${file} || echo YNH_NULL | head -n1)" # Remove comments if needed
local expression="$(echo "$expression_with_comment" | sed "s@$comments[^$string]*\$@@" | sed "s@\s*[$endline]*\s*]*\$@@")"
local first_char="${crazy_value:0:1}" local first_char="${expression:0:1}"
if [[ "$first_char" == '"' ]] ; then if [[ "$first_char" == '"' ]] ; then
echo "$crazy_value" | grep -m1 -o -P '"\K([^"](\\")?)*[^\\](?=")' | head -n1 | sed 's/\\"/"/g' echo "$expression" | grep -m1 -o -P '"\K([^"](\\")?)*[^\\](?=")' | head -n1 | sed 's/\\"/"/g'
elif [[ "$first_char" == "'" ]] ; then elif [[ "$first_char" == "'" ]] ; then
echo "$crazy_value" | grep -m1 -o -P "'\K([^'](\\\\')?)*[^\\\\](?=')" | head -n1 | sed "s/\\\\'/'/g" echo "$expression" | grep -m1 -o -P "'\K([^'](\\\\')?)*[^\\\\](?=')" | head -n1 | sed "s/\\\\'/'/g"
else else
echo "$crazy_value" echo "$expression"
fi fi
} }
@ -538,6 +564,7 @@ ynh_read_var_in_file() {
# #
# Requires YunoHost version 4.3 or higher. # Requires YunoHost version 4.3 or higher.
ynh_write_var_in_file() { ynh_write_var_in_file() {
set +o xtrace
# Declare an array to define the options of this helper. # Declare an array to define the options of this helper.
local legacy_args=fkv local legacy_args=fkv
local -A args_array=( [f]=file= [k]=key= [v]=value=) local -A args_array=( [f]=file= [k]=key= [v]=value=)
@ -546,9 +573,10 @@ ynh_write_var_in_file() {
local value local value
# Manage arguments with getopts # Manage arguments with getopts
ynh_handle_getopts_args "$@" ynh_handle_getopts_args "$@"
local var_part='[ \t]*\$?(\w*\[)?[ \t]*["'"']?${key}['"'"]?[ \t]*\]?[ \t]*[:=]>?[ \t]*' set +o xtrace
local var_part='\s*\$?([\w.]*\[)?\s*["'"']?${key}['"'"]?\s*\]?\s*[:=]>?\s*'
local crazy_value="$(grep -i -o -P '^[ \t]*\$?(\w*\[)?[ \t]*["'"']?${key}['"'"]?[ \t]*\]?[ \t]*[:=]>?[ \t]*\K.*(?=[ \t,\n;]*$)' ${file} | head -n1)" local crazy_value="$(grep -i -o -P '^\s*\$?([\w.]*\[)?\s*["'"']?${key}['"'"]?\s*\]?\s*[:=]>?\s*\K.*(?=[\s,;]*$)' ${file} | head -n1)"
# local crazy_value="$(grep -i -o -P "^${var_part}\K.*(?=[ \t,\n;]*\$)" ${file} | head -n1)" # local crazy_value="$(grep -i -o -P "^${var_part}\K.*(?=[ \t,\n;]*\$)" ${file} | head -n1)"
local first_char="${crazy_value:0:1}" local first_char="${crazy_value:0:1}"
delimiter=$'\001' delimiter=$'\001'
@ -556,13 +584,13 @@ ynh_write_var_in_file() {
# \ and sed is quite complex you need 2 \\ to get one in a sed # \ and sed is quite complex you need 2 \\ to get one in a sed
# So we need \\\\ to go through 2 sed # So we need \\\\ to go through 2 sed
value="$(echo "$value" | sed 's/"/\\\\"/g')" value="$(echo "$value" | sed 's/"/\\\\"/g')"
sed -ri s$delimiter'^('"${var_part}"'")([^"]|\\")*("[ \t;,]*)$'$delimiter'\1'"${value}"'\4'$delimiter'i' ${file} sed -ri s$delimiter'^('"${var_part}"'")([^"]|\\")*("[\s;,]*)$'$delimiter'\1'"${value}"'\4'$delimiter'i' ${file}
elif [[ "$first_char" == "'" ]] ; then elif [[ "$first_char" == "'" ]] ; then
# \ and sed is quite complex you need 2 \\ to get one in a sed # \ and sed is quite complex you need 2 \\ to get one in a sed
# However double quotes implies to double \\ to # However double quotes implies to double \\ to
# So we need \\\\\\\\ to go through 2 sed and 1 double quotes str # So we need \\\\\\\\ to go through 2 sed and 1 double quotes str
value="$(echo "$value" | sed "s/'/\\\\\\\\'/g")" value="$(echo "$value" | sed "s/'/\\\\\\\\'/g")"
sed -ri "s$delimiter^(${var_part}')([^']|\\')*('"'[ \t,;]*)$'$delimiter'\1'"${value}"'\4'$delimiter'i' ${file} sed -ri "s$delimiter^(${var_part}')([^']|\\')*('"'[\s,;]*)$'$delimiter'\1'"${value}"'\4'$delimiter'i' ${file}
else else
if [[ "$value" == *"'"* ]] || [[ "$value" == *'"'* ]] ; then if [[ "$value" == *"'"* ]] || [[ "$value" == *'"'* ]] ; then
value='\"'"$(echo "$value" | sed 's/"/\\\\"/g')"'\"' value='\"'"$(echo "$value" | sed 's/"/\\\\"/g')"'\"'

View file

@ -27,11 +27,13 @@ ENABLED = False
# TITLE = "Old title" # TITLE = "Old title"
TITLE = "Lorem Ipsum" TITLE = "Lorem Ipsum"
THEME = "colib'ris" THEME = "colib'ris"
EMAIL = "root@example.com" EMAIL = "root@example.com" # This is a comment without quotes
PORT = 1234 PORT = 1234 # This is a comment without quotes
URL = 'https://yunohost.org' URL = 'https://yunohost.org'
DICT = {} DICT = {}
DICT['ldap_base'] = "ou=users,dc=yunohost,dc=org" DICT['ldap_base'] = "ou=users,dc=yunohost,dc=org"
DICT['ldap_conf'] = {}
DICT['ldap_conf']['user'] = "camille"
EOF EOF
test "$(_read_py "$file" "FOO")" == "None" test "$(_read_py "$file" "FOO")" == "None"
@ -56,6 +58,8 @@ EOF
test "$(ynh_read_var_in_file "$file" "URL")" == "https://yunohost.org" test "$(ynh_read_var_in_file "$file" "URL")" == "https://yunohost.org"
test "$(ynh_read_var_in_file "$file" "ldap_base")" == "ou=users,dc=yunohost,dc=org" test "$(ynh_read_var_in_file "$file" "ldap_base")" == "ou=users,dc=yunohost,dc=org"
test "$(ynh_read_var_in_file "$file" "user")" == "camille"
! _read_py "$file" "NONEXISTENT" ! _read_py "$file" "NONEXISTENT"
test "$(ynh_read_var_in_file "$file" "NONEXISTENT")" == "YNH_NULL" test "$(ynh_read_var_in_file "$file" "NONEXISTENT")" == "YNH_NULL"
@ -64,7 +68,7 @@ EOF
test "$(ynh_read_var_in_file "$file" "ENABLE")" == "YNH_NULL" test "$(ynh_read_var_in_file "$file" "ENABLE")" == "YNH_NULL"
} }
ynhtest_config_write_py() { nhtest_config_write_py() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.py" file="$dummy_dir/dummy.py"
@ -75,8 +79,8 @@ ENABLED = False
# TITLE = "Old title" # TITLE = "Old title"
TITLE = "Lorem Ipsum" TITLE = "Lorem Ipsum"
THEME = "colib'ris" THEME = "colib'ris"
EMAIL = "root@example.com" EMAIL = "root@example.com" // This is a comment without quotes
PORT = 1234 PORT = 1234 // This is a comment without quotes
URL = 'https://yunohost.org' URL = 'https://yunohost.org'
DICT = {} DICT = {}
DICT['ldap_base'] = "ou=users,dc=yunohost,dc=org" DICT['ldap_base'] = "ou=users,dc=yunohost,dc=org"
@ -141,7 +145,7 @@ _read_ini() {
ynhtest_config_read_ini() { ynhtest_config_read_ini() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.yml" file="$dummy_dir/dummy.ini"
cat << EOF > $file cat << EOF > $file
# Some comment # Some comment
@ -152,8 +156,8 @@ enabled = False
# title = Old title # title = Old title
title = Lorem Ipsum title = Lorem Ipsum
theme = colib'ris theme = colib'ris
email = root@example.com email = root@example.com # This is a comment without quotes
port = 1234 port = 1234 # This is a comment without quotes
url = https://yunohost.org url = https://yunohost.org
[dict] [dict]
ldap_base = ou=users,dc=yunohost,dc=org ldap_base = ou=users,dc=yunohost,dc=org
@ -190,7 +194,7 @@ EOF
} }
ynhtest_config_write_ini() { nhtest_config_write_ini() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.ini" file="$dummy_dir/dummy.ini"
@ -203,8 +207,8 @@ enabled = False
# title = Old title # title = Old title
title = Lorem Ipsum title = Lorem Ipsum
theme = colib'ris theme = colib'ris
email = root@example.com email = root@example.com # This is a comment without quotes
port = 1234 port = 1234 # This is a comment without quotes
url = https://yunohost.org url = https://yunohost.org
[dict] [dict]
ldap_base = ou=users,dc=yunohost,dc=org ldap_base = ou=users,dc=yunohost,dc=org
@ -280,8 +284,8 @@ enabled: false
# title: old title # title: old title
title: Lorem Ipsum title: Lorem Ipsum
theme: colib'ris theme: colib'ris
email: root@example.com email: root@example.com # This is a comment without quotes
port: 1234 port: 1234 # This is a comment without quotes
url: https://yunohost.org url: https://yunohost.org
dict: dict:
ldap_base: ou=users,dc=yunohost,dc=org ldap_base: ou=users,dc=yunohost,dc=org
@ -318,7 +322,7 @@ EOF
} }
ynhtest_config_write_yaml() { nhtest_config_write_yaml() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.yml" file="$dummy_dir/dummy.yml"
@ -329,8 +333,8 @@ enabled: false
# title: old title # title: old title
title: Lorem Ipsum title: Lorem Ipsum
theme: colib'ris theme: colib'ris
email: root@example.com email: root@example.com # This is a comment without quotes
port: 1234 port: 1234 # This is a comment without quotes
url: https://yunohost.org url: https://yunohost.org
dict: dict:
ldap_base: ou=users,dc=yunohost,dc=org ldap_base: ou=users,dc=yunohost,dc=org
@ -415,10 +419,10 @@ EOF
test "$(_read_json "$file" "foo")" == "None" test "$(_read_json "$file" "foo")" == "None"
test "$(ynh_read_var_in_file "$file" "foo")" == "null," # FIXME FIXME FIXME trailing , test "$(ynh_read_var_in_file "$file" "foo")" == "null"
test "$(_read_json "$file" "enabled")" == "False" test "$(_read_json "$file" "enabled")" == "False"
test "$(ynh_read_var_in_file "$file" "enabled")" == "false," # FIXME FIXME FIXME trailing , test "$(ynh_read_var_in_file "$file" "enabled")" == "false"
test "$(_read_json "$file" "title")" == "Lorem Ipsum" test "$(_read_json "$file" "title")" == "Lorem Ipsum"
test "$(ynh_read_var_in_file "$file" "title")" == "Lorem Ipsum" test "$(ynh_read_var_in_file "$file" "title")" == "Lorem Ipsum"
@ -430,7 +434,7 @@ EOF
test "$(ynh_read_var_in_file "$file" "email")" == "root@example.com" test "$(ynh_read_var_in_file "$file" "email")" == "root@example.com"
test "$(_read_json "$file" "port")" == "1234" test "$(_read_json "$file" "port")" == "1234"
test "$(ynh_read_var_in_file "$file" "port")" == "1234," # FIXME FIXME FIXME trailing , test "$(ynh_read_var_in_file "$file" "port")" == "1234"
test "$(_read_json "$file" "url")" == "https://yunohost.org" test "$(_read_json "$file" "url")" == "https://yunohost.org"
test "$(ynh_read_var_in_file "$file" "url")" == "https://yunohost.org" test "$(ynh_read_var_in_file "$file" "url")" == "https://yunohost.org"
@ -445,7 +449,7 @@ EOF
} }
ynhtest_config_write_json() { nhtest_config_write_json() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.json" file="$dummy_dir/dummy.json"
@ -538,20 +542,23 @@ ynhtest_config_read_php() {
// \$title = "old title"; // \$title = "old title";
\$title = "Lorem Ipsum"; \$title = "Lorem Ipsum";
\$theme = "colib'ris"; \$theme = "colib'ris";
\$email = "root@example.com"; \$email = "root@example.com"; // This is a comment without quotes
\$port = 1234; \$port = 1234; // This is a second comment without quotes
\$url = "https://yunohost.org"; \$url = "https://yunohost.org";
\$dict = [ \$dict = [
'ldap_base' => "ou=users,dc=yunohost,dc=org", 'ldap_base' => "ou=users,dc=yunohost,dc=org",
'ldap_conf' => []
]; ];
\$dict['ldap_conf']['user'] = 'camille';
const DB_HOST = 'localhost';
?> ?>
EOF EOF
test "$(_read_php "$file" "foo")" == "NULL" test "$(_read_php "$file" "foo")" == "NULL"
test "$(ynh_read_var_in_file "$file" "foo")" == "NULL;" # FIXME FIXME FIXME trailing ; test "$(ynh_read_var_in_file "$file" "foo")" == "NULL"
test "$(_read_php "$file" "enabled")" == "false" test "$(_read_php "$file" "enabled")" == "false"
test "$(ynh_read_var_in_file "$file" "enabled")" == "false;" # FIXME FIXME FIXME trailing ; test "$(ynh_read_var_in_file "$file" "enabled")" == "false"
test "$(_read_php "$file" "title")" == "Lorem Ipsum" test "$(_read_php "$file" "title")" == "Lorem Ipsum"
test "$(ynh_read_var_in_file "$file" "title")" == "Lorem Ipsum" test "$(ynh_read_var_in_file "$file" "title")" == "Lorem Ipsum"
@ -563,12 +570,16 @@ EOF
test "$(ynh_read_var_in_file "$file" "email")" == "root@example.com" test "$(ynh_read_var_in_file "$file" "email")" == "root@example.com"
test "$(_read_php "$file" "port")" == "1234" test "$(_read_php "$file" "port")" == "1234"
test "$(ynh_read_var_in_file "$file" "port")" == "1234;" # FIXME FIXME FIXME trailing ; test "$(ynh_read_var_in_file "$file" "port")" == "1234"
test "$(_read_php "$file" "url")" == "https://yunohost.org" test "$(_read_php "$file" "url")" == "https://yunohost.org"
test "$(ynh_read_var_in_file "$file" "url")" == "https://yunohost.org" test "$(ynh_read_var_in_file "$file" "url")" == "https://yunohost.org"
test "$(ynh_read_var_in_file "$file" "ldap_base")" == "ou=users,dc=yunohost,dc=org" test "$(ynh_read_var_in_file "$file" "ldap_base")" == "ou=users,dc=yunohost,dc=org"
test "$(ynh_read_var_in_file "$file" "user")" == "camille"
test "$(ynh_read_var_in_file "$file" "DB_HOST")" == "localhost"
! _read_php "$file" "nonexistent" ! _read_php "$file" "nonexistent"
test "$(ynh_read_var_in_file "$file" "nonexistent")" == "YNH_NULL" test "$(ynh_read_var_in_file "$file" "nonexistent")" == "YNH_NULL"
@ -578,7 +589,7 @@ EOF
} }
ynhtest_config_write_php() { nhtest_config_write_php() {
local dummy_dir="$(mktemp -d -p $VAR_WWW)" local dummy_dir="$(mktemp -d -p $VAR_WWW)"
file="$dummy_dir/dummy.php" file="$dummy_dir/dummy.php"
@ -590,8 +601,8 @@ ynhtest_config_write_php() {
// \$title = "old title"; // \$title = "old title";
\$title = "Lorem Ipsum"; \$title = "Lorem Ipsum";
\$theme = "colib'ris"; \$theme = "colib'ris";
\$email = "root@example.com"; \$email = "root@example.com"; // This is a comment without quotes
\$port = 1234; \$port = 1234; // This is a comment without quotes
\$url = "https://yunohost.org"; \$url = "https://yunohost.org";
\$dict = [ \$dict = [
'ldap_base' => "ou=users,dc=yunohost,dc=org", 'ldap_base' => "ou=users,dc=yunohost,dc=org",