From fde364e7f53445b84cdfe44e26bf2512dc4df0e2 Mon Sep 17 00:00:00 2001 From: Hamish Buckmaster Date: Tue, 25 May 2021 21:55:51 +1000 Subject: [PATCH] feat(publish/index.js): Added OutputJson Command Outputs the packages and versions from publishing to a JSON file. --- commands/publish/README.md | 22 +++++++++++++++ .../publish/__tests__/publish-command.test.js | 27 +++++++++++++++++++ commands/publish/command.js | 5 ++++ commands/publish/index.js | 24 +++++++++++++++-- 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/commands/publish/README.md b/commands/publish/README.md index f86b27c781..b5c282c6e0 100644 --- a/commands/publish/README.md +++ b/commands/publish/README.md @@ -65,6 +65,7 @@ This is useful when a previous `lerna publish` failed to publish all packages to - [`--tag-version-prefix`](#--tag-version-prefix) - [`--temp-tag`](#--temp-tag) - [`--yes`](#--yes) +- [`--summary-file `](#--summary-file) ### `--canary` @@ -291,6 +292,27 @@ lerna publish --canary --yes When run with this flag, `lerna publish` will skip all confirmation prompts. Useful in [Continuous integration (CI)](https://en.wikipedia.org/wiki/Continuous_integration) to automatically answer the publish confirmation prompt. +### `--summary-file` + +```sh +lerna publish --canary --yes --summary-file ./output.json +``` + +When run with this flag, once a successfully publish it will create a json summary report(see below for an example). + +```json +[ + { + "packageName": "package1", + "version": "v1.0.1-alpha" + }, + { + "packageName": "package2", + "version": "v2.0.1-alpha" + } +] +``` + ## Deprecated Options ### `--skip-npm` diff --git a/commands/publish/__tests__/publish-command.test.js b/commands/publish/__tests__/publish-command.test.js index 75a50df3e9..a50e79df5a 100644 --- a/commands/publish/__tests__/publish-command.test.js +++ b/commands/publish/__tests__/publish-command.test.js @@ -34,6 +34,8 @@ const initFixture = require("@lerna-test/init-fixture")(__dirname); const path = require("path"); const fs = require("fs-extra"); +const fsmain = require("fs"); + // file under test const lernaPublish = require("@lerna-test/command-runner")(require("../command")); @@ -306,6 +308,31 @@ Map { }); }); + describe("--summary-file", () => { + it("skips creating the summary file", async () => { + const cwd = await initFixture("normal"); + const fsSpy = jest.spyOn(fs, "writeFileSync"); + await lernaPublish(cwd); + + expect(fsSpy).not.toHaveBeenCalled(); + }); + + it("creates the summary file", async () => { + const cwd = await initFixture("normal"); + const fsSpy = jest.spyOn(fsmain, "writeFileSync"); + await lernaPublish(cwd)("--summary-file", "./output.json"); + + const expectedJsonResponse = [ + { packageName: "package-1", version: "1.0.1" }, + { packageName: "package-2", version: "1.0.1" }, + { packageName: "package-3", version: "1.0.1" }, + { packageName: "package-4", version: "1.0.1" }, + ]; + expect(fsSpy).toHaveBeenCalled(); + expect(fsSpy).toHaveBeenCalledWith("./output.json", JSON.stringify(expectedJsonResponse)); + }); + }); + describe("--no-verify-access", () => { it("skips package access verification", async () => { const cwd = await initFixture("normal"); diff --git a/commands/publish/command.js b/commands/publish/command.js index ec2d3e9b0d..39f2b6a50b 100644 --- a/commands/publish/command.js +++ b/commands/publish/command.js @@ -110,6 +110,11 @@ exports.builder = (yargs) => { hidden: true, type: "boolean", }, + "summary-file": { + // Json output. + hidden: true, + type: "string", + }, // y: { // describe: "Skip all confirmation prompts.", // alias: "yes", diff --git a/commands/publish/index.js b/commands/publish/index.js index 16d12a2c88..dd5851838d 100644 --- a/commands/publish/index.js +++ b/commands/publish/index.js @@ -1,6 +1,7 @@ "use strict"; const os = require("os"); +const fs = require("fs"); const path = require("path"); const crypto = require("crypto"); const pMap = require("p-map"); @@ -237,10 +238,29 @@ class PublishCommand extends Command { return chain.then(() => { const count = this.packagesToPublish.length; - const message = this.packagesToPublish.map((pkg) => ` - ${pkg.name}@${pkg.version}`); output("Successfully published:"); - output(message.join(os.EOL)); + + if (this.options.summaryFile) { + // create a json object and output it to a file location. + const filePath = this.options.summaryFile || "./output.json"; + const jsonObject = this.packagesToPublish.map((pkg) => { + return { + packageName: pkg.name, + version: pkg.version, + }; + }); + output(jsonObject); + try { + fs.writeFileSync(filePath, JSON.stringify(jsonObject)); + output("Locate Summary Report Here: ", filePath); + } catch (error) { + output("Failed to create the summary report", error); + } + } else { + const message = this.packagesToPublish.map((pkg) => ` - ${pkg.name}@${pkg.version}`); + output(message.join(os.EOL)); + } this.logger.success("published", "%d %s", count, count === 1 ? "package" : "packages"); });