Invalidate units when loaded sources change
This commit is contained in:
parent
d857930ceb
commit
02ed75fc85
@ -48,4 +48,7 @@ if [[ ! -S "$socket_path" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
url="http://localhost/tests/cli_runner.uce?action=${action}&include_kill=${include_kill}&skip_local_service_pages=${skip_local_service_pages}"
|
url="http://localhost/tests/cli_runner.uce?action=${action}&include_kill=${include_kill}&skip_local_service_pages=${skip_local_service_pages}"
|
||||||
exec curl -sS --fail-with-body --unix-socket "$socket_path" "$url"
|
curl -sS --fail-with-body --unix-socket "$socket_path" "$url"
|
||||||
|
if [[ "$action" == "run" ]]; then
|
||||||
|
scripts/test_dependency_invalidation.sh
|
||||||
|
fi
|
||||||
|
|||||||
38
scripts/test_dependency_invalidation.sh
Executable file
38
scripts/test_dependency_invalidation.sh
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
test_name="dependency-cache-test-$$"
|
||||||
|
source_dir="site/$test_name"
|
||||||
|
cache_dir="${BIN_DIRECTORY:-/tmp/uce/work}$(pwd)/$source_dir"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "$source_dir" "$cache_dir"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
mkdir -p "$source_dir"
|
||||||
|
|
||||||
|
printf '%s\n' \
|
||||||
|
'#ifndef UCE_DEPENDENCY_CACHE_CHILD' \
|
||||||
|
'#define UCE_DEPENDENCY_CACHE_CHILD' \
|
||||||
|
'String dependency_cache_marker() { return("dependency-marker-a"); }' \
|
||||||
|
'#endif' >"$source_dir/child.uce"
|
||||||
|
printf '%s\n' \
|
||||||
|
'#load "child.uce"' \
|
||||||
|
'CLI(Request& context) { print(dependency_cache_marker()); }' \
|
||||||
|
'RENDER(Request& context) { print(dependency_cache_marker()); }' >"$source_dir/parent.uce"
|
||||||
|
|
||||||
|
first=$(scripts/uce-cli "/$test_name/parent.uce")
|
||||||
|
if [[ "$first" != *dependency-marker-a* ]]; then
|
||||||
|
echo "dependency invalidation setup failed: $first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i 's/dependency-marker-a/dependency-marker-b/' "$source_dir/child.uce"
|
||||||
|
second=$(scripts/uce-cli "/$test_name/parent.uce")
|
||||||
|
if [[ "$second" != *dependency-marker-b* ]]; then
|
||||||
|
echo "loaded dependency change did not recompile parent: $second" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "dependency invalidation passed"
|
||||||
@ -12,6 +12,8 @@ Includes another UCE file.
|
|||||||
|
|
||||||
Use `#load` when you want the current file to pull in declarations or reusable content from another UCE source file.
|
Use `#load` when you want the current file to pull in declarations or reusable content from another UCE source file.
|
||||||
|
|
||||||
|
Loaded sources are tracked transitively. Changing a direct or nested `#load` dependency invalidates and recompiles the entry unit before its next execution.
|
||||||
|
|
||||||
|
|
||||||
:example
|
:example
|
||||||
// #load "file.uce" includes another unit at COMPILE time (a preprocessor directive,
|
// #load "file.uce" includes another unit at COMPILE time (a preprocessor directive,
|
||||||
|
|||||||
@ -87,6 +87,55 @@ StringMap compiler_parse_unit_metadata(String content)
|
|||||||
return(metadata);
|
return(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringList compiler_unit_load_paths(String file_name, String content)
|
||||||
|
{
|
||||||
|
StringList paths;
|
||||||
|
u64 line_start = 0;
|
||||||
|
while(line_start < content.length())
|
||||||
|
{
|
||||||
|
u64 line_end = content.find("\n", line_start);
|
||||||
|
if(line_end == String::npos)
|
||||||
|
break;
|
||||||
|
String line = content.substr(line_start, line_end - line_start);
|
||||||
|
if(str_starts_with(line, "#load "))
|
||||||
|
{
|
||||||
|
u64 first_quote = line.find('"', 6);
|
||||||
|
u64 second_quote = first_quote == String::npos ? String::npos : line.find('"', first_quote + 1);
|
||||||
|
if(first_quote != String::npos && second_quote != String::npos)
|
||||||
|
{
|
||||||
|
String loaded = line.substr(first_quote + 1, second_quote - first_quote - 1);
|
||||||
|
if(loaded != "")
|
||||||
|
paths.push_back(loaded[0] == '/' ? loaded : expand_path(loaded, dirname(file_name)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line_start = line_end + 1;
|
||||||
|
}
|
||||||
|
return(paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void compiler_append_unit_source_signature(String file_name, std::set<String>& visited, String& signature)
|
||||||
|
{
|
||||||
|
String normalized = path_real(file_name);
|
||||||
|
if(normalized == "")
|
||||||
|
normalized = file_name;
|
||||||
|
if(visited.find(normalized) != visited.end())
|
||||||
|
return;
|
||||||
|
visited.insert(normalized);
|
||||||
|
|
||||||
|
String content = file_get_contents(file_name);
|
||||||
|
signature += normalized + ":" + gen_sha1(content) + "\n";
|
||||||
|
for(String loaded : compiler_unit_load_paths(file_name, content))
|
||||||
|
compiler_append_unit_source_signature(loaded, visited, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
String compiler_unit_source_signature(String file_name)
|
||||||
|
{
|
||||||
|
std::set<String> visited;
|
||||||
|
String signature = "uce-load-graph-v1\n";
|
||||||
|
compiler_append_unit_source_signature(file_name, visited, signature);
|
||||||
|
return(gen_sha1(signature));
|
||||||
|
}
|
||||||
|
|
||||||
String compiler_unit_input_signature(Request* context, SharedUnit* su)
|
String compiler_unit_input_signature(Request* context, SharedUnit* su)
|
||||||
{
|
{
|
||||||
if(!context || !su || !file_exists(su->file_name))
|
if(!context || !su || !file_exists(su->file_name))
|
||||||
@ -94,7 +143,7 @@ String compiler_unit_input_signature(Request* context, SharedUnit* su)
|
|||||||
|
|
||||||
String setup_template = context->server->config["COMPILER_SYS_PATH"] + "/" + context->server->config["SETUP_TEMPLATE"];
|
String setup_template = context->server->config["COMPILER_SYS_PATH"] + "/" + context->server->config["SETUP_TEMPLATE"];
|
||||||
return(
|
return(
|
||||||
gen_sha1(file_get_contents(su->file_name)) + ":" +
|
compiler_unit_source_signature(su->file_name) + ":" +
|
||||||
gen_sha1(file_get_contents(setup_template)) + ":" +
|
gen_sha1(file_get_contents(setup_template)) + ":" +
|
||||||
std::to_string(UCE_UNIT_ABI_VERSION)
|
std::to_string(UCE_UNIT_ABI_VERSION)
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user