// link [args] // Commands: // list List all active links // sync Ensure all symlinks are in place // delete Remove a link // clear Remove all links // Link the package in to that path // Link to (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') if (length(args) < 1) { log.console("Usage: link [args] or link [package] ") log.console("Commands:") log.console(" list List all active links") log.console(" sync Ensure all symlinks are in place") log.console(" delete Remove a link and restore original") log.console(" clear Remove all links") log.console(" Link the package in to that path") log.console(" Link to (path or package)") $stop() return } var cmd = args[0] if (cmd == 'list') { var links = link.load() var 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...") var result = link.sync_all(shop) log.console("Synced " + result.synced + " link(s)") if (length(result.errors) > 0) { log.console("Errors:") for (var 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 ") $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 = (length(args) > 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 (starts_with(target, './') || starts_with(target, '../')) { // Relative path that doesn't exist yet - try to resolve anyway var cwd = fd.realpath('.') if (starts_with(target, './')) { target = cwd + text(target, 1) } else { // For ../ paths, var 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 (starts_with(target, './') || starts_with(target, '../')) { 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 ") $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 (starts_with(target, '/')) { 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) log.error(e) $stop() return } } $stop()