better path resolution
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user