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
|
||||
|
||||
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.
|
||||
|
||||
Loaded sources are tracked transitively. Changing a direct or nested `#load` dependency invalidates and recompiles the entry unit before its next execution.
|
||||
|
||||
|
||||
:example
|
||||
// #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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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"];
|
||||
return(
|
||||
gen_sha1(file_get_contents(su->file_name)) + ":" +
|
||||
compiler_unit_source_signature(su->file_name) + ":" +
|
||||
gen_sha1(file_get_contents(setup_template)) + ":" +
|
||||
std::to_string(UCE_UNIT_ABI_VERSION)
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user