Skip to content

Commit 524682b

Browse files
committed
modules: Ensure plugin's modules precede parent's
Realized that if a plugin contains an internal or exported module that matches the same filename as an internal or exported module in the parent, that the code as it was would find the parent module first. The fix was straightforward: extract most operations into `_@go.find_module`. Touching up the "modules/use: prevent self, circular, and multiple importing" test case required a bit more care to touch-up, since the plugin module in the test could no longer access its parent's modules any longer.
1 parent 2068c96 commit 524682b

File tree

4 files changed

+59
-46
lines changed

4 files changed

+59
-46
lines changed

go-core.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ declare -r -x _GO_USE_MODULES="$_GO_CORE_DIR/lib/internal/use"
9393
declare _GO_IMPORTED_MODULES=()
9494

9595
# Tracks the locations of files corresponding to _GO_IMPORTED_MODULES
96-
# Used for to detect and warn about plugin module namespace collisions.
96+
# Used to detect and warn about plugin module namespace collisions.
9797
declare _GO_IMPORTED_MODULE_FILES=()
9898

9999
# Tracks where each module _GO_IMPORTED_MODULES was first imported

lib/internal/use

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,30 +86,30 @@ _@go.set_use_caller() {
8686
__go_use_caller="${BASH_SOURCE[2]}:${BASH_LINENO[1]} ${FUNCNAME[2]}"
8787
}
8888

89-
_@go.find_plugin_module_impl() {
89+
_@go.find_plugin_module() {
9090
[[ -f "$1/$__go_module_file" ]] && __go_module_file="$1/$__go_module_file"
9191
}
9292

93-
_@go.find_plugin_module() {
93+
_@go.find_module() {
9494
# If a script imports a plugin module, and that module (`__go_use_caller`)
9595
# tries to import another module from the same plugin, this block will adjust
9696
# the search parameters accordingly.
97-
if [[ "$__go_use_caller" =~ ^$_GO_PLUGINS_DIR/.*/lib/ ]]; then
97+
if [[ -n "$_GO_PLUGINS_DIR" &&
98+
"$__go_use_caller" =~ ^$_GO_PLUGINS_DIR/.*/lib/ ]]; then
9899
local _GO_SCRIPTS_DIR="${__go_use_caller%/lib/*}/bin"
100+
local _GO_ROOTDIR="${_GO_SCRIPTS_DIR%/bin}"
101+
fi
102+
__go_module_file="$_GO_SCRIPTS_DIR/lib/$__go_module_name"
99103

100-
__go_module_file="$_GO_SCRIPTS_DIR/lib/$__go_module_name"
101-
if [[ -f "$__go_module_file" ]]; then
102-
return
103-
fi
104-
__go_module_file="${__go_module_file%/bin/*}/lib/$__go_module_name"
105-
if [[ -f "$__go_module_file" ]]; then
106-
return
104+
if [[ ! -f "$__go_module_file" ]]; then
105+
__go_module_file="$_GO_ROOTDIR/lib/$__go_module_name"
106+
107+
if [[ ! -f "$__go_module_file" ]]; then
108+
# Convert <plugin>/<module> to plugins/<plugin>/lib/<module>
109+
__go_module_file="${__go_module_name/\///lib/}"
110+
@go.search_plugins '_@go.find_plugin_module'
107111
fi
108112
fi
109-
110-
# Convert <plugin>/<module> to plugins/<plugin>/lib/<module>
111-
__go_module_file="${__go_module_name/\///lib/}"
112-
@go.search_plugins '_@go.find_plugin_module_impl'
113113
}
114114

115115
for __go_module_name in "$@"; do
@@ -125,18 +125,10 @@ for __go_module_name in "$@"; do
125125
fi
126126
fi
127127

128-
if [[ ! -f "$__go_module_file" ]]; then
129-
__go_module_file="$_GO_SCRIPTS_DIR/lib/$__go_module_name"
130-
131-
if [[ ! -f "$__go_module_file" ]]; then
132-
__go_module_file="$_GO_ROOTDIR/lib/$__go_module_name"
133-
134-
if [[ ! -f "$__go_module_file" ]] && ! _@go.find_plugin_module; then
135-
@go.printf 'ERROR: Module %s not found at:\n' "$__go_module_name" >&2
136-
@go.print_stack_trace 1 >&2
137-
exit 1
138-
fi
139-
fi
128+
if [[ ! -f "$__go_module_file" ]] && ! _@go.find_module; then
129+
@go.printf 'ERROR: Module %s not found at:\n' "$__go_module_name" >&2
130+
@go.print_stack_trace 1 >&2
131+
exit 1
140132
fi
141133

142134
# If we found the module in our project, but we're installed as a plugin,

tests/modules/use.bats

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -114,33 +114,42 @@ teardown() {
114114
@test "$SUITE: prevent self, circular, and multiple importing" {
115115
local module
116116

117-
for module in "${TEST_MODULES[@]}"; do
118-
echo ". \"\$_GO_USE_MODULES\" ${IMPORTS[@]}" >> "$module"
119-
done
120-
121-
run "$TEST_GO_SCRIPT" "${IMPORTS[@]}"
117+
# We have to be careful because the plugin module can only access itself and
118+
# the builtin module.
119+
printf '. "$_GO_USE_MODULES" %s' \
120+
"internal-test export-test test-plugin/plugin-test" \
121+
>>"$INTERNAL_MODULE_FILE"
122+
printf '. "$_GO_USE_MODULES" %s' \
123+
"internal-test export-test test-plugin/plugin-test" \
124+
>>"$EXPORT_MODULE_FILE"
125+
printf '. "$_GO_USE_MODULES" %s' \
126+
"test-plugin/plugin-test builtin-test" \
127+
>>"$PLUGIN_MODULE_FILE"
128+
printf '. "$_GO_USE_MODULES" %s' \
129+
"builtin-test" \
130+
>>"$BUILTIN_MODULE_FILE"
131+
132+
run "$TEST_GO_SCRIPT" 'internal-test' 'export-test' 'builtin-test' \
133+
'test-plugin/plugin-test'
122134
assert_success
123135

124-
# Note the change in `caller:` values. Basically, each module is loaded by the
125-
# module loaded immediately before it. Only the first one is loaded by the
126-
# `TEST_GO_SCRIPT`.
127136
assert_lines_equal \
128-
'plugin-test loaded' \
129137
'internal-test loaded' \
130-
'builtin-test loaded' \
131138
'export-test loaded' \
132-
'module: test-plugin/plugin-test' \
133-
"source: $PLUGIN_MODULE_FILE" \
134-
"caller: $CALLER" \
139+
'plugin-test loaded' \
140+
'builtin-test loaded' \
135141
'module: internal-test' \
136142
"source: $INTERNAL_MODULE_FILE" \
137-
"caller: $PLUGIN_MODULE_FILE:2 source" \
138-
'module: builtin-test' \
139-
"source: $BUILTIN_MODULE_FILE" \
140-
"caller: $INTERNAL_MODULE_FILE:2 source" \
143+
"caller: $CALLER" \
141144
'module: export-test' \
142145
"source: $EXPORT_MODULE_FILE" \
143-
"caller: $BUILTIN_MODULE_FILE:2 source"
146+
"caller: $INTERNAL_MODULE_FILE:2 source" \
147+
'module: test-plugin/plugin-test' \
148+
"source: $PLUGIN_MODULE_FILE" \
149+
"caller: $EXPORT_MODULE_FILE:2 source" \
150+
'module: builtin-test' \
151+
"source: $BUILTIN_MODULE_FILE" \
152+
"caller: $PLUGIN_MODULE_FILE:2 source"
144153
}
145154

146155
@test "$SUITE: error if module contains errors" {

tests/modules/use/plugins.bats

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ teardown() {
6666
assert_success "$TEST_GO_PLUGINS_DIR/$module_path" 'bar/bar' 'bar/bar-2'
6767
}
6868

69-
7069
@test "$SUITE: nested plugin imports own exported module" {
7170
local module_path='foo/bin/plugins/bar/lib/bar-2'
7271
@go.create_test_command_script 'plugins/foo/bin/foo' \
@@ -91,6 +90,19 @@ teardown() {
9190
assert_success "$TEST_GO_PLUGINS_DIR/$module_path" 'bar/bar' 'baz/baz'
9291
}
9392

93+
@test "$SUITE: nested plugin imports own module instead of parent module" {
94+
local module_path='foo/bin/plugins/bar/lib/bar-2'
95+
@go.create_test_command_script 'plugins/foo/bin/foo' \
96+
'. "$_GO_USE_MODULES" bar/bar'
97+
@go.create_test_command_script 'plugins/foo/bin/plugins/bar/lib/bar' \
98+
'. "$_GO_USE_MODULES" bar-2'
99+
@go.create_test_command_script "plugins/foo/lib/bar-2" "$PRINT_SOURCE"
100+
@go.create_test_command_script "plugins/$module_path" "$PRINT_SOURCE"
101+
102+
run "$TEST_GO_SCRIPT" 'foo'
103+
assert_success "$TEST_GO_PLUGINS_DIR/$module_path" 'bar/bar' 'bar/bar-2'
104+
}
105+
94106
@test "$SUITE: nested plugin imports module from parent plugin" {
95107
local module_path='foo/lib/foo'
96108
@go.create_test_command_script 'plugins/foo/bin/foo' \

0 commit comments

Comments
 (0)