From 25d43dab65bde34027a40ce2f36438b793d6b34d Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Wed, 2 Dec 2020 18:36:32 +0100 Subject: [PATCH 1/8] Dont fail status command if there are no changed packages --- .../src/commands/status/__tests__/status.ts | 53 +++++++++++++++++-- packages/cli/src/commands/status/index.ts | 24 ++++++--- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/commands/status/__tests__/status.ts b/packages/cli/src/commands/status/__tests__/status.ts index 1a57df630..95bddc780 100644 --- a/packages/cli/src/commands/status/__tests__/status.ts +++ b/packages/cli/src/commands/status/__tests__/status.ts @@ -1,6 +1,7 @@ import fixtures from "fixturez"; import fs from "fs-extra"; import path from "path"; +import * as git from "@changesets/git"; import { defaultConfig } from "@changesets/config"; import { temporarilySilenceLogs } from "@changesets/test-utils"; import writeChangeset from "@changesets/write"; @@ -11,6 +12,7 @@ import humanId from "human-id"; import { NewChangeset, ReleasePlan } from "@changesets/types"; jest.mock("human-id"); +jest.mock("@changesets/git"); const f = fixtures(__dirname); @@ -53,8 +55,6 @@ const simpleReleasePlan: ReleasePlan = { preState: undefined }; -jest.mock("@changesets/git"); - const writeChangesets = (changesets: NewChangeset[], cwd: string) => { return Promise.all(changesets.map(commit => writeChangeset(commit, cwd))); }; @@ -64,6 +64,8 @@ describe("status", () => { let cwd: string; beforeEach(async () => { + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation(() => []); cwd = await f.copy("simple-project"); }); @@ -76,13 +78,58 @@ describe("status", () => { const releaseObj = await status(cwd, {}, defaultConfig); expect(releaseObj).toEqual(simpleReleasePlan); }); - it("should exit with a non-zero error code when there are no changesets", async () => { + + it("should exit early with a non-zero error code when there are changed packages but no changesets", async () => { // @ts-ignore const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation(() => [ + { + name: "pkg-a", + version: "0.0.1" + } + ]); + await status(cwd, {}, defaultConfig); + expect(mockExit).toHaveBeenCalledWith(1); }); + it("should not exit early with a non-zero error code when there are no changed packages", async () => { + // @ts-ignore + const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); + + const releaseObj = await status(cwd, {}, defaultConfig); + + expect(mockExit).not.toHaveBeenCalled(); + expect(releaseObj).toEqual({ + changesets: [], + releases: [], + preState: undefined + }); + }); + + it("should not exit early with a non-zero code when there are changed packages and also a changeset", async () => { + // @ts-ignore + const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation(() => [ + { + name: "pkg-a", + version: "0.0.1" + } + ]); + const changesetID = "ascii"; + // @ts-ignore + humanId.mockReturnValueOnce(changesetID); + + await writeChangesets([simpleChangeset], cwd); + const releaseObj = await status(cwd, {}, defaultConfig); + + expect(releaseObj).toEqual(simpleReleasePlan); + expect(mockExit).not.toHaveBeenCalled(); + }); + it.skip("should respect since master flag", () => false); it.skip("should respect the verbose flag", () => false); it("should respect the output flag", async () => { diff --git a/packages/cli/src/commands/status/index.ts b/packages/cli/src/commands/status/index.ts index f53eba24b..0dcecae91 100644 --- a/packages/cli/src/commands/status/index.ts +++ b/packages/cli/src/commands/status/index.ts @@ -2,6 +2,8 @@ import chalk from "chalk"; import table from "tty-table"; import fs from "fs-extra"; import path from "path"; + +import * as git from "@changesets/git"; import getReleasePlan from "@changesets/get-release-plan"; import { error, log, info, warn } from "@changesets/logger"; import { @@ -32,16 +34,22 @@ export default async function getStatus( ); warn("Use --since=master instead"); } - const releasePlan = await getReleasePlan( - cwd, - since === undefined ? (sinceMaster ? "master" : undefined) : since, - config - ); - + const sinceBranch = + since === undefined ? (sinceMaster ? "master" : undefined) : since; + const releasePlan = await getReleasePlan(cwd, sinceBranch, config); const { changesets, releases } = releasePlan; + const changedPackages = await git.getChangedPackagesSinceRef({ + cwd, + ref: sinceBranch || config.baseBranch + }); - if (changesets.length < 1) { - error("No changesets present"); + if (changedPackages.length > 0 && changesets.length === 0) { + error( + "Some packages have been changed but no changesets were found. Run `changeset add` to resolve this error." + ); + error( + "If this change doesn't need a release, run `changeset add --empty`." + ); process.exit(1); } From 12275948da16018a726ca0e33f5de13dd270153c Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Wed, 23 Dec 2020 17:53:28 +0100 Subject: [PATCH 2/8] Mock process.exit separately for each test --- .../cli/src/commands/status/__tests__/status.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/commands/status/__tests__/status.ts b/packages/cli/src/commands/status/__tests__/status.ts index 95bddc780..db33431be 100644 --- a/packages/cli/src/commands/status/__tests__/status.ts +++ b/packages/cli/src/commands/status/__tests__/status.ts @@ -66,6 +66,8 @@ describe("status", () => { beforeEach(async () => { // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation(() => []); + // @ts-ignore + jest.spyOn(process, "exit").mockImplementation(() => {}); cwd = await f.copy("simple-project"); }); @@ -80,8 +82,6 @@ describe("status", () => { }); it("should exit early with a non-zero error code when there are changed packages but no changesets", async () => { - // @ts-ignore - const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation(() => [ { @@ -92,16 +92,13 @@ describe("status", () => { await status(cwd, {}, defaultConfig); - expect(mockExit).toHaveBeenCalledWith(1); + expect(process.exit).toHaveBeenCalledWith(1); }); it("should not exit early with a non-zero error code when there are no changed packages", async () => { - // @ts-ignore - const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); - const releaseObj = await status(cwd, {}, defaultConfig); - expect(mockExit).not.toHaveBeenCalled(); + expect(process.exit).not.toHaveBeenCalled(); expect(releaseObj).toEqual({ changesets: [], releases: [], @@ -110,8 +107,6 @@ describe("status", () => { }); it("should not exit early with a non-zero code when there are changed packages and also a changeset", async () => { - // @ts-ignore - const mockExit = jest.spyOn(process, "exit").mockImplementation(() => {}); // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation(() => [ { @@ -127,7 +122,7 @@ describe("status", () => { const releaseObj = await status(cwd, {}, defaultConfig); expect(releaseObj).toEqual(simpleReleasePlan); - expect(mockExit).not.toHaveBeenCalled(); + expect(process.exit).not.toHaveBeenCalled(); }); it.skip("should respect since master flag", () => false); From d37fa45e74e1f2aa1dd1c927ddb2e091ab96e17a Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Wed, 23 Dec 2020 17:56:01 +0100 Subject: [PATCH 3/8] Remove leftover console.log for debugging --- packages/cli/src/commands/add/createChangeset.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index e52ebed99..527a8c814 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -218,7 +218,6 @@ export default async function createChangeset( )}? (current version is ${pkg.packageJson.version})`, ["patch", "minor", "major"] ); - console.log(type); if (type === "major") { let shouldReleaseAsMajor = await confirmMajorRelease(pkg.packageJson); if (!shouldReleaseAsMajor) { From 9560e3a4b8779bd3c785b3e647858e55a61103b6 Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Wed, 23 Dec 2020 18:44:58 +0100 Subject: [PATCH 4/8] Improve getChangedPackagesSinceRef mocking --- .../src/commands/status/__tests__/status.ts | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/packages/cli/src/commands/status/__tests__/status.ts b/packages/cli/src/commands/status/__tests__/status.ts index db33431be..4eeb38368 100644 --- a/packages/cli/src/commands/status/__tests__/status.ts +++ b/packages/cli/src/commands/status/__tests__/status.ts @@ -10,6 +10,7 @@ import status from ".."; import humanId from "human-id"; import { NewChangeset, ReleasePlan } from "@changesets/types"; +import { Package } from "@manypkg/get-packages"; jest.mock("human-id"); jest.mock("@changesets/git"); @@ -55,6 +56,17 @@ const simpleReleasePlan: ReleasePlan = { preState: undefined }; +const simpleChangedPackagesList: Package[] = [ + { + packageJson: { name: "pkg-a", version: "1.0.0", dependencies: {} }, + dir: "/fake/folder/doesnt/matter" + }, + { + packageJson: { name: "pkg-b", version: "1.0.0" }, + dir: "/fake/folder/doesnt/matter" + } +]; + const writeChangesets = (changesets: NewChangeset[], cwd: string) => { return Promise.all(changesets.map(commit => writeChangeset(commit, cwd))); }; @@ -64,8 +76,6 @@ describe("status", () => { let cwd: string; beforeEach(async () => { - // @ts-ignore - git.getChangedPackagesSinceRef.mockImplementation(() => []); // @ts-ignore jest.spyOn(process, "exit").mockImplementation(() => {}); cwd = await f.copy("simple-project"); @@ -75,6 +85,10 @@ describe("status", () => { const changesetID = "ascii"; // @ts-ignore humanId.mockReturnValueOnce(changesetID); + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation( + () => simpleChangedPackagesList + ); await writeChangesets([simpleChangeset], cwd); const releaseObj = await status(cwd, {}, defaultConfig); @@ -83,12 +97,9 @@ describe("status", () => { it("should exit early with a non-zero error code when there are changed packages but no changesets", async () => { // @ts-ignore - git.getChangedPackagesSinceRef.mockImplementation(() => [ - { - name: "pkg-a", - version: "0.0.1" - } - ]); + git.getChangedPackagesSinceRef.mockImplementation( + () => simpleChangedPackagesList + ); await status(cwd, {}, defaultConfig); @@ -96,6 +107,9 @@ describe("status", () => { }); it("should not exit early with a non-zero error code when there are no changed packages", async () => { + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation(() => []); + const releaseObj = await status(cwd, {}, defaultConfig); expect(process.exit).not.toHaveBeenCalled(); @@ -108,12 +122,9 @@ describe("status", () => { it("should not exit early with a non-zero code when there are changed packages and also a changeset", async () => { // @ts-ignore - git.getChangedPackagesSinceRef.mockImplementation(() => [ - { - name: "pkg-a", - version: "0.0.1" - } - ]); + git.getChangedPackagesSinceRef.mockImplementation( + () => simpleChangedPackagesList + ); const changesetID = "ascii"; // @ts-ignore humanId.mockReturnValueOnce(changesetID); @@ -130,6 +141,10 @@ describe("status", () => { it("should respect the output flag", async () => { const output = "nonsense.json"; + // @ts-ignore + git.getChangedPackagesSinceRef.mockImplementation( + () => simpleChangedPackagesList + ); const changesetID = "ascii"; // @ts-ignore humanId.mockReturnValueOnce(changesetID); From fc54526978727ab04f0b237be2fc81efc18e02f7 Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Wed, 23 Dec 2020 18:56:55 +0100 Subject: [PATCH 5/8] Mock process.exit in each test for clarity --- packages/cli/src/commands/status/__tests__/status.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/status/__tests__/status.ts b/packages/cli/src/commands/status/__tests__/status.ts index 4eeb38368..376f1e04d 100644 --- a/packages/cli/src/commands/status/__tests__/status.ts +++ b/packages/cli/src/commands/status/__tests__/status.ts @@ -76,8 +76,6 @@ describe("status", () => { let cwd: string; beforeEach(async () => { - // @ts-ignore - jest.spyOn(process, "exit").mockImplementation(() => {}); cwd = await f.copy("simple-project"); }); @@ -96,6 +94,8 @@ describe("status", () => { }); it("should exit early with a non-zero error code when there are changed packages but no changesets", async () => { + // @ts-ignore + jest.spyOn(process, "exit").mockImplementation(() => {}); // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation( () => simpleChangedPackagesList @@ -107,6 +107,8 @@ describe("status", () => { }); it("should not exit early with a non-zero error code when there are no changed packages", async () => { + // @ts-ignore + jest.spyOn(process, "exit").mockImplementation(() => {}); // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation(() => []); @@ -121,6 +123,8 @@ describe("status", () => { }); it("should not exit early with a non-zero code when there are changed packages and also a changeset", async () => { + // @ts-ignore + jest.spyOn(process, "exit").mockImplementation(() => {}); // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation( () => simpleChangedPackagesList From eb4f31a2660d9ecc27750260302b4ec1ed87cbaa Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Tue, 29 Dec 2020 13:34:57 +0100 Subject: [PATCH 6/8] Add mising temporarilySilenceLogs call to test files --- packages/cli/src/commands/publish/__tests__/index.test.ts | 2 ++ .../cli/src/commands/publish/__tests__/publishPackages.test.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/cli/src/commands/publish/__tests__/index.test.ts b/packages/cli/src/commands/publish/__tests__/index.test.ts index bf33cf49c..44a724081 100644 --- a/packages/cli/src/commands/publish/__tests__/index.test.ts +++ b/packages/cli/src/commands/publish/__tests__/index.test.ts @@ -4,6 +4,7 @@ import { defaultConfig } from "@changesets/config"; import * as path from "path"; import * as pre from "@changesets/pre"; import { Config } from "@changesets/types"; +import { temporarilySilenceLogs } from "@changesets/test-utils"; let changelogPath = path.resolve(__dirname, "../../changelog"); let modifiedDefaultConfig: Config = { @@ -18,6 +19,7 @@ jest.mock("../publishPackages.ts"); jest.mock("@changesets/pre"); describe("Publish command", () => { + temporarilySilenceLogs(); let cwd: string; beforeEach(async () => { diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index ad1533b59..ac3ffe179 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -3,6 +3,7 @@ import fixtures from "fixturez"; import publishPackages from "../publishPackages"; import * as npmUtils from "../npm-utils"; import { getPackages } from "@manypkg/get-packages"; +import { temporarilySilenceLogs } from "@changesets/test-utils"; jest.mock("../npm-utils"); jest.mock("is-ci", () => true); @@ -10,6 +11,7 @@ jest.mock("is-ci", () => true); const f = fixtures(__dirname); describe("publishPackages", () => { + temporarilySilenceLogs(); let cwd: string; beforeEach(async () => { From 5346bd05a77edaa211d96bc083e02d37f3879adb Mon Sep 17 00:00:00 2001 From: Vitor Balocco Date: Thu, 7 Jan 2021 10:56:22 +0100 Subject: [PATCH 7/8] Add changeset --- .changeset/chatty-plums-watch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chatty-plums-watch.md diff --git a/.changeset/chatty-plums-watch.md b/.changeset/chatty-plums-watch.md new file mode 100644 index 000000000..bf5715cc1 --- /dev/null +++ b/.changeset/chatty-plums-watch.md @@ -0,0 +1,5 @@ +--- +"@changesets/cli": minor +--- + +`changeset status` command no longer errors when no publishable packages have been changed. From 7877be2ba645ae30e49f409a3ebf27cd033d563e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 13 Jan 2021 17:14:29 +0100 Subject: [PATCH 8/8] Update .changeset/chatty-plums-watch.md --- .changeset/chatty-plums-watch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/chatty-plums-watch.md b/.changeset/chatty-plums-watch.md index bf5715cc1..9be3afd01 100644 --- a/.changeset/chatty-plums-watch.md +++ b/.changeset/chatty-plums-watch.md @@ -2,4 +2,4 @@ "@changesets/cli": minor --- -`changeset status` command no longer errors when no publishable packages have been changed. +`changeset status` command no longer errors when no packages have been changed.