Skip to content

Commit 65f894e

Browse files
committed
feat: Implement set-array
1 parent 55e4635 commit 65f894e

File tree

5 files changed

+134
-44
lines changed

5 files changed

+134
-44
lines changed

pkg/lib/traverse-set.sh

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ bash_object.traverse-set() {
1111
local filter="$3"
1212
local final_value="$4"
1313

14+
# TODO: test this
15+
if bash_object.ensure.variable_does_exist "$final_value"; then :; else
16+
return
17+
fi
18+
1419
# Start traversing at the root object
1520
local current_object_name="$root_object_name"
1621
local -n current_object="$root_object_name"
@@ -52,45 +57,69 @@ bash_object.traverse-set() {
5257
# If we are at the last element in the query
5358
elif ((i+1 == ${#REPLIES[@]})); then
5459
if [ "$final_value_type" = object ]; then
55-
bash_object.util.generate_vobject_name
56-
local new_current_object_name="$REPLY"
60+
local oldIFS="$IFS"
61+
IFS='_'
62+
local filter_stack_string="${filter_stack[*]}"
63+
IFS="$oldIFS"
5764

58-
# TODO: double-check if new_current_object_name only has underscores, dots, etc. (printf %q?)
65+
bash_object.util.generate_vobject_name "$root_object_name" "$filter_stack_string"
66+
local global_object_name="$REPLY"
5967

60-
if ((BASH_VERSINFO[0] >= 5)) || ((BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 2)); then
61-
if [[ -v "$new_current_object_name" ]]; then
62-
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' "Autogenerated variable '$new_current_object_name' already exists. Did RANDOM or SRANDOM get unset?"
63-
return
64-
fi
65-
else
66-
if ! eval "
67-
if ! [ -z \${$new_current_object_name+x} ]; then
68-
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' \"Autogenerated variable '$new_current_object_name' already exists. Did RANDOM or SRANDOM get unset?\"
69-
return
70-
fi
71-
"; then
72-
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' 'Eval unset test'
73-
return
74-
fi
68+
if bash_object.ensure.variable_is_valid "$global_object_name"; then :; else
69+
return
7570
fi
7671

77-
if ! eval "declare -gA $new_current_object_name=()"; then
72+
if bash_object.ensure.variable_does_not_exist "$global_object_name"; then :; else
73+
return
74+
fi
75+
76+
if ! eval "declare -gA $global_object_name=()"; then
7877
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' 'Eval declare failed'
7978
return
8079
fi
8180

82-
local -n new_current_object="$new_current_object_name"
81+
current_object["$key"]=$'\x1C\x1D'"type=object;&$global_object_name"
82+
83+
local -n globel_object="$global_object_name"
84+
local -n object_to_copy_from="$final_value"
8385

84-
current_object["$key"]=$'\x1C\x1D'"type=object;&$new_current_object_name"
86+
# TODO: test if object_to_copy is of the correct type
8587

86-
local -n object_to_copy="$final_value"
87-
# test if the object_to_copy is of the right type
88-
for key in "${!object_to_copy[@]}"; do
89-
new_current_object["$key"]="${object_to_copy["$key"]}"
88+
for key in "${!object_to_copy_from[@]}"; do
89+
# shellcheck disable=SC2034
90+
globel_object["$key"]="${object_to_copy_from["$key"]}"
9091
done
9192
elif [ "$final_value_type" = array ]; then
92-
:
93-
# current_object["$key"]=("${new_array[@]}")
93+
local oldIFS="$IFS"
94+
IFS='_'
95+
local filter_stack_string="${filter_stack[*]}"
96+
IFS="$oldIFS"
97+
98+
bash_object.util.generate_vobject_name "$root_object_name" "$filter_stack_string"
99+
local global_array_name="$REPLY"
100+
101+
if bash_object.ensure.variable_is_valid "$global_array_name"; then :; else
102+
return
103+
fi
104+
105+
if bash_object.ensure.variable_does_not_exist "$global_array_name"; then :; else
106+
return
107+
fi
108+
109+
if ! eval "declare -ga $global_array_name=()"; then
110+
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' 'Eval declare failed'
111+
return
112+
fi
113+
114+
current_object["$key"]=$'\x1C\x1D'"type=array;&$global_array_name"
115+
116+
local -n global_array="$global_array_name"
117+
local -n array_to_copy_from="$final_value"
118+
119+
# TODO: test if object_to_copy is of the correct type
120+
121+
# shellcheck disable=SC2034
122+
global_array=("${array_to_copy_from[@]}")
94123
elif [ "$final_value_type" = string ]; then
95124
current_object["$key"]="$final_value"
96125
else

pkg/lib/util/ensure.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# shellcheck shell=bash
2+
3+
# TODO: double-check if new_current_object_name only has underscores, dots, etc. (printf %q?)
4+
bash_object.ensure.variable_is_valid() {
5+
return 0
6+
}
7+
8+
# TODO: swap with does_not
9+
bash_object.ensure.variable_does_exist() {
10+
if bash_object.ensure.variable_does_not_exist "$1"; then
11+
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' "Variable '$1' does not exist, but it should"
12+
return
13+
else
14+
:
15+
fi
16+
}
17+
18+
# @description Test if the variable already exists. Note that the variable _must_ be sanitized before using this function
19+
bash_object.ensure.variable_does_not_exist() {
20+
local variable_name="$1"
21+
22+
if [ -z "$variable_name" ]; then
23+
bash_object.util.die "ERROR_INTERNAL_MISCELLANEOUS" "Parameter to function 'bash_object.ensure.variable_does_not_exist' was empty"
24+
return
25+
fi
26+
27+
if ((BASH_VERSINFO[0] >= 5)) || ((BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 2)); then
28+
if [[ -v "$variable_name" ]]; then
29+
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' "Variable '$variable_name' exists, but it shouldn't"
30+
return
31+
fi
32+
else
33+
if ! eval "
34+
if ! [ -z \${$variable_name+x} ]; then
35+
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' \"Variable '$variable_name' exists, but it shouldn't\"
36+
return
37+
fi
38+
"; then
39+
bash_object.util.die 'ERROR_INTERNAL_MISCELLANEOUS' 'Eval unset test'
40+
return
41+
fi
42+
fi
43+
}

pkg/lib/util/util.sh

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,28 +40,31 @@ bash_object.util.die() {
4040
bash_object.util.generate_vobject_name() {
4141
unset REPLY
4242

43+
local root_object_name="$1"
44+
local root_object_query="$2"
45+
4346
local random_string=
4447
if ((BASH_VERSINFO[0] >= 6)) || ((BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 1)); then
4548
random_string="${SRANDOM}_${SRANDOM}_${SRANDOM}_${SRANDOM}_${SRANDOM}"
4649
else
4750
random_string="${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}_${RANDOM}"
4851
fi
4952

50-
REPLY="__bash_object_${root_object_name}_tree_${key}_${random_string}"
53+
REPLY="__bash_object_${root_object_name}_${root_object_query}_${random_string}"
5154
}
5255

5356
# TODO
5457
stdtrace.log() {
55-
local level="$1"
56-
local message="$2"
58+
local level="$1"
59+
local message="$2"
5760

58-
local padding=
59-
case "$level" in
60-
0) padding= ;;
61-
1) padding=" " ;;
62-
2) padding=" " ;;
63-
3) padding=" " ;;
64-
esac
61+
local padding=
62+
case "$level" in
63+
0) padding= ;;
64+
1) padding=" " ;;
65+
2) padding=" " ;;
66+
3) padding=" " ;;
67+
esac
6568

66-
printf '%s\n' "TRACE $level: $padding| $message" >&3
69+
printf '%s\n' "TRACE $level: $padding| $message" >&3
6770
}

tests/set-array.bats

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,24 @@
22

33
load './util/init.sh'
44

5-
# @test "correctly sets array" {
6-
# declare -a arr=(omicron pi rho)
7-
# declare -A OBJECT=()
5+
@test "correctly sets array" {
6+
declare -a arr=(omicron pi rho)
7+
declare -A OBJECT=()
88

9-
# bash_object.traverse-set array
10-
# }
9+
bash_object.traverse-set array 'OBJECT' '.arr' arr
10+
11+
bash_object.traverse-get array 'OBJECT' '.arr'
12+
assert [ ${#REPLY[@]} -eq 3 ]
13+
assert [ "${REPLY[0]}" = omicron ]
14+
assert [ "${REPLY[1]}" = pi ]
15+
assert [ "${REPLY[2]}" = rho ]
16+
17+
bash_object.traverse-get string 'OBJECT' '.["arr"].[0]'
18+
assert [ "$REPLY" = omicron ]
19+
20+
bash_object.traverse-get string 'OBJECT' '.["arr"].[1]'
21+
assert [ "$REPLY" = pi ]
22+
23+
bash_object.traverse-get string 'OBJECT' '.["arr"].[2]'
24+
assert [ "$REPLY" = rho ]
25+
}

tests/set.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ load './util/init.sh'
1212

1313
assert_failure
1414
assert_output -p 'ERROR_INTERNAL_MISCELLANEOUS'
15-
assert_output -p "Autogenerated variable 'some_other_var' already exists"
15+
assert_output -p "Variable 'some_other_var' exists, but it shouldn't"
1616
}

0 commit comments

Comments
 (0)