122 lines
3.0 KiB
Plaintext
122 lines
3.0 KiB
Plaintext
// cell clone <origin> <path>
|
|
// Clones a cell package <origin> to the local <path>, and links it.
|
|
|
|
var shop = use('internal/shop')
|
|
var link = use('link')
|
|
var fd = use('fd')
|
|
var http = use('http')
|
|
var miniz = use('miniz')
|
|
|
|
if (length(args) < 2) {
|
|
log.console("Usage: cell clone <origin> <path>")
|
|
log.console("Clones a cell package to a local path and links it.")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var origin = args[0]
|
|
var target_path = args[1]
|
|
|
|
// Resolve target path to absolute
|
|
if (target_path == '.' || starts_with(target_path, './') || starts_with(target_path, '../')) {
|
|
var resolved = fd.realpath(target_path)
|
|
if (resolved) {
|
|
target_path = resolved
|
|
} else {
|
|
// Path doesn't exist yet, resolve relative to cwd
|
|
var cwd = fd.realpath('.')
|
|
if (target_path == '.') {
|
|
target_path = cwd
|
|
} else if (starts_with(target_path, './')) {
|
|
target_path = cwd + text(target_path, 1)
|
|
} else if (starts_with(target_path, '../')) {
|
|
// Go up one directory from cwd
|
|
var parent = fd.dirname(cwd)
|
|
target_path = parent + text(target_path, 2)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if target already exists
|
|
if (fd.is_dir(target_path)) {
|
|
log.console("Error: " + target_path + " already exists")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
log.console("Cloning " + origin + " to " + target_path + "...")
|
|
|
|
// Get the latest commit
|
|
var info = shop.resolve_package_info(origin)
|
|
if (!info || info == 'local') {
|
|
log.console("Error: " + origin + " is not a remote package")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
// Update to get the commit hash
|
|
var update_result = shop.update(origin)
|
|
if (!update_result) {
|
|
log.console("Error: Could not fetch " + origin)
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
// Fetch and extract to the target path
|
|
var lock = shop.load_lock()
|
|
var entry = lock[origin]
|
|
if (!entry || !entry.commit) {
|
|
log.console("Error: No commit found for " + origin)
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
var download_url = shop.get_download_url(origin, entry.commit)
|
|
log.console("Downloading from " + download_url)
|
|
|
|
try {
|
|
var zip_blob = http.fetch(download_url)
|
|
|
|
// Extract zip to target path
|
|
var zip = miniz.read(zip_blob)
|
|
if (!zip) {
|
|
log.console("Error: Failed to read zip archive")
|
|
$stop()
|
|
return
|
|
}
|
|
|
|
// Create target directory
|
|
fd.mkdir(target_path)
|
|
|
|
var count = zip.count()
|
|
for (var i = 0; i < count; i++) {
|
|
if (zip.is_directory(i)) continue
|
|
var filename = zip.get_filename(i)
|
|
var first_slash = search(filename, '/')
|
|
if (first_slash == null) continue
|
|
if (first_slash + 1 >= length(filename)) continue
|
|
|
|
var rel_path = text(filename, first_slash + 1)
|
|
var full_path = target_path + '/' + rel_path
|
|
var dir_path = fd.dirname(full_path)
|
|
|
|
// Ensure directory exists
|
|
if (!fd.is_dir(dir_path)) {
|
|
fd.mkdir(dir_path)
|
|
}
|
|
fd.slurpwrite(full_path, zip.slurp(filename))
|
|
}
|
|
|
|
log.console("Extracted to " + target_path)
|
|
|
|
// Link the origin to the cloned path
|
|
link.add(origin, target_path, shop)
|
|
log.console("Linked " + origin + " -> " + target_path)
|
|
|
|
} catch (e) {
|
|
log.console("Error: " + e.message)
|
|
if (e.stack) log.console(e.stack)
|
|
}
|
|
|
|
$stop()
|