UNPKG

md-nw-builder

Version:
196 lines (174 loc) 6.55 kB
var request = require('request'); var progress = require('progress'); var fs = require('fs'); var path = require('path'); var zlib = require('zlib'); var tar = require('tar-fs'); var temp = require('temp'); var ncp = require('graceful-ncp').ncp; var rimraf = require('rimraf'); var extract = require('extract-zip'); // Automatically track and cleanup files at exit temp.track(); var isWin = /^win/.test(process.platform); // one progressbar for all downloads var bar; module.exports = { checkCache: function(cachepath, files) { var missing; // if the version is >=0.12.3, then we don't know which files we want from the archives, so just check that the // folder exists and has at least 3 files in it. if(files.length === 1 && files[0] === '*'){ return fs.existsSync(cachepath) && fs.readdirSync(cachepath).length >= 2; } files.forEach(function(file) { if (missing) { return; } if (!fs.existsSync(path.join(cachepath, file))) { missing = true; } }); return !missing; }, clearProgressbar: function() { bar && bar.terminate(); bar = null; }, downloadAndUnpack: function(cachepath, url) { var extention = path.extname(url), self = this, rq = request(url), len, stream; function format(statusCode) { return statusCode + ': ' + require('http').STATUS_CODES[statusCode]; } return new Promise(function(resolve, reject){ //国内镜像网址,关闭代理 rq.proxy = false; rq.on('error', function(err) { console.log(err); bar && bar.terminate(); reject(err); }); rq.on('response', function (res) { len = parseInt(res.headers['content-length'], 10); if (res.statusCode !== 200) { 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') { rq.on('response', function(res) { if(res.statusCode !== 200) return; stream = temp.createWriteStream(); stream.on('finish', function() { self.extractZip(stream.path, cachepath).then(self.stripRootFolder).then(function(files) { resolve(files); }); }); rq.pipe(stream); }); } else if (extention === '.gz') { rq.on('response', function(res) { if(res.statusCode !== 200) return; self.extractTar(res, cachepath).then(self.stripRootFolder).then(function(files) { resolve(files); }); }); } }); }, extractTar: function(tarstream, destination) { var gunzip = zlib.createGunzip(), files = []; return new Promise(function(resolve, reject){ tarstream .pipe(gunzip) .on('error', function(err){ console.err(err); reject(err); }) .pipe(tar.extract(destination, { umask: (isWin ? false : 0), map: function(header) { files.push({path: path.basename(header.name)}); return header; } })) .on('finish', function() { resolve({files:files, destination:destination}); }); }); }, extractZip: function(zipfile, destination) { var files = []; var onEntry = function(entry){ files.push({ mode: entry.externalFileAttributes >>> 16, path: entry.fileName }); }; return new Promise(function(resolve, reject){ extract(zipfile, { dir: destination, onEntry: onEntry }, function(err){ if(err){ return reject(err); } // Setup chmodSync to fix permissions files.forEach(function(file) { fs.chmodSync(path.join(destination, file.path), file.mode); }); resolve({ files: files, destination: destination }); }); }); }, stripRootFolder: function(extracted){ var 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--; } } return new Promise(function(resolve, reject){ // move stripped folder to destination ncp(fromDir, destination, function (err) { if (err) { return reject(); } else rimraf(fromDir, function(){ resolve(files); }); }); }); } else { return Promise.resolve(files); } } };