// 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 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 [] [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)) { 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) status_parts.push("linked") if (is_local) status_parts.push("local") if (!is_in_lock) status_parts.push("not in lock") if (!is_fetched) status_parts.push("not fetched") if (is_built) status_parts.push("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()