diff --git a/__fixtures__/lockfile-leaf/lerna.json b/__fixtures__/lockfile-leaf/lerna.json new file mode 100644 index 0000000000..1587a66968 --- /dev/null +++ b/__fixtures__/lockfile-leaf/lerna.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} diff --git a/__fixtures__/lockfile-leaf/package.json b/__fixtures__/lockfile-leaf/package.json new file mode 100644 index 0000000000..5fa36b4fcd --- /dev/null +++ b/__fixtures__/lockfile-leaf/package.json @@ -0,0 +1,5 @@ +{ + "name": "leaf-lockfile", + "version": "0.0.0-lerna", + "private": true +} diff --git a/__fixtures__/lockfile-leaf/packages/package-1/package-lock.json b/__fixtures__/lockfile-leaf/packages/package-1/package-lock.json new file mode 100644 index 0000000000..0e72a417dc --- /dev/null +++ b/__fixtures__/lockfile-leaf/packages/package-1/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "package-1", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "tiny-tarball": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tiny-tarball/-/tiny-tarball-1.0.0.tgz", + "integrity": "sha1-u/EC1a5zr+LFUyleD7AiMCFvZbE=" + } + } +} diff --git a/__fixtures__/lockfile-leaf/packages/package-1/package.json b/__fixtures__/lockfile-leaf/packages/package-1/package.json new file mode 100644 index 0000000000..ee217c2df6 --- /dev/null +++ b/__fixtures__/lockfile-leaf/packages/package-1/package.json @@ -0,0 +1,7 @@ +{ + "name": "package-1", + "version": "1.0.0", + "dependencies": { + "tiny-tarball": "^1.0.0" + } +} diff --git a/commands/version/__tests__/update-lockfile-version.test.js b/commands/version/__tests__/update-lockfile-version.test.js new file mode 100644 index 0000000000..b0af8de818 --- /dev/null +++ b/commands/version/__tests__/update-lockfile-version.test.js @@ -0,0 +1,40 @@ +"use strict"; + +const path = require("path"); +const fs = require("fs-extra"); + +// mocked or stubbed modules +const loadJsonFile = require("load-json-file"); + +// helpers +const { getPackages } = require("@lerna/project"); +const initFixture = require("@lerna-test/init-fixture")(__dirname); + +const { updateLockfileVersion } = require("../lib/update-lockfile-version"); + +test("updateLockfileVersion", async () => { + const cwd = await initFixture("lockfile-leaf"); + const [pkg] = await getPackages(cwd); + + pkg.version = "2.0.0"; + + const returnedLockfilePath = await updateLockfileVersion(pkg); + + expect(returnedLockfilePath).toBe(path.join(pkg.location, "package-lock.json")); + expect(Array.from(loadJsonFile.registry.keys())).toStrictEqual(["/packages/package-1"]); + expect(fs.readJSONSync(returnedLockfilePath)).toHaveProperty("version", "2.0.0"); +}); + +test("updateLockfileVersion without sibling lockfile", async () => { + const cwd = await initFixture("lifecycle", false); + const [pkg] = await getPackages(cwd); + + pkg.version = "1.1.0"; + + loadJsonFile.mockImplementationOnce(() => Promise.reject(new Error("file not found"))); + + const returnedLockfilePath = await updateLockfileVersion(pkg); + + expect(returnedLockfilePath).toBeUndefined(); + expect(fs.pathExistsSync(path.join(pkg.location, "package-lock.json"))).toBe(false); +}); diff --git a/commands/version/__tests__/version-command.test.js b/commands/version/__tests__/version-command.test.js index 8f0f4f27c6..692e4242f5 100644 --- a/commands/version/__tests__/version-command.test.js +++ b/commands/version/__tests__/version-command.test.js @@ -724,4 +724,14 @@ describe("VersionCommand", () => { expect(message).toBe("v1.0.1"); }); }); + + describe("with leaf lockfiles", () => { + it("updates lockfile version to new package version", async () => { + const cwd = await initFixture("lockfile-leaf"); + await lernaVersion(cwd)("--yes", "major"); + + const changedFiles = await showCommit(cwd, "--name-only"); + expect(changedFiles).toContain("packages/package-1/package-lock.json"); + }); + }); }); diff --git a/commands/version/index.js b/commands/version/index.js index 7c7f158767..80bd8db148 100644 --- a/commands/version/index.js +++ b/commands/version/index.js @@ -32,6 +32,7 @@ const isBreakingChange = require("./lib/is-breaking-change"); const isAnythingCommitted = require("./lib/is-anything-committed"); const makePromptVersion = require("./lib/prompt-version"); const createRelease = require("./lib/create-release"); +const { updateLockfileVersion } = require("./lib/update-lockfile-version"); const { collectPackages, getPackagesForOption } = collectUpdates; @@ -511,10 +512,14 @@ class VersionCommand extends Command { } } - return pkg.serialize().then(() => { + return Promise.all([updateLockfileVersion(pkg), pkg.serialize()]).then(([lockfilePath]) => { // commit the updated manifest changedFiles.add(pkg.manifestLocation); + if (lockfilePath) { + changedFiles.add(lockfilePath); + } + return pkg; }); }, diff --git a/commands/version/lib/update-lockfile-version.js b/commands/version/lib/update-lockfile-version.js new file mode 100644 index 0000000000..4172d17a95 --- /dev/null +++ b/commands/version/lib/update-lockfile-version.js @@ -0,0 +1,27 @@ +"use strict"; + +const path = require("path"); +const loadJsonFile = require("load-json-file"); +const writeJsonFile = require("write-json-file"); + +module.exports.updateLockfileVersion = updateLockfileVersion; + +function updateLockfileVersion(pkg) { + const lockfilePath = path.join(pkg.location, "package-lock.json"); + + let chain = Promise.resolve(); + + chain = chain.then(() => loadJsonFile(lockfilePath).catch(() => {})); + chain = chain.then(obj => { + if (obj) { + obj.version = pkg.version; + + return writeJsonFile(lockfilePath, obj, { + detectIndent: true, + indent: 2, + }).then(() => lockfilePath); + } + }); + + return chain; +} diff --git a/commands/version/package.json b/commands/version/package.json index 20ed2466c9..a6ae8533f3 100644 --- a/commands/version/package.json +++ b/commands/version/package.json @@ -49,6 +49,7 @@ "@lerna/validation-error": "file:../../core/validation-error", "chalk": "^2.3.1", "dedent": "^0.7.0", + "load-json-file": "^5.3.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "p-map": "^2.1.0", @@ -57,6 +58,7 @@ "p-waterfall": "^1.0.0", "semver": "^6.2.0", "slash": "^2.0.0", - "temp-write": "^3.4.0" + "temp-write": "^3.4.0", + "write-json-file": "^3.2.0" } } diff --git a/package-lock.json b/package-lock.json index e0f5ecbbea..e0d86e5728 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1351,6 +1351,7 @@ "@lerna/validation-error": "file:core/validation-error", "chalk": "^2.3.1", "dedent": "^0.7.0", + "load-json-file": "^5.3.0", "minimatch": "^3.0.4", "npmlog": "^4.1.2", "p-map": "^2.1.0", @@ -1359,7 +1360,8 @@ "p-waterfall": "^1.0.0", "semver": "^6.2.0", "slash": "^2.0.0", - "temp-write": "^3.4.0" + "temp-write": "^3.4.0", + "write-json-file": "^3.2.0" } }, "@lerna/write-log-file": {