@monorepolint/rules 0.5.0-alpha.9 → 0.5.0-alpha.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__tests__/alphabeticalScripts.spec.d.ts +8 -0
- package/lib/__tests__/alphabeticalScripts.spec.d.ts.map +1 -0
- package/lib/__tests__/alphabeticalScripts.spec.js +61 -0
- package/lib/__tests__/alphabeticalScripts.spec.js.map +1 -0
- package/lib/__tests__/bannedDependencies.spec.d.ts +2 -0
- package/lib/__tests__/bannedDependencies.spec.d.ts.map +1 -0
- package/lib/__tests__/bannedDependencies.spec.js +161 -0
- package/lib/__tests__/bannedDependencies.spec.js.map +1 -0
- package/lib/__tests__/consistentDependencies.spec.js +30 -23
- package/lib/__tests__/consistentDependencies.spec.js.map +1 -1
- package/lib/__tests__/consistentVersions.spec.d.ts +8 -0
- package/lib/__tests__/consistentVersions.spec.d.ts.map +1 -0
- package/lib/__tests__/consistentVersions.spec.js +183 -0
- package/lib/__tests__/consistentVersions.spec.js.map +1 -0
- package/lib/__tests__/fileContents.spec.d.ts +8 -0
- package/lib/__tests__/fileContents.spec.d.ts.map +1 -0
- package/lib/__tests__/fileContents.spec.js +59 -0
- package/lib/__tests__/fileContents.spec.js.map +1 -0
- package/lib/__tests__/mustSatisfyPeerDependencies.spec.d.ts +8 -0
- package/lib/__tests__/mustSatisfyPeerDependencies.spec.d.ts.map +1 -0
- package/lib/__tests__/mustSatisfyPeerDependencies.spec.js +1063 -0
- package/lib/__tests__/mustSatisfyPeerDependencies.spec.js.map +1 -0
- package/lib/__tests__/nestedWorkspaces.spec.d.ts +2 -0
- package/lib/__tests__/nestedWorkspaces.spec.d.ts.map +1 -0
- package/lib/__tests__/nestedWorkspaces.spec.js +124 -0
- package/lib/__tests__/nestedWorkspaces.spec.js.map +1 -0
- package/lib/__tests__/packageEntry.spec.js +72 -27
- package/lib/__tests__/packageEntry.spec.js.map +1 -1
- package/lib/__tests__/packageOrder.spec.js +34 -33
- package/lib/__tests__/packageOrder.spec.js.map +1 -1
- package/lib/__tests__/packageScript.spec.js +50 -51
- package/lib/__tests__/packageScript.spec.js.map +1 -1
- package/lib/__tests__/requireDependency.spec.d.ts +2 -0
- package/lib/__tests__/requireDependency.spec.d.ts.map +1 -0
- package/lib/__tests__/requireDependency.spec.js +123 -0
- package/lib/__tests__/requireDependency.spec.js.map +1 -0
- package/lib/__tests__/utils.d.ts +69 -1
- package/lib/__tests__/utils.d.ts.map +1 -1
- package/lib/__tests__/utils.js +72 -12
- package/lib/__tests__/utils.js.map +1 -1
- package/lib/alphabeticalDependencies.d.ts +3 -1
- package/lib/alphabeticalDependencies.d.ts.map +1 -1
- package/lib/alphabeticalDependencies.js +5 -39
- package/lib/alphabeticalDependencies.js.map +1 -1
- package/lib/alphabeticalScripts.d.ts +12 -0
- package/lib/alphabeticalScripts.d.ts.map +1 -0
- package/lib/alphabeticalScripts.js +20 -0
- package/lib/alphabeticalScripts.js.map +1 -0
- package/lib/bannedDependencies.d.ts +23 -5
- package/lib/bannedDependencies.d.ts.map +1 -1
- package/lib/bannedDependencies.js +110 -36
- package/lib/bannedDependencies.js.map +1 -1
- package/lib/consistentDependencies.d.ts +8 -1
- package/lib/consistentDependencies.d.ts.map +1 -1
- package/lib/consistentDependencies.js +30 -12
- package/lib/consistentDependencies.js.map +1 -1
- package/lib/consistentVersions.d.ts +14 -0
- package/lib/consistentVersions.d.ts.map +1 -0
- package/lib/consistentVersions.js +94 -0
- package/lib/consistentVersions.js.map +1 -0
- package/lib/fileContents.d.ts +8 -8
- package/lib/fileContents.d.ts.map +1 -1
- package/lib/fileContents.js +32 -27
- package/lib/fileContents.js.map +1 -1
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +19 -8
- package/lib/index.js.map +1 -1
- package/lib/mustSatisfyPeerDependencies.d.ts +240 -0
- package/lib/mustSatisfyPeerDependencies.d.ts.map +1 -0
- package/lib/mustSatisfyPeerDependencies.js +636 -0
- package/lib/mustSatisfyPeerDependencies.js.map +1 -0
- package/lib/nestedWorkspaces.d.ts +13 -0
- package/lib/nestedWorkspaces.d.ts.map +1 -0
- package/lib/nestedWorkspaces.js +50 -0
- package/lib/nestedWorkspaces.js.map +1 -0
- package/lib/packageEntry.d.ts +15 -6
- package/lib/packageEntry.d.ts.map +1 -1
- package/lib/packageEntry.js +53 -18
- package/lib/packageEntry.js.map +1 -1
- package/lib/packageOrder.d.ts +3 -3
- package/lib/packageOrder.d.ts.map +1 -1
- package/lib/packageOrder.js +8 -7
- package/lib/packageOrder.js.map +1 -1
- package/lib/packageScript.d.ts +10 -10
- package/lib/packageScript.js +6 -5
- package/lib/packageScript.js.map +1 -1
- package/lib/requireDependency.d.ts +15 -0
- package/lib/requireDependency.d.ts.map +1 -0
- package/lib/requireDependency.js +65 -0
- package/lib/requireDependency.js.map +1 -0
- package/lib/standardTsconfig.d.ts +20 -8
- package/lib/standardTsconfig.d.ts.map +1 -1
- package/lib/standardTsconfig.js +36 -18
- package/lib/standardTsconfig.js.map +1 -1
- package/lib/util/checkAlpha.d.ts +10 -0
- package/lib/util/checkAlpha.d.ts.map +1 -0
- package/lib/util/checkAlpha.js +51 -0
- package/lib/util/checkAlpha.js.map +1 -0
- package/lib/util/makeDirectory.d.ts +8 -0
- package/lib/util/makeDirectory.d.ts.map +1 -0
- package/lib/util/makeDirectory.js +28 -0
- package/lib/util/makeDirectory.js.map +1 -0
- package/lib/util/packageDependencyGraphService.d.ts +37 -0
- package/lib/util/packageDependencyGraphService.d.ts.map +1 -0
- package/lib/util/packageDependencyGraphService.js +70 -0
- package/lib/util/packageDependencyGraphService.js.map +1 -0
- package/package.json +18 -15
- package/src/__tests__/alphabeticalScripts.spec.ts +75 -0
- package/src/__tests__/bannedDependencies.spec.ts +191 -0
- package/src/__tests__/consistentDependencies.spec.ts +39 -26
- package/src/__tests__/consistentVersions.spec.ts +223 -0
- package/src/__tests__/fileContents.spec.ts +74 -0
- package/src/__tests__/mustSatisfyPeerDependencies.spec.ts +1188 -0
- package/src/__tests__/nestedWorkspaces.spec.ts +152 -0
- package/src/__tests__/packageEntry.spec.ts +98 -31
- package/src/__tests__/packageOrder.spec.ts +46 -40
- package/src/__tests__/packageScript.spec.ts +62 -54
- package/src/__tests__/requireDependency.spec.ts +151 -0
- package/src/__tests__/utils.ts +113 -11
- package/src/alphabeticalDependencies.ts +3 -47
- package/src/alphabeticalScripts.ts +19 -0
- package/src/bannedDependencies.ts +133 -43
- package/src/consistentDependencies.ts +34 -12
- package/src/consistentVersions.ts +140 -0
- package/src/fileContents.ts +31 -27
- package/src/index.ts +5 -0
- package/src/mustSatisfyPeerDependencies.ts +739 -0
- package/src/nestedWorkspaces.ts +59 -0
- package/src/packageEntry.ts +67 -24
- package/src/packageOrder.ts +6 -6
- package/src/packageScript.ts +3 -3
- package/src/requireDependency.ts +69 -0
- package/src/standardTsconfig.ts +40 -18
- package/src/util/checkAlpha.ts +59 -0
- package/src/util/makeDirectory.ts +24 -0
- package/src/util/packageDependencyGraphService.ts +114 -0
- package/tsconfig.tsbuildinfo +1 -2439
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright 2020 Palantir Technologies, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
import { WorkspaceContext } from "@monorepolint/core";
|
|
8
|
+
import { SimpleHost } from "@monorepolint/utils";
|
|
9
|
+
import { writeFileSync } from "fs";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import * as tmp from "tmp";
|
|
12
|
+
import { bannedDependencies, Options } from "../bannedDependencies";
|
|
13
|
+
import { makeDirectoryRecursively } from "../util/makeDirectory";
|
|
14
|
+
import { jsonToString } from "./utils";
|
|
15
|
+
|
|
16
|
+
const EMPTY_PACKAGE = jsonToString({});
|
|
17
|
+
|
|
18
|
+
describe("bannedDependencies", () => {
|
|
19
|
+
tmp.setGracefulCleanup();
|
|
20
|
+
|
|
21
|
+
let cleanupJobs: Array<() => void> = [];
|
|
22
|
+
let cwd: string | undefined;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
const dir = tmp.dirSync({ unsafeCleanup: true });
|
|
26
|
+
cleanupJobs.push(() => dir.removeCallback());
|
|
27
|
+
cwd = dir.name;
|
|
28
|
+
|
|
29
|
+
const spy = jest.spyOn(process, "cwd");
|
|
30
|
+
spy.mockReturnValue(cwd);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
for (const cleanupJob of cleanupJobs) {
|
|
35
|
+
cleanupJob();
|
|
36
|
+
}
|
|
37
|
+
cleanupJobs = [];
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
function makeWorkspace() {
|
|
41
|
+
const workspaceContext = new WorkspaceContext(
|
|
42
|
+
cwd!,
|
|
43
|
+
{
|
|
44
|
+
rules: [],
|
|
45
|
+
fix: false,
|
|
46
|
+
verbose: false,
|
|
47
|
+
silent: true,
|
|
48
|
+
},
|
|
49
|
+
new SimpleHost()
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
function checkAndSpy(options: Options) {
|
|
53
|
+
const addErrorSpy = jest.spyOn(workspaceContext, "addError");
|
|
54
|
+
bannedDependencies.check(workspaceContext, {
|
|
55
|
+
...options,
|
|
56
|
+
});
|
|
57
|
+
return { addErrorSpy };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function addFile(filePath: string, content: string) {
|
|
61
|
+
const dirPath = path.resolve(cwd!, path.dirname(filePath));
|
|
62
|
+
const resolvedFilePath = path.resolve(cwd!, filePath);
|
|
63
|
+
|
|
64
|
+
makeDirectoryRecursively(dirPath);
|
|
65
|
+
writeFileSync(resolvedFilePath, content);
|
|
66
|
+
return resolvedFilePath;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return { addFile, workspaceContext, checkAndSpy };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
it("Flags banned dependencies correctly", async () => {
|
|
73
|
+
const { addFile, checkAndSpy } = makeWorkspace();
|
|
74
|
+
const rootPackageJson = jsonToString({
|
|
75
|
+
dependencies: {
|
|
76
|
+
aaa: "0.0.1",
|
|
77
|
+
ccc: "0.0.1",
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
addFile("./package.json", rootPackageJson);
|
|
81
|
+
|
|
82
|
+
const { addErrorSpy: addErrorSpy1 } = checkAndSpy({ bannedDependencies: ["ccc"] });
|
|
83
|
+
expect(addErrorSpy1).toHaveBeenCalledTimes(1);
|
|
84
|
+
addErrorSpy1.mockReset();
|
|
85
|
+
|
|
86
|
+
const { addErrorSpy: addErrorSpy2 } = checkAndSpy({ bannedDependencies: ["ddd"] });
|
|
87
|
+
expect(addErrorSpy2).toHaveBeenCalledTimes(0);
|
|
88
|
+
addErrorSpy2.mockReset();
|
|
89
|
+
|
|
90
|
+
const { addErrorSpy: addErrorSpy3 } = checkAndSpy({ bannedDependencies: ["ccc", "ddd"] });
|
|
91
|
+
expect(addErrorSpy3).toHaveBeenCalledTimes(1);
|
|
92
|
+
addErrorSpy3.mockReset();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("Flags banned dependencies correctly w legacy globs", async () => {
|
|
96
|
+
const { addFile, checkAndSpy } = makeWorkspace();
|
|
97
|
+
const rootPackageJson = jsonToString({
|
|
98
|
+
dependencies: {
|
|
99
|
+
aaa: "0.0.1",
|
|
100
|
+
ccc: "0.0.1",
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
addFile("./package.json", rootPackageJson);
|
|
104
|
+
|
|
105
|
+
const { addErrorSpy: addErrorSpy1 } = checkAndSpy({ bannedDependencies: ["c*c"] });
|
|
106
|
+
expect(addErrorSpy1).toHaveBeenCalledTimes(1);
|
|
107
|
+
addErrorSpy1.mockReset();
|
|
108
|
+
|
|
109
|
+
const { addErrorSpy: addErrorSpy2 } = checkAndSpy({ bannedDependencies: ["d*d"] });
|
|
110
|
+
expect(addErrorSpy2).toHaveBeenCalledTimes(0);
|
|
111
|
+
addErrorSpy2.mockReset();
|
|
112
|
+
|
|
113
|
+
const { addErrorSpy: addErrorSpy3 } = checkAndSpy({ bannedDependencies: ["c*c", "d*d"] });
|
|
114
|
+
expect(addErrorSpy3).toHaveBeenCalledTimes(1);
|
|
115
|
+
addErrorSpy3.mockReset();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("Flags banned dependencies correctly w new globs", async () => {
|
|
119
|
+
const { addFile, checkAndSpy } = makeWorkspace();
|
|
120
|
+
const rootPackageJson = jsonToString({
|
|
121
|
+
dependencies: {
|
|
122
|
+
aaa: "0.0.1",
|
|
123
|
+
ccc: "0.0.1",
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
addFile("./package.json", rootPackageJson);
|
|
127
|
+
|
|
128
|
+
const { addErrorSpy: addErrorSpy1 } = checkAndSpy({ bannedDependencies: { glob: ["c*c"] } });
|
|
129
|
+
expect(addErrorSpy1).toHaveBeenCalledTimes(1);
|
|
130
|
+
addErrorSpy1.mockReset();
|
|
131
|
+
|
|
132
|
+
const { addErrorSpy: addErrorSpy2 } = checkAndSpy({ bannedDependencies: { glob: ["d*d"] } });
|
|
133
|
+
expect(addErrorSpy2).toHaveBeenCalledTimes(0);
|
|
134
|
+
addErrorSpy2.mockReset();
|
|
135
|
+
|
|
136
|
+
const { addErrorSpy: addErrorSpy3 } = checkAndSpy({ bannedDependencies: { glob: ["c*c", "d*d"] } });
|
|
137
|
+
expect(addErrorSpy3).toHaveBeenCalledTimes(1);
|
|
138
|
+
addErrorSpy3.mockReset();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("Flags banned dependencies correctly w exact", async () => {
|
|
142
|
+
const { addFile, checkAndSpy } = makeWorkspace();
|
|
143
|
+
const rootPackageJson = jsonToString({
|
|
144
|
+
dependencies: {
|
|
145
|
+
aaa: "0.0.1",
|
|
146
|
+
ccc: "0.0.1",
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
addFile("./package.json", rootPackageJson);
|
|
150
|
+
|
|
151
|
+
const { addErrorSpy: addErrorSpy1 } = checkAndSpy({ bannedDependencies: { exact: ["ccc"] } });
|
|
152
|
+
expect(addErrorSpy1).toHaveBeenCalledTimes(1);
|
|
153
|
+
addErrorSpy1.mockReset();
|
|
154
|
+
|
|
155
|
+
const { addErrorSpy: addErrorSpy2 } = checkAndSpy({ bannedDependencies: { exact: ["ddd"] } });
|
|
156
|
+
expect(addErrorSpy2).toHaveBeenCalledTimes(0);
|
|
157
|
+
addErrorSpy2.mockReset();
|
|
158
|
+
|
|
159
|
+
const { addErrorSpy: addErrorSpy3 } = checkAndSpy({ bannedDependencies: { exact: ["ccc", "ddd"] } });
|
|
160
|
+
expect(addErrorSpy3).toHaveBeenCalledTimes(1);
|
|
161
|
+
addErrorSpy3.mockReset();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("Flags banned transitives correctly", async () => {
|
|
165
|
+
const { addFile, checkAndSpy } = makeWorkspace();
|
|
166
|
+
const rootPackageJson = jsonToString({
|
|
167
|
+
dependencies: {
|
|
168
|
+
aaa: "0.0.1",
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
addFile("./package.json", rootPackageJson);
|
|
172
|
+
|
|
173
|
+
const aaaPackageJson = jsonToString({
|
|
174
|
+
dependencies: {
|
|
175
|
+
bbb: "0.0.1",
|
|
176
|
+
ccc: "0.0.1",
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
addFile("./node_modules/aaa/package.json", aaaPackageJson);
|
|
180
|
+
const bbbPackageJson = jsonToString({
|
|
181
|
+
dependencies: {
|
|
182
|
+
ddd: "0.0.1",
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
addFile("./node_modules/aaa/node_modules/bbb/package.json", bbbPackageJson);
|
|
186
|
+
addFile("./node_modules/aaa/node_modules/bbb/node_modules/ddd/package.json", EMPTY_PACKAGE);
|
|
187
|
+
addFile("./node_modules/aaa/node_modules/ccc/package.json", EMPTY_PACKAGE);
|
|
188
|
+
|
|
189
|
+
expect(checkAndSpy({ bannedTransitiveDependencies: ["ccc", "ddd"] }).addErrorSpy).toHaveBeenCalledTimes(2);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
7
7
|
import { WorkspaceContext } from "@monorepolint/core";
|
|
8
|
-
import {
|
|
8
|
+
import { SimpleHost } from "@monorepolint/utils";
|
|
9
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
9
10
|
import * as path from "path";
|
|
10
11
|
import * as tmp from "tmp";
|
|
11
|
-
import { consistentDependencies } from "../consistentDependencies";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return JSON.stringify(obj, undefined, 2) + "\n";
|
|
15
|
-
}
|
|
12
|
+
import { consistentDependencies, Options } from "../consistentDependencies";
|
|
13
|
+
import { makeDirectoryRecursively } from "../util/makeDirectory";
|
|
14
|
+
import { jsonToString } from "./utils";
|
|
16
15
|
|
|
17
16
|
const PACKAGE_ROOT = jsonToString({
|
|
18
17
|
workspaces: {
|
|
@@ -29,6 +28,12 @@ const PACKAGE_CHILD_WITH_STAR = jsonToString({
|
|
|
29
28
|
},
|
|
30
29
|
});
|
|
31
30
|
|
|
31
|
+
const PACKAGE_CHILD_WITH_LATEST = jsonToString({
|
|
32
|
+
dependencies: {
|
|
33
|
+
foo: "latest",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
32
37
|
const PACKAGE_CHILD_WITH_RIGHT_VERSION = jsonToString({
|
|
33
38
|
dependencies: {
|
|
34
39
|
foo: "5",
|
|
@@ -54,19 +59,24 @@ describe("consistentDependencies", () => {
|
|
|
54
59
|
});
|
|
55
60
|
|
|
56
61
|
function makeWorkspace({ fix }: { fix: boolean }) {
|
|
57
|
-
const dir: tmp.DirResult = tmp.dirSync();
|
|
62
|
+
const dir: tmp.DirResult = tmp.dirSync({ unsafeCleanup: true });
|
|
58
63
|
cleanupJobs.push(() => dir.removeCallback());
|
|
59
64
|
|
|
60
|
-
const workspaceContext = new WorkspaceContext(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
const workspaceContext = new WorkspaceContext(
|
|
66
|
+
dir.name,
|
|
67
|
+
{
|
|
68
|
+
rules: [],
|
|
69
|
+
fix,
|
|
70
|
+
verbose: false,
|
|
71
|
+
silent: true,
|
|
72
|
+
},
|
|
73
|
+
new SimpleHost()
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
function checkAndSpy(q: string, opts?: Options) {
|
|
67
77
|
const context = workspaceContext.createChildContext(path.resolve(dir.name, q));
|
|
68
78
|
const addErrorSpy = jest.spyOn(context, "addError");
|
|
69
|
-
consistentDependencies.check(context,
|
|
79
|
+
consistentDependencies.check(context, opts);
|
|
70
80
|
return { context, addErrorSpy };
|
|
71
81
|
}
|
|
72
82
|
|
|
@@ -74,17 +84,7 @@ describe("consistentDependencies", () => {
|
|
|
74
84
|
const dirPath = path.resolve(dir.name, path.dirname(filePath));
|
|
75
85
|
const resolvedFilePath = path.resolve(dir.name, filePath);
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
// so we manually do it instead
|
|
79
|
-
const dirSegments = dirPath.split(path.sep);
|
|
80
|
-
for (let i = 2; i <= dirSegments.length; i++) {
|
|
81
|
-
// we skip the empty segment
|
|
82
|
-
const curDirPath = dirSegments.slice(0, i).join(path.sep);
|
|
83
|
-
if (!existsSync(curDirPath)) {
|
|
84
|
-
mkdirSync(curDirPath);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
87
|
+
makeDirectoryRecursively(dirPath);
|
|
88
88
|
writeFileSync(resolvedFilePath, content);
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -99,6 +99,7 @@ describe("consistentDependencies", () => {
|
|
|
99
99
|
const { addFile, workspaceContext, checkAndSpy } = makeWorkspace({ fix: false });
|
|
100
100
|
addFile("./package.json", PACKAGE_ROOT);
|
|
101
101
|
addFile("./packages/star/package.json", PACKAGE_CHILD_WITH_STAR);
|
|
102
|
+
addFile("./packages/latest/package.json", PACKAGE_CHILD_WITH_LATEST);
|
|
102
103
|
addFile("./packages/right/package.json", PACKAGE_CHILD_WITH_RIGHT_VERSION);
|
|
103
104
|
addFile("./packages/wrong/package.json", PACKAGE_CHILD_WITH_WRONG_VERSION);
|
|
104
105
|
|
|
@@ -107,6 +108,9 @@ describe("consistentDependencies", () => {
|
|
|
107
108
|
const star = checkAndSpy("./packages/star");
|
|
108
109
|
expect(star.addErrorSpy).toHaveBeenCalledTimes(0);
|
|
109
110
|
|
|
111
|
+
const latest = checkAndSpy("./packages/latest");
|
|
112
|
+
expect(latest.addErrorSpy).toHaveBeenCalledTimes(0);
|
|
113
|
+
|
|
110
114
|
const right = checkAndSpy("./packages/right");
|
|
111
115
|
expect(right.addErrorSpy).toHaveBeenCalledTimes(0);
|
|
112
116
|
|
|
@@ -125,4 +129,13 @@ describe("consistentDependencies", () => {
|
|
|
125
129
|
const contents = readFile("./packages/wrong/package.json");
|
|
126
130
|
expect(contents).toEqual(PACKAGE_CHILD_WITH_RIGHT_VERSION);
|
|
127
131
|
});
|
|
132
|
+
|
|
133
|
+
it("ignores ignored dependencies", () => {
|
|
134
|
+
const { addFile, checkAndSpy } = makeWorkspace({ fix: false });
|
|
135
|
+
addFile("./package.json", PACKAGE_ROOT);
|
|
136
|
+
addFile("./packages/wrong/package.json", PACKAGE_CHILD_WITH_WRONG_VERSION);
|
|
137
|
+
|
|
138
|
+
const ignored = checkAndSpy("./packages/wrong", { ignoredDependencies: ["foo"] });
|
|
139
|
+
expect(ignored.addErrorSpy).toHaveBeenCalledTimes(0);
|
|
140
|
+
});
|
|
128
141
|
});
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright 2020 Palantir Technologies, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { WorkspaceContext } from "@monorepolint/core";
|
|
9
|
+
import { Host, PackageJson, SimpleHost } from "@monorepolint/utils";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import * as tmp from "tmp";
|
|
12
|
+
import { consistentVersions, Options } from "../consistentVersions";
|
|
13
|
+
import { makeDirectoryRecursively } from "../util/makeDirectory";
|
|
14
|
+
|
|
15
|
+
describe("consistentVersions", () => {
|
|
16
|
+
tmp.setGracefulCleanup();
|
|
17
|
+
|
|
18
|
+
let cleanupJobs: Array<() => void> = [];
|
|
19
|
+
let cwd: string | undefined;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
const dir = tmp.dirSync({ unsafeCleanup: true });
|
|
23
|
+
cleanupJobs.push(() => dir.removeCallback());
|
|
24
|
+
cwd = dir.name;
|
|
25
|
+
|
|
26
|
+
const spy = jest.spyOn(process, "cwd");
|
|
27
|
+
spy.mockReturnValue(cwd);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
for (const cleanupJob of cleanupJobs) {
|
|
32
|
+
cleanupJob();
|
|
33
|
+
}
|
|
34
|
+
cleanupJobs = [];
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
function makeWorkspace(fix = false) {
|
|
38
|
+
const host: Host = new SimpleHost();
|
|
39
|
+
const workspaceContext = new WorkspaceContext(
|
|
40
|
+
cwd!,
|
|
41
|
+
{
|
|
42
|
+
rules: [],
|
|
43
|
+
fix,
|
|
44
|
+
verbose: false,
|
|
45
|
+
silent: true,
|
|
46
|
+
},
|
|
47
|
+
host
|
|
48
|
+
);
|
|
49
|
+
const addErrorSpy = jest.spyOn(workspaceContext, "addError");
|
|
50
|
+
|
|
51
|
+
function check(options: Options = { matchDependencyVersions: {} }) {
|
|
52
|
+
consistentVersions.check(workspaceContext, options);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { addErrorSpy, check, host };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function addPackageJson(host: Host, filePath: string, packageJson: PackageJson) {
|
|
59
|
+
const dirPath = path.resolve(cwd!, path.dirname(filePath));
|
|
60
|
+
const resolvedFilePath = path.resolve(cwd!, filePath);
|
|
61
|
+
|
|
62
|
+
makeDirectoryRecursively(dirPath);
|
|
63
|
+
host.writeJson(resolvedFilePath, packageJson);
|
|
64
|
+
return (): PackageJson => {
|
|
65
|
+
return host.readJson(resolvedFilePath);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("standard tests", () => {
|
|
70
|
+
let testPackageJson: PackageJson;
|
|
71
|
+
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
testPackageJson = {
|
|
74
|
+
name: "test",
|
|
75
|
+
dependencies: {
|
|
76
|
+
greatLib: "^15",
|
|
77
|
+
both: "1",
|
|
78
|
+
},
|
|
79
|
+
peerDependencies: {
|
|
80
|
+
whatever: "15",
|
|
81
|
+
},
|
|
82
|
+
devDependencies: {
|
|
83
|
+
else: "27.2.1",
|
|
84
|
+
both: "1",
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("Does nothing when arguments are empty", async () => {
|
|
90
|
+
const { addErrorSpy, check, host } = makeWorkspace();
|
|
91
|
+
addPackageJson(host, "./package.json", testPackageJson);
|
|
92
|
+
|
|
93
|
+
check();
|
|
94
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
95
|
+
check({ matchDependencyVersions: {} });
|
|
96
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("Fixes packages that have an incorrect dependency version", async () => {
|
|
100
|
+
const { addErrorSpy, check, host } = makeWorkspace(true);
|
|
101
|
+
const readTestPackageJson = addPackageJson(host, "./package.json", testPackageJson);
|
|
102
|
+
|
|
103
|
+
const requiredGreatLibVersion = "1.2.3";
|
|
104
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
105
|
+
check({
|
|
106
|
+
matchDependencyVersions: { both: testPackageJson.dependencies!.both, greatLib: requiredGreatLibVersion },
|
|
107
|
+
});
|
|
108
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(1);
|
|
109
|
+
expect(readTestPackageJson().dependencies!.greatLib).toEqual(requiredGreatLibVersion);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("Ignores packages that have a correct dependency version", async () => {
|
|
113
|
+
const { addErrorSpy, check, host } = makeWorkspace();
|
|
114
|
+
addPackageJson(host, "./package.json", testPackageJson);
|
|
115
|
+
|
|
116
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
117
|
+
check({
|
|
118
|
+
matchDependencyVersions: {
|
|
119
|
+
both: testPackageJson.dependencies!.both,
|
|
120
|
+
greatLib: testPackageJson.dependencies!.greatLib,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("Fixes packages that have an incorrect devDependency version", async () => {
|
|
127
|
+
const { addErrorSpy, check, host } = makeWorkspace(true);
|
|
128
|
+
const readTestPackageJson = addPackageJson(host, "./package.json", testPackageJson);
|
|
129
|
+
|
|
130
|
+
const requiredElseLibVersion = "1.2.3";
|
|
131
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
132
|
+
check({ matchDependencyVersions: { both: testPackageJson.dependencies!.both, else: requiredElseLibVersion } });
|
|
133
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(1);
|
|
134
|
+
expect(readTestPackageJson().devDependencies!.else).toEqual(requiredElseLibVersion);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("Ignores packages that have a correct devDependency version", async () => {
|
|
138
|
+
const { addErrorSpy, check, host } = makeWorkspace();
|
|
139
|
+
addPackageJson(host, "./package.json", testPackageJson);
|
|
140
|
+
|
|
141
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
142
|
+
check({
|
|
143
|
+
matchDependencyVersions: {
|
|
144
|
+
both: testPackageJson.dependencies!.both,
|
|
145
|
+
greatLib: testPackageJson.dependencies!.greatLib,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("Fixes packages that have an incorrect dependency and devDependency versions", async () => {
|
|
152
|
+
const { addErrorSpy, check, host } = makeWorkspace(true);
|
|
153
|
+
const readTestPackageJson = addPackageJson(host, "./package.json", testPackageJson);
|
|
154
|
+
|
|
155
|
+
const requiredBothVersion = "1.2.3";
|
|
156
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
157
|
+
check({ matchDependencyVersions: { both: requiredBothVersion } });
|
|
158
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(2);
|
|
159
|
+
expect(readTestPackageJson().dependencies!.both).toEqual(requiredBothVersion);
|
|
160
|
+
expect(readTestPackageJson().devDependencies!.both).toEqual(requiredBothVersion);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe("Multiple accepted versions tests", () => {
|
|
165
|
+
let testPackageJson: PackageJson;
|
|
166
|
+
|
|
167
|
+
beforeEach(() => {
|
|
168
|
+
testPackageJson = {
|
|
169
|
+
name: "test",
|
|
170
|
+
dependencies: {
|
|
171
|
+
greatLib: "^15",
|
|
172
|
+
both: "1",
|
|
173
|
+
},
|
|
174
|
+
peerDependencies: {
|
|
175
|
+
whatever: "15",
|
|
176
|
+
},
|
|
177
|
+
devDependencies: {
|
|
178
|
+
else: "27.2.1",
|
|
179
|
+
both: "1",
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("Accepts a match when multiple versions are configured", async () => {
|
|
185
|
+
const { addErrorSpy, check, host } = makeWorkspace();
|
|
186
|
+
addPackageJson(host, "./package.json", testPackageJson);
|
|
187
|
+
|
|
188
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
189
|
+
check({ matchDependencyVersions: { greatLib: [testPackageJson.dependencies!.greatLib] } });
|
|
190
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
191
|
+
check({ matchDependencyVersions: { greatLib: ["1", "2", testPackageJson.dependencies!.greatLib] } });
|
|
192
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
193
|
+
check({ matchDependencyVersions: { greatLib: ["1", "2", testPackageJson.dependencies!.greatLib, "99", "100"] } });
|
|
194
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
195
|
+
check({ matchDependencyVersions: { greatLib: [testPackageJson.dependencies!.greatLib, "99", "100"] } });
|
|
196
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it("Errors when version does not match", async () => {
|
|
200
|
+
const { addErrorSpy, check, host } = makeWorkspace();
|
|
201
|
+
addPackageJson(host, "./package.json", testPackageJson);
|
|
202
|
+
|
|
203
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
204
|
+
check({ matchDependencyVersions: { greatLib: ["1", "2"] } });
|
|
205
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(1);
|
|
206
|
+
addErrorSpy.mockReset();
|
|
207
|
+
|
|
208
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(0);
|
|
209
|
+
check({ matchDependencyVersions: { both: ["99", "100"] } });
|
|
210
|
+
expect(addErrorSpy).toHaveBeenCalledTimes(2);
|
|
211
|
+
expect(addErrorSpy.mock.calls[0][0].message).toEqual(
|
|
212
|
+
`Expected dependency on both to match one of '["99","100"]', got '${
|
|
213
|
+
testPackageJson.dependencies!.both
|
|
214
|
+
}' instead.`
|
|
215
|
+
);
|
|
216
|
+
expect(addErrorSpy.mock.calls[1][0].message).toEqual(
|
|
217
|
+
`Expected devDependency on both to match one of '["99","100"]', got '${
|
|
218
|
+
testPackageJson.devDependencies!.both
|
|
219
|
+
}' instead.`
|
|
220
|
+
);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright 2019 Palantir Technologies, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// tslint:disable:no-console
|
|
9
|
+
import { createTestingWorkspace, HOST_FACTORIES, TestingWorkspace } from "./utils";
|
|
10
|
+
import { AddErrorOptions, Failure } from "@monorepolint/core";
|
|
11
|
+
import { fileContents } from "../fileContents";
|
|
12
|
+
|
|
13
|
+
const EXPECTED_FOO_FILE = "hello world";
|
|
14
|
+
|
|
15
|
+
describe.each(HOST_FACTORIES)("fileContents ($name)", (hostFactory) => {
|
|
16
|
+
describe("fix: true", () => {
|
|
17
|
+
let workspace: TestingWorkspace;
|
|
18
|
+
let spy: jest.SpyInstance<void, [AddErrorOptions]>;
|
|
19
|
+
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
workspace = await createTestingWorkspace({
|
|
22
|
+
fixFlag: true,
|
|
23
|
+
host: hostFactory.make(),
|
|
24
|
+
});
|
|
25
|
+
workspace.writeFile("shared/foo-template.txt", EXPECTED_FOO_FILE);
|
|
26
|
+
|
|
27
|
+
spy = jest.spyOn(workspace.context, "addError");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("fixes missing file", () => {
|
|
31
|
+
fileContents.check(workspace.context, {
|
|
32
|
+
file: "foo.txt",
|
|
33
|
+
templateFile: "shared/foo-template.txt",
|
|
34
|
+
generator: undefined,
|
|
35
|
+
template: undefined,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
39
|
+
|
|
40
|
+
const failure: Failure = spy.mock.calls[0][0];
|
|
41
|
+
expect(failure).toMatchObject(
|
|
42
|
+
workspace.failureMatcher({
|
|
43
|
+
file: "foo.txt",
|
|
44
|
+
hasFixer: true,
|
|
45
|
+
message: "Expect file contents to match",
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(workspace.readFile("foo.txt")).toEqual(EXPECTED_FOO_FILE);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("fixes missing nested file", () => {
|
|
53
|
+
fileContents.check(workspace.context, {
|
|
54
|
+
file: "nested/foo.txt",
|
|
55
|
+
templateFile: "shared/foo-template.txt",
|
|
56
|
+
generator: undefined,
|
|
57
|
+
template: undefined,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
61
|
+
|
|
62
|
+
const failure: Failure = spy.mock.calls[0][0];
|
|
63
|
+
expect(failure).toMatchObject(
|
|
64
|
+
workspace.failureMatcher({
|
|
65
|
+
file: "nested/foo.txt",
|
|
66
|
+
hasFixer: true,
|
|
67
|
+
message: "Expect file contents to match",
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
expect(workspace.readFile("nested/foo.txt")).toEqual(EXPECTED_FOO_FILE);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|