179 lines
5.1 KiB
Plaintext
179 lines
5.1 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('shop')
|
|
var fd = use('fd')
|
|
var toml = use('toml')
|
|
|
|
if (args.length < 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)")
|
|
$_.stop()
|
|
return
|
|
}
|
|
|
|
var cmd = args[0]
|
|
|
|
if (cmd == 'list') {
|
|
var links = link.load()
|
|
var count = 0
|
|
for (var k in links) {
|
|
log.console(k + " -> " + links[k])
|
|
count++
|
|
}
|
|
if (count == 0) log.console("No links.")
|
|
|
|
} else if (cmd == 'sync') {
|
|
log.console("Syncing links...")
|
|
var result = link.sync_all(shop)
|
|
log.console("Synced " + result.synced + " link(s)")
|
|
if (result.errors.length > 0) {
|
|
log.console("Errors:")
|
|
for (var i = 0; i < result.errors.length; i++) {
|
|
log.console(" " + result.errors[i])
|
|
}
|
|
}
|
|
|
|
} else if (cmd == 'delete' || cmd == 'rm') {
|
|
if (args.length < 2) {
|
|
log.console("Usage: link delete <package>")
|
|
$_.stop()
|
|
return
|
|
}
|
|
|
|
var pkg = args[1]
|
|
|
|
if (link.remove(pkg)) {
|
|
// Try to restore the original package
|
|
log.console("Restoring " + pkg + "...")
|
|
try {
|
|
shop.fetch(pkg)
|
|
shop.extract(pkg)
|
|
log.console("Restored " + pkg)
|
|
} catch (e) {
|
|
log.console("Could not restore: " + e.message)
|
|
log.console("Run 'cell update " + pkg + "' to 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
|
|
var pkg_name = null
|
|
var target = null
|
|
|
|
// Check for 'add' compatibility
|
|
var start_idx = 0
|
|
if (cmd == 'add') {
|
|
start_idx = 1
|
|
}
|
|
|
|
var arg1 = args[start_idx]
|
|
var arg2 = (args.length > start_idx + 1) ? args[start_idx + 1] : null
|
|
|
|
if (!arg1) {
|
|
log.console("Error: target or package required")
|
|
$_.stop()
|
|
return
|
|
}
|
|
|
|
if (arg2) {
|
|
// Two arguments: explicit package name and target
|
|
pkg_name = arg1
|
|
target = arg2
|
|
|
|
// Resolve target if it's a local path
|
|
if (target == '.' || fd.is_dir(target)) {
|
|
target = fd.realpath(target)
|
|
} else if (target.startsWith('./') || target.startsWith('../')) {
|
|
// Relative path that doesn't exist yet - try to resolve anyway
|
|
var cwd = fd.realpath('.')
|
|
if (target.startsWith('./')) {
|
|
target = cwd + target.substring(1)
|
|
} else {
|
|
// For ../ paths, let fd.realpath handle it if possible
|
|
target = fd.realpath(target) || target
|
|
}
|
|
}
|
|
// Otherwise target is a package name (e.g., github.com/prosperon)
|
|
|
|
} else {
|
|
// One argument: assume it's a local path, infer package name from cell.toml
|
|
target = arg1
|
|
|
|
// Resolve path
|
|
if (target == '.' || fd.is_dir(target)) {
|
|
target = fd.realpath(target)
|
|
} else if (target.startsWith('./') || target.startsWith('../')) {
|
|
target = fd.realpath(target) || target
|
|
}
|
|
|
|
// Must be a local path with cell.toml
|
|
var 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>")
|
|
$_.stop()
|
|
return
|
|
}
|
|
|
|
// Read package name from cell.toml
|
|
try {
|
|
var content = toml.decode(text(fd.slurp(toml_path)))
|
|
if (content.package) {
|
|
pkg_name = content.package
|
|
} else {
|
|
log.console("Error: cell.toml at " + target + " does not define 'package'")
|
|
$_.stop()
|
|
return
|
|
}
|
|
} catch (e) {
|
|
log.console("Error reading cell.toml: " + e)
|
|
$_.stop()
|
|
return
|
|
}
|
|
}
|
|
|
|
// Validate: if target is a local path, it must have cell.toml
|
|
if (target.startsWith('/')) {
|
|
if (!fd.is_file(target + '/cell.toml')) {
|
|
log.console("Error: " + target + " is not a valid package (no cell.toml)")
|
|
$_.stop()
|
|
return
|
|
}
|
|
}
|
|
|
|
// Add the link (this also creates the symlink)
|
|
try {
|
|
link.add(pkg_name, target, shop)
|
|
} catch (e) {
|
|
log.console("Error: " + e.message)
|
|
$_.stop()
|
|
return
|
|
}
|
|
}
|
|
|
|
$_.stop() |