Skip to content

Commit

Permalink
feat(version): use npmClientArgs in npm install after lerna version (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
fahslaj committed Dec 21, 2022
1 parent e057f56 commit e019e3f
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 2 deletions.
37 changes: 37 additions & 0 deletions commands/version/README.md
Expand Up @@ -70,6 +70,7 @@ Running `lerna version --conventional-commits` without the above flags will rele
- [`--no-granular-pathspec`](#--no-granular-pathspec)
- [`--no-private`](#--no-private)
- [`--no-push`](#--no-push)
- [`--npm-client-args`](#--npm-client-args)
- [`--preid`](#--preid)
- [`--signoff-git-commit`](#--signoff-git-commit)
- [`--sign-git-commit`](#--sign-git-commit)
Expand Down Expand Up @@ -398,6 +399,42 @@ Note that this option does _not_ exclude [private scoped packages](https://docs.
By default, `lerna version` will push the committed and tagged changes to the configured [git remote](#--git-remote-name).
Pass `--no-push` to disable this behavior.

### `--npm-client-args`

This option allows arguments to be passed to the `npm install` that `lerna version` performs to update the lockfile.

For example:

```sh
lerna version 3.3.3 --npm-client-args=--legacy-peer-deps

lerna version 3.3.3 --npm-client-args="--legacy-peer-deps,--force"

lerna version 3.3.3 --npm-client-args="--legacy-peer-deps --force"
```

This can also be set in `lerna.json`:

```json
{
...
"npmClientArgs": ["--legacy-peer-deps", "--production"]
}
```

or specifically for the version command:

```json
{
...
"command": {
"version": {
"npmClientArgs": ["--legacy-peer-deps", "--production"]
}
}
}
```

### `--preid`

```sh
Expand Down
4 changes: 4 additions & 0 deletions commands/version/command.js
Expand Up @@ -168,6 +168,10 @@ exports.builder = (yargs, composed) => {
requiresArg: true,
defaultDescription: "v",
},
"npm-client-args": {
describe: "Additional arguments to pass to the npm client when performing 'npm install'.",
type: "array",
},
y: {
describe: "Skip all confirmation prompts.",
alias: "yes",
Expand Down
11 changes: 9 additions & 2 deletions commands/version/index.js
Expand Up @@ -616,11 +616,14 @@ class VersionCommand extends Command {
);
}

const npmClientArgsRaw = this.options.npmClientArgs || [];
const npmClientArgs = npmClientArgsRaw.reduce((args, arg) => args.concat(arg.split(/\s|,/)), []);

if (this.options.npmClient === "pnpm") {
chain = chain.then(() => {
this.logger.verbose("version", "Updating root pnpm-lock.yaml");
return childProcess
.exec("pnpm", ["install", "--lockfile-only", "--ignore-scripts"], this.execOpts)
.exec("pnpm", ["install", "--lockfile-only", "--ignore-scripts", ...npmClientArgs], this.execOpts)
.then(() => {
const lockfilePath = path.join(this.project.rootPath, "pnpm-lock.yaml");
changedFiles.add(lockfilePath);
Expand All @@ -634,7 +637,11 @@ class VersionCommand extends Command {
chain = chain.then(() => {
this.logger.verbose("version", "Updating root package-lock.json");
return childProcess
.exec("npm", ["install", "--package-lock-only", "--ignore-scripts"], this.execOpts)
.exec(
"npm",
["install", "--package-lock-only", "--ignore-scripts", ...npmClientArgs],
this.execOpts
)
.then(() => {
changedFiles.add(lockfilePath);
});
Expand Down
13 changes: 13 additions & 0 deletions core/lerna/schemas/lerna-schema.json
Expand Up @@ -1067,6 +1067,9 @@
"npmClient": {
"$ref": "#/$defs/globals/npmClient"
},
"npmClientArgs": {
"$ref": "#/$defs/globals/npmClientArgs"
},
"loglevel": {
"$ref": "#/$defs/globals/loglevel"
},
Expand Down Expand Up @@ -1123,6 +1126,9 @@
"npmClient": {
"$ref": "#/$defs/globals/npmClient"
},
"npmClientArgs": {
"$ref": "#/$defs/globals/npmClientArgs"
},
"loglevel": {
"$ref": "#/$defs/globals/loglevel"
},
Expand Down Expand Up @@ -1423,6 +1429,13 @@
"default": "npm",
"enum": ["npm", "yarn", "pnpm"]
},
"npmClientArgs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Arguments to pass to the npm client when running commands."
},
"loglevel": {
"type": "string",
"description": "The level of logging to use when running commands. Defaults to info if unspecified.",
Expand Down
97 changes: 97 additions & 0 deletions e2e/version/src/npm-client-args.spec.ts
@@ -0,0 +1,97 @@
import { Fixture, normalizeCommitSHAs, normalizeEnvironment } from "@lerna/e2e-utils";

expect.addSnapshotSerializer({
serialize(str: string) {
return normalizeCommitSHAs(normalizeEnvironment(str));
},
test(val: string) {
return val != null && typeof val === "string";
},
});

describe("lerna-version-npm-client-args", () => {
let fixture: Fixture;

beforeEach(async () => {
fixture = await Fixture.create({
name: "lerna-version-npm-client-args",
packageManager: "npm",
initializeGit: true,
runLernaInit: true,
installDependencies: true,
});
await fixture.lerna("create package-a -y");

// eslint-plugin-react-app@6.2.2 requires a peer dependency of eslint@"6.x".
// Without it, the npm install at the end of `lerna version` will fail if
// --legacy-peer-deps is not passed correctly.
await fixture.updateJson("package.json", (json) => ({
...json,
dependencies: {
...(json.dependencies as Record<string, string>),
"eslint-plugin-react-app": "6.2.2",
eslint: "8.25.0",
},
}));
await fixture.exec(
"npm install eslint-plugin-react-app@6.2.2 eslint@8.25.0 --save=false --legacy-peer-deps"
);
await fixture.createInitialGitCommit();
await fixture.exec("git push origin test-main");
});
afterEach(() => fixture.destroy());

it("should add npmClientArgs to npm install at the end of the version command", async () => {
const output = await fixture.lerna("version 3.3.3 -y --npm-client-args=--legacy-peer-deps");
expect(output.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info current version 0.0.0
lerna info Assuming all packages changed
Changes:
- package-a: 0.0.0 => 3.3.3
lerna info auto-confirmed
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna success version finished
`);
});

it("should support multiple arguments, comma delimited", async () => {
const output = await fixture.lerna('version 3.3.3 -y --npm-client-args="--legacy-peer-deps,--fund"');
expect(output.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info current version 0.0.0
lerna info Assuming all packages changed
Changes:
- package-a: 0.0.0 => 3.3.3
lerna info auto-confirmed
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna success version finished
`);
});

it("should support multiple arguments, space delimited", async () => {
const output = await fixture.lerna('version 3.3.3 -y --npm-client-args="--legacy-peer-deps --fund"');
expect(output.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info current version 0.0.0
lerna info Assuming all packages changed
Changes:
- package-a: 0.0.0 => 3.3.3
lerna info auto-confirmed
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna success version finished
`);
});
});

0 comments on commit e019e3f

Please sign in to comment.