Files
cell/resolve.ce
2026-02-26 08:13:18 -06:00

220 lines
5.8 KiB
Plaintext

// cell resolve [<locator>] - Print fully resolved dependency closure
//
// Usage:
// cell resolve Resolve current directory package
// cell resolve . Resolve current directory package
// cell resolve <locator> Resolve specific package
//
// Options:
// --target <triple> Annotate builds for target platform
// --locked Show lock state without applying links
// --refresh Refresh floating refs before printing
var shop = use('internal/shop')
var pkg = use('package')
var link = use('link')
var build = use('build')
var fd = use('fd')
var target_locator = null
var target_triple = null
var show_locked = false
var refresh_first = false
var i = 0
var run = function() {
for (i = 0; i < length(args); i++) {
if (args[i] == '--target' || args[i] == '-t') {
if (i + 1 < length(args)) {
target_triple = args[++i]
} else {
log.error('--target requires a triple')
return
}
} else if (args[i] == '--locked') {
show_locked = true
} else if (args[i] == '--refresh') {
refresh_first = true
} else if (args[i] == '--help' || args[i] == '-h') {
log.console("Usage: cell resolve [<locator>] [options]")
log.console("")
log.console("Print the fully resolved dependency closure.")
log.console("")
log.console("Options:")
log.console(" --target <triple> Annotate builds for target platform")
log.console(" --locked Show lock state without applying links")
log.console(" --refresh Refresh floating refs before printing")
return
} else if (!starts_with(args[i], '-')) {
target_locator = args[i]
}
}
// Default to current directory
if (!target_locator) {
target_locator = '.'
}
// Resolve local paths
target_locator = shop.resolve_locator(target_locator)
// Check if it's a valid package
var pkg_dir = null
if (!fd.is_file(target_locator + '/cell.toml')) {
// Try to find it in the shop
pkg_dir = shop.get_package_dir(target_locator)
if (!fd.is_file(pkg_dir + '/cell.toml')) {
log.error("Not a valid package: " + target_locator)
return
}
}
// Detect target if not specified
if (!target_triple) {
target_triple = build.detect_host_target()
}
var lock = shop.load_lock()
var links = link.load()
// Gather all dependencies recursively
var all_deps = {}
var visited = {}
function gather_deps(locator, depth) {
if (visited[locator]) return
visited[locator] = true
all_deps[locator] = { depth: depth }
var _gather = function() {
var deps = pkg.dependencies(locator)
if (deps) {
arrfor(array(deps), function(alias) {
var dep_locator = deps[alias]
gather_deps(dep_locator, depth + 1)
})
}
} disruption {
// Package might not have dependencies
}
_gather()
}
gather_deps(target_locator, 0)
// Print header
log.console("Resolved dependency closure for: " + target_locator)
log.console("Target: " + target_triple)
log.console("")
// Sort by depth then alphabetically
var sorted = array(array(all_deps), function(locator) { return { locator: locator, depth: all_deps[locator].depth } })
sorted = sort(sorted, "locator")
sorted = sort(sorted, "depth")
var j = 0
var locator = null
var depth = 0
var indent = null
var info = null
var lock_entry = null
var link_target = null
var effective_locator = null
var is_linked = false
var is_in_lock = false
var is_local = false
var is_fetched = false
var has_c_files = false
var status_parts = null
var commit_str = null
var line = null
var cflags = null
var ldflags = null
var _show_flags = null
for (i = 0; i < length(sorted); i++) {
locator = sorted[i].locator
depth = sorted[i].depth
indent = ""
for (j = 0; j < depth; j++) indent += " "
// Get info about this package
info = shop.resolve_package_info(locator)
lock_entry = lock[locator]
link_target = show_locked ? null : links[locator]
effective_locator = link_target || locator
// Check status
is_linked = link_target != null
is_in_lock = lock_entry != null
is_local = info == 'local'
// Check if fetched (package directory exists)
pkg_dir = shop.get_package_dir(locator)
is_fetched = fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)
// Check if package has C modules (built on demand)
has_c_files = false
var _check_c = function() {
var c_files = pkg.get_c_files(locator, target_triple, true)
if (c_files && length(c_files) > 0) has_c_files = true
} disruption {}
_check_c()
// Format output
status_parts = []
if (is_linked) status_parts[] = "linked"
if (is_local) status_parts[] = "local"
if (!is_in_lock) status_parts[] = "not in lock"
if (!is_fetched) status_parts[] = "not fetched"
if (has_c_files) status_parts[] = "has C modules"
commit_str = ""
if (lock_entry && lock_entry.commit) {
commit_str = " @" + text(lock_entry.commit, 0, 8)
} else if (lock_entry && lock_entry.type == 'local') {
commit_str = " (local)"
}
line = indent + locator + commit_str
if (is_linked && !show_locked) {
line += " -> " + link_target
}
if (length(status_parts) > 0) {
line += " [" + text(status_parts, ", ") + "]"
}
log.console(line)
// Show compilation inputs if requested (verbose)
if (depth == 0) {
_show_flags = function() {
cflags = pkg.get_flags(locator, 'CFLAGS', target_triple)
ldflags = pkg.get_flags(locator, 'LDFLAGS', target_triple)
if (length(cflags) > 0 || length(ldflags) > 0) {
log.console(indent + " Compilation inputs:")
if (length(cflags) > 0) {
log.console(indent + " CFLAGS: " + text(cflags, ' '))
}
if (length(ldflags) > 0) {
log.console(indent + " LDFLAGS: " + text(ldflags, ' '))
}
}
} disruption {
// Skip if can't read config
}
_show_flags()
}
}
log.console("")
log.console("Total: " + text(length(sorted)) + " package(s)")
}
run()
$stop()