// cell imports [] - Trace module-level imports // // Usage: // cell imports Trace imports for current package entry // cell imports Trace imports starting from a .ce or .cm file // cell imports Trace imports starting from a .cm file // // Options: // --flat Flat list instead of tree // --packages Only show unique packages, not individual modules var shop = use('internal/shop') var pkg = use('package') var fd = use('fd') var target = null var flat_mode = false var packages_only = false var i = 0 var pkg_dir = null var config = null var target_path = null for (i = 0; i < length(args); i++) { if (args[i] == '--flat') { flat_mode = true } else if (args[i] == '--packages') { packages_only = true } else if (args[i] == '--help' || args[i] == '-h') { log.console("Usage: cell imports [] [options]") log.console("") log.console("Trace module-level imports across packages.") log.console("") log.console("Options:") log.console(" --flat Flat list instead of tree") log.console(" --packages Only show unique packages, not individual modules") $stop() } else if (!starts_with(args[i], '-')) { target = args[i] } } // Resolve target file if (target) { if (!ends_with(target, '.ce') && !ends_with(target, '.cm')) target = target + '.ce' if (fd.is_file(target)) target_path = fd.realpath(target) else { pkg_dir = pkg.find_package_dir('.') if (pkg_dir) target_path = pkg_dir + '/' + target } } else { pkg_dir = pkg.find_package_dir('.') if (pkg_dir) { config = pkg.load_config(null) if (config.entry) target_path = pkg_dir + '/' + config.entry } } if (!target_path || !fd.is_file(target_path)) { log.error('Could not find file: ' + (target || '(no target specified)')) $stop() } // Collect all imports recursively var visited = {} var all_imports = [] var all_packages = {} function trace_imports(file_path, depth) { if (visited[file_path]) return visited[file_path] = true var fi = shop.file_info(file_path) var file_pkg = fi.package || '(local)' var idx = null var j = 0 var imp = null var mod_path = null var resolved = null var imp_pkg = null var imp_type = null var rinfo = null all_packages[file_pkg] = true var _trace = function() { idx = shop.index_file(file_path) if (!idx || !idx.imports) return j = 0 while (j < length(idx.imports)) { imp = idx.imports[j] mod_path = imp.module_path resolved = null imp_pkg = '?' imp_type = 'unresolved' // Use the full resolver that checks .cm files, C symbols, and aliases rinfo = shop.resolve_import_info(mod_path, file_pkg) if (rinfo) { resolved = rinfo.resolved_path imp_pkg = rinfo.package || '?' imp_type = rinfo.type } all_packages[imp_pkg] = true all_imports[] = { from: file_path, from_pkg: file_pkg, module_path: mod_path, resolved_path: resolved, package: imp_pkg, type: imp_type, depth: depth } // Recurse into resolved scripts if (resolved && (ends_with(resolved, '.cm') || ends_with(resolved, '.ce'))) { trace_imports(resolved, depth + 1) } j = j + 1 } } disruption { // File might fail to parse/index } _trace() } trace_imports(target_path, 0) // Output results var fi2 = null if (packages_only) { log.console("Packages used by " + target_path + ":") log.console("") arrfor(array(all_packages), function(p) { log.console(" " + p) }) } else if (flat_mode) { log.console("Imports from " + target_path + ":") log.console("") arrfor(all_imports, function(imp) { var suffix = '' if (imp.type == 'native') suffix = ' [native]' if (imp.type == 'unresolved') suffix = ' [unresolved]' log.console(" " + imp.module_path + " -> " + imp.package + suffix) }) } else { // Tree output function print_tree(file_path, prefix, is_last) { var children = filter(all_imports, function(imp) { return imp.from == file_path }) var j = 0 var imp = null var last = false var connector = null var suffix = null var child_prefix = null while (j < length(children)) { imp = children[j] last = (j == length(children) - 1) connector = last ? "\\-- " : "|-- " suffix = " (" + imp.package + ")" if (imp.type == 'native') suffix = suffix + " [native]" if (imp.type == 'unresolved') suffix = suffix + " [unresolved]" log.console(prefix + connector + imp.module_path + suffix) if (imp.resolved_path) { child_prefix = prefix + (last ? " " : "| ") print_tree(imp.resolved_path, child_prefix, last) } j = j + 1 } } fi2 = shop.file_info(target_path) log.console(target_path + " (" + (fi2.package || 'local') + ")") print_tree(target_path, "", true) } $stop()