@monorepolint/utils 0.6.0-alpha.2 → 0.6.0-alpha.3
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/.turbo/turbo-clean.log +1 -1
- package/.turbo/turbo-compile-typescript.log +1 -1
- package/.turbo/turbo-lint.log +7 -7
- package/.turbo/turbo-test.log +14 -10
- package/.turbo/turbo-transpile-typescript.log +3 -3
- package/CHANGELOG.md +2 -0
- package/build/js/index.js +493 -443
- package/build/js/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/CachingHost.d.ts.map +1 -1
- package/build/types/Host.d.ts.map +1 -1
- package/build/types/PackageJson.d.ts.map +1 -1
- package/build/types/SimpleHost.d.ts.map +1 -1
- package/build/types/Table.d.ts.map +1 -1
- package/build/types/findWorkspaceDir.d.ts.map +1 -1
- package/build/types/getPackageNameToDir.d.ts.map +1 -1
- package/build/types/getWorkspacePackageDirs.d.ts.map +1 -1
- package/build/types/index.d.ts +7 -7
- package/build/types/index.d.ts.map +1 -1
- package/build/types/matchesAnyGlob.d.ts.map +1 -1
- package/build/types/mutateJson.d.ts.map +1 -1
- package/build/types/nanosecondsToSanity.d.ts.map +1 -1
- package/coverage/AggregateTiming.ts.html +2 -2
- package/coverage/CachingHost.ts.html +258 -42
- package/coverage/Host.ts.html +15 -3
- package/coverage/PackageJson.ts.html +4 -4
- package/coverage/SimpleHost.ts.html +40 -7
- package/coverage/Table.ts.html +148 -31
- package/coverage/Timing.ts.html +1 -1
- package/coverage/clover.xml +533 -389
- package/coverage/coverage-final.json +13 -13
- package/coverage/findWorkspaceDir.ts.html +4 -4
- package/coverage/getPackageNameToDir.ts.html +18 -6
- package/coverage/getWorkspacePackageDirs.ts.html +174 -138
- package/coverage/index.html +40 -40
- package/coverage/index.ts.html +30 -30
- package/coverage/matchesAnyGlob.ts.html +37 -10
- package/coverage/mutateJson.ts.html +17 -5
- package/coverage/nanosecondsToSanity.ts.html +11 -5
- package/package.json +1 -2
- package/src/AggregateTiming.ts +1 -1
- package/src/CachingHost.ts +106 -34
- package/src/Host.ts +5 -1
- package/src/PackageJson.ts +3 -3
- package/src/SimpleHost.ts +14 -3
- package/src/Table.ts +62 -23
- package/src/__tests__/CachingHost.spec.ts +203 -166
- package/src/findWorkspaceDir.ts +3 -3
- package/src/getPackageNameToDir.ts +6 -2
- package/src/getWorkspacePackageDirs.ts +22 -10
- package/src/index.ts +7 -7
- package/src/matchesAnyGlob.ts +12 -3
- package/src/mutateJson.ts +5 -1
- package/src/nanosecondsToSanity.ts +3 -1
- package/vitest.config.mjs +10 -7
- package/vitest.config.mjs.timestamp-1736878329730-aa478e2241542.mjs +2 -2
package/build/js/index.js
CHANGED
|
@@ -1,149 +1,291 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
import readYamlFile from "read-yaml-file";
|
|
7
|
-
import { findPackages } from "find-packages";
|
|
8
|
-
async function findPNPMWorkspacePackages(workspaceRoot) {
|
|
9
|
-
workspaceRoot = fs.realpathSync(workspaceRoot);
|
|
10
|
-
const workspaceManifest = await readYamlFile.default(
|
|
11
|
-
path.join(workspaceRoot, "pnpm-workspace.yaml")
|
|
12
|
-
);
|
|
13
|
-
return findPackages(workspaceRoot, {
|
|
14
|
-
ignore: ["**/node_modules/**", "**/bower_components/**"],
|
|
15
|
-
includeRoot: true,
|
|
16
|
-
patterns: workspaceManifest.packages
|
|
17
|
-
});
|
|
1
|
+
// src/nanosecondsToSanity.ts
|
|
2
|
+
function nanosecondsToSanity(n, precision = 9) {
|
|
3
|
+
return n / BigInt(1e9) + "." + ("" + n % BigInt(1e9)).padStart(9, "0").substring(0, precision) + "s";
|
|
18
4
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
|
|
6
|
+
// src/Table.ts
|
|
7
|
+
var Table = class {
|
|
8
|
+
#rows = [];
|
|
9
|
+
#config;
|
|
10
|
+
#columnWidths = [];
|
|
11
|
+
#footer = [];
|
|
12
|
+
#footerRowConfig;
|
|
13
|
+
#totalWidth = 0;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.#config = {
|
|
16
|
+
padding: 2,
|
|
17
|
+
...config
|
|
18
|
+
};
|
|
19
|
+
this.#columnWidths.fill(0, 0, config.columns.length);
|
|
20
|
+
if (config.showFooter) {
|
|
21
|
+
this.#footerRowConfig = [];
|
|
22
|
+
for (const columnConfig of config.columns) {
|
|
23
|
+
if (columnConfig.footer === void 0) {
|
|
24
|
+
throw new Error("Must specify footer fields when showFooter is true");
|
|
25
|
+
} else if (typeof columnConfig.footer === "string") {
|
|
26
|
+
this.#footerRowConfig.push({
|
|
27
|
+
type: "string",
|
|
28
|
+
alignment: "left",
|
|
29
|
+
aggregate: "static",
|
|
30
|
+
value: columnConfig.footer
|
|
31
|
+
});
|
|
32
|
+
} else if ("value" in columnConfig.footer) {
|
|
33
|
+
this.#footerRowConfig.push({
|
|
34
|
+
type: "string",
|
|
35
|
+
alignment: "left",
|
|
36
|
+
...columnConfig.footer
|
|
37
|
+
});
|
|
38
|
+
} else if ("aggregate" in columnConfig.footer) {
|
|
39
|
+
if (columnConfig.type !== "bigint") {
|
|
40
|
+
throw new Error("expecting bigint for aggregate");
|
|
41
|
+
}
|
|
42
|
+
this.#footerRowConfig.push({
|
|
43
|
+
type: columnConfig.type,
|
|
44
|
+
renderAs: columnConfig.renderAs,
|
|
45
|
+
precision: columnConfig.precision,
|
|
46
|
+
alignment: "right",
|
|
47
|
+
...columnConfig.footer
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
26
51
|
}
|
|
27
|
-
return workspacePackages.map((project) => project.dir).filter((d) => d !== workspaceDir);
|
|
28
52
|
}
|
|
29
|
-
|
|
30
|
-
|
|
53
|
+
addRow(...data) {
|
|
54
|
+
this.#rows.push(data);
|
|
31
55
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
#sumColumn(c) {
|
|
57
|
+
let total = BigInt(0);
|
|
58
|
+
for (const row of this.#rows) {
|
|
59
|
+
total += row[c];
|
|
60
|
+
}
|
|
61
|
+
return total;
|
|
62
|
+
}
|
|
63
|
+
#updateFooterRow() {
|
|
64
|
+
const footerRowConfig = this.#footerRowConfig;
|
|
65
|
+
if (footerRowConfig) {
|
|
66
|
+
for (let c = 0; c < footerRowConfig.length; c++) {
|
|
67
|
+
const footerColConfig = footerRowConfig[c];
|
|
68
|
+
switch (footerColConfig.aggregate) {
|
|
69
|
+
case "sum":
|
|
70
|
+
this.#footer[c] = this.#sumColumn(c);
|
|
71
|
+
break;
|
|
72
|
+
case "average":
|
|
73
|
+
this.#footer[c] = this.#sumColumn(c) / BigInt(this.#rows.length);
|
|
74
|
+
break;
|
|
75
|
+
case "static":
|
|
76
|
+
this.#footer[c] = footerColConfig.value;
|
|
77
|
+
break;
|
|
42
78
|
}
|
|
43
79
|
}
|
|
44
80
|
}
|
|
45
81
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const maybePnpmWorkspaceDir = await findPnpmWorkspaceDir(dir);
|
|
68
|
-
if (maybePnpmWorkspaceDir != null) {
|
|
69
|
-
return maybePnpmWorkspaceDir;
|
|
82
|
+
#calculateColumnWidths() {
|
|
83
|
+
var _a;
|
|
84
|
+
this.#columnWidths.fill(0, 0, this.#config.columns.length);
|
|
85
|
+
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
86
|
+
const colConfig = this.#config.columns[c];
|
|
87
|
+
this.#columnWidths[c] = Math.max(
|
|
88
|
+
(this.#config.columns[c].header ?? "").length,
|
|
89
|
+
...this.#rows.map(
|
|
90
|
+
(a) => this.#getCellValueAsString(a[c], colConfig).length
|
|
91
|
+
),
|
|
92
|
+
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(
|
|
93
|
+
((_a = this.#footer) == null ? void 0 : _a[c]) ?? "",
|
|
94
|
+
this.#footerRowConfig[c]
|
|
95
|
+
).length : 0
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
this.#totalWidth = 0;
|
|
99
|
+
for (const colWidth of this.#columnWidths) {
|
|
100
|
+
this.#totalWidth += colWidth;
|
|
101
|
+
}
|
|
102
|
+
this.#totalWidth += (this.#columnWidths.length - 1) * this.#config.padding;
|
|
70
103
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
#printSeparator(fillString) {
|
|
105
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
106
|
+
let hr2 = "";
|
|
107
|
+
for (let c = 0; c < this.#columnWidths.length; c++) {
|
|
108
|
+
hr2 += "".padStart(this.#columnWidths[c], fillString) + paddingString;
|
|
76
109
|
}
|
|
110
|
+
hr2 = hr2.trimRight();
|
|
111
|
+
console.log(hr2);
|
|
77
112
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
113
|
+
#printHeaderRow() {
|
|
114
|
+
if (this.#config.showHeader) {
|
|
115
|
+
const colConfigs = this.#config.columns;
|
|
116
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
117
|
+
let hr = "";
|
|
118
|
+
for (let c = 0; c < colConfigs.length; c++) {
|
|
119
|
+
const heading = colConfigs[c].header ?? "";
|
|
120
|
+
hr += heading.padEnd(this.#columnWidths[c], " ") + paddingString;
|
|
121
|
+
}
|
|
122
|
+
hr = hr.trimRight();
|
|
123
|
+
console.log(hr);
|
|
124
|
+
this.#printSeparator("-");
|
|
125
|
+
}
|
|
81
126
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (name === void 0) {
|
|
94
|
-
throw new Error(`Package needs a name: ${packagePath}`);
|
|
127
|
+
#printFooterRow() {
|
|
128
|
+
const footerRow = this.#footer;
|
|
129
|
+
if (footerRow) {
|
|
130
|
+
this.#printSeparator("=");
|
|
131
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
132
|
+
let hr = "";
|
|
133
|
+
for (let c = 0; c < footerRow.length; c++) {
|
|
134
|
+
hr += this.#getCellValueAligned(footerRow[c], this.#footerRowConfig[c], c) + paddingString;
|
|
135
|
+
}
|
|
136
|
+
hr = hr.trimRight();
|
|
137
|
+
console.log(hr);
|
|
95
138
|
}
|
|
96
|
-
ret.set(name, packageDir);
|
|
97
139
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this
|
|
140
|
+
print() {
|
|
141
|
+
if (this.#config.sortColumn !== void 0) {
|
|
142
|
+
}
|
|
143
|
+
this.#updateFooterRow();
|
|
144
|
+
this.#calculateColumnWidths();
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(`${this.#config.title}`);
|
|
147
|
+
console.log("".padStart(this.#totalWidth, "="));
|
|
148
|
+
const paddingString = "".padStart(this.#config.padding, " ");
|
|
149
|
+
if (this.#config.showHeader) {
|
|
150
|
+
this.#printHeaderRow();
|
|
151
|
+
}
|
|
152
|
+
for (let r = 0; r < this.#rows.length; r++) {
|
|
153
|
+
let rowText = "";
|
|
154
|
+
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
155
|
+
rowText += this.getEntryAsStringAligned(c, r) + paddingString;
|
|
156
|
+
}
|
|
157
|
+
rowText.trim();
|
|
158
|
+
console.log(rowText);
|
|
159
|
+
}
|
|
160
|
+
if (this.#config.showFooter) this.#printFooterRow();
|
|
161
|
+
console.log();
|
|
106
162
|
}
|
|
107
|
-
|
|
108
|
-
|
|
163
|
+
#getCellValueAsString(value, config) {
|
|
164
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
165
|
+
return nanosecondsToSanity(value, config.precision ?? 9);
|
|
166
|
+
} else {
|
|
167
|
+
return "" + value;
|
|
168
|
+
}
|
|
109
169
|
}
|
|
110
|
-
|
|
111
|
-
|
|
170
|
+
#getCellValueAligned(value, config, column) {
|
|
171
|
+
let result;
|
|
172
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
173
|
+
result = nanosecondsToSanity(value, config.precision ?? 9);
|
|
174
|
+
} else {
|
|
175
|
+
result = "" + value;
|
|
176
|
+
}
|
|
177
|
+
if (config.alignment === "left") {
|
|
178
|
+
return result.padEnd(this.#columnWidths[column]);
|
|
179
|
+
} else {
|
|
180
|
+
return result.padStart(this.#columnWidths[column]);
|
|
181
|
+
}
|
|
112
182
|
}
|
|
113
|
-
|
|
114
|
-
|
|
183
|
+
getEntryAsString(colNum, rowNum) {
|
|
184
|
+
const config = this.#config.columns[colNum];
|
|
185
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
186
|
+
return nanosecondsToSanity(
|
|
187
|
+
this.#rows[rowNum][colNum],
|
|
188
|
+
config.precision ?? 9
|
|
189
|
+
);
|
|
190
|
+
} else {
|
|
191
|
+
return "" + this.#rows[rowNum][colNum];
|
|
192
|
+
}
|
|
115
193
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
194
|
+
getEntryAsStringAligned(colNum, rowNum) {
|
|
195
|
+
const config = this.#config.columns[colNum];
|
|
196
|
+
let result;
|
|
197
|
+
if (config.type === "bigint" && config.renderAs === "nanoseconds") {
|
|
198
|
+
result = nanosecondsToSanity(
|
|
199
|
+
this.#rows[rowNum][colNum],
|
|
200
|
+
config.precision ?? 9
|
|
201
|
+
);
|
|
119
202
|
} else {
|
|
120
|
-
this
|
|
203
|
+
result = "" + this.#rows[rowNum][colNum];
|
|
204
|
+
}
|
|
205
|
+
if (config.alignment === "left") {
|
|
206
|
+
return result.padEnd(this.#columnWidths[colNum]);
|
|
207
|
+
} else {
|
|
208
|
+
return result.padStart(this.#columnWidths[colNum]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
getColumnWidth(colNum, config) {
|
|
212
|
+
let maxWidth = Math.max(
|
|
213
|
+
(config.header ?? "").length,
|
|
214
|
+
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(
|
|
215
|
+
this.#footer[colNum],
|
|
216
|
+
this.#footerRowConfig[colNum]
|
|
217
|
+
).length : 0
|
|
218
|
+
);
|
|
219
|
+
for (let r = 0; r < this.#rows.length; r++) {
|
|
220
|
+
maxWidth = Math.max(maxWidth, this.getEntryAsString(colNum, r).length);
|
|
221
|
+
}
|
|
222
|
+
return maxWidth;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// src/AggregateTiming.ts
|
|
227
|
+
var AggregateTiming = class {
|
|
228
|
+
constructor(title) {
|
|
229
|
+
this.title = title;
|
|
230
|
+
}
|
|
231
|
+
#data = /* @__PURE__ */ new Map();
|
|
232
|
+
#last;
|
|
233
|
+
start(name) {
|
|
234
|
+
const time = process.hrtime.bigint();
|
|
235
|
+
if (this.#last) {
|
|
236
|
+
this.#last.total += time;
|
|
237
|
+
}
|
|
238
|
+
let data = this.#data.get(name);
|
|
239
|
+
if (data === void 0) {
|
|
240
|
+
data = { count: 1, total: -time };
|
|
241
|
+
this.#data.set(name, data);
|
|
242
|
+
} else {
|
|
243
|
+
data.total -= time;
|
|
244
|
+
data.count++;
|
|
121
245
|
}
|
|
246
|
+
this.#last = data;
|
|
122
247
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
248
|
+
stop() {
|
|
249
|
+
const time = process.hrtime.bigint();
|
|
250
|
+
if (this.#last) {
|
|
251
|
+
this.#last.total += time;
|
|
252
|
+
this.#last = void 0;
|
|
126
253
|
}
|
|
127
|
-
return this.fs.readFileSync(path4, opts == null ? void 0 : opts.encoding);
|
|
128
|
-
}
|
|
129
|
-
deleteFile(path4) {
|
|
130
|
-
this.fs.unlinkSync(path4);
|
|
131
|
-
}
|
|
132
|
-
readJson(filename) {
|
|
133
|
-
const contents = this.fs.readFileSync(filename, "utf-8");
|
|
134
|
-
return JSON.parse(contents);
|
|
135
|
-
}
|
|
136
|
-
writeJson(path4, o) {
|
|
137
|
-
return this.fs.writeFileSync(path4, JSON.stringify(o, void 0, 2) + "\n");
|
|
138
254
|
}
|
|
139
|
-
|
|
140
|
-
|
|
255
|
+
printResults() {
|
|
256
|
+
const table = new Table({
|
|
257
|
+
sortColumn: -1,
|
|
258
|
+
showFooter: true,
|
|
259
|
+
showHeader: true,
|
|
260
|
+
title: this.title,
|
|
261
|
+
columns: [
|
|
262
|
+
{
|
|
263
|
+
header: "Duration",
|
|
264
|
+
type: "bigint",
|
|
265
|
+
renderAs: "nanoseconds",
|
|
266
|
+
footer: { aggregate: "sum" }
|
|
267
|
+
},
|
|
268
|
+
{ header: "Task", type: "string", alignment: "left", footer: "TOTAL" },
|
|
269
|
+
{ header: "Count", type: "bigint", footer: { aggregate: "sum" } },
|
|
270
|
+
{ header: "Avg", type: "bigint", footer: { aggregate: "average" } }
|
|
271
|
+
]
|
|
272
|
+
});
|
|
273
|
+
for (const [name, value] of this.#data) {
|
|
274
|
+
table.addRow(
|
|
275
|
+
value.total,
|
|
276
|
+
name,
|
|
277
|
+
BigInt(value.count),
|
|
278
|
+
// fixme this can be a number later
|
|
279
|
+
value.total / BigInt(value.count)
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
table.print();
|
|
141
283
|
}
|
|
142
284
|
};
|
|
143
285
|
|
|
144
286
|
// src/CachingHost.ts
|
|
145
|
-
import * as
|
|
146
|
-
import * as
|
|
287
|
+
import * as realFs from "node:fs";
|
|
288
|
+
import * as path from "node:path";
|
|
147
289
|
function assertNoTombstone(node) {
|
|
148
290
|
if (node.tombstone) {
|
|
149
291
|
throw new Error(`Unexpected tombstone ${JSON.stringify(node)}`);
|
|
@@ -170,7 +312,7 @@ function assertHasParent(node) {
|
|
|
170
312
|
}
|
|
171
313
|
}
|
|
172
314
|
var CachingHost = class {
|
|
173
|
-
constructor(fs3 =
|
|
315
|
+
constructor(fs3 = realFs) {
|
|
174
316
|
this.fs = fs3;
|
|
175
317
|
}
|
|
176
318
|
// We need many trees because of windows, key is the `root`
|
|
@@ -183,19 +325,21 @@ var CachingHost = class {
|
|
|
183
325
|
parent: node.parent,
|
|
184
326
|
dir: node.dir
|
|
185
327
|
};
|
|
186
|
-
node.parent.dir.set(
|
|
328
|
+
node.parent.dir.set(path.basename(node.fullPath), newNode);
|
|
187
329
|
return newNode;
|
|
188
330
|
}
|
|
189
331
|
#unstubDirectory(node) {
|
|
190
332
|
for (const child of this.fs.readdirSync(node.fullPath)) {
|
|
191
|
-
this.#getNode(
|
|
333
|
+
this.#getNode(path.join(node.fullPath, child));
|
|
192
334
|
}
|
|
193
335
|
node.stub = false;
|
|
194
336
|
}
|
|
195
337
|
#stubify(filePath, parent) {
|
|
196
|
-
const canonicalPath =
|
|
197
|
-
if (!parent && canonicalPath !==
|
|
198
|
-
throw new Error(
|
|
338
|
+
const canonicalPath = path.resolve(filePath);
|
|
339
|
+
if (!parent && canonicalPath !== path.parse(canonicalPath).root) {
|
|
340
|
+
throw new Error(
|
|
341
|
+
`parent can only be null if path is root. Instead got: ${canonicalPath}`
|
|
342
|
+
);
|
|
199
343
|
}
|
|
200
344
|
const stat = this.fs.lstatSync(canonicalPath);
|
|
201
345
|
let node;
|
|
@@ -225,15 +369,19 @@ var CachingHost = class {
|
|
|
225
369
|
needsFlush: false
|
|
226
370
|
};
|
|
227
371
|
} else {
|
|
228
|
-
throw new Error(
|
|
372
|
+
throw new Error(
|
|
373
|
+
`what is not a file nor symlink nor directory? nothing we care about: ${canonicalPath}`
|
|
374
|
+
);
|
|
229
375
|
}
|
|
230
376
|
if (!parent && node.type === "dir") {
|
|
231
377
|
this.#trees.set(canonicalPath, node);
|
|
232
378
|
return node;
|
|
233
379
|
} else if (parent) {
|
|
234
|
-
parent.dir.set(
|
|
380
|
+
parent.dir.set(path.basename(canonicalPath), node);
|
|
235
381
|
} else {
|
|
236
|
-
throw new Error(
|
|
382
|
+
throw new Error(
|
|
383
|
+
`root can only be a dir, got ${JSON.stringify(node)} for path: ${canonicalPath}`
|
|
384
|
+
);
|
|
237
385
|
}
|
|
238
386
|
return node;
|
|
239
387
|
}
|
|
@@ -242,13 +390,13 @@ var CachingHost = class {
|
|
|
242
390
|
* You should check the `fullPath` of the result.
|
|
243
391
|
*/
|
|
244
392
|
#getNearestAncestorNode(filePath) {
|
|
245
|
-
const canonicalPath =
|
|
246
|
-
const { root } =
|
|
393
|
+
const canonicalPath = path.resolve(filePath);
|
|
394
|
+
const { root } = path.parse(canonicalPath);
|
|
247
395
|
const parts = [];
|
|
248
396
|
let maybePath = canonicalPath;
|
|
249
397
|
while (maybePath !== root) {
|
|
250
|
-
parts.unshift(
|
|
251
|
-
maybePath =
|
|
398
|
+
parts.unshift(path.basename(maybePath));
|
|
399
|
+
maybePath = path.dirname(maybePath);
|
|
252
400
|
}
|
|
253
401
|
let curPath = root;
|
|
254
402
|
let curNode = this.#trees.get(root) ?? this.#stubify(curPath, void 0);
|
|
@@ -257,7 +405,9 @@ var CachingHost = class {
|
|
|
257
405
|
assertNoTombstone(curNode);
|
|
258
406
|
assertNotType(curNode, "file");
|
|
259
407
|
if (curNode.type === "symlink") {
|
|
260
|
-
const linkedNode = this.#getNodeResolvingSymlinks(
|
|
408
|
+
const linkedNode = this.#getNodeResolvingSymlinks(
|
|
409
|
+
path.resolve(path.dirname(curPath), curNode.symlink)
|
|
410
|
+
);
|
|
261
411
|
assertExists(linkedNode);
|
|
262
412
|
assertNoTombstone(linkedNode);
|
|
263
413
|
assertType(linkedNode, "dir");
|
|
@@ -265,16 +415,18 @@ var CachingHost = class {
|
|
|
265
415
|
}
|
|
266
416
|
assertType(curNode, "dir");
|
|
267
417
|
assertNoTombstone(curNode);
|
|
268
|
-
curNode = curNode.dir.get(part) ?? this.#stubify(
|
|
269
|
-
curPath =
|
|
418
|
+
curNode = curNode.dir.get(part) ?? this.#stubify(path.join(curNode.fullPath, part), curNode);
|
|
419
|
+
curPath = path.join(curPath, part);
|
|
270
420
|
}
|
|
271
421
|
} catch (e) {
|
|
272
422
|
}
|
|
273
423
|
return { pathWithSymlinks: curPath, node: curNode };
|
|
274
424
|
}
|
|
275
425
|
#getNode(filePath) {
|
|
276
|
-
const canonicalPath =
|
|
277
|
-
const { pathWithSymlinks, node } = this.#getNearestAncestorNode(
|
|
426
|
+
const canonicalPath = path.resolve(filePath);
|
|
427
|
+
const { pathWithSymlinks, node } = this.#getNearestAncestorNode(
|
|
428
|
+
canonicalPath
|
|
429
|
+
);
|
|
278
430
|
if (pathWithSymlinks === canonicalPath) {
|
|
279
431
|
return node;
|
|
280
432
|
}
|
|
@@ -287,16 +439,18 @@ var CachingHost = class {
|
|
|
287
439
|
return this.#getNodeResolvingSymlinks(node.symlink, follows--);
|
|
288
440
|
}
|
|
289
441
|
mkdir(filePath, opts = { recursive: false }) {
|
|
290
|
-
const canonicalPath =
|
|
291
|
-
const { node, pathWithSymlinks } = this.#getNearestAncestorNode(
|
|
442
|
+
const canonicalPath = path.resolve(filePath);
|
|
443
|
+
const { node, pathWithSymlinks } = this.#getNearestAncestorNode(
|
|
444
|
+
canonicalPath
|
|
445
|
+
);
|
|
292
446
|
if (filePath === pathWithSymlinks) {
|
|
293
447
|
assertType(node, "dir");
|
|
294
448
|
assertHasParent(node);
|
|
295
449
|
if (!node.tombstone) return;
|
|
296
|
-
} else if (
|
|
450
|
+
} else if (path.dirname(filePath) === pathWithSymlinks) {
|
|
297
451
|
assertType(node, "dir");
|
|
298
452
|
assertNoTombstone(node);
|
|
299
|
-
node.dir.set(
|
|
453
|
+
node.dir.set(path.basename(filePath), {
|
|
300
454
|
type: "dir",
|
|
301
455
|
fullPath: filePath,
|
|
302
456
|
parent: node,
|
|
@@ -305,15 +459,17 @@ var CachingHost = class {
|
|
|
305
459
|
});
|
|
306
460
|
return;
|
|
307
461
|
}
|
|
308
|
-
if (!opts.recursive &&
|
|
462
|
+
if (!opts.recursive && path.dirname(canonicalPath) !== pathWithSymlinks) {
|
|
309
463
|
throw new Error("no such file or directory");
|
|
310
464
|
}
|
|
311
465
|
const rootPath = pathWithSymlinks;
|
|
312
466
|
let maybePath = canonicalPath;
|
|
313
467
|
const toMake = [];
|
|
314
468
|
while (maybePath !== rootPath) {
|
|
315
|
-
toMake.unshift(
|
|
316
|
-
|
|
469
|
+
toMake.unshift(
|
|
470
|
+
path.resolve(node.fullPath, path.relative(rootPath, maybePath))
|
|
471
|
+
);
|
|
472
|
+
maybePath = path.dirname(maybePath);
|
|
317
473
|
}
|
|
318
474
|
for (const dirToMake of toMake) {
|
|
319
475
|
this.mkdir(dirToMake);
|
|
@@ -366,7 +522,7 @@ var CachingHost = class {
|
|
|
366
522
|
}
|
|
367
523
|
writeFile(filePath, body, opts) {
|
|
368
524
|
const fileContentsAsBuffer = typeof body === "string" ? Buffer.from(body, opts == null ? void 0 : opts.encoding) : Buffer.from(body);
|
|
369
|
-
const canonicalPath =
|
|
525
|
+
const canonicalPath = path.resolve(filePath);
|
|
370
526
|
const existingNode = this.#getNodeResolvingSymlinks(canonicalPath);
|
|
371
527
|
if (existingNode) {
|
|
372
528
|
if (existingNode.type === "dir") {
|
|
@@ -379,11 +535,13 @@ var CachingHost = class {
|
|
|
379
535
|
});
|
|
380
536
|
return;
|
|
381
537
|
}
|
|
382
|
-
const maybeDirNode = this.#getNodeResolvingSymlinks(
|
|
538
|
+
const maybeDirNode = this.#getNodeResolvingSymlinks(
|
|
539
|
+
path.dirname(canonicalPath)
|
|
540
|
+
);
|
|
383
541
|
assertExists(maybeDirNode);
|
|
384
542
|
assertType(maybeDirNode, "dir");
|
|
385
543
|
assertNoTombstone(maybeDirNode);
|
|
386
|
-
maybeDirNode.dir.set(
|
|
544
|
+
maybeDirNode.dir.set(path.basename(canonicalPath), {
|
|
387
545
|
type: "file",
|
|
388
546
|
fullPath: canonicalPath,
|
|
389
547
|
parent: maybeDirNode,
|
|
@@ -392,7 +550,7 @@ var CachingHost = class {
|
|
|
392
550
|
});
|
|
393
551
|
}
|
|
394
552
|
deleteFile(filePath) {
|
|
395
|
-
const canonicalPath =
|
|
553
|
+
const canonicalPath = path.resolve(filePath);
|
|
396
554
|
const node = this.#getNode(canonicalPath);
|
|
397
555
|
if (!node || node.type === "file" && node.tombstone === true) return;
|
|
398
556
|
assertNotType(node, "dir");
|
|
@@ -427,265 +585,167 @@ var CachingHost = class {
|
|
|
427
585
|
async #flushSymlinkNode(node) {
|
|
428
586
|
if (!node.needsFlush) return;
|
|
429
587
|
try {
|
|
430
|
-
const linkValue = await this.fs.promises.readlink(node.fullPath);
|
|
431
|
-
if (linkValue === node.symlink) {
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
} catch (e) {
|
|
435
|
-
}
|
|
436
|
-
return this.fs.promises.symlink(node.symlink, node.fullPath);
|
|
437
|
-
}
|
|
438
|
-
async #flushDirNode(node) {
|
|
439
|
-
if (!node.tombstone && node.needsFlush) {
|
|
440
|
-
try {
|
|
441
|
-
await this.fs.promises.access(node.fullPath);
|
|
442
|
-
} catch (e) {
|
|
443
|
-
await this.fs.promises.mkdir(node.fullPath);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
const promises2 = [];
|
|
447
|
-
for (const child of node.dir.values()) {
|
|
448
|
-
if (node.tombstone && !child.tombstone) {
|
|
449
|
-
throw new Error("Unexpected failure during sanity check. A non-deleted child is on a deleted dir");
|
|
450
|
-
}
|
|
451
|
-
if (child.type === "dir") {
|
|
452
|
-
promises2.push(this.#flushDirNode(child));
|
|
453
|
-
} else if (child.type === "file") {
|
|
454
|
-
promises2.push(this.#flushFileNode(child));
|
|
455
|
-
} else if (child.type === "symlink") {
|
|
456
|
-
promises2.push(this.#flushSymlinkNode(child));
|
|
457
|
-
} else {
|
|
458
|
-
throw new Error("should never happen");
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
await Promise.all(promises2);
|
|
462
|
-
if (node.tombstone) {
|
|
463
|
-
return this.fs.promises.rmdir(node.fullPath);
|
|
464
|
-
}
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
flush() {
|
|
468
|
-
const promises2 = [];
|
|
469
|
-
for (const rootNode of this.#trees.values()) {
|
|
470
|
-
promises2.push(this.#flushDirNode(rootNode));
|
|
471
|
-
}
|
|
472
|
-
return Promise.all(promises2);
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
|
|
476
|
-
// src/matchesAnyGlob.ts
|
|
477
|
-
import micromatch from "micromatch";
|
|
478
|
-
|
|
479
|
-
// src/nanosecondsToSanity.ts
|
|
480
|
-
function nanosecondsToSanity(n, precision = 9) {
|
|
481
|
-
return n / BigInt(1e9) + "." + ("" + n % BigInt(1e9)).padStart(9, "0").substring(0, precision) + "s";
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// src/Table.ts
|
|
485
|
-
var Table = class {
|
|
486
|
-
#rows = [];
|
|
487
|
-
#config;
|
|
488
|
-
#columnWidths = [];
|
|
489
|
-
#footer = [];
|
|
490
|
-
#footerRowConfig;
|
|
491
|
-
#totalWidth = 0;
|
|
492
|
-
constructor(config) {
|
|
493
|
-
this.#config = {
|
|
494
|
-
padding: 2,
|
|
495
|
-
...config
|
|
496
|
-
};
|
|
497
|
-
this.#columnWidths.fill(0, 0, config.columns.length);
|
|
498
|
-
if (config.showFooter) {
|
|
499
|
-
this.#footerRowConfig = [];
|
|
500
|
-
for (const columnConfig of config.columns) {
|
|
501
|
-
if (columnConfig.footer === void 0) {
|
|
502
|
-
throw new Error("Must specify footer fields when showFooter is true");
|
|
503
|
-
} else if (typeof columnConfig.footer === "string") {
|
|
504
|
-
this.#footerRowConfig.push({
|
|
505
|
-
type: "string",
|
|
506
|
-
alignment: "left",
|
|
507
|
-
aggregate: "static",
|
|
508
|
-
value: columnConfig.footer
|
|
509
|
-
});
|
|
510
|
-
} else if ("value" in columnConfig.footer) {
|
|
511
|
-
this.#footerRowConfig.push({
|
|
512
|
-
type: "string",
|
|
513
|
-
alignment: "left",
|
|
514
|
-
...columnConfig.footer
|
|
515
|
-
});
|
|
516
|
-
} else if ("aggregate" in columnConfig.footer) {
|
|
517
|
-
if (columnConfig.type !== "bigint") throw new Error("expecting bigint for aggregate");
|
|
518
|
-
this.#footerRowConfig.push({
|
|
519
|
-
type: columnConfig.type,
|
|
520
|
-
renderAs: columnConfig.renderAs,
|
|
521
|
-
precision: columnConfig.precision,
|
|
522
|
-
alignment: "right",
|
|
523
|
-
...columnConfig.footer
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
addRow(...data) {
|
|
530
|
-
this.#rows.push(data);
|
|
531
|
-
}
|
|
532
|
-
#sumColumn(c) {
|
|
533
|
-
let total = BigInt(0);
|
|
534
|
-
for (const row of this.#rows) {
|
|
535
|
-
total += row[c];
|
|
536
|
-
}
|
|
537
|
-
return total;
|
|
538
|
-
}
|
|
539
|
-
#updateFooterRow() {
|
|
540
|
-
const footerRowConfig = this.#footerRowConfig;
|
|
541
|
-
if (footerRowConfig) {
|
|
542
|
-
for (let c = 0; c < footerRowConfig.length; c++) {
|
|
543
|
-
const footerColConfig = footerRowConfig[c];
|
|
544
|
-
switch (footerColConfig.aggregate) {
|
|
545
|
-
case "sum":
|
|
546
|
-
this.#footer[c] = this.#sumColumn(c);
|
|
547
|
-
break;
|
|
548
|
-
case "average":
|
|
549
|
-
this.#footer[c] = this.#sumColumn(c) / BigInt(this.#rows.length);
|
|
550
|
-
break;
|
|
551
|
-
case "static":
|
|
552
|
-
this.#footer[c] = footerColConfig.value;
|
|
553
|
-
break;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
#calculateColumnWidths() {
|
|
559
|
-
var _a;
|
|
560
|
-
this.#columnWidths.fill(0, 0, this.#config.columns.length);
|
|
561
|
-
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
562
|
-
const colConfig = this.#config.columns[c];
|
|
563
|
-
this.#columnWidths[c] = Math.max(
|
|
564
|
-
(this.#config.columns[c].header ?? "").length,
|
|
565
|
-
...this.#rows.map((a) => this.#getCellValueAsString(a[c], colConfig).length),
|
|
566
|
-
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(((_a = this.#footer) == null ? void 0 : _a[c]) ?? "", this.#footerRowConfig[c]).length : 0
|
|
567
|
-
);
|
|
568
|
-
}
|
|
569
|
-
this.#totalWidth = 0;
|
|
570
|
-
for (const colWidth of this.#columnWidths) {
|
|
571
|
-
this.#totalWidth += colWidth;
|
|
572
|
-
}
|
|
573
|
-
this.#totalWidth += (this.#columnWidths.length - 1) * this.#config.padding;
|
|
574
|
-
}
|
|
575
|
-
#printSeparator(fillString) {
|
|
576
|
-
const paddingString = "".padStart(this.#config.padding, " ");
|
|
577
|
-
let hr2 = "";
|
|
578
|
-
for (let c = 0; c < this.#columnWidths.length; c++) {
|
|
579
|
-
hr2 += "".padStart(this.#columnWidths[c], fillString) + paddingString;
|
|
580
|
-
}
|
|
581
|
-
hr2 = hr2.trimRight();
|
|
582
|
-
console.log(hr2);
|
|
583
|
-
}
|
|
584
|
-
#printHeaderRow() {
|
|
585
|
-
if (this.#config.showHeader) {
|
|
586
|
-
const colConfigs = this.#config.columns;
|
|
587
|
-
const paddingString = "".padStart(this.#config.padding, " ");
|
|
588
|
-
let hr = "";
|
|
589
|
-
for (let c = 0; c < colConfigs.length; c++) {
|
|
590
|
-
const heading = colConfigs[c].header ?? "";
|
|
591
|
-
hr += heading.padEnd(this.#columnWidths[c], " ") + paddingString;
|
|
592
|
-
}
|
|
593
|
-
hr = hr.trimRight();
|
|
594
|
-
console.log(hr);
|
|
595
|
-
this.#printSeparator("-");
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
#printFooterRow() {
|
|
599
|
-
const footerRow = this.#footer;
|
|
600
|
-
if (footerRow) {
|
|
601
|
-
this.#printSeparator("=");
|
|
602
|
-
const paddingString = "".padStart(this.#config.padding, " ");
|
|
603
|
-
let hr = "";
|
|
604
|
-
for (let c = 0; c < footerRow.length; c++) {
|
|
605
|
-
hr += this.#getCellValueAligned(footerRow[c], this.#footerRowConfig[c], c) + paddingString;
|
|
606
|
-
}
|
|
607
|
-
hr = hr.trimRight();
|
|
608
|
-
console.log(hr);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
print() {
|
|
612
|
-
if (this.#config.sortColumn !== void 0) {
|
|
613
|
-
}
|
|
614
|
-
this.#updateFooterRow();
|
|
615
|
-
this.#calculateColumnWidths();
|
|
616
|
-
console.log();
|
|
617
|
-
console.log(`${this.#config.title}`);
|
|
618
|
-
console.log("".padStart(this.#totalWidth, "="));
|
|
619
|
-
const paddingString = "".padStart(this.#config.padding, " ");
|
|
620
|
-
if (this.#config.showHeader) {
|
|
621
|
-
this.#printHeaderRow();
|
|
622
|
-
}
|
|
623
|
-
for (let r = 0; r < this.#rows.length; r++) {
|
|
624
|
-
let rowText = "";
|
|
625
|
-
for (let c = 0; c < this.#config.columns.length; c++) {
|
|
626
|
-
rowText += this.getEntryAsStringAligned(c, r) + paddingString;
|
|
588
|
+
const linkValue = await this.fs.promises.readlink(node.fullPath);
|
|
589
|
+
if (linkValue === node.symlink) {
|
|
590
|
+
return;
|
|
627
591
|
}
|
|
628
|
-
|
|
629
|
-
console.log(rowText);
|
|
592
|
+
} catch (e) {
|
|
630
593
|
}
|
|
631
|
-
|
|
632
|
-
console.log();
|
|
594
|
+
return this.fs.promises.symlink(node.symlink, node.fullPath);
|
|
633
595
|
}
|
|
634
|
-
#
|
|
635
|
-
if (
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
596
|
+
async #flushDirNode(node) {
|
|
597
|
+
if (!node.tombstone && node.needsFlush) {
|
|
598
|
+
try {
|
|
599
|
+
await this.fs.promises.access(node.fullPath);
|
|
600
|
+
} catch (e) {
|
|
601
|
+
await this.fs.promises.mkdir(node.fullPath);
|
|
602
|
+
}
|
|
639
603
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
604
|
+
const promises2 = [];
|
|
605
|
+
for (const child of node.dir.values()) {
|
|
606
|
+
if (node.tombstone && !child.tombstone) {
|
|
607
|
+
throw new Error(
|
|
608
|
+
"Unexpected failure during sanity check. A non-deleted child is on a deleted dir"
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
if (child.type === "dir") {
|
|
612
|
+
promises2.push(this.#flushDirNode(child));
|
|
613
|
+
} else if (child.type === "file") {
|
|
614
|
+
promises2.push(this.#flushFileNode(child));
|
|
615
|
+
} else if (child.type === "symlink") {
|
|
616
|
+
promises2.push(this.#flushSymlinkNode(child));
|
|
617
|
+
} else {
|
|
618
|
+
throw new Error("should never happen");
|
|
619
|
+
}
|
|
647
620
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
return result.padStart(this.#columnWidths[column]);
|
|
621
|
+
await Promise.all(promises2);
|
|
622
|
+
if (node.tombstone) {
|
|
623
|
+
return this.fs.promises.rmdir(node.fullPath);
|
|
652
624
|
}
|
|
625
|
+
return;
|
|
653
626
|
}
|
|
654
|
-
|
|
655
|
-
const
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
} else {
|
|
659
|
-
return "" + this.#rows[rowNum][colNum];
|
|
627
|
+
flush() {
|
|
628
|
+
const promises2 = [];
|
|
629
|
+
for (const rootNode of this.#trees.values()) {
|
|
630
|
+
promises2.push(this.#flushDirNode(rootNode));
|
|
660
631
|
}
|
|
632
|
+
return Promise.all(promises2);
|
|
661
633
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
// src/findWorkspaceDir.ts
|
|
637
|
+
import { findUp } from "find-up";
|
|
638
|
+
import * as fs from "fs";
|
|
639
|
+
import * as path2 from "path";
|
|
640
|
+
async function findPnpmWorkspaceDir(cwd) {
|
|
641
|
+
const workspaceManifestLocation = await findUp("pnpm-workspace.yaml", {
|
|
642
|
+
cwd: await fs.promises.realpath(cwd)
|
|
643
|
+
});
|
|
644
|
+
return workspaceManifestLocation && path2.dirname(workspaceManifestLocation);
|
|
645
|
+
}
|
|
646
|
+
async function findWorkspaceDir(host, dir) {
|
|
647
|
+
const maybePnpmWorkspaceDir = await findPnpmWorkspaceDir(dir);
|
|
648
|
+
if (maybePnpmWorkspaceDir != null) {
|
|
649
|
+
return maybePnpmWorkspaceDir;
|
|
650
|
+
}
|
|
651
|
+
const packagePath = path2.join(dir, "package.json");
|
|
652
|
+
if (host.exists(packagePath)) {
|
|
653
|
+
const packageJson = host.readJson(packagePath);
|
|
654
|
+
if (packageJson.workspaces !== void 0) {
|
|
655
|
+
return dir;
|
|
669
656
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
657
|
+
}
|
|
658
|
+
const nextDir = path2.normalize(path2.join(dir, ".."));
|
|
659
|
+
if (nextDir === dir) {
|
|
660
|
+
return void 0;
|
|
661
|
+
}
|
|
662
|
+
return findWorkspaceDir(host, nextDir);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// src/getPackageNameToDir.ts
|
|
666
|
+
import { join as pathJoin } from "path";
|
|
667
|
+
|
|
668
|
+
// src/getWorkspacePackageDirs.ts
|
|
669
|
+
import { findPackages } from "find-packages";
|
|
670
|
+
import { existsSync } from "fs";
|
|
671
|
+
import * as glob from "glob";
|
|
672
|
+
import * as fs2 from "node:fs";
|
|
673
|
+
import * as path3 from "node:path";
|
|
674
|
+
import readYamlFile from "read-yaml-file";
|
|
675
|
+
async function findPNPMWorkspacePackages(workspaceRoot) {
|
|
676
|
+
workspaceRoot = fs2.realpathSync(workspaceRoot);
|
|
677
|
+
const workspaceManifest = await readYamlFile.default(
|
|
678
|
+
path3.join(workspaceRoot, "pnpm-workspace.yaml")
|
|
679
|
+
);
|
|
680
|
+
return findPackages(workspaceRoot, {
|
|
681
|
+
ignore: ["**/node_modules/**", "**/bower_components/**"],
|
|
682
|
+
includeRoot: true,
|
|
683
|
+
patterns: workspaceManifest.packages
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
async function getWorkspacePackageDirs(host, workspaceDir, resolvePaths = false) {
|
|
687
|
+
const packageJson = host.readJson(
|
|
688
|
+
path3.join(workspaceDir, "package.json")
|
|
689
|
+
);
|
|
690
|
+
const isPnpmWorkspace = host.exists(
|
|
691
|
+
path3.join(workspaceDir, "pnpm-workspace.yaml")
|
|
692
|
+
);
|
|
693
|
+
if (isPnpmWorkspace) {
|
|
694
|
+
const workspacePackages = await findPNPMWorkspacePackages(workspaceDir);
|
|
695
|
+
if (workspacePackages.length === 0) {
|
|
696
|
+
throw new Error("Invalid workspaceDir: " + workspaceDir);
|
|
674
697
|
}
|
|
698
|
+
return workspacePackages.map((project) => project.dir).filter(
|
|
699
|
+
(d) => d !== workspaceDir
|
|
700
|
+
);
|
|
675
701
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
this.#footer && this.#footerRowConfig ? this.#getCellValueAsString(this.#footer[colNum], this.#footerRowConfig[colNum]).length : 0
|
|
702
|
+
if (!packageJson.workspaces) {
|
|
703
|
+
throw new Error(
|
|
704
|
+
"Unsupported! Monorepo is not backed by either pnpm nor yarn workspaces."
|
|
680
705
|
);
|
|
681
|
-
|
|
682
|
-
|
|
706
|
+
}
|
|
707
|
+
const ret = [];
|
|
708
|
+
const packageGlobs = Array.isArray(packageJson.workspaces) ? packageJson.workspaces : packageJson.workspaces.packages || [];
|
|
709
|
+
for (const pattern of packageGlobs) {
|
|
710
|
+
for (const packagePath of glob.sync(pattern, { cwd: workspaceDir })) {
|
|
711
|
+
const packageJsonPath = path3.join(
|
|
712
|
+
workspaceDir,
|
|
713
|
+
packagePath,
|
|
714
|
+
"package.json"
|
|
715
|
+
);
|
|
716
|
+
if (existsSync(packageJsonPath)) {
|
|
717
|
+
if (resolvePaths === true) {
|
|
718
|
+
ret.push(path3.resolve(path3.join(workspaceDir, packagePath)));
|
|
719
|
+
} else {
|
|
720
|
+
ret.push(packagePath);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
683
723
|
}
|
|
684
|
-
return maxWidth;
|
|
685
724
|
}
|
|
686
|
-
|
|
725
|
+
return ret;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// src/getPackageNameToDir.ts
|
|
729
|
+
async function getPackageNameToDir(host, workspaceDir, resolvePaths = false) {
|
|
730
|
+
const ret = /* @__PURE__ */ new Map();
|
|
731
|
+
const workspacePackages = await getWorkspacePackageDirs(
|
|
732
|
+
host,
|
|
733
|
+
workspaceDir,
|
|
734
|
+
resolvePaths
|
|
735
|
+
);
|
|
736
|
+
for (const packageDir of workspacePackages) {
|
|
737
|
+
const packagePath = pathJoin(packageDir, "package.json");
|
|
738
|
+
const { name } = host.readJson(packagePath);
|
|
739
|
+
if (name === void 0) {
|
|
740
|
+
throw new Error(`Package needs a name: ${packagePath}`);
|
|
741
|
+
}
|
|
742
|
+
ret.set(name, packageDir);
|
|
743
|
+
}
|
|
744
|
+
return ret;
|
|
745
|
+
}
|
|
687
746
|
|
|
688
747
|
// src/matchesAnyGlob.ts
|
|
748
|
+
import micromatch from "micromatch";
|
|
689
749
|
var cache = /* @__PURE__ */ new Map();
|
|
690
750
|
var singleMatcherCache = /* @__PURE__ */ new Map();
|
|
691
751
|
var compiledGlobCache = /* @__PURE__ */ new Map();
|
|
@@ -755,63 +815,53 @@ matchesAnyGlob.printStats = () => {
|
|
|
755
815
|
table.print();
|
|
756
816
|
};
|
|
757
817
|
|
|
758
|
-
// src/
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
818
|
+
// src/mutateJson.ts
|
|
819
|
+
function mutateJson(path4, host, mutator) {
|
|
820
|
+
let file = host.readJson(path4);
|
|
821
|
+
file = mutator(file);
|
|
822
|
+
host.writeJson(path4, file);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// src/SimpleHost.ts
|
|
826
|
+
import * as realFs2 from "fs";
|
|
827
|
+
var SimpleHost = class {
|
|
828
|
+
constructor(fs3 = realFs2) {
|
|
829
|
+
this.fs = fs3;
|
|
762
830
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
831
|
+
mkdir(directoryPath, opts) {
|
|
832
|
+
this.fs.mkdirSync(directoryPath, { recursive: (opts == null ? void 0 : opts.recursive) ?? false });
|
|
833
|
+
}
|
|
834
|
+
rmdir(directoryPath) {
|
|
835
|
+
this.fs.rmdirSync(directoryPath);
|
|
836
|
+
}
|
|
837
|
+
exists(path4) {
|
|
838
|
+
return this.fs.existsSync(path4);
|
|
839
|
+
}
|
|
840
|
+
writeFile(path4, body, opts) {
|
|
841
|
+
if (opts) {
|
|
842
|
+
this.fs.writeFileSync(path4, body, { encoding: opts.encoding });
|
|
774
843
|
} else {
|
|
775
|
-
|
|
776
|
-
data.count++;
|
|
844
|
+
this.fs.writeFileSync(path4, body);
|
|
777
845
|
}
|
|
778
|
-
this.#last = data;
|
|
779
846
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
this.#last.total += time;
|
|
784
|
-
this.#last = void 0;
|
|
847
|
+
readFile(path4, opts) {
|
|
848
|
+
if (opts == null ? void 0 : opts.asJson) {
|
|
849
|
+
return JSON.parse(this.fs.readFileSync(path4, "utf-8"));
|
|
785
850
|
}
|
|
851
|
+
return this.fs.readFileSync(path4, opts == null ? void 0 : opts.encoding);
|
|
786
852
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
},
|
|
800
|
-
{ header: "Task", type: "string", alignment: "left", footer: "TOTAL" },
|
|
801
|
-
{ header: "Count", type: "bigint", footer: { aggregate: "sum" } },
|
|
802
|
-
{ header: "Avg", type: "bigint", footer: { aggregate: "average" } }
|
|
803
|
-
]
|
|
804
|
-
});
|
|
805
|
-
for (const [name, value] of this.#data) {
|
|
806
|
-
table.addRow(
|
|
807
|
-
value.total,
|
|
808
|
-
name,
|
|
809
|
-
BigInt(value.count),
|
|
810
|
-
// fixme this can be a number later
|
|
811
|
-
value.total / BigInt(value.count)
|
|
812
|
-
);
|
|
813
|
-
}
|
|
814
|
-
table.print();
|
|
853
|
+
deleteFile(path4) {
|
|
854
|
+
this.fs.unlinkSync(path4);
|
|
855
|
+
}
|
|
856
|
+
readJson(filename) {
|
|
857
|
+
const contents = this.fs.readFileSync(filename, "utf-8");
|
|
858
|
+
return JSON.parse(contents);
|
|
859
|
+
}
|
|
860
|
+
writeJson(path4, o) {
|
|
861
|
+
return this.fs.writeFileSync(path4, JSON.stringify(o, void 0, 2) + "\n");
|
|
862
|
+
}
|
|
863
|
+
flush() {
|
|
864
|
+
return Promise.resolve();
|
|
815
865
|
}
|
|
816
866
|
};
|
|
817
867
|
|
|
@@ -871,13 +921,13 @@ export {
|
|
|
871
921
|
nanosecondsToSanity
|
|
872
922
|
};
|
|
873
923
|
/*!
|
|
874
|
-
* Copyright
|
|
924
|
+
* Copyright 2022 Palantir Technologies, Inc.
|
|
875
925
|
*
|
|
876
926
|
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
877
927
|
*
|
|
878
928
|
*/
|
|
879
929
|
/*!
|
|
880
|
-
* Copyright
|
|
930
|
+
* Copyright 2019 Palantir Technologies, Inc.
|
|
881
931
|
*
|
|
882
932
|
* Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
883
933
|
*
|