execute = function (config) { // get packages var packages = []; fs.readdirSync(config.packagesLoc).forEach(function (loc) { var name = path.basename(loc); if (name[0] === ".") return; var pkgLoc = path.join(config.packagesLoc, name, "package.json"); if (!fs.existsSync(pkgLoc)) return; var pkg = require(pkgLoc); packages.push({ folder: name, pkg: pkg, name: pkg.name }); }); var completed = false; var tick = progressBar(packages.length); async.parallelLimit(packages.map(function (root) { return function (done) { var tasks = []; var nodeModulesLoc = path.join(config.packagesLoc, root.folder, "node_modules"); tasks.push(function (done) { mkdirp(nodeModulesLoc, done); }); tasks.push(function (done) { async.each(packages, function (sub, done) { var ver = false; if (root.pkg.dependencies) ver = root.pkg.dependencies[sub.name]; if (root.pkg.devDependencies && !ver) ver = root.pkg.devDependencies[sub.name]; if (!ver) return done(); // ensure that this is referring to a local package if (ver[0] !== "^" || ver[1] !== config.currentVersion[0]) return done(); var linkSrc = path.join(config.packagesLoc, sub.folder); var linkDest = path.join(nodeModulesLoc, sub.name); rimraf(linkDest, function (err) { if (err) return done(err); mkdirp(linkDest, function (err) { if (err) return done(err); fs.writeFile(path.join(linkDest, "package.json"), JSON.stringify({ name: sub.name, version: require(path.join(linkSrc, "package.json")).version }, null, " "), function (err) { if (err) return done(err); fs.writeFile(path.join(linkDest, "index.js"), "module.exports = require(" + JSON.stringify(linkSrc) + ");", done ); }); }); }); }, done); }); tasks.push(function (done) { child.exec("npm install", { cwd: path.join(config.packagesLoc, root.folder) }, function (err, stdout, stderr) { if (err != null) { done(stderr); } else { done(); } }); }); tasks.push(function (done) { if (!completed) tick(root.name); done(); }); async.series(tasks, done); }; }), 4, function (err) { // don't display the ticker if we hit an error and we still have workers completed = true; if (err) { console.error(err); console.log(); process.exit(1); } else { console.log(chalk.green("Successfully bootstrapped " + packages.length + " packages.")); console.log(); process.exit(); } }); }
...
if (!(arg in commands)) {
console.error("Unknown command " + JSON.stringify(arg));
process.exit(1);
}
var command = commands[arg];
command.execute(init(arg, process.cwd()));
...
execute = function (config) { var changedPackages = []; var changedFiles = [config.versionLoc]; var FORCE_VERSION = process.env.FORCE_VERSION; FORCE_VERSION = FORCE_VERSION ? FORCE_VERSION.split(",") : []; var NEW_VERSION = getVersion(); fs.writeFileSync(config.versionLoc, NEW_VERSION, "utf8"); // try { changedPackages = checkUpdatedPackages(config); console.log("Packages to be updated"); console.log(changedPackages.map(function(pkg) { return "- " + pkg; }).join("\n")); updateChangedPackages(); updateTag(); publish(); } catch (err) { onError(err); } // var createdTag = false; function updateTag() { var NEW_TAG_NAME = "v" + NEW_VERSION; execSync("git commit -m " + NEW_TAG_NAME); execSync("git tag " + NEW_TAG_NAME); createdTag = true; } function removeTag() { if (createdTag) { console.error(chalk.red("Attempting to roll back tag creation.")); execSync("git tag -d v" + NEW_VERSION); } } function getVersion() { var input = readline.question("New version (Leave blank for patch version): "); var ver = semver.valid(input); if (!ver) { ver = semver.inc(config.currentVersion, input || "patch"); } if (ver) { return ver; } else { console.log("Version provided is not valid semver."); return getVersion(); } } function execSync(cmd) { return child.execSync(cmd, { encoding: "utf8" }).trim(); } function getPackageLocation(name) { return config.packagesLoc + "/" + name; } function updateDepsObject(deps) { for (var depName in deps) { // ensure this was generated and we're on the same major if (deps[depName][0] !== "^" || deps[depName][1] !== NEW_VERSION[0]) continue; if (changedPackages.indexOf(depName) >= 0) { deps[depName] = "^" + NEW_VERSION; } } } function updateChangedPackages() { changedPackages.forEach(function (name) { var pkgLoc = getPackageLocation(name) + "/package.json"; var pkg = require(pkgLoc); // set new version pkg.version = NEW_VERSION; // updated dependencies updateDepsObject(pkg.dependencies); updateDepsObject(pkg.devDependencies); // write new package fs.writeFileSync(pkgLoc, JSON.stringify(pkg, null, " ") + "\n"); // push to be git committed changedFiles.push(pkgLoc); }); changedFiles.forEach(function (loc) { execSync("git add " + loc); }); } function publish() { changedPackages.forEach(function (name) { // prepublish script var prePub = getPackageLocation(name) + "/scripts/prepublish.js"; if (fs.existsSync(prePub)) require(prePub); }); console.log("Publishing tagged packages..."); var tick = progressBar(changedPackages.length); async.parallelLimit(changedPackages.map(function (name) { var retries = 0; return function run(done) { var loc = getPackageLocation(name); child.exec("cd " + loc + " && npm publish --tag prerelease", function (err, stdout, stderr) { if (err || stderr) { err = stderr || err.stack; if (err.indexOf("You cannot publish over the previously published version") < 0) { if (++retries < 5) { console.log(chalk.yellow("Attempting to retry publishing " + name + "...")); return run(done); } else { console.log(chalk.red("Ran out of retries while publishing " + name)); return done(err); } } else { // publishing over an existing package which is likely due to a timeout or something return done(); } } tick(name); // postpublish script var postPub = loc + "/scripts/postpublish.js"; if (fs.existsSync(postPub)) require(postPub); done(); }); }; }), 4, function (err) { onError(err); ship(); }); } function onError(err) { i ...
...
if (!(arg in commands)) {
console.error("Unknown command " + JSON.stringify(arg));
process.exit(1);
}
var command = commands[arg];
command.execute(init(arg, process.cwd()));
...
checkUpdatedPackages = function (config) { var changedPackages = []; var FORCE_VERSION = process.env.FORCE_VERSION; FORCE_VERSION = FORCE_VERSION ? FORCE_VERSION.split(",") : []; console.log("Checking packages..."); var packageNames = fs.readdirSync(config.packagesLoc).filter(function (name) { return name[0] !== "." && fs.statSync(config.packagesLoc + "/" + name).isDirectory(); }); var tick = progressBar(packageNames.length); var hasTags = !!execSync("git tag"); var lastTagCommit; var lastTag; if (hasTags) { lastTagCommit = execSync("git rev-list --tags --max-count=1"); lastTag = execSync("git describe --tags " + lastTagCommit); } packageNames.forEach(function (name) { var cfg = getPackageConfig(config, name); tick(name); if (cfg.private) return; if (!hasTags) { changedPackages.push(name); return; } // check if package has changed since last release var diff = FORCE_VERSION.indexOf("*") >= 0 || FORCE_VERSION.indexOf(name) >= 0 || execSync("git diff " + lastTag + " -- " + getPackageLocation(config, name)); if (diff) { changedPackages.push(name); } }); if (!changedPackages.length && !FORCE_VERSION.length) { console.error(chalk.red("No updated packages to publish.")); process.exit(1); } else { return changedPackages; } }
...
var chalk = require("chalk");
var child = require("child_process");
var fs = require("fs");
exports.description = "Check which packages have changed since the last release";
exports.execute = function (config) {
var changedPackages = exports.checkUpdatedPackages(config).map(function(pkg) {
return "- " + pkg;
}).join("\n");
console.log(changedPackages);
}
exports.checkUpdatedPackages = function (config) {
...
execute = function (config) { var changedPackages = exports.checkUpdatedPackages(config).map(function(pkg) { return "- " + pkg; }).join("\n"); console.log(changedPackages); }
...
if (!(arg in commands)) {
console.error("Unknown command " + JSON.stringify(arg));
process.exit(1);
}
var command = commands[arg];
command.execute(init(arg, process.cwd()));
...