219 lines
5.7 KiB
Plaintext
219 lines
5.7 KiB
Plaintext
// cell clean [<scope>] - 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 <locator> 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 < length(args); 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 [<scope>] [options]")
|
|
log.console("")
|
|
log.console("Remove cached material to force refetch/rebuild.")
|
|
log.console("")
|
|
log.console("Scopes:")
|
|
log.console(" <locator> 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 (!starts_with(args[i], '-')) {
|
|
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 == '.' || starts_with(scope, './') || starts_with(scope, '../') || 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
|
|
push(packages_to_clean, scope)
|
|
|
|
if (deep) {
|
|
try {
|
|
var deps = pkg.gather_dependencies(scope)
|
|
arrfor(deps, function(dep) {
|
|
push(packages_to_clean, 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 = replace(shop.get_package_dir(''), /\/$/, '') // Get base packages dir
|
|
|
|
if (clean_build) {
|
|
if (is_shop_scope) {
|
|
// Clean entire build and lib directories
|
|
if (fd.is_dir(build_dir)) {
|
|
push(dirs_to_delete, build_dir)
|
|
}
|
|
if (fd.is_dir(lib_dir)) {
|
|
push(dirs_to_delete, lib_dir)
|
|
}
|
|
} else {
|
|
// Clean specific package libraries
|
|
arrfor(packages_to_clean, function(p) {
|
|
if (p == 'core') return
|
|
|
|
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)) {
|
|
push(files_to_delete, 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)) {
|
|
push(files_to_delete, so_path)
|
|
}
|
|
if (fd.is_file(dll_path)) {
|
|
push(files_to_delete, dll_path)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
if (clean_fetch) {
|
|
if (is_shop_scope) {
|
|
// Clean entire packages directory (dangerous!)
|
|
if (fd.is_dir(packages_dir)) {
|
|
push(dirs_to_delete, packages_dir)
|
|
}
|
|
} else {
|
|
// Clean specific package directories
|
|
arrfor(packages_to_clean, function(p) {
|
|
if (p == 'core') return
|
|
|
|
var pkg_dir = shop.get_package_dir(p)
|
|
if (fd.is_dir(pkg_dir) || fd.is_link(pkg_dir)) {
|
|
push(dirs_to_delete, pkg_dir)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Execute or report
|
|
if (dry_run) {
|
|
log.console("Would delete:")
|
|
if (length(files_to_delete) == 0 && length(dirs_to_delete) == 0) {
|
|
log.console(" (nothing to clean)")
|
|
} else {
|
|
arrfor(files_to_delete, function(f) {
|
|
log.console(" [file] " + f)
|
|
})
|
|
arrfor(dirs_to_delete, function(d) {
|
|
log.console(" [dir] " + d)
|
|
})
|
|
}
|
|
} else {
|
|
var deleted_count = 0
|
|
|
|
arrfor(files_to_delete, function(f) {
|
|
try {
|
|
fd.unlink(f)
|
|
log.console("Deleted: " + f)
|
|
deleted_count++
|
|
} catch (e) {
|
|
log.error("Failed to delete " + f + ": " + e)
|
|
}
|
|
})
|
|
|
|
arrfor(dirs_to_delete, function(d) {
|
|
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()
|