better error print

This commit is contained in:
2026-02-20 19:14:45 -06:00
parent 0e86d6f5a1
commit bb8536f6c9
2 changed files with 126 additions and 3 deletions

View File

@@ -37,6 +37,7 @@ var total_ok = 0
var total_errors = 0
var total_scripts = 0
var all_failures = []
var all_unresolved = []
if (target_package) {
packages = [target_package]
@@ -57,6 +58,12 @@ arrfor(packages, function(p) {
arrfor(result.errors, function(e) {
push(all_failures, p + ": " + e)
})
// Check use() resolution
var resolution = shop.audit_use_resolution(p)
arrfor(resolution.unresolved, function(u) {
push(all_unresolved, p + '/' + u.script + ": use('" + u.module + "') cannot be resolved")
})
})
log.console("")
@@ -68,7 +75,18 @@ if (length(all_failures) > 0) {
log.console("")
}
log.console("Audit complete: " + text(total_ok) + "/" + text(total_scripts) + " scripts compiled" + (total_errors > 0 ? ", " + text(total_errors) + " failed" : ""))
if (length(all_unresolved) > 0) {
log.console("Unresolved modules:")
arrfor(all_unresolved, function(u) {
log.console(" " + u)
})
log.console("")
}
var summary = "Audit complete: " + text(total_ok) + "/" + text(total_scripts) + " scripts compiled"
if (total_errors > 0) summary = summary + ", " + text(total_errors) + " failed"
if (length(all_unresolved) > 0) summary = summary + ", " + text(length(all_unresolved)) + " unresolved use() calls"
log.console(summary)
}
run()

View File

@@ -48,6 +48,9 @@ function hash_path(content, salt)
var Shop = {}
// Stack tracking the chain of use() calls for error reporting
var use_stack = []
var SCOPE_LOCAL = 0
var SCOPE_PACKAGE = 1
var SCOPE_CORE = 2
@@ -1301,6 +1304,8 @@ Shop.use = function use(path, package_context) {
var info = resolve_module_info(path, package_context)
var _ctx_dir2 = null
var _alias2 = null
var _use_entry = path + ' (package: ' + package_context + ')'
var _chain = null
if (!info) {
log.shop(`Module '${path}' could not be found in package '${package_context}'`)
_ctx_dir2 = package_context ? (starts_with(package_context, '/') ? package_context : get_packages_dir() + '/' + fd.safe_package_path(package_context)) : null
@@ -1311,13 +1316,32 @@ Shop.use = function use(path, package_context) {
_alias2 = pkg_tools.split_alias(package_context, path)
if (_alias2 == null && search(path, '/') != null)
log.shop(`Alias '${array(path, '/')[0]}' could not be resolved in package '${package_context}'`)
if (length(use_stack) > 0) {
_chain = 'use() chain:'
arrfor(use_stack, function(frame) { _chain = _chain + '\n -> ' + frame })
_chain = _chain + '\n -> ' + path + ' [NOT FOUND]'
log.error(_chain)
}
disrupt
}
if (use_cache[info.cache_key])
return use_cache[info.cache_key]
use_cache[info.cache_key] = execute_module(info)
return use_cache[info.cache_key]
push(use_stack, _use_entry)
var _use_result = null
var _use_ok = false
var _load = function() {
_use_result = execute_module(info)
_use_ok = true
} disruption {
pop(use_stack)
disrupt
}
_load()
pop(use_stack)
use_cache[info.cache_key] = _use_result
return _use_result
}
// Resolve a use() module path to a filesystem path without compiling.
@@ -1856,6 +1880,30 @@ function get_package_scripts(package)
return scripts
}
// Extract use() call arguments from source text.
// Returns an array of literal string arguments found in use('...') calls.
function extract_use_calls(source) {
var uses = []
var idx = 0
var start = 0
var end = 0
var arg = null
idx = search(source, "use(")
while (idx != null) {
start = idx + 5
end = search(text(source, start), "'")
if (end == null) end = search(text(source, start), '"')
if (end != null) {
arg = text(source, start, start + end)
push(uses, arg)
}
idx = search(text(source, idx + 4), "use(")
if (idx != null) idx = idx + (source.length - (source.length - idx))
else break
}
return uses
}
Shop.build_package_scripts = function(package)
{
// compiles all .ce and .cm files in a package
@@ -1879,6 +1927,63 @@ Shop.build_package_scripts = function(package)
return {ok: ok, errors: errors, total: length(scripts)}
}
// Check if all use() calls in a package's scripts can be resolved.
// Returns {ok, unresolved: [{script, module}], total}
Shop.audit_use_resolution = function(package) {
var scripts = get_package_scripts(package)
var pkg_dir = starts_with(package, '/') ? package : get_package_abs_dir(package)
var unresolved = []
var checked = 0
var src = null
var content = null
var uses = null
var info = null
arrfor(scripts, function(script) {
var _check = function() {
src = pkg_dir + '/' + script
if (!fd.is_file(src)) return
content = text(fd.slurp(src))
if (!content || length(content) == 0) return
// Simple regex-free extraction: find use(' and use(" patterns
uses = []
var pos = 0
var rest = content
var ui = null
var quote = null
var end = null
var arg = null
while (length(rest) > 0) {
ui = search(rest, "use(")
if (ui == null) break
rest = text(rest, ui + 4)
if (length(rest) == 0) break
quote = text(rest, 0, 1)
if (quote != "'" && quote != '"') continue
rest = text(rest, 1)
end = search(rest, quote)
if (end == null) continue
arg = text(rest, 0, end)
if (length(arg) > 0) push(uses, arg)
rest = text(rest, end + 1)
}
arrfor(uses, function(mod) {
var _resolve = function() {
info = resolve_module_info(mod, package)
if (!info) push(unresolved, {script: script, module: mod})
} disruption {}
_resolve()
})
checked = checked + 1
} disruption {}
_check()
})
return {ok: checked, unresolved: unresolved, total: length(scripts)}
}
Shop.get_package_scripts = get_package_scripts
Shop.list_packages = function()