Files
cell/link.ce
2026-02-21 02:18:42 -06:00

181 lines
4.8 KiB
Plaintext

// link <command> [args]
// Commands:
// list List all active links
// sync Ensure all symlinks are in place
// delete <package> Remove a link
// clear Remove all links
// <path> Link the package in <path> to that path
// <package> <target> Link <package> to <target> (path or another package)
//
// Examples:
// cell link ../cell-steam (Links package in ../cell-steam)
// cell link gitea.pockle.world/john/prosperon ../prosperon (Links prosperon to local path)
// cell link gitea.pockle.world/john/prosperon github.com/prosperon (Links to another remote)
var link = use('link')
var shop = use('internal/shop')
var fd = use('fd')
var toml = use('toml')
var links = null
var count = 0
var result = null
var i = 0
var pkg = null
var cmd = null
var pkg_name = null
var target = null
var start_idx = 0
var arg1 = null
var arg2 = null
var toml_path = null
var content = null
var _restore = null
var _read_toml = null
var _add_link = null
var run = function() {
if (length(args) < 1) {
log.console("Usage: link <command> [args] or link [package] <target>")
log.console("Commands:")
log.console(" list List all active links")
log.console(" sync Ensure all symlinks are in place")
log.console(" delete <package> Remove a link and restore original")
log.console(" clear Remove all links")
log.console(" <path> Link the package in <path> to that path")
log.console(" <package> <target> Link <package> to <target> (path or package)")
return
}
cmd = args[0]
if (cmd == 'list') {
links = link.load()
count = 0
arrfor(array(links), function(k) {
log.console(k + " -> " + links[k])
count++
})
if (count == 0) log.console("No links.")
} else if (cmd == 'sync') {
log.console("Syncing links...")
result = link.sync_all(shop)
log.console("Synced " + result.synced + " link(s)")
if (length(result.errors) > 0) {
log.console("Errors:")
for (i = 0; i < length(result.errors); i++) {
log.console(" " + result.errors[i])
}
}
} else if (cmd == 'delete' || cmd == 'rm') {
if (length(args) < 2) {
log.console("Usage: link delete <package>")
return
}
pkg = args[1]
_restore = null
if (link.remove(pkg)) {
// Try to restore the original package
log.console("Restoring " + pkg + "...")
_restore = function() {
shop.fetch(pkg)
shop.extract(pkg)
log.console("Restored " + pkg)
} disruption {
log.console("Could not restore")
log.console("Run 'cell update " + pkg + "' to restore")
}
_restore()
} else {
log.console("No link found for " + pkg)
}
} else if (cmd == 'clear') {
link.clear()
log.console("Links cleared. Run 'cell update' to restore packages.")
} else {
// Linking logic
pkg_name = null
target = null
// Check for 'add' compatibility
start_idx = 0
if (cmd == 'add') {
start_idx = 1
}
arg1 = args[start_idx]
arg2 = (length(args) > start_idx + 1) ? args[start_idx + 1] : null
if (!arg1) {
log.console("Error: target or package required")
return
}
if (arg2) {
// Two arguments: explicit package name and target
pkg_name = arg1
target = arg2
// Resolve target if it's a local path
target = shop.resolve_locator(target)
} else {
// One argument: assume it's a local path, infer package name from cell.toml
target = arg1
// Resolve path
target = shop.resolve_locator(target)
// Must be a local path with cell.toml
toml_path = target + '/cell.toml'
if (!fd.is_file(toml_path)) {
log.console("Error: No cell.toml found at " + target)
log.console("For linking to another package, use: link <package> <target>")
return
}
// Derive canonical package name from the target directory
_read_toml = function() {
var info = shop.file_info(target + '/cell.toml')
if (info && info.package) {
pkg_name = info.package
} else {
log.console("Error: could not determine package name for " + target)
log.console("Ensure it is installed or has a git remote matching a lock entry")
$stop()
}
} disruption {
log.console("Error determining package name for " + target)
$stop()
}
_read_toml()
}
// Validate: if target is a local path, it must have cell.toml
if (starts_with(target, '/')) {
if (!fd.is_file(target + '/cell.toml')) {
log.console("Error: " + target + " is not a valid package (no cell.toml)")
return
}
}
// Add the link (this also creates the symlink)
_add_link = function() {
link.add(pkg_name, target, shop)
} disruption {
log.console("Error adding link")
$stop()
}
_add_link()
}
}
run()
$stop()