nyx_server
Version:
Node内容发布
117 lines (107 loc) • 3.94 kB
JavaScript
/* global process */
var tmp = require("tmp")
var Promise = require("bluebird");
var copy = require("./utils/copy");
var md5 = require("./utils/md5");
var path = require("path");
var fs = require("fs");
var cmd = require("./utils/cmd");
var rimraf = require("rimraf");
var EmptyContext = require("./EmptyContext");
var statusFutureCache = {};
/**
* 从远程地址中装载一个项目
* 最终返回checkout的目录位置
*/
function loadResource(name, gitRepo, version, installBaseDir) {
var context = this.log ? this : EmptyContext;
var log = context.log;
log.info("从git中checkout指定版本项目。", arguments);
var dir = name + "_" + md5(gitRepo);
var key = name + "_" + md5(gitRepo + "#" + (version || ""));
var checkoutFuture = statusFutureCache[key];
if (checkoutFuture) {
log.info("项目已经checkout,使用缓存");
return checkoutFuture;
}
var projectDir = path.join(installBaseDir, dir, version);
log.debug("installDir : " + projectDir);
var ret = new Promise(function (resolve, reject) {
fs.exists(projectDir, function (exists) {
if (exists) {
resolve({ needCpoy: false });
} else {
tmp.dir({ unsafeCleanup: false }, function (err, path, cleanupCallback) {
if (err) throw err;
log.debug('temp dir : ' + path);
_clone(gitRepo, path)
.then(function () {
return _checkout(version, path);
})
.then(function () {
return _cleanup.bind(context)(path);
})
.then(function () {
resolve({ 'needCopy': true, 'path': path, 'cleanFn': cleanupCallback });
})
.catch(function (err) {
log.error(err);
throw new Error(err);
}).error(function (err) {
log.error(err);
});
});
}
});
}).then(function (status) {
var ret1 = { "projectBaseDir": projectDir, 'name': name, "gitRepo": gitRepo, 'version': version };
if (!status.needCopy) {
return ret1;
}
var srcPath = status.path; //临时目录
return copy.copyDir(srcPath, projectDir, { ignore: [".ignore", ".gitignore"] }).then(function () {
fs.rmdir(srcPath, function () { });
return ret1;
}).error(function (err) {
log.error(err);
});
}).then(function (result) {
log.info("完成项目checkout");
return result;
});
statusFutureCache[key] = ret;
return ret;
}
function _clone(repo, clonePath) {
return cmd('git', ['clone', repo, clonePath, '--progress']);
};
// Override the checkout function to work with the local copy
function _checkout(v, path) {
return cmd('git', ['checkout', '-f', v], { 'cwd': path }) // Copy files to the path directory first
.then(cmd.bind(cmd, 'git', ['clean', '-f', '-d'], { 'cwd': path })); // Cleanup unstaged files
};
function _cleanup(targetDir) {
var context = this.log ? this : EmptyContext;
var log = context.log;
var gitFolder = path.join(targetDir, '.git');
log.debug("gitFolder : " + gitFolder);
return new Promise(function (resolve, reject) {
rimraf(gitFolder, function (err) {
if (err) {
reject(err);
} else {
resolve();
}
});
});
};
function _getTags() {
return cmd('git', ['tag']).then(function (data) {
return data[0].match(/.*[\r|\n]/g);
});
}
module.exports = {
'loadResource': loadResource,
"clone": _clone,
"checkout": _checkout
};