Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(init): default useNx and useWorkspaces to true for new lerna workspaces #3255

Merged
Merged
3 changes: 2 additions & 1 deletion __fixtures__/cycle-intersection/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion __fixtures__/cycle-parent/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion __fixtures__/cycle-separate/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion __fixtures__/licenses-missing/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion __fixtures__/licenses/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion __fixtures__/lifecycle/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
5 changes: 4 additions & 1 deletion __fixtures__/normal/lerna.json
@@ -1,3 +1,6 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": [
"packages/*"
]
}
3 changes: 2 additions & 1 deletion __fixtures__/toposort/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
3 changes: 2 additions & 1 deletion commands/bootstrap/__tests__/__fixtures__/ci/lerna.json
@@ -1,3 +1,4 @@
{
"version": "1.0.0"
"version": "1.0.0",
"packages": ["packages/*"]
}
252 changes: 212 additions & 40 deletions commands/init/__tests__/init-command.test.js
Expand Up @@ -4,6 +4,8 @@ const fs = require("fs-extra");
const path = require("path");
const tempy = require("tempy");

const { loggingOutput } = require("@lerna-test/helpers/logging-output");

// helpers
const initFixture = require("@lerna-test/helpers").initFixtureFactory(__dirname);

Expand All @@ -13,6 +15,17 @@ const lernaInit = require("@lerna-test/helpers").commandRunner(require("../comma
describe("InitCommand", () => {
const lernaVersion = "__TEST_VERSION__";

it("should link to docs site after success", async () => {
const testDir = tempy.directory();

await lernaInit(testDir)();

const logMessages = loggingOutput("info");
expect(logMessages).toContain(
"New to Lerna? Check out the docs: https://lerna.js.org/docs/getting-started"
);
});

describe("in an empty directory", () => {
it("initializes git repo with lerna files", async () => {
const testDir = tempy.directory();
Expand All @@ -26,15 +39,26 @@ describe("InitCommand", () => {
fs.exists(path.join(testDir, ".git")),
]);

expect(lernaJson).toMatchObject({
packages: ["packages/*"],
version: "0.0.0",
});
expect(pkgJson).toMatchObject({
devDependencies: {
lerna: `^${lernaVersion}`,
},
});
expect(lernaJson).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useNx": true,
"useWorkspaces": true,
"version": "0.0.0",
}
`);
expect(pkgJson).toMatchInlineSnapshot(`
Object {
"devDependencies": Object {
"lerna": "^__TEST_VERSION__",
},
"name": "root",
"private": true,
"workspaces": Array [
"packages/*",
],
}
`);
expect(packagesDirExists).toBe(true);
expect(gitDirExists).toBe(true);
});
Expand Down Expand Up @@ -75,6 +99,14 @@ describe("InitCommand", () => {
});
});
});

it("creates packages directory", async () => {
const testDir = tempy.directory();

await lernaInit(testDir)();

expect(fs.existsSync(path.join(testDir, "packages"))).toBe(true);
});
});

describe("in a subdirectory of a git repo", () => {
Expand All @@ -91,16 +123,26 @@ describe("InitCommand", () => {
fs.exists(path.join(testDir, "packages")),
]);

expect(lernaJson).toMatchObject({
$schema: "node_modules/lerna/schemas/lerna-schema.json",
packages: ["packages/*"],
version: "0.0.0",
});
expect(pkgJson).toMatchObject({
devDependencies: {
lerna: `^${lernaVersion}`,
},
});
expect(lernaJson).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useNx": true,
"useWorkspaces": true,
"version": "0.0.0",
}
`);
expect(pkgJson).toMatchInlineSnapshot(`
Object {
"devDependencies": Object {
"lerna": "^__TEST_VERSION__",
},
"name": "root",
"private": true,
"workspaces": Array [
"packages/*",
],
}
`);
expect(packagesDirExists).toBe(true);
});
});
Expand Down Expand Up @@ -177,12 +219,69 @@ describe("InitCommand", () => {
},
});
});

describe("when workspaces are already configured", () => {
it("does not overwrite existing workspaces", async () => {
const testDir = await initFixture("has-package");
const pkgJsonPath = path.join(testDir, "package.json");

await fs.outputJSON(pkgJsonPath, {
workspaces: ["modules/*", "others/*"],
});

await lernaInit(testDir)();

expect(await fs.readJSON(pkgJsonPath)).toMatchObject({
workspaces: ["modules/*", "others/*"],
});
});
});

describe("when workspaces are not yet configured", () => {
it("sets workspaces to include default packages location", async () => {
const testDir = await initFixture("has-package");
const pkgJsonPath = path.join(testDir, "package.json");

await lernaInit(testDir)();

expect(await fs.readJSON(pkgJsonPath)).toMatchObject({
workspaces: ["packages/*"],
});
});
});
});

describe("when lerna.json exists", () => {
it("deletes lerna property if found", async () => {
describe("when useWorkspaces is false or missing", () => {
it("updates to explicitly set useNx, $schema, and packages", async () => {
const testDir = await initFixture("has-lerna");
const lernaJsonPath = path.join(testDir, "lerna.json");

await fs.outputJSON(lernaJsonPath, {
lerna: "0.1.100",
version: "1.2.3",
});

await lernaInit(testDir)();

expect(await fs.readJSON(lernaJsonPath)).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"packages": Array [
"packages/*",
],
"useNx": false,
"useWorkspaces": false,
"version": "1.2.3",
}
`);
});
});

it("creates package.json without workspaces configured", async () => {
const testDir = await initFixture("has-lerna");
const lernaJsonPath = path.join(testDir, "lerna.json");
const packageJsonPath = path.join(testDir, "package.json");

await fs.outputJSON(lernaJsonPath, {
lerna: "0.1.100",
Expand All @@ -191,30 +290,98 @@ describe("InitCommand", () => {

await lernaInit(testDir)();

expect(await fs.readJSON(lernaJsonPath)).toEqual({
$schema: "node_modules/lerna/schemas/lerna-schema.json",
packages: ["packages/*"],
useNx: false,
version: "1.2.3",
});
expect(await fs.readJSON(packageJsonPath)).toMatchInlineSnapshot(`
Object {
"devDependencies": Object {
"lerna": "^__TEST_VERSION__",
},
"name": "root",
"private": true,
}
`);
});

it("creates package directories when glob is configured", async () => {
const testDir = await initFixture("has-lerna");
const lernaJsonPath = path.join(testDir, "lerna.json");

await fs.outputJSON(lernaJsonPath, {
version: "1.2.3",
packages: ["modules/*"],
});

await lernaInit(testDir)();

expect(await fs.exists(path.join(testDir, "modules"))).toBe(true);
});

describe("when useNx is false", () => {
it("preserves useNx false and does not add nx as dependency", async () => {
const testDir = await initFixture("has-lerna");
const lernaJsonPath = path.join(testDir, "lerna.json");

await fs.outputJSON(lernaJsonPath, {
lerna: "0.1.100",
version: "1.2.3",
useNx: false,
});

await lernaInit(testDir)();

expect(await fs.readJSON(lernaJsonPath)).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"packages": Array [
"packages/*",
],
"useNx": false,
"useWorkspaces": false,
"version": "1.2.3",
}
`);

expect(await fs.readJSON(path.join(testDir, "package.json"))).toMatchInlineSnapshot(`
Object {
"devDependencies": Object {
"lerna": "^__TEST_VERSION__",
},
"name": "root",
"private": true,
}
`);
});
});

describe("when useNx is true", () => {
it("preserves useNx true", async () => {
const testDir = await initFixture("has-lerna");
const lernaJsonPath = path.join(testDir, "lerna.json");

await fs.outputJSON(lernaJsonPath, {
lerna: "0.1.100",
version: "1.2.3",
useNx: true,
});

await lernaInit(testDir)();

expect(await fs.readJSON(lernaJsonPath)).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"packages": Array [
"packages/*",
],
"useNx": true,
"useWorkspaces": false,
"version": "1.2.3",
}
`);
});
});
});

describe("when re-initializing with --exact", () => {
it("sets lerna.json command.init.exact to true", async () => {
it("sets lerna.json command.init.exact to true and explicitly sets useNx, useWorkspaces, $schema, and packages", async () => {
const testDir = await initFixture("updates");
const lernaJsonPath = path.join(testDir, "lerna.json");
const pkgJsonPath = path.join(testDir, "package.json");
Expand All @@ -237,20 +404,25 @@ describe("InitCommand", () => {

await lernaInit(testDir)("--exact");

expect(await fs.readJSON(lernaJsonPath)).toEqual({
command: {
bootstrap: {
hoist: true,
},
init: {
exact: true,
expect(await fs.readJSON(lernaJsonPath)).toMatchInlineSnapshot(`
Object {
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"command": Object {
"bootstrap": Object {
"hoist": true,
},
"init": Object {
"exact": true,
},
},
},
$schema: "node_modules/lerna/schemas/lerna-schema.json",
packages: ["packages/*"],
useNx: false,
version: "1.2.3",
});
"packages": Array [
"packages/*",
],
"useNx": false,
"useWorkspaces": false,
"version": "1.2.3",
}
`);
});
});
});