Files
cell/scripts/mod.ce

139 lines
3.7 KiB
Plaintext

var shop = use('shop')
var http = use('http')
var miniz = use('miniz')
var io = use('io')
var crypto = use('crypto')
var text = use('text')
var toml = use('toml')
var time = use('time')
var uses = {}
uses.download = function()
{
var mods = shop.load_config().dependencies
var cache_dir = '.cell/cache'
var modules_dir = '.cell/modules'
var lock_path = '.cell/lock.toml'
// Ensure directories exist
if (!io.exists(cache_dir))
io.mkdir(cache_dir)
if (!io.exists(modules_dir))
io.mkdir(modules_dir)
// Load or create lock file
var lock = {}
if (io.exists(lock_path)) {
var lock_content = io.slurp(lock_path)
lock = toml.decode(lock_content)
}
if (!lock.modules) lock.modules = {}
for (var mod in mods) {
var cache_path = cache_dir + '/' + mod + '.zip'
var module_path = modules_dir + '/' + mod
var zip
var need_download = false
// Check if module exists in lock file
if (!lock.modules[mod] || !lock.modules[mod].hash) {
log.console(`${mod}: not in lock file, will download`)
need_download = true
} else if (!io.exists(cache_path)) {
log.console(`${mod}: cache missing, will download`)
need_download = true
}
if (!need_download) {
// Verify cached file hash
log.console(`${mod}: verifying cached version`)
zip = io.slurpbytes(cache_path)
var hash = crypto.hash(zip)
var hash_b32 = text(hash, "t")
if (hash_b32 !== lock.modules[mod].hash) {
log.console(`${mod}: hash mismatch, will redownload`)
log.console(` expected: ${lock.modules[mod].hash}`)
log.console(` actual: ${hash_b32}`)
need_download = true
} else {
log.console(`${mod}: hash verified`)
}
}
if (need_download) {
// Download the module
log.console(`downloading ${mod} at ${mods[mod]}`)
log.console(shop.get_download_url(mods[mod]))
zip = http.fetch(shop.get_download_url(mods[mod]))
io.slurpwrite(cache_path, zip)
log.console(`${mod}: downloaded ${zip.length} bytes`)
// Calculate and store hash
var hash = crypto.hash(zip)
var hash_b32 = text(hash, "t")
lock.modules[mod] = {
hash: hash_b32,
url: mods[mod],
downloaded: time.text()
}
log.console(`${mod}: hash = ${hash_b32}`)
// Save updated lock file
io.slurpwrite(lock_path, toml.encode(lock))
}
// Extract the module
var reader = miniz.read(zip)
var count = reader.count()
log.console(`extracting ${mod} (${count} files)...`)
// Create module directory
if (!io.exists(module_path))
io.mkdir(module_path)
// Extract each file
for (var i = 0; i < count; i++) {
if (reader.is_directory(i))
continue
var filename = reader.get_filename(i)
// Strip the module name prefix if present
var prefix = mod + '/'
if (filename.indexOf(prefix) === 0)
filename = filename.substring(prefix.length)
// Skip if filename is empty after stripping
if (!filename)
continue
var filepath = module_path + '/' + filename
// Create subdirectories if needed
var parts = filename.split('/')
if (parts.length > 1) {
var dir = module_path
for (var j = 0; j < parts.length - 1; j++) {
dir = dir + '/' + parts[j]
if (!io.exists(dir))
io.mkdir(dir)
}
}
// Extract and write file
var data = reader.slurp(reader.get_filename(i))
io.slurpwrite(filepath, data)
}
log.console(`${mod}: extracted to ${module_path}`)
}
}
if (uses[arg[0]])
uses[arg[0]]()
else
console.log(`Command ${arg[0]} not understood.`)