// cell clone // Clones a cell package to the local , and links it. var shop = use('internal/shop') var link = use('link') var fd = use('fd') var http = use('http') var miniz = use('miniz') var resolved = null var cwd = null var parent = null if (length(args) < 2) { log.console("Usage: cell clone ") log.console("Clones a cell package to a local path and links it.") $stop() } 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, '../')) { resolved = fd.realpath(target_path) if (resolved) { target_path = resolved } else { // Path doesn't exist yet, resolve relative to cwd 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 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() } 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() } // Update to get the commit hash var update_result = shop.update(origin) if (!update_result) { log.console("Error: Could not fetch " + origin) $stop() } // 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() } var download_url = shop.get_download_url(origin, entry.commit) log.console("Downloading from " + download_url) var zip_blob = null var zip = null var count = 0 var i = 0 var filename = null var first_slash = null var rel_path = null var full_path = null var dir_path = null var _clone = function() { zip_blob = http.fetch(download_url) // Extract zip to target path zip = miniz.read(zip_blob) if (!zip) { log.console("Error: Failed to read zip archive") $stop() } // Create target directory fd.mkdir(target_path) count = zip.count() for (i = 0; i < count; i++) { if (zip.is_directory(i)) continue filename = zip.get_filename(i) first_slash = search(filename, '/') if (first_slash == null) continue if (first_slash + 1 >= length(filename)) continue rel_path = text(filename, first_slash + 1) full_path = target_path + '/' + rel_path 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) } disruption { log.console("Error during clone") } _clone() $stop()