Skip to content

Commit a01efc9

Browse files
Create @manypkg/tools and refactor find-root and get-packages (#151)
* Create sample core package * Initial round of feedback * eliminate index-based zip * Add BoltTool * Add PnpmTool * Add Yarn and None tools, update findroot unit tests * Implement sync methods for all Tools, fixing findRootSync tests * wip: 90% of get-packages converted to use Tools * revert back to original snaps * Small tool fixes * add latest content * Rename NoneTool to SinglePackageTool, it is never the root of a monorepo * Swap references to SinglePackageTool * Remove errant comment * Implement core type changes for Packages and Package * Suggested feedback * Mass prettier update after pull from main * additional PR feedback * errant console.log * Type fixes * Rename manypkg/core -> manypkg/tools * fix unit tests, snapshots * snapshot updates * Fixed the `PackagesWithConfig` type * Adjust checks implementations after changes * Support both dir and relativeDir * pr feedback * unused importrs * Fix prettier config, add changeset * Introduce `getRootWs` test helper * Exports only tools from `/tools` and handle default order in `/find-root` * Fix suggested path.join * Make root tool last * Split up changesets * Cleanup `/find-root` * Update .changeset/frozen-yogurt.md Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Fix some test and type issues, feedback * Refactor all try-catch blocks to assert positive instead of negative * Revert change to jest default test timeout * Update packages/tools/package.json Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/get-packages/package.json Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
1 parent 45b396d commit a01efc9

33 files changed

+1253
-473
lines changed

.changeset/curly-days-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@manypkg/find-root": major
3+
---
4+
5+
The `find-root` package now returns a new `MonorepoRoot` interface, instead of a string. This interface provides a `rootDir` for the discovered monorepo, and a `tool` object, which is an object using the new `Tool` interface provided by `@manypkg/tools`.

.changeset/frozen-yogurt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@manypkg/tools": minor
3+
---
4+
5+
Introduces a new `Tool` API that provides key functions related to a specific implementation of a monorepo, like `isMonorepoRoot` and `getPackages`. Existing tool implementations in manypkg have been converted to use this new interface.

.changeset/upstream-animal-park.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@manypkg/get-packages": major
3+
---
4+
5+
The `get-packages` package now returns a slightly different structure. The old `tool` string has been replaced with a `tool` object, using the new `Tool` interface provided by `@manypkg/tools`. Each `Package` now contains both the absolute directory and relative directory path. Last, the `root` package has been renamed `rootPackage` and is optional, to support monorepos that do not contain a root package.

.prettierrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ module.exports = {
99
proseWrap: "never",
1010

1111
// Disabling search dirs and pointing directly at plugins to keep configuration explicit
12-
pluginSearchDirs: false,
12+
pluginSearchDirs: [],
1313
plugins: [require("prettier-plugin-packagejson")],
1414
};

packages/cli/src/checks/INCORRECT_REPOSITORY_FIELD.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import parseGithubUrl from "parse-github-url";
2-
import path from "path";
32
import normalizePath from "normalize-path";
43
import { Package } from "@manypkg/get-packages";
54

@@ -15,7 +14,8 @@ type ErrorType = {
1514
export default makeCheck<ErrorType>({
1615
type: "all",
1716
validate: (workspace, allWorkspaces, rootWorkspace, options) => {
18-
let rootRepositoryField = (rootWorkspace.packageJson as any).repository;
17+
let rootRepositoryField: unknown = (rootWorkspace?.packageJson as any)
18+
?.repository;
1919

2020
if (typeof rootRepositoryField === "string") {
2121
let result = parseGithubUrl(rootRepositoryField);
@@ -48,12 +48,10 @@ export default makeCheck<ErrorType>({
4848
if (result.host === "github.com") {
4949
correctRepositoryField = `${baseRepositoryUrl}/tree/${
5050
options.defaultBranch
51-
}/${normalizePath(
52-
path.relative(rootWorkspace.dir, workspace.dir)
53-
)}`;
51+
}/${normalizePath(workspace.relativeDir)}`;
5452
} else if (result.host === "dev.azure.com") {
5553
correctRepositoryField = `${baseRepositoryUrl}?path=${normalizePath(
56-
path.relative(rootWorkspace.dir, workspace.dir)
54+
workspace.relativeDir
5755
)}&version=GB${options.defaultBranch}&_a=contents`;
5856
}
5957

packages/cli/src/checks/INVALID_PACKAGE_NAME.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default makeCheck<ErrorType>({
4040
print: (error) => {
4141
if (!error.workspace.packageJson.name) {
4242
return `The package at ${JSON.stringify(
43-
error.workspace.dir
43+
error.workspace.relativeDir
4444
)} does not have a name`;
4545
}
4646
return `${

packages/cli/src/checks/__tests__/EXTERNAL_MISMATCH.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import internalMismatch from "../EXTERNAL_MISMATCH";
2-
import { getWS, getFakeWS } from "../../test-helpers";
2+
import { getWS, getFakeWS, getRootWS } from "../../test-helpers";
33

4-
let rootWorkspace = getFakeWS("root");
4+
let rootWorkspace = getRootWS();
55

66
it("should error if the ranges are valid and they are not equal", () => {
77
let ws = getWS();
@@ -27,14 +27,15 @@ it("should error if the ranges are valid and they are not equal", () => {
2727
"mostCommonDependencyRange": "2.0.0",
2828
"type": "EXTERNAL_MISMATCH",
2929
"workspace": {
30-
"dir": "some/fake/dir/pkg-1",
30+
"dir": "fake/monorepo/packages/pkg-1",
3131
"packageJson": {
3232
"dependencies": {
3333
"something": "1.0.0",
3434
},
3535
"name": "pkg-1",
3636
"version": "1.0.0",
3737
},
38+
"relativeDir": "packages/pkg-1",
3839
},
3940
},
4041
]
@@ -76,14 +77,15 @@ it("should error and return the correct mostCommonDependencyRange when the range
7677
"mostCommonDependencyRange": "1.0.0",
7778
"type": "EXTERNAL_MISMATCH",
7879
"workspace": {
79-
"dir": "some/fake/dir/pkg-2",
80+
"dir": "fake/monorepo/packages/pkg-2",
8081
"packageJson": {
8182
"dependencies": {
8283
"something": "2.0.0",
8384
},
8485
"name": "pkg-2",
8586
"version": "1.0.0",
8687
},
88+
"relativeDir": "packages/pkg-2",
8789
},
8890
},
8991
]
@@ -123,14 +125,15 @@ it("should error and return the correct mostCommonDependencyRange when the range
123125
"mostCommonDependencyRange": "1.0.0",
124126
"type": "EXTERNAL_MISMATCH",
125127
"workspace": {
126-
"dir": "some/fake/dir/pkg-1",
128+
"dir": "fake/monorepo/packages/pkg-1",
127129
"packageJson": {
128130
"dependencies": {
129131
"something": "2.0.0",
130132
},
131133
"name": "pkg-1",
132134
"version": "1.0.0",
133135
},
136+
"relativeDir": "packages/pkg-1",
134137
},
135138
},
136139
]
@@ -172,14 +175,15 @@ it("should error and return the correct mostCommonDependencyRange when the range
172175
"mostCommonDependencyRange": "3.0.0",
173176
"type": "EXTERNAL_MISMATCH",
174177
"workspace": {
175-
"dir": "some/fake/dir/pkg-1",
178+
"dir": "fake/monorepo/packages/pkg-1",
176179
"packageJson": {
177180
"dependencies": {
178181
"something": "1.0.0",
179182
},
180183
"name": "pkg-1",
181184
"version": "1.0.0",
182185
},
186+
"relativeDir": "packages/pkg-1",
183187
},
184188
},
185189
]
@@ -195,14 +199,15 @@ it("should error and return the correct mostCommonDependencyRange when the range
195199
"mostCommonDependencyRange": "3.0.0",
196200
"type": "EXTERNAL_MISMATCH",
197201
"workspace": {
198-
"dir": "some/fake/dir/pkg-2",
202+
"dir": "fake/monorepo/packages/pkg-2",
199203
"packageJson": {
200204
"dependencies": {
201205
"something": "2.0.0",
202206
},
203207
"name": "pkg-2",
204208
"version": "1.0.0",
205209
},
210+
"relativeDir": "packages/pkg-2",
206211
},
207212
},
208213
]

packages/cli/src/checks/__tests__/INCORRECT_REPOSITORY_FIELD.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import path from "path";
22
import check from "../INCORRECT_REPOSITORY_FIELD";
3-
import { getWS, getFakeWS, getFakeString } from "../../test-helpers";
3+
import { getWS, getFakeWS, getFakeString, getRootWS } from "../../test-helpers";
44

55
describe("incorrect repository field", () => {
66
describe("github", () => {
77
it("should work", () => {
88
let ws = getWS();
9-
let rootWorkspace = getFakeWS("root");
9+
let rootWorkspace = getRootWS();
1010
let defaultBranch = `b${getFakeString(5)}`;
1111

1212
(rootWorkspace.packageJson as any).repository =
1313
"https://github.com/Thinkmill/manypkg";
14-
rootWorkspace.dir = __dirname;
1514
let workspace = getFakeWS("no-repository-field");
16-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
1715
ws.set("depends-on-one", workspace);
1816
ws.set("root", rootWorkspace);
1917
let errors = check.validate(workspace, ws, rootWorkspace, {
@@ -38,15 +36,13 @@ describe("incorrect repository field", () => {
3836
});
3937
it("should fix root in a different format", () => {
4038
let ws = getWS();
41-
let rootWorkspace = getFakeWS("root");
39+
let rootWorkspace = getRootWS();
4240
let defaultBranch = `b${getFakeString(5)}`;
4341

4442
(rootWorkspace.packageJson as any).repository =
4543
"https://github.com/Thinkmill/manypkg.git";
4644

47-
rootWorkspace.dir = __dirname;
4845
let workspace = getFakeWS("no-repository-field");
49-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
5046
ws.set("depends-on-one", workspace);
5147
ws.set("root", rootWorkspace);
5248
let errors = check.validate(rootWorkspace, ws, rootWorkspace, {
@@ -71,15 +67,13 @@ describe("incorrect repository field", () => {
7167
});
7268
it("should do nothing if already in good format", () => {
7369
let ws = getWS();
74-
let rootWorkspace = getFakeWS("root");
70+
let rootWorkspace = getRootWS();
7571
let defaultBranch = `b${getFakeString(5)}`;
7672

7773
(rootWorkspace.packageJson as any).repository =
7874
"https://github.com/Thinkmill/manypkg";
7975

80-
rootWorkspace.dir = __dirname;
8176
let workspace = getFakeWS("no-repository-field");
82-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
8377
ws.set("depends-on-one", workspace);
8478
ws.set("root", rootWorkspace);
8579
let errors = check.validate(rootWorkspace, ws, rootWorkspace, {
@@ -98,14 +92,12 @@ describe("incorrect repository field", () => {
9892
describe("azure devops", () => {
9993
it("should work", () => {
10094
let ws = getWS();
101-
let rootWorkspace = getFakeWS("root");
95+
let rootWorkspace = getRootWS();
10296
let defaultBranch = `b${getFakeString(5)}`;
10397

10498
(rootWorkspace.packageJson as any).repository =
10599
"https://dev.azure.com/Thinkmill/monorepos/_git/manypkg";
106-
rootWorkspace.dir = __dirname;
107100
let workspace = getFakeWS("no-repository-field");
108-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
109101
ws.set("depends-on-one", workspace);
110102
ws.set("root", rootWorkspace);
111103
let errors = check.validate(workspace, ws, rootWorkspace, {
@@ -130,15 +122,13 @@ describe("incorrect repository field", () => {
130122
});
131123
it("should fix root in a different format", () => {
132124
let ws = getWS();
133-
let rootWorkspace = getFakeWS("root");
125+
let rootWorkspace = getRootWS();
134126
let defaultBranch = `b${getFakeString(5)}`;
135127

136128
(rootWorkspace.packageJson as any).repository =
137129
"https://Thinkmill@dev.azure.com/Thinkmill/monorepos/_git/manypkg";
138130

139-
rootWorkspace.dir = __dirname;
140131
let workspace = getFakeWS("no-repository-field");
141-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
142132
ws.set("depends-on-one", workspace);
143133
ws.set("root", rootWorkspace);
144134
let errors = check.validate(rootWorkspace, ws, rootWorkspace, {
@@ -163,15 +153,13 @@ describe("incorrect repository field", () => {
163153
});
164154
it("should do nothing if already in good format", () => {
165155
let ws = getWS();
166-
let rootWorkspace = getFakeWS("root");
156+
let rootWorkspace = getRootWS();
167157
let defaultBranch = `b${getFakeString(5)}`;
168158

169159
(rootWorkspace.packageJson as any).repository =
170160
"https://dev.azure.com/Thinkmill/monorepos/_git/manypkg";
171161

172-
rootWorkspace.dir = __dirname;
173162
let workspace = getFakeWS("no-repository-field");
174-
workspace.dir = path.join(__dirname, "packages/no-repository-field");
175163
ws.set("depends-on-one", workspace);
176164
ws.set("root", rootWorkspace);
177165
let errors = check.validate(rootWorkspace, ws, rootWorkspace, {

packages/cli/src/checks/__tests__/INTERNAL_MISMATCH.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import makeCheck, { ErrorType } from "../INTERNAL_MISMATCH";
2-
import { getWS, getFakeWS } from "../../test-helpers";
2+
import { getWS, getFakeWS, getRootWS } from "../../test-helpers";
33

4-
let rootWorkspace = getFakeWS("root");
4+
let rootWorkspace = getRootWS();
55

66
describe("internal mismatch", () => {
77
it("should not error if internal version is compatible", () => {
@@ -62,22 +62,24 @@ describe("internal mismatch", () => {
6262
{
6363
"dependencyRange": "^0.1.0",
6464
"dependencyWorkspace": {
65-
"dir": "some/fake/dir/pkg-1",
65+
"dir": "fake/monorepo/packages/pkg-1",
6666
"packageJson": {
6767
"name": "pkg-1",
6868
"version": "1.0.0",
6969
},
70+
"relativeDir": "packages/pkg-1",
7071
},
7172
"type": "INTERNAL_MISMATCH",
7273
"workspace": {
73-
"dir": "some/fake/dir/depends-on-one",
74+
"dir": "fake/monorepo/packages/depends-on-one",
7475
"packageJson": {
7576
"devDependencies": {
7677
"pkg-1": "^0.1.0",
7778
},
7879
"name": "depends-on-one",
7980
"version": "1.0.0",
8081
},
82+
"relativeDir": "packages/depends-on-one",
8183
},
8284
},
8385
]

packages/cli/src/checks/__tests__/INVALID_DEV_AND_PEER_DEPENDENCY.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import makeCheck from "../INVALID_DEV_AND_PEER_DEPENDENCY_RELATIONSHIP";
2-
import { getWS, getFakeWS } from "../../test-helpers";
2+
import { getWS, getFakeWS, getRootWS } from "../../test-helpers";
33

4-
let rootWorkspace = getFakeWS("root");
4+
let rootWorkspace = getRootWS();
55

66
describe("invalid dev and peer dependency", () => {
77
describe("internal dependencies", () => {

0 commit comments

Comments
 (0)