kef-cloudbuild-runner
Version:
runner for cloudbuild
110 lines (95 loc) • 2.78 kB
JavaScript
;
const path = require('path');
const md5 = require('md5');
const fs = require('fs-extra');
const tar_stream = require('tar-stream');
const zlib = require('zlib');
const s_log = require('./log');
const glob = require('glob');
exports.run = function* (options) {
s_log.info('构建完成,正在获取构建结果');
// 检查构建结果是否为空
const dir = path.join(options.projectDir, options.buildDest);
const stats = yield fs.stat(dir).catch(e => {
return Promise.reject(Error(`错误:构建结果为空。修复请参考文档:http://def.alibaba-inc.com/doc/build/config/config_dest`));
});
if (!stats.isDirectory()) {
throw Error(`错误:构建结果不是目录`);
};
// 打包构建结果(tar.gz 文件流)
s_log.info('正在打包构建结果');
const tgz_stream = yield pack(dir);
// 为了获取文件 md5,先把 tgz 存放在临时目录中
const tgzfile = path.join(options.projectDir, '__def_tmp.tar.gz');
yield new Promise((resolve, reject) => {
tgz_stream.pipe(zlib.createGzip()).pipe(fs.createWriteStream(tgzfile)).on('error', (err) => {
reject(err);
}).on('finish', () => {
resolve();
});
});
// 计算 md5
const file_md5 = yield fs.readFile(tgzfile).then(function(buf) {
return md5(buf);
});
// 返回流和 md5
return {
file: tgzfile,
md5: file_md5
};
};
exports.getPackFiles = getPackFiles;
function *pack(cwd) {
const files = yield getPackFiles({
where: cwd
});
const stream = yield getStream(cwd, files);
return stream;
}
// 获取待打包文件列表
function* getPackFiles(options) {
const where = options.where,
ignore = options.ignore,
patterns = options.patterns || '**/*';
return new Promise(function (resolve, reject) {
var tar_pack;
glob(patterns, {
cwd: where,
dot: true
}, function (err, matches) {
if (err) {
return reject(err);
};
if (ignore) {
matches = ignore.filter(matches);
};
resolve(matches);
});
});
}
// 提取文件并加入到 tar stream 中
function* getStream(where, files) {
if (!files.length) {
throw Error('待打包文件夹下无文件');
};
const tar_pack = tar_stream.pack();
for (let file of files) {
let filePath = path.join(where, file);
let stat = fs.statSync(filePath);
// 必须设置 mtime,否则每次生成的 gzip 包 md5 不一致
if (stat.isDirectory()) {
tar_pack.entry({
name: file,
mtime: new Date(stat.mtime),
type: 'directory'
});
} else {
tar_pack.entry({
name: file,
mtime: new Date(stat.mtime),
}, fs.readFileSync(filePath))
}
};
tar_pack.finalize();
return tar_pack;
};