UNPKG

grunt-download-wcjs

Version:

Grunt task to download pre-built WebChimera.js for Electron & NW.JS.

142 lines (127 loc) 4.44 kB
var Promise = require('bluebird'); var request = require('request'); var progress = require('progress'); var fs = require('fs'); var path = require('path'); var temp = require('temp'); var DecompressZip = require('decompress-zip'); var ncp = require('graceful-ncp').ncp; var rimraf = require('rimraf'); // Automatically track and cleanup files at exit temp.track(); var isWin = /^win/.test(process.platform); // one progressbar for all downloads var bar; module.exports = { clearProgressbar: function() { bar && bar.terminate(); bar = null; }, downloadAndUnpack: function(cachepath, url) { var extention = path.extname(url), done = Promise.defer(), self = this, rq = request(url), len, stream; function format(statusCode) { return statusCode + ': ' + require('http').STATUS_CODES[statusCode]; } rq.on('error', function(err) { bar && bar.terminate(); done.reject(err); }); rq.on('response', function(res) { len = parseInt(res.headers['content-length'], 10); if (res.statusCode !== 200) { done.reject({ statusCode: res.statusCode, msg: 'Recieved status code ' + format(res.statusCode) }); } else if (len) { if (!bar) { bar = new progress(' downloading [:bar] :percent :etas', { complete: '=', incomplete: '-', width: 20, total: len }); } else { bar.total += len; } } }); rq.on('data', function(chunk) { len && bar && bar.tick(chunk.length); }); if (extention === '.zip') { stream = temp.createWriteStream(); stream.on('close', function() { if (done.promise.isRejected()) return; self.extractZip(stream.path, cachepath).then(self.stripRootFolder).then(function(files) { done.resolve(files); }); }); rq.pipe(stream); } return done.promise; }, extractZip: function(zipfile, destination) { var files = [], done = Promise.defer(); new DecompressZip(zipfile) .on('error', function(err) { done.reject(err); }) .on('extract', function(log) { // Setup chmodSync to fix permissions files.forEach(function(file) { fs.chmodSync(path.join(destination, file.path), file.mode); }); done.resolve({ files: files, destination: destination }); }) .extract({ path: destination, filter: function(entry) { files.push({ path: entry.path, mode: entry.mode.toString(8) }); return true; } }); return done.promise; }, stripRootFolder: function(extracted) { var done = Promise.defer(), files = extracted.files, destination = extracted.destination, rootFiles = fs.readdirSync(destination), fromDir = path.join(destination, rootFiles.length === 1 ? rootFiles[0] : ''); // strip out root folder if it exists if (rootFiles.length === 1 && fs.statSync(fromDir).isDirectory()) { // strip folder from files for (var i = 0; i < files.length; i++) { var file = files[i]; file.path = path.relative(rootFiles[0], file.path); if (file.path === '') { files.splice(i, 1); i--; } } // move stripped folder to destination ncp(fromDir, destination, function(err) { if (err) done.reject(); else rimraf(fromDir, function() { done.resolve(files); }); }); } else { done.resolve(files); } return done.promise; } };