Skip to content

Commit

Permalink
refactor(publish,version): Compose package actions into reusable pipe…
Browse files Browse the repository at this point in the history
…lines
  • Loading branch information
evocateur committed Aug 27, 2018
1 parent 8e0aa96 commit 0d7ffcf
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 100 deletions.
110 changes: 56 additions & 54 deletions commands/publish/index.js
Expand Up @@ -4,6 +4,7 @@ const os = require("os");
const path = require("path");
const pFinally = require("p-finally");
const pMap = require("p-map");
const pPipe = require("p-pipe");
const pReduce = require("p-reduce");
const semver = require("semver");

Expand Down Expand Up @@ -386,12 +387,8 @@ class PublishCommand extends Command {
} catch (ex) {
this.logger.silly("execScript", `No ${script} script found at ${scriptLocation}`);
}
}

runPrepublishScripts(pkg) {
return Promise.resolve()
.then(() => this.runPackageLifecycle(pkg, "prepare"))
.then(() => this.runPackageLifecycle(pkg, "prepublishOnly"));
return pkg;
}

removeTempLicensesOnError(error) {
Expand All @@ -414,12 +411,7 @@ class PublishCommand extends Command {
packUpdated() {
const tracker = this.logger.newItem("npm pack");

tracker.addWork(
this.options.requireScripts
? // track completion of prepublish.js on updates as well
this.packagesToPublish.length + this.updates.length
: this.packagesToPublish.length
);
tracker.addWork(this.packagesToPublish.length);

let chain = Promise.resolve();

Expand All @@ -428,22 +420,25 @@ class PublishCommand extends Command {
});

chain = chain.then(() => createTempLicenses(this.project.licensePath, this.packagesToBeLicensed));
chain = chain.then(() => this.runPrepublishScripts(this.project.manifest));

chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "prepare"));
chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "prepublishOnly"));

const actions = [];

if (this.options.requireScripts) {
chain = chain.then(() =>
pMap(this.updates, ({ pkg }) => {
this.execScript(pkg, "prepublish");
tracker.completeWork(1);
})
);
actions.push(pkg => this.execScript(pkg, "prepublish"));
}

const mapper = pPipe(actions);

chain = chain.then(() =>
pReduce(this.batchedPackages, (_, batch) =>
this.npmPack(batch).then(() => {
tracker.completeWork(batch.length);
})
pMap(batch, mapper)
.then(() => this.npmPack(batch))
.then(() => {
tracker.completeWork(batch.length);
})
)
);

Expand All @@ -464,22 +459,26 @@ class PublishCommand extends Command {

let chain = Promise.resolve();

chain = chain.then(() =>
runParallelBatches(this.batchedPackages, this.concurrency, pkg =>
npmPublish(pkg, distTag, this.npmConfig)
// postpublish is _not_ run when publishing a tarball
.then(() => this.runPackageLifecycle(pkg, "postpublish"))
.then(() => {
tracker.info("published", pkg.name);
const actions = [
pkg => npmPublish(pkg, distTag, this.npmConfig),
// postpublish is _not_ run when publishing a tarball
pkg => this.runPackageLifecycle(pkg, "postpublish"),
];

if (this.options.requireScripts) {
this.execScript(pkg, "postpublish");
}
if (this.options.requireScripts) {
actions.push(pkg => this.execScript(pkg, "postpublish"));
}

tracker.completeWork(1);
})
)
);
actions.push(pkg => {
tracker.info("published", pkg.name, pkg.version);
tracker.completeWork(1);

return pkg;
});

const mapper = pPipe(actions);

chain = chain.then(() => runParallelBatches(this.batchedPackages, this.concurrency, mapper));

chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "postpublish"));

Expand All @@ -494,27 +493,30 @@ class PublishCommand extends Command {

let chain = Promise.resolve();

chain = chain.then(() =>
runParallelBatches(this.batchedPackages, this.concurrency, pkg =>
this.updateTag(pkg, distTag).then(() => {
tracker.info("dist-tag", "%s@%s => %j", pkg.name, pkg.version, distTag);
tracker.completeWork(1);
})
)
);
const actions = [
pkg =>
Promise.resolve()
.then(() => npmDistTag.check(pkg, "lerna-temp", this.npmConfig))
.then(exists => {
if (exists) {
return npmDistTag.remove(pkg, "lerna-temp", this.npmConfig);
}
})
.then(() => npmDistTag.add(pkg, distTag, this.npmConfig))
.then(() => pkg),
pkg => {
tracker.info("dist-tag", "%s@%s => %j", pkg.name, pkg.version, distTag);
tracker.completeWork(1);

return pFinally(chain, () => tracker.finish());
}
return pkg;
},
];

updateTag(pkg, distTag) {
return Promise.resolve()
.then(() => npmDistTag.check(pkg, "lerna-temp", this.npmConfig))
.then(exists => {
if (exists) {
return npmDistTag.remove(pkg, "lerna-temp", this.npmConfig);
}
})
.then(() => npmDistTag.add(pkg, distTag, this.npmConfig));
const mapper = pPipe(actions);

chain = chain.then(() => runParallelBatches(this.batchedPackages, this.concurrency, mapper));

return pFinally(chain, () => tracker.finish());
}

getDistTag() {
Expand Down
1 change: 1 addition & 0 deletions commands/publish/package.json
Expand Up @@ -52,6 +52,7 @@
"npmlog": "^4.1.2",
"p-finally": "^1.0.0",
"p-map": "^1.2.0",
"p-pipe": "^1.2.0",
"p-reduce": "^1.0.0",
"semver": "^5.5.0"
}
Expand Down
89 changes: 43 additions & 46 deletions commands/version/index.js
Expand Up @@ -5,6 +5,7 @@ const chalk = require("chalk");
const dedent = require("dedent");
const minimatch = require("minimatch");
const pMap = require("p-map");
const pPipe = require("p-pipe");
const pReduce = require("p-reduce");
const pWaterfall = require("p-waterfall");
const semver = require("semver");
Expand Down Expand Up @@ -367,61 +368,57 @@ class VersionCommand extends Command {
// exec preversion lifecycle in root (before all updates)
chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "preversion"));

chain = chain.then(() => {
const mapUpdate = ({ pkg, localDependencies }) => {
// start the chain
let tasks = Promise.resolve();
const actions = [
pkg => this.runPackageLifecycle(pkg, "preversion"),
pkg => {
// set new version
pkg.version = this.updatesVersions.get(pkg.name);

// exec preversion script
tasks = tasks.then(() => this.runPackageLifecycle(pkg, "preversion"));
// update pkg dependencies
for (const [depName, resolved] of this.packageGraph.get(pkg.name).localDependencies) {
const depVersion = this.updatesVersions.get(depName);

// write new package
tasks = tasks.then(() => {
// set new version
pkg.version = this.updatesVersions.get(pkg.name);

// update pkg dependencies
for (const [depName, resolved] of localDependencies) {
const depVersion = this.updatesVersions.get(depName);

if (depVersion && resolved.type !== "directory") {
// don't overwrite local file: specifiers, they only change during publish
pkg.updateLocalDependency(resolved, depVersion, this.savePrefix);
}
if (depVersion && resolved.type !== "directory") {
// don't overwrite local file: specifiers, they only change during publish
pkg.updateLocalDependency(resolved, depVersion, this.savePrefix);
}
}

return pkg.serialize().then(() => {
// commit the updated manifest
changedFiles.add(pkg.manifestLocation);
});
return pkg.serialize().then(() => {
// commit the updated manifest
changedFiles.add(pkg.manifestLocation);

return pkg;
});
},
pkg => this.runPackageLifecycle(pkg, "version"),
];

// exec version script
tasks = tasks.then(() => this.runPackageLifecycle(pkg, "version"));

if (conventionalCommits) {
tasks = tasks.then(() => {
// we can now generate the Changelog, based on the
// the updated version that we're about to release.
const type = independentVersions ? "independent" : "fixed";

return ConventionalCommitUtilities.updateChangelog(pkg, type, {
changelogPreset,
rootPath,
tagPrefix: this.tagPrefix,
}).then(changelogLocation => {
// commit the updated changelog
changedFiles.add(changelogLocation);
});
});
}
if (conventionalCommits) {
// we can now generate the Changelog, based on the
// the updated version that we're about to release.
const type = independentVersions ? "independent" : "fixed";

return tasks;
};
actions.push(pkg =>
ConventionalCommitUtilities.updateChangelog(pkg, type, {
changelogPreset,
rootPath,
tagPrefix: this.tagPrefix,
}).then(changelogLocation => {
// commit the updated changelog
changedFiles.add(changelogLocation);

return pkg;
})
);
}

const mapUpdate = pPipe(actions);

chain = chain.then(() =>
// TODO: tune the concurrency?
return pMap(this.updates, mapUpdate, { concurrency: 100 });
});
pMap(this.updates, mapUpdate, { concurrency: 100 })
);

if (!independentVersions) {
this.project.version = this.globalVersion;
Expand Down
1 change: 1 addition & 0 deletions commands/version/package.json
Expand Up @@ -46,6 +46,7 @@
"minimatch": "^3.0.4",
"npmlog": "^4.1.2",
"p-map": "^1.2.0",
"p-pipe": "^1.2.0",
"p-reduce": "^1.0.0",
"p-waterfall": "^1.0.0",
"semver": "^5.5.0",
Expand Down
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0d7ffcf

Please sign in to comment.