Skip to content

Commit

Permalink
feat(init): detect existing package manager and auto-install packages (
Browse files Browse the repository at this point in the history
  • Loading branch information
fahslaj committed Aug 15, 2023
1 parent 1a113f7 commit 2204c34
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 18 deletions.
94 changes: 94 additions & 0 deletions e2e/init/src/init-npm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { Fixture, normalizeEnvironment } from "@lerna/e2e-utils";
import { writeFileSync } from "fs-extra";

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

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

beforeEach(async () => {
fixture = await Fixture.create({
e2eRoot: process.env.E2E_ROOT,
name: "lerna-init-npm",
packageManager: "npm",
initializeGit: false,
lernaInit: false,
installDependencies: false,
});

writeFileSync(
fixture.getWorkspacePath("package.json"),
JSON.stringify({
name: "root",
private: true,
workspaces: ["packages/*"],
})
);

await fixture.install();
});

afterEach(() => fixture.destroy());

it("should not set npmClient in lerna.json", async () => {
const result = await fixture.lernaInit();

expect(result.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info Applying the following file system updates:
CREATE lerna.json
UPDATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
`);

const lernaJson = await fixture.readWorkspaceFile("lerna.json");

expect(lernaJson).toMatchInlineSnapshot(`
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.0.0"
}
`);
});

describe("--skip-install", () => {
it("should not install packages", async () => {
const result = await fixture.lernaInit("--skip-install");

expect(result.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info Applying the following file system updates:
CREATE lerna.json
UPDATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
`);

const lernaJson = await fixture.readWorkspaceFile("lerna.json");

expect(lernaJson).toMatchInlineSnapshot(`
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.0.0"
}
`);
});
});
});
71 changes: 71 additions & 0 deletions e2e/init/src/init-pnpm.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Fixture, getPublishedVersion, normalizeEnvironment } from "@lerna/e2e-utils";
import { writeFileSync } from "fs-extra";

expect.addSnapshotSerializer({
serialize(str: string) {
return normalizeEnvironment(str)
.replace(/\.+\/\.?pnpm.*\n/g, "")
.replace("info cli using local version of lerna\n", "");
},
test(val: string) {
return val != null && typeof val === "string";
},
});

describe("lerna-init-pnpm", () => {
let fixture: Fixture;

beforeEach(async () => {
fixture = await Fixture.create({
e2eRoot: process.env.E2E_ROOT,
name: "lerna-init-pnpm",
packageManager: "pnpm",
initializeGit: false,
lernaInit: false,
installDependencies: false,
});

writeFileSync(
fixture.getWorkspacePath("package.json"),
JSON.stringify({
name: "root",
private: true,
devDependencies: {
lerna: getPublishedVersion(),
},
})
);

await fixture.install();
});

afterEach(() => fixture.destroy());

it("should set npmClient to pnpm in lerna.json", async () => {
const result = await fixture.lernaInit();

expect(result.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info Applying the following file system updates:
CREATE lerna.json
UPDATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using pnpm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
`);

const lernaJson = await fixture.readWorkspaceFile("lerna.json");

expect(lernaJson).toMatchInlineSnapshot(`
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.0.0",
"npmClient": "pnpm"
}
`);
});
});
67 changes: 67 additions & 0 deletions e2e/init/src/init-yarn.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Fixture, normalizeEnvironment } from "@lerna/e2e-utils";
import { writeFileSync } from "fs-extra";

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

describe("lerna-init-yarn", () => {
let fixture: Fixture;

beforeEach(async () => {
fixture = await Fixture.create({
e2eRoot: process.env.E2E_ROOT,
name: "lerna-init-yarn",
packageManager: "yarn",
initializeGit: false,
lernaInit: false,
installDependencies: false,
});

writeFileSync(
fixture.getWorkspacePath("package.json"),
JSON.stringify({
name: "root",
private: true,
workspaces: ["packages/*"],
})
);

await fixture.install();
});

afterEach(() => fixture.destroy());

it("should set npmClient to yarn in lerna.json", async () => {
const result = await fixture.lernaInit();

expect(result.combinedOutput).toMatchInlineSnapshot(`
lerna notice cli v999.9.9-e2e.0
lerna info Applying the following file system updates:
CREATE lerna.json
UPDATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using yarn to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
`);

const lernaJson = await fixture.readWorkspaceFile("lerna.json");

expect(lernaJson).toMatchInlineSnapshot(`
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "0.0.0",
"npmClient": "yarn"
}
`);
});
});
5 changes: 5 additions & 0 deletions e2e/init/src/init.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe("lerna-init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
"
Expand Down Expand Up @@ -65,6 +66,7 @@ describe("lerna-init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
"
Expand Down Expand Up @@ -106,6 +108,7 @@ describe("lerna-init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
"
Expand Down Expand Up @@ -147,6 +150,7 @@ describe("lerna-init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
"
Expand Down Expand Up @@ -188,6 +192,7 @@ describe("lerna-init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
"
Expand Down
1 change: 1 addition & 0 deletions integration/__tests__/lerna-init.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe("lerna init", () => {
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
`);
Expand Down
50 changes: 41 additions & 9 deletions libs/commands/init/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `lerna init`

> Create a new Lerna repo or upgrade an existing repo to the current version of Lerna
> Create a new Lerna repo or add Lerna to an existing repo
Install [lerna](https://www.npmjs.com/package/lerna) for access to the `lerna` CLI.

Expand All @@ -10,35 +10,65 @@ Install [lerna](https://www.npmjs.com/package/lerna) for access to the `lerna` C
$ lerna init
```

Create a new Lerna repo or upgrade an existing repo to the current version of Lerna.

> Lerna assumes the repo has already been initialized with `git init`.
Create a new Lerna repo or add Lerna to an existing repo.

When run, this command will:

1. Add `lerna` as a [`devDependency`](https://docs.npmjs.com/files/package.json#devdependencies) in `package.json` if it doesn't already exist.
2. Create a `lerna.json` config file to store the `version` number.
2. Create a `lerna.json` config file.
3. Generate a `.gitignore` file if one doesn't already exist.
4. Initialize a git repository if one doesn't already exist.
5. Install dependencies with the detected package manager. If no lockfile is present, Lerna will default to using `npm`.

Example output on a new git repo:

```sh
$ lerna init
lerna info version v2.0.0
lerna info Updating package.json
lerna info Creating lerna.json
lerna info version v7.1.4
lerna info Applying the following file system updates:
CREATE lerna.json
CREATE package.json
CREATE .gitignore
lerna info Initializing Git repository
lerna info Using npm to install packages
lerna success Initialized Lerna files
lerna info New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started
```

## Options

### `--dry-run`

```sh
$ lerna init --dry-run
```

Preview the changes that will be made to the file system without actually modifying anything.

### `--independent`

```sh
$ lerna init --independent
```

This flag tells Lerna to use independent versioning mode.
This flag tells Lerna to use independent versioning mode. See [Version and Publish](https://lerna.js.org/docs/features/version-and-publish#versioning-strategies) for details.

### `--packages`

```sh
$ lerna init --packages="packages/*"
$ lerna init --packages="packages/*" --packages="components/*"
```

Set the `packages` globs used to find packages in the repo. If not specified, then Lerna will use [package manager workspaces](https://lerna.js.org/docs/faq#how-does-lerna-detect-packages) to detect packages.

> NOTE: if you are initializing Lerna in an existing repo, you will need to either enable [package manager workspaces](https://lerna.js.org/docs/faq#how-does-lerna-detect-packages) OR provide the `--packages` argument.
### `--skip-install`

Skip running `npm/yarn/pnpm install` after initializing Lerna in the repo.

## Deprecated Options

### `--exact`

Expand All @@ -62,3 +92,5 @@ It will configure `lerna.json` to enforce exact match for all subsequent executi
"version": "0.0.0"
}
```

> `--exact` is deprecated because `lerna init` should no longer be run on an existing Lerna repo.
4 changes: 4 additions & 0 deletions libs/commands/init/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const command: CommandModule = {
type: "boolean",
default: false,
},
skipInstall: {
describe: "Skip installation of dependencies after initialization",
type: "boolean",
},
},
handler(argv) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
Expand Down

0 comments on commit 2204c34

Please sign in to comment.