link
This commit is contained in:
21
install.ce
21
install.ce
@@ -79,12 +79,20 @@ log.console("Installing " + locator + "...")
|
||||
|
||||
// Gather all packages that will be installed
|
||||
var packages_to_install = []
|
||||
var skipped_packages = []
|
||||
var visited = {}
|
||||
|
||||
function gather_packages(pkg_locator) {
|
||||
if (visited[pkg_locator]) return
|
||||
visited[pkg_locator] = true
|
||||
|
||||
// Check if this is a local path that doesn't exist
|
||||
if (pkg_locator.startsWith('/') && !fd.is_dir(pkg_locator)) {
|
||||
skipped_packages.push(pkg_locator)
|
||||
log.console(" Skipping missing local package: " + pkg_locator)
|
||||
return
|
||||
}
|
||||
|
||||
packages_to_install.push(pkg_locator)
|
||||
|
||||
// Try to read dependencies
|
||||
@@ -123,6 +131,13 @@ if (dry_run) {
|
||||
var exists = lock[p] != null
|
||||
log.console(" " + p + (exists ? " (already installed)" : ""))
|
||||
}
|
||||
if (skipped_packages.length > 0) {
|
||||
log.console("")
|
||||
log.console("Would skip (missing local paths):")
|
||||
for (var p of skipped_packages) {
|
||||
log.console(" " + p)
|
||||
}
|
||||
}
|
||||
$stop()
|
||||
}
|
||||
|
||||
@@ -150,6 +165,10 @@ for (var p of packages_to_install) {
|
||||
install_package(p)
|
||||
}
|
||||
|
||||
log.console("Installed " + text(packages_to_install.length) + " package(s).")
|
||||
var summary = "Installed " + text(packages_to_install.length) + " package(s)."
|
||||
if (skipped_packages.length > 0) {
|
||||
summary += " Skipped " + text(skipped_packages.length) + " missing local path(s)."
|
||||
}
|
||||
log.console(summary)
|
||||
|
||||
$stop()
|
||||
|
||||
@@ -161,6 +161,13 @@ function abs_path_to_package(package_dir)
|
||||
if (package_dir.startsWith(packages_prefix))
|
||||
return package_dir.substring(packages_prefix.length)
|
||||
|
||||
// Check if this local path is the target of a link
|
||||
// If so, return the canonical package name (link origin) instead
|
||||
var link_origin = link.get_origin(package_dir)
|
||||
if (link_origin) {
|
||||
return link_origin
|
||||
}
|
||||
|
||||
// in this case, the dir is the package
|
||||
if (package_in_shop(package_dir))
|
||||
return package_dir
|
||||
@@ -987,6 +994,11 @@ Shop.update = function(pkg) {
|
||||
log.console(`checking ${pkg}`)
|
||||
|
||||
if (info == 'local') {
|
||||
// Check if local path exists
|
||||
if (!fd.is_dir(pkg)) {
|
||||
log.console(` Local path does not exist: ${pkg}`)
|
||||
return null
|
||||
}
|
||||
// Local packages always get a lock entry
|
||||
var new_entry = {
|
||||
type: 'local',
|
||||
|
||||
70
link.cm
70
link.cm
@@ -109,6 +109,36 @@ Link.add = function(canonical, target, shop) {
|
||||
// Create the symlink immediately
|
||||
Link.sync_one(canonical, target, shop)
|
||||
|
||||
// Install dependencies of the linked package
|
||||
// Read the target's cell.toml to find its dependencies
|
||||
var target_path = target.startsWith('/') ? target : get_package_abs_dir(target)
|
||||
var toml_path = target_path + '/cell.toml'
|
||||
if (fd.is_file(toml_path)) {
|
||||
try {
|
||||
var content = text(fd.slurp(toml_path))
|
||||
var cfg = toml.decode(content)
|
||||
if (cfg.dependencies) {
|
||||
for (var alias in cfg.dependencies) {
|
||||
var dep_locator = cfg.dependencies[alias]
|
||||
// Skip local dependencies that don't exist
|
||||
if (dep_locator.startsWith('/') && !fd.is_dir(dep_locator)) {
|
||||
log.console(" Skipping missing local dependency: " + dep_locator)
|
||||
continue
|
||||
}
|
||||
// Install the dependency if not already in shop
|
||||
try {
|
||||
shop.get(dep_locator)
|
||||
shop.extract(dep_locator)
|
||||
} catch (e) {
|
||||
log.console(" Warning: Could not install dependency " + dep_locator + ": " + e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log.console(" Warning: Could not read dependencies from " + toml_path)
|
||||
}
|
||||
}
|
||||
|
||||
log.console("Linked " + canonical + " -> " + target)
|
||||
return true
|
||||
}
|
||||
@@ -177,7 +207,7 @@ Link.sync_one = function(canonical, target, shop) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Sync all links - ensure all symlinks are in place
|
||||
// Sync all links - ensure all symlinks are in place and dependencies are installed
|
||||
Link.sync_all = function(shop) {
|
||||
var links = Link.load()
|
||||
var count = 0
|
||||
@@ -198,6 +228,32 @@ Link.sync_all = function(shop) {
|
||||
}
|
||||
|
||||
Link.sync_one(canonical, target, shop)
|
||||
|
||||
// Install dependencies of the linked package
|
||||
var toml_path = link_target + '/cell.toml'
|
||||
try {
|
||||
var content = text(fd.slurp(toml_path))
|
||||
var cfg = toml.decode(content)
|
||||
if (cfg.dependencies) {
|
||||
for (var alias in cfg.dependencies) {
|
||||
var dep_locator = cfg.dependencies[alias]
|
||||
// Skip local dependencies that don't exist
|
||||
if (dep_locator.startsWith('/') && !fd.is_dir(dep_locator)) {
|
||||
continue
|
||||
}
|
||||
// Install the dependency if not already in shop
|
||||
try {
|
||||
shop.get(dep_locator)
|
||||
shop.extract(dep_locator)
|
||||
} catch (e) {
|
||||
// Silently continue - dependency may already be installed
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Could not read dependencies - continue anyway
|
||||
}
|
||||
|
||||
count++
|
||||
} catch (e) {
|
||||
errors.push(canonical + ': ' + e.message)
|
||||
@@ -219,4 +275,16 @@ Link.get_target = function(canonical) {
|
||||
return links[canonical] || null
|
||||
}
|
||||
|
||||
// Get the canonical package name that links to this target (reverse lookup)
|
||||
// Returns null if no package links to this target
|
||||
Link.get_origin = function(target) {
|
||||
var links = Link.load()
|
||||
for (var origin in links) {
|
||||
if (links[origin] == target) {
|
||||
return origin
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return Link
|
||||
|
||||
Reference in New Issue
Block a user