197 lines
5.5 KiB
Plaintext
197 lines
5.5 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
|
|
|
|
for (var 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')
|
|
$stop()
|
|
}
|
|
} 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")
|
|
$stop()
|
|
} else if (!starts_with(args[i], '-')) {
|
|
target_locator = args[i]
|
|
}
|
|
}
|
|
|
|
// Default to current directory
|
|
if (!target_locator) {
|
|
target_locator = '.'
|
|
}
|
|
|
|
// Resolve local paths
|
|
if (target_locator == '.' || starts_with(target_locator, './') || starts_with(target_locator, '../') || fd.is_dir(target_locator)) {
|
|
var resolved = fd.realpath(target_locator)
|
|
if (resolved) {
|
|
target_locator = resolved
|
|
}
|
|
}
|
|
|
|
// Check if it's a valid package
|
|
if (!fd.is_file(target_locator + '/cell.toml')) {
|
|
// Try to find it in the shop
|
|
var pkg_dir = shop.get_package_dir(target_locator)
|
|
if (!fd.is_file(pkg_dir + '/cell.toml')) {
|
|
log.error("Not a valid package: " + target_locator)
|
|
$stop()
|
|
}
|
|
}
|
|
|
|
// 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 }
|
|
|
|
try {
|
|
var deps = pkg.dependencies(locator)
|
|
if (deps) {
|
|
arrfor(array(deps), function(alias) {
|
|
var dep_locator = deps[alias]
|
|
gather_deps(dep_locator, depth + 1)
|
|
})
|
|
}
|
|
} catch (e) {
|
|
// Package might not have dependencies
|
|
}
|
|
}
|
|
|
|
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")
|
|
|
|
for (var i = 0; i < length(sorted); i++) {
|
|
var locator = sorted[i].locator
|
|
var depth = sorted[i].depth
|
|
|
|
var indent = ""
|
|
for (var j = 0; j < depth; j++) indent += " "
|
|
|
|
// Get info about this package
|
|
var info = shop.resolve_package_info(locator)
|
|
var lock_entry = lock[locator]
|
|
var link_target = show_locked ? null : links[locator]
|
|
var effective_locator = link_target || locator
|
|
|
|
// Check status
|
|
var is_linked = link_target != null
|
|
var is_in_lock = lock_entry != null
|
|
var is_local = info == 'local'
|
|
|
|
// Check if fetched (package directory exists)
|
|
var pkg_dir = shop.get_package_dir(locator)
|
|
var is_fetched = fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)
|
|
|
|
// Check if built (library exists)
|
|
var lib_dir = shop.get_lib_dir()
|
|
var lib_name = shop.lib_name_for_package(locator)
|
|
var dylib_ext = '.dylib' // TODO: detect from target
|
|
var lib_path = lib_dir + '/' + lib_name + dylib_ext
|
|
var is_built = fd.is_file(lib_path)
|
|
|
|
// Format output
|
|
var status_parts = []
|
|
if (is_linked) push(status_parts, "linked")
|
|
if (is_local) push(status_parts, "local")
|
|
if (!is_in_lock) push(status_parts, "not in lock")
|
|
if (!is_fetched) push(status_parts, "not fetched")
|
|
if (is_built) push(status_parts, "built")
|
|
|
|
var 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)"
|
|
}
|
|
|
|
var 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) {
|
|
try {
|
|
var cflags = pkg.get_flags(locator, 'CFLAGS', target_triple)
|
|
var 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, ' '))
|
|
}
|
|
}
|
|
} catch (e) {
|
|
// Skip if can't read config
|
|
}
|
|
}
|
|
}
|
|
|
|
log.console("")
|
|
log.console("Total: " + text(length(sorted)) + " package(s)")
|
|
|
|
$stop()
|