better path resolution

This commit is contained in:
2026-02-20 13:39:26 -06:00
parent 54e5be0773
commit f0c2486a5c
8 changed files with 188 additions and 78 deletions

View File

@@ -778,6 +778,11 @@ function resolve_path(path, ctx)
var ctx_path = null
var alias = null
var package_path = null
var lock = null
var best_pkg = null
var best_remainder = null
var shop_dir = null
var shop_file = null
if (explicit) {
if (is_internal_path(explicit.path) && ctx && explicit.package != ctx)
@@ -823,6 +828,25 @@ function resolve_path(path, ctx)
if (fd.is_file(package_path))
return {path: package_path, scope: SCOPE_PACKAGE, pkg: ctx}
// Shop package scanning: longest prefix match against lock.toml entries
lock = Shop.load_lock()
best_pkg = null
best_remainder = null
arrfor(array(lock), function(pkg_name) {
if (starts_with(path, pkg_name + '/')) {
if (!best_pkg || length(pkg_name) > length(best_pkg)) {
best_pkg = pkg_name
best_remainder = text(path, length(pkg_name) + 1)
}
}
})
if (best_pkg && best_remainder) {
shop_dir = get_packages_dir() + '/' + safe_package_path(best_pkg)
shop_file = shop_dir + '/' + best_remainder
if (fd.is_file(shop_file))
return {path: shop_file, scope: SCOPE_PACKAGE, pkg: best_pkg}
}
core_dir = Shop.get_core_dir()
core_file_path = core_dir + '/' + path
if (fd.is_file(core_file_path))
@@ -1298,6 +1322,64 @@ Shop.resolve_use_path = function(path, ctx) {
return info.path
}
// Resolve a program (.ce) path using the unified resolver.
// Returns {path, scope, pkg} or null.
// If the path looks like a remote package locator and is not found locally,
// attempts to auto-fetch and install it.
Shop.resolve_program = function(prog, package_context) {
var info = resolve_path(prog + '.ce', package_context)
if (info) return info
// Auto-install: if the path matches a recognized remote locator, try fetching
var lock = Shop.load_lock()
var best_pkg = null
var best_remainder = null
var pkg_info = null
var parts = array(prog, '/')
var i = 0
var candidate = null
var _auto = null
arrfor(array(lock), function(pkg_name) {
if (starts_with(prog, pkg_name + '/')) {
if (!best_pkg || length(pkg_name) > length(best_pkg)) {
best_pkg = pkg_name
best_remainder = text(prog, length(pkg_name) + 1)
}
}
})
// If not in lock, check if this looks like a fetchable package
if (!best_pkg) {
for (i = length(parts) - 1; i >= 1; i--) {
candidate = text(array(parts, 0, i), '/')
pkg_info = Shop.resolve_package_info(candidate)
if (pkg_info && pkg_info != 'local') {
best_pkg = candidate
best_remainder = text(array(parts, i), '/')
break
}
}
}
if (best_pkg && best_remainder) {
log.console('fetching ' + best_pkg + '...')
_auto = function() {
Shop.update(best_pkg)
Shop.fetch(best_pkg)
Shop.extract(best_pkg)
Shop.build_package_scripts(best_pkg)
} disruption {
return null
}
_auto()
// Retry resolution
info = resolve_path(prog + '.ce', package_context)
if (info) return info
}
return null
}
// Resolve a use() module path to {resolved_path, package, type} without compiling.
// type is 'script', 'native', or null. Checks .cm files, C symbols, and aliases.
Shop.resolve_import_info = function(path, ctx) {
@@ -1410,7 +1492,7 @@ Shop.fetch = function(pkg) {
if (actual_hash == expected_hash) {
return { status: 'cached' }
}
log.console("Zip hash mismatch for " + pkg + ", re-fetching...")
log.shop("Zip hash mismatch for " + pkg + ", re-fetching...")
} else {
// No hash stored yet - compute and store it
actual_hash = text(crypto.blake2(zip_blob), 'h')
@@ -1522,13 +1604,13 @@ Shop.update = function(pkg) {
var lock_entry = lock[pkg]
var info = Shop.resolve_package_info(pkg)
log.console(`checking ${pkg}`)
log.shop(`checking ${pkg}`)
var new_entry = null
if (info == 'local') {
// Check if local path exists
if (!fd.is_dir(pkg)) {
log.console(` Local path does not exist: ${pkg}`)
log.shop(` Local path does not exist: ${pkg}`)
return null
}
// Local packages always get a lock entry
@@ -1544,8 +1626,8 @@ Shop.update = function(pkg) {
var local_commit = lock_entry ? lock_entry.commit : null
var remote_commit = fetch_remote_hash(pkg)
log.console(`local commit: ${local_commit}`)
log.console(`remote commit: ${remote_commit}`)
log.shop(`local commit: ${local_commit}`)
log.shop(`remote commit: ${remote_commit}`)
if (!remote_commit) {
log.error("Could not resolve commit for " + pkg)
@@ -1574,7 +1656,7 @@ function install_zip(zip_blob, target_dir) {
if (fd.is_link(target_dir)) fd.unlink(target_dir)
if (fd.is_dir(target_dir)) fd.rmdir(target_dir, 1)
log.console("Extracting to " + target_dir)
log.shop("Extracting to " + target_dir)
ensure_dir(target_dir)
var count = zip.count()