// cell clean [] - Remove cached material to force refetch/rebuild // // Usage: // cell clean Clean build outputs for current directory package // cell clean . Clean build outputs for current directory package // cell clean Clean build outputs for specific package // cell clean shop Clean entire shop // cell clean world Clean all world packages // // Options: // --build Remove build outputs only (default) // --fetch Remove fetched sources only // --all Remove both build outputs and fetched sources // --deep Apply to full dependency closure // --dry-run Show what would be deleted var shop = use('internal/shop') var pkg = use('package') var fd = use('fd') var scope = null var clean_build = false var clean_fetch = false var deep = false var dry_run = false for (var i = 0; i < args.length; i++) { if (args[i] == '--build') { clean_build = true } else if (args[i] == '--fetch') { clean_fetch = true } else if (args[i] == '--all') { clean_build = true clean_fetch = true } else if (args[i] == '--deep') { deep = true } else if (args[i] == '--dry-run') { dry_run = true } else if (args[i] == '--help' || args[i] == '-h') { log.console("Usage: cell clean [] [options]") log.console("") log.console("Remove cached material to force refetch/rebuild.") log.console("") log.console("Scopes:") log.console(" Clean specific package") log.console(" shop Clean entire shop") log.console(" world Clean all world packages") log.console("") log.console("Options:") log.console(" --build Remove build outputs only (default)") log.console(" --fetch Remove fetched sources only") log.console(" --all Remove both build outputs and fetched sources") log.console(" --deep Apply to full dependency closure") log.console(" --dry-run Show what would be deleted") $stop() } else if (!args[i].startsWith('-')) { scope = args[i] } } // Default to --build if nothing specified if (!clean_build && !clean_fetch) { clean_build = true } // Default scope to current directory if (!scope) { scope = '.' } // Resolve local paths for single package scope var is_shop_scope = (scope == 'shop') var is_world_scope = (scope == 'world') if (!is_shop_scope && !is_world_scope) { if (scope == '.' || scope.startsWith('./') || scope.startsWith('../') || fd.is_dir(scope)) { var resolved = fd.realpath(scope) if (resolved) { scope = resolved } } } var files_to_delete = [] var dirs_to_delete = [] // Gather packages to clean var packages_to_clean = [] if (is_shop_scope) { packages_to_clean = shop.list_packages() } else if (is_world_scope) { // For now, world is the same as shop packages_to_clean = shop.list_packages() } else { // Single package packages_to_clean.push(scope) if (deep) { try { var deps = pkg.gather_dependencies(scope) for (var dep of deps) { packages_to_clean.push(dep) } } catch (e) { // Skip if can't read dependencies } } } // Gather files to clean var lib_dir = shop.get_lib_dir() var build_dir = shop.get_build_dir() var packages_dir = shop.get_package_dir('').replace(/\/$/, '') // Get base packages dir if (clean_build) { if (is_shop_scope) { // Clean entire build and lib directories if (fd.is_dir(build_dir)) { dirs_to_delete.push(build_dir) } if (fd.is_dir(lib_dir)) { dirs_to_delete.push(lib_dir) } } else { // Clean specific package libraries for (var p of packages_to_clean) { if (p == 'core') continue var lib_name = shop.lib_name_for_package(p) var dylib_ext = '.dylib' var lib_path = lib_dir + '/' + lib_name + dylib_ext if (fd.is_file(lib_path)) { files_to_delete.push(lib_path) } // Also check for .so and .dll var so_path = lib_dir + '/' + lib_name + '.so' var dll_path = lib_dir + '/' + lib_name + '.dll' if (fd.is_file(so_path)) { files_to_delete.push(so_path) } if (fd.is_file(dll_path)) { files_to_delete.push(dll_path) } } } } if (clean_fetch) { if (is_shop_scope) { // Clean entire packages directory (dangerous!) if (fd.is_dir(packages_dir)) { dirs_to_delete.push(packages_dir) } } else { // Clean specific package directories for (var p of packages_to_clean) { if (p == 'core') continue var pkg_dir = shop.get_package_dir(p) if (fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)) { dirs_to_delete.push(pkg_dir) } } } } // Execute or report if (dry_run) { log.console("Would delete:") if (files_to_delete.length == 0 && dirs_to_delete.length == 0) { log.console(" (nothing to clean)") } else { for (var f of files_to_delete) { log.console(" [file] " + f) } for (var d of dirs_to_delete) { log.console(" [dir] " + d) } } } else { var deleted_count = 0 for (var f of files_to_delete) { try { fd.unlink(f) log.console("Deleted: " + f) deleted_count++ } catch (e) { log.error("Failed to delete " + f + ": " + e) } } for (var d of dirs_to_delete) { try { if (fd.is_link(d)) { fd.unlink(d) } else { fd.rmdir(d, 1) // recursive } log.console("Deleted: " + d) deleted_count++ } catch (e) { log.error("Failed to delete " + d + ": " + e) } } if (deleted_count == 0) { log.console("Nothing to clean.") } else { log.console("") log.console("Clean complete: " + text(deleted_count) + " item(s) deleted.") } } $stop()