Skip to content

Commit 7d4a541

Browse files
committed
feat: Add Nx support and Yarn berry
1 parent ffc24f3 commit 7d4a541

File tree

9 files changed

+192
-50
lines changed

9 files changed

+192
-50
lines changed

packages/monorepo/src/MonoRepo.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import get from "lodash/get";
22
import hasYarn from "has-yarn";
33
import logger from "fancy-log";
44
import {join} from "path";
5-
import {npm, yarn} from "./utils/cli/index.js";
5+
import {lerna, npm, nx, yarn} from "./utils/cli/index.js";
66
import {getDependencies} from "./utils/depencencies/getDependencies.js";
77
import {syncExamples} from "./utils/examples/syncExample.js";
88
import {syncDependencies} from "./utils/depencencies/syncDependencies.js";
@@ -23,6 +23,7 @@ import {publishHeroku} from "./utils/heroku/publishHeroku.js";
2323
import {cleanTagsDocker} from "./utils/docker/cleanTagsDocker.js";
2424
import {getWorkspaces} from "./utils/workspace/getWorkspaces.js";
2525
import {cleanPackages} from "./utils/packages/cleanPackages.js";
26+
import {yarnBerry} from "./utils/cli/YarnBerry.js";
2627

2728
function getDefaultOptions(rootPkg) {
2829
return {
@@ -260,17 +261,33 @@ export class MonoRepo {
260261
}
261262

262263
get manager() {
263-
return this.hasYarn ? yarn : npm;
264+
return this.hasYarn ? (this.hasYarnBerry ? yarnBerry : yarn) : npm;
265+
}
266+
267+
get workspaceManager() {
268+
return this.hasNx ? nx : lerna;
264269
}
265270

266271
get hasYarn() {
267272
return hasYarn(this.rootDir);
268273
}
269274

275+
get hasWorkspaceManager() {
276+
return this.hasNx || this.hasLerna;
277+
}
278+
279+
get hasYarnBerry() {
280+
return this.hasYarn && (this.rootPkg.packageManager || "").includes("yarn@");
281+
}
282+
270283
get hasLerna() {
271284
return Boolean(this.rootPkg.dependencies.lerna || this.rootPkg.devDependencies.lerna);
272285
}
273286

287+
get hasNx() {
288+
return Boolean(this.rootPkg.dependencies.nx || this.rootPkg.devDependencies.nx);
289+
}
290+
274291
get hasBuild() {
275292
return Boolean(this.rootPkg.scripts.build);
276293
}

packages/monorepo/src/utils/cli/Lerna.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ class LernaCli extends Cli {
1313
return this.sync("version", ...args);
1414
}
1515

16-
run(...args) {
17-
return super.run("run", ...args);
16+
run(cmd, ...args) {
17+
return super.run("run", cmd, "--stream", ...args);
1818
}
1919

20-
install(...args) {
21-
return super.run("install", ...args);
20+
runMany(cmd, ...args) {
21+
return super.run("run", cmd, "--stream", ...args);
2222
}
2323
}
2424

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Cli} from "./Cli.js";
2+
3+
class NxCli extends Cli {
4+
constructor() {
5+
super("nx");
6+
}
7+
8+
run(cmd, ...args) {
9+
return super.run(cmd, ...args);
10+
}
11+
12+
runMany(cmd, ...args) {
13+
return super.run("run-many", `--target=${cmd}`, "--all", ...args);
14+
}
15+
16+
install(...args) {
17+
return super.run("install", ...args);
18+
}
19+
}
20+
21+
export const nx = new NxCli();

packages/monorepo/src/utils/cli/Yarn.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ class YarnCli extends Cli {
66
}
77

88
newVersion(version) {
9+
10+
11+
912
return this.version("--no-git-tag-version", "--new-version", version);
1013
}
1114

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {Cli} from "./Cli.js";
2+
import {bumpPackagesVersion} from "../packages/bumpPackagesVersion.js";
3+
4+
class YarnBerryCli extends Cli {
5+
constructor() {
6+
super("yarn");
7+
}
8+
9+
newVersion(version, context) {
10+
return bumpPackagesVersion(version, context);
11+
}
12+
13+
version(...args) {
14+
return this.sync("version", ...args);
15+
}
16+
17+
run(...args) {
18+
return super.run(...args);
19+
}
20+
21+
install(...args) {
22+
return super.run(args.length ? "add" : "install", ...args);
23+
}
24+
25+
/**
26+
* Reinstall dependencies without yarn.lock mutation
27+
* @returns {Promise<unknown>}
28+
*/
29+
restore() {
30+
return super.run("install", "--immutable");
31+
}
32+
}
33+
34+
export const yarnBerry = new YarnBerryCli();

packages/monorepo/src/utils/cli/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./Cli";
22
export * from "./Docker";
33
export * from "./Lerna";
4+
export * from "./Nx";
45
export * from "./Npm";
56
export * from "./Yarn";
67
export * from "./Git";
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import globby from "globby";
2+
import fs from "fs-extra";
3+
4+
const PACKAGE_JSON_PROPS = ["dependencies", "devDependencies", "peerDependencies"];
5+
6+
/**
7+
* @param version {string}
8+
* @param context {MonoRepo}
9+
* @returns {Promise<void>}
10+
*/
11+
export async function bumpPackagesVersion(version, context) {
12+
const {workspaces, cwd} = context;
13+
const patterns = workspaces.map((path) => `${path}/package.json`).concat("package.json");
14+
15+
const files = await globby(patterns, {
16+
cwd,
17+
absolute: true
18+
});
19+
20+
const names = new Set();
21+
22+
const packages = await Promise.all(
23+
files.map(async (file) => {
24+
const pkg = await fs.readJson(file);
25+
26+
names.add(pkg.name);
27+
28+
return {file, pkg};
29+
})
30+
);
31+
32+
packages.map(({pkg, file}) => {
33+
pkg.version = version;
34+
35+
PACKAGE_JSON_PROPS.forEach((key) => bumpDependencies(pkg, key, version, names));
36+
37+
return fs.writeJson(file, pkg);
38+
});
39+
}
40+
41+
function bumpDependencies(pkg, key, version, names) {
42+
pkg[key] = pkg[key] || {};
43+
44+
if (pkg[key]) {
45+
names.forEach((name) => {
46+
if (pkg[key][name] && !pkg[key][name].startsWith("workspace:")) {
47+
pkg[key][name] = version;
48+
}
49+
});
50+
}
51+
}
Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,54 @@
1-
import {lerna} from "../cli/index.js";
21
import chalk from "chalk";
3-
import {dirname, join} from "path";
2+
import {dirname} from "path";
43
import {findPackages} from "./findPackages.js";
54

6-
/**
7-
*
8-
* @param context {MonoRepo}
9-
* @returns {Promise<void>}
10-
*/
11-
export async function compilePackages(context) {
12-
const {buildCmd, logger, manager, hasLerna} = context;
5+
async function compilePackagesWithWorkspaceManager(manager, context) {
6+
const {buildCmd, logger} = context;
7+
8+
const child = manager.runMany(buildCmd).toStream();
9+
10+
child.stdout.on("data", (data) => {
11+
data
12+
.toString()
13+
.split("\n")
14+
.filter((line) => !!line.trim())
15+
.map((line) => {
16+
logger.info(line);
17+
});
18+
});
19+
20+
child.stderr.on("data", (data) => {
21+
data
22+
.toString()
23+
.split("\n")
24+
.filter((line) => !!line.trim())
25+
.map((line) => {
26+
logger.error(line);
27+
});
28+
});
29+
30+
await child;
31+
}
32+
33+
async function compilePackagesWithPackageManager(context) {
34+
const {buildCmd, logger, manager} = context;
35+
36+
const pkgs = await findPackages(context);
1337

14-
if (hasLerna) {
15-
const child = lerna.run(buildCmd, "--stream").toStream();
38+
for (const {path, pkg} of pkgs) {
39+
const cwd = dirname(path);
40+
41+
const child = manager.run(buildCmd).sync({
42+
cwd
43+
});
1644

1745
child.stdout.on("data", (data) => {
1846
data
1947
.toString()
2048
.split("\n")
2149
.filter((line) => !!line.trim())
2250
.map((line) => {
23-
logger.info(line);
51+
logger.info(chalk.magenta(pkg.name), line.replace(/^ > /, ""));
2452
});
2553
});
2654
child.stderr.on("data", (data) => {
@@ -29,40 +57,25 @@ export async function compilePackages(context) {
2957
.split("\n")
3058
.filter((line) => !!line.trim())
3159
.map((line) => {
32-
logger.error(line);
60+
logger.error(chalk.red(pkg.name), line.replace(/^ > /, ""));
3361
});
3462
});
3563

3664
await child;
37-
} else {
38-
const pkgs = await findPackages(context);
39-
40-
for (const {path, pkg} of pkgs) {
41-
const cwd = dirname(path);
42-
const child = manager.run(buildCmd).sync({
43-
cwd
44-
});
65+
}
66+
}
4567

46-
child.stdout.on("data", (data) => {
47-
data
48-
.toString()
49-
.split("\n")
50-
.filter((line) => !!line.trim())
51-
.map((line) => {
52-
logger.info(chalk.magenta(pkg.name), line.replace(/^ > /, ""));
53-
});
54-
});
55-
child.stderr.on("data", (data) => {
56-
data
57-
.toString()
58-
.split("\n")
59-
.filter((line) => !!line.trim())
60-
.map((line) => {
61-
logger.error(chalk.red(pkg.name), line.replace(/^ > /, ""));
62-
});
63-
});
68+
/**
69+
*
70+
* @param context {MonoRepo}
71+
* @returns {Promise<void>}
72+
*/
73+
export async function compilePackages(context) {
74+
const {workspaceManager, manager, hasWorkspaceManager} = context;
6475

65-
await child;
66-
}
76+
if (hasWorkspaceManager) {
77+
return compilePackagesWithWorkspaceManager(workspaceManager, context);
6778
}
79+
80+
return compilePackagesWithPackageManager(manager);
6881
}

packages/monorepo/src/utils/packages/newVersion.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import {lerna} from "../cli/index.js";
44
* @param context {MonoRepo}
55
*/
66
export async function newVersion(context) {
7-
if (context.hasLerna) {
8-
lerna.newVersion(context.version);
7+
const {hasLerna} = context
8+
9+
if (hasLerna) {
10+
lerna.newVersion(context.version, context);
911
}
1012

11-
return context.manager.newVersion(context.version);
13+
return context.manager.newVersion(context.version, context);
1214
}

0 commit comments

Comments
 (0)