// cell resolve [] - Print fully resolved dependency closure // // Usage: // cell resolve Resolve current directory package // cell resolve . Resolve current directory package // cell resolve Resolve specific package // // Options: // --target 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 resolved = null 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') $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 [] [options]") log.console("") log.console("Print the fully resolved dependency closure.") log.console("") log.console("Options:") log.console(" --target 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)) { resolved = fd.realpath(target_locator) if (resolved) { target_locator = resolved } } // 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) $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 } 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) 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 (has_c_files) push(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)") $stop()