@savvy-web/silk-effects 5.1.3 → 5.2.1
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/README.md +22 -22
- package/changesets/api/transformer.js +2 -1
- package/changesets/changelog/getReleaseLine.js +7 -4
- package/changesets/changelog/index.js +8 -6
- package/changesets/index.js +6 -11
- package/changesets/services/branch-analyzer.js +20 -19
- package/changesets/services/changelog.js +1 -1
- package/changesets/services/config-inspector.js +17 -17
- package/changesets/services/deps-regen.js +36 -34
- package/changesets/services/github.js +39 -40
- package/changesets/services/release-planner.js +7 -6
- package/changesets/utils/dependency-table.js +2 -1
- package/changesets/utils/jsonpath.js +5 -7
- package/changesets/utils/publishability.js +2 -2
- package/commitlint/detection/dco.js +2 -1
- package/commitlint/index.js +2 -1
- package/index.d.ts +224 -213
- package/index.js +7 -7
- package/lint/handlers/PnpmWorkspace.js +2 -1
- package/lint/handlers/Yaml.js +8 -4
- package/package.json +10 -10
- package/repos/index.js +3 -5
- package/repos/services/config-store.js +68 -67
- package/repos/services/manager.js +259 -258
- package/services/BiomeSchemaSync.js +65 -64
- package/services/ChangesetConfig.js +50 -50
- package/services/ChangesetConfigReader.js +59 -58
- package/services/ConfigDiscovery.js +42 -41
- package/services/SilkPublishability.js +54 -53
- package/services/SilkWorkspaceAnalyzer.js +110 -109
- package/turbo/index.js +2 -3
- package/turbo/services/TurboInspector.js +80 -79
|
@@ -25,7 +25,7 @@ import { DependencyGraph, PackageManagerDetector, VersioningStrategy, WorkspaceD
|
|
|
25
25
|
* const analyzer = yield* SilkWorkspaceAnalyzer;
|
|
26
26
|
* return yield* analyzer.analyze("/path/to/monorepo");
|
|
27
27
|
* }).pipe(
|
|
28
|
-
* Effect.provide(
|
|
28
|
+
* Effect.provide(SilkWorkspaceAnalyzer.layer),
|
|
29
29
|
* // ... provide all transitive layers
|
|
30
30
|
* )
|
|
31
31
|
* );
|
|
@@ -34,7 +34,114 @@ import { DependencyGraph, PackageManagerDetector, VersioningStrategy, WorkspaceD
|
|
|
34
34
|
* @since 0.2.0
|
|
35
35
|
* @public
|
|
36
36
|
*/
|
|
37
|
-
var SilkWorkspaceAnalyzer = class extends Context.Service()("@savvy-web/silk-effects/SilkWorkspaceAnalyzer") {
|
|
37
|
+
var SilkWorkspaceAnalyzer = class extends Context.Service()("@savvy-web/silk-effects/SilkWorkspaceAnalyzer") {
|
|
38
|
+
/**
|
|
39
|
+
* Production implementation of {@link SilkWorkspaceAnalyzer}.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Requires `WorkspaceDiscovery`, `PackageManagerDetector` and
|
|
43
|
+
* {@link ChangesetConfigReader}. Versioning and tag classification are pure
|
|
44
|
+
* `@effected/workspaces` value operations, so neither adds a requirement.
|
|
45
|
+
*
|
|
46
|
+
* @since 0.2.0
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
static layer = Layer.effect(this, Effect.gen(function* () {
|
|
50
|
+
const fs = yield* FileSystem.FileSystem;
|
|
51
|
+
const discovery = yield* WorkspaceDiscovery;
|
|
52
|
+
const pmDetector = yield* PackageManagerDetector;
|
|
53
|
+
const configReader = yield* ChangesetConfigReader;
|
|
54
|
+
const analyze = (root) => Effect.gen(function* () {
|
|
55
|
+
const pm = yield* pmDetector.detect(root).pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
56
|
+
root,
|
|
57
|
+
reason: `Package manager detection failed: ${String(err)}`
|
|
58
|
+
})));
|
|
59
|
+
const packages = yield* discovery.listPackages().pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
60
|
+
root,
|
|
61
|
+
reason: `Workspace discovery failed: ${String(err)}`
|
|
62
|
+
})));
|
|
63
|
+
const topoOrder = yield* DependencyGraph.make({ packages }).sort().pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
64
|
+
root,
|
|
65
|
+
reason: `Cyclic dependency detected: ${String(err)}`
|
|
66
|
+
})));
|
|
67
|
+
const packagesByName = new Map(packages.map((p) => [p.name, p]));
|
|
68
|
+
const reordered = topoOrder.flatMap((name) => {
|
|
69
|
+
const pkg = packagesByName.get(name);
|
|
70
|
+
return pkg ? [pkg] : [];
|
|
71
|
+
});
|
|
72
|
+
const sortedPackages = reordered.length > 0 ? reordered : [...packages];
|
|
73
|
+
const changesetConfigOption = yield* configReader.read(root).pipe(Effect.option);
|
|
74
|
+
const changesetConfig = Option.getOrNull(changesetConfigOption);
|
|
75
|
+
const analyzedWorkspaces = [];
|
|
76
|
+
for (const pkg of sortedPackages) {
|
|
77
|
+
const pkgJson = yield* readRawPkgJson(fs, pkg.packageJsonPath);
|
|
78
|
+
const binding = yield* readTargetsBinding(fs, pkg.path);
|
|
79
|
+
const targets = SilkPublishability.detect(pkg.name, pkgJson, binding);
|
|
80
|
+
const isPublishable = targets.length > 0;
|
|
81
|
+
const isRoot = pkg.relativePath === ".";
|
|
82
|
+
const { versioned, tagged, released } = computeReleaseStatus(pkg.name, pkg.private, isPublishable, changesetConfig);
|
|
83
|
+
const analyzed = new AnalyzedWorkspace({
|
|
84
|
+
name: pkg.name,
|
|
85
|
+
version: { current: pkg.version },
|
|
86
|
+
path: pkg.path,
|
|
87
|
+
root: isRoot,
|
|
88
|
+
publishConfig: null,
|
|
89
|
+
publishable: isPublishable,
|
|
90
|
+
targets: [...targets],
|
|
91
|
+
versioned,
|
|
92
|
+
tagged,
|
|
93
|
+
released,
|
|
94
|
+
linked: [],
|
|
95
|
+
fixed: []
|
|
96
|
+
});
|
|
97
|
+
analyzedWorkspaces.push(analyzed);
|
|
98
|
+
}
|
|
99
|
+
if (changesetConfig) {
|
|
100
|
+
const fixedGroups = changesetConfig.fixed ?? [];
|
|
101
|
+
const linkedGroups = changesetConfig.linked ?? [];
|
|
102
|
+
const fixedByName = /* @__PURE__ */ new Map();
|
|
103
|
+
for (const group of fixedGroups) {
|
|
104
|
+
const members = analyzedWorkspaces.filter((w) => group.includes(w.name));
|
|
105
|
+
for (const member of members) fixedByName.set(member.name, members.filter((m) => m !== member));
|
|
106
|
+
}
|
|
107
|
+
const linkedByName = /* @__PURE__ */ new Map();
|
|
108
|
+
for (const group of linkedGroups) {
|
|
109
|
+
const members = analyzedWorkspaces.filter((w) => group.includes(w.name));
|
|
110
|
+
for (const member of members) linkedByName.set(member.name, members.filter((m) => m !== member));
|
|
111
|
+
}
|
|
112
|
+
for (let i = 0; i < analyzedWorkspaces.length; i++) {
|
|
113
|
+
const ws = analyzedWorkspaces[i];
|
|
114
|
+
const fixedRefs = fixedByName.get(ws.name) ?? [];
|
|
115
|
+
const linkedRefs = linkedByName.get(ws.name) ?? [];
|
|
116
|
+
if (fixedRefs.length > 0 || linkedRefs.length > 0) analyzedWorkspaces[i] = new AnalyzedWorkspace({
|
|
117
|
+
...ws,
|
|
118
|
+
fixed: fixedRefs,
|
|
119
|
+
linked: linkedRefs
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const publishableNames = analyzedWorkspaces.filter((w) => w.publishable).map((w) => w.name);
|
|
124
|
+
const versioning = VersioningStrategy.classify({
|
|
125
|
+
packages: publishableNames,
|
|
126
|
+
fixedGroups: changesetConfig?.fixed ?? []
|
|
127
|
+
});
|
|
128
|
+
const tagStrategyType = versioning.tagStyle;
|
|
129
|
+
return new WorkspaceAnalysis({
|
|
130
|
+
root,
|
|
131
|
+
runtime: pm.runtime,
|
|
132
|
+
packageManager: {
|
|
133
|
+
type: pm.name,
|
|
134
|
+
...Option.isSome(pm.version) ? { version: pm.version.value } : {}
|
|
135
|
+
},
|
|
136
|
+
workspaces: analyzedWorkspaces,
|
|
137
|
+
changesetConfig,
|
|
138
|
+
versioning,
|
|
139
|
+
tagStrategy: tagStrategyType
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
return { analyze };
|
|
143
|
+
}));
|
|
144
|
+
};
|
|
38
145
|
/**
|
|
39
146
|
* Read the raw package.json from disk as an untyped record.
|
|
40
147
|
*
|
|
@@ -99,112 +206,6 @@ function computeReleaseStatus(pkgName, isPrivate, isPublishable, config) {
|
|
|
99
206
|
released: versioned && tagged
|
|
100
207
|
};
|
|
101
208
|
}
|
|
102
|
-
/**
|
|
103
|
-
* Live implementation of {@link SilkWorkspaceAnalyzer}.
|
|
104
|
-
*
|
|
105
|
-
* @remarks
|
|
106
|
-
* Requires `WorkspaceDiscovery`, `PackageManagerDetector` and
|
|
107
|
-
* {@link ChangesetConfigReader}. Versioning and tag classification are pure
|
|
108
|
-
* `@effected/workspaces` value operations, so neither adds a requirement.
|
|
109
|
-
*
|
|
110
|
-
* @since 0.2.0
|
|
111
|
-
* @public
|
|
112
|
-
*/
|
|
113
|
-
const SilkWorkspaceAnalyzerLive = Layer.effect(SilkWorkspaceAnalyzer, Effect.gen(function* () {
|
|
114
|
-
const fs = yield* FileSystem.FileSystem;
|
|
115
|
-
const discovery = yield* WorkspaceDiscovery;
|
|
116
|
-
const pmDetector = yield* PackageManagerDetector;
|
|
117
|
-
const configReader = yield* ChangesetConfigReader;
|
|
118
|
-
const analyze = (root) => Effect.gen(function* () {
|
|
119
|
-
const pm = yield* pmDetector.detect(root).pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
120
|
-
root,
|
|
121
|
-
reason: `Package manager detection failed: ${String(err)}`
|
|
122
|
-
})));
|
|
123
|
-
const packages = yield* discovery.listPackages().pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
124
|
-
root,
|
|
125
|
-
reason: `Workspace discovery failed: ${String(err)}`
|
|
126
|
-
})));
|
|
127
|
-
const topoOrder = yield* DependencyGraph.make({ packages }).sort().pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
|
|
128
|
-
root,
|
|
129
|
-
reason: `Cyclic dependency detected: ${String(err)}`
|
|
130
|
-
})));
|
|
131
|
-
const packagesByName = new Map(packages.map((p) => [p.name, p]));
|
|
132
|
-
const reordered = topoOrder.flatMap((name) => {
|
|
133
|
-
const pkg = packagesByName.get(name);
|
|
134
|
-
return pkg ? [pkg] : [];
|
|
135
|
-
});
|
|
136
|
-
const sortedPackages = reordered.length > 0 ? reordered : [...packages];
|
|
137
|
-
const changesetConfigOption = yield* configReader.read(root).pipe(Effect.option);
|
|
138
|
-
const changesetConfig = Option.getOrNull(changesetConfigOption);
|
|
139
|
-
const analyzedWorkspaces = [];
|
|
140
|
-
for (const pkg of sortedPackages) {
|
|
141
|
-
const pkgJson = yield* readRawPkgJson(fs, pkg.packageJsonPath);
|
|
142
|
-
const binding = yield* readTargetsBinding(fs, pkg.path);
|
|
143
|
-
const targets = SilkPublishability.detect(pkg.name, pkgJson, binding);
|
|
144
|
-
const isPublishable = targets.length > 0;
|
|
145
|
-
const isRoot = pkg.relativePath === ".";
|
|
146
|
-
const { versioned, tagged, released } = computeReleaseStatus(pkg.name, pkg.private, isPublishable, changesetConfig);
|
|
147
|
-
const analyzed = new AnalyzedWorkspace({
|
|
148
|
-
name: pkg.name,
|
|
149
|
-
version: { current: pkg.version },
|
|
150
|
-
path: pkg.path,
|
|
151
|
-
root: isRoot,
|
|
152
|
-
publishConfig: null,
|
|
153
|
-
publishable: isPublishable,
|
|
154
|
-
targets: [...targets],
|
|
155
|
-
versioned,
|
|
156
|
-
tagged,
|
|
157
|
-
released,
|
|
158
|
-
linked: [],
|
|
159
|
-
fixed: []
|
|
160
|
-
});
|
|
161
|
-
analyzedWorkspaces.push(analyzed);
|
|
162
|
-
}
|
|
163
|
-
if (changesetConfig) {
|
|
164
|
-
const fixedGroups = changesetConfig.fixed ?? [];
|
|
165
|
-
const linkedGroups = changesetConfig.linked ?? [];
|
|
166
|
-
const fixedByName = /* @__PURE__ */ new Map();
|
|
167
|
-
for (const group of fixedGroups) {
|
|
168
|
-
const members = analyzedWorkspaces.filter((w) => group.includes(w.name));
|
|
169
|
-
for (const member of members) fixedByName.set(member.name, members.filter((m) => m !== member));
|
|
170
|
-
}
|
|
171
|
-
const linkedByName = /* @__PURE__ */ new Map();
|
|
172
|
-
for (const group of linkedGroups) {
|
|
173
|
-
const members = analyzedWorkspaces.filter((w) => group.includes(w.name));
|
|
174
|
-
for (const member of members) linkedByName.set(member.name, members.filter((m) => m !== member));
|
|
175
|
-
}
|
|
176
|
-
for (let i = 0; i < analyzedWorkspaces.length; i++) {
|
|
177
|
-
const ws = analyzedWorkspaces[i];
|
|
178
|
-
const fixedRefs = fixedByName.get(ws.name) ?? [];
|
|
179
|
-
const linkedRefs = linkedByName.get(ws.name) ?? [];
|
|
180
|
-
if (fixedRefs.length > 0 || linkedRefs.length > 0) analyzedWorkspaces[i] = new AnalyzedWorkspace({
|
|
181
|
-
...ws,
|
|
182
|
-
fixed: fixedRefs,
|
|
183
|
-
linked: linkedRefs
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
const publishableNames = analyzedWorkspaces.filter((w) => w.publishable).map((w) => w.name);
|
|
188
|
-
const versioning = VersioningStrategy.classify({
|
|
189
|
-
packages: publishableNames,
|
|
190
|
-
fixedGroups: changesetConfig?.fixed ?? []
|
|
191
|
-
});
|
|
192
|
-
const tagStrategyType = versioning.tagStyle;
|
|
193
|
-
return new WorkspaceAnalysis({
|
|
194
|
-
root,
|
|
195
|
-
runtime: pm.runtime,
|
|
196
|
-
packageManager: {
|
|
197
|
-
type: pm.name,
|
|
198
|
-
...Option.isSome(pm.version) ? { version: pm.version.value } : {}
|
|
199
|
-
},
|
|
200
|
-
workspaces: analyzedWorkspaces,
|
|
201
|
-
changesetConfig,
|
|
202
|
-
versioning,
|
|
203
|
-
tagStrategy: tagStrategyType
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
return { analyze };
|
|
207
|
-
}));
|
|
208
209
|
|
|
209
210
|
//#endregion
|
|
210
|
-
export { SilkWorkspaceAnalyzer
|
|
211
|
+
export { SilkWorkspaceAnalyzer };
|
package/turbo/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { TurboDigest } from "./digest.js";
|
|
|
3
3
|
import { DryRunParseError, NotATurboRepoError, TurboExecError, TurboNotInstalledError } from "./errors.js";
|
|
4
4
|
import { TurboCache, TurboDryRun, TurboDryTask, TurboEnvVars, TurboGlobalCacheInputs } from "./schemas/DryRun.js";
|
|
5
5
|
import { AffectedResult, CacheDiagnosis, GlobalHashSummary, GraphNode, MissExplanation, PackageCacheStatus, TaskGraphResult } from "./schemas/results.js";
|
|
6
|
-
import { TurboInspector
|
|
6
|
+
import { TurboInspector } from "./services/TurboInspector.js";
|
|
7
7
|
|
|
8
8
|
//#region src/turbo/index.ts
|
|
9
9
|
var turbo_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -24,9 +24,8 @@ var turbo_exports = /* @__PURE__ */ __exportAll({
|
|
|
24
24
|
TurboExecError: () => TurboExecError,
|
|
25
25
|
TurboGlobalCacheInputs: () => TurboGlobalCacheInputs,
|
|
26
26
|
TurboInspector: () => TurboInspector,
|
|
27
|
-
TurboInspectorLive: () => TurboInspectorLive,
|
|
28
27
|
TurboNotInstalledError: () => TurboNotInstalledError
|
|
29
28
|
});
|
|
30
29
|
|
|
31
30
|
//#endregion
|
|
32
|
-
export { AffectedResult, CacheDiagnosis, DryRunParseError, GlobalHashSummary, GraphNode, MissExplanation, NotATurboRepoError, PackageCacheStatus, TaskGraphResult, TurboCache, TurboDigest, TurboDryRun, TurboDryTask, TurboEnvVars, TurboExecError, TurboGlobalCacheInputs, TurboInspector,
|
|
31
|
+
export { AffectedResult, CacheDiagnosis, DryRunParseError, GlobalHashSummary, GraphNode, MissExplanation, NotATurboRepoError, PackageCacheStatus, TaskGraphResult, TurboCache, TurboDigest, TurboDryRun, TurboDryTask, TurboEnvVars, TurboExecError, TurboGlobalCacheInputs, TurboInspector, TurboNotInstalledError, turbo_exports };
|
|
@@ -18,90 +18,91 @@ import { Run, Tool, ToolDiscovery } from "@effected/commands";
|
|
|
18
18
|
*
|
|
19
19
|
* @since 0.7.0
|
|
20
20
|
*/
|
|
21
|
-
var TurboInspector = class extends Context.Service()("@savvy-web/silk-effects/TurboInspector") {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
21
|
+
var TurboInspector = class extends Context.Service()("@savvy-web/silk-effects/TurboInspector") {
|
|
22
|
+
/**
|
|
23
|
+
* Production implementation of {@link TurboInspector}.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Requires `ToolDiscovery` from `@effected/commands` to resolve the `turbo`
|
|
27
|
+
* binary, plus `ChildProcessSpawner` and `FileSystem` from core (provide
|
|
28
|
+
* `NodeServices.layer` at the app edge) and `Git` from `@effected/git`. The
|
|
29
|
+
* spawner is captured at layer construction and discharged onto each `Run`
|
|
30
|
+
* effect with `Effect.provideService`, keeping the public method effects at
|
|
31
|
+
* `R = never`.
|
|
32
|
+
*
|
|
33
|
+
* @since 0.7.0
|
|
34
|
+
*/
|
|
35
|
+
static layer = Layer.effect(this, Effect.gen(function* () {
|
|
36
|
+
const discovery = yield* ToolDiscovery;
|
|
37
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
38
|
+
const fs = yield* FileSystem.FileSystem;
|
|
39
|
+
const git = yield* Git;
|
|
40
|
+
const runTurbo = (cwd, args, env) => discovery.resolve(TURBO).pipe(Effect.mapError((e) => new TurboNotInstalledError({ reason: e.message })), Effect.flatMap((resolved) => {
|
|
41
|
+
const base = ChildProcess.setCwd(resolved.command(...args), cwd);
|
|
42
|
+
const command = env ? Run.extendEnv(base, env) : base;
|
|
43
|
+
return Effect.provideService(Run.text(command), ChildProcessSpawner.ChildProcessSpawner, spawner).pipe(Effect.mapError((e) => new TurboExecError({
|
|
44
|
+
args: [...args],
|
|
45
|
+
reason: String(e)
|
|
46
|
+
})));
|
|
47
|
+
}));
|
|
48
|
+
/** The paths changed between `base` and HEAD, via `@effected/git`. */
|
|
49
|
+
const changedPaths = (cwd, base) => git.changedFiles(cwd, {
|
|
50
|
+
base,
|
|
51
|
+
head: "HEAD"
|
|
52
|
+
}).pipe(Effect.mapError((e) => new TurboExecError({
|
|
53
|
+
args: [
|
|
54
|
+
"git",
|
|
55
|
+
"diff",
|
|
56
|
+
"--name-only",
|
|
57
|
+
`${base}...HEAD`
|
|
58
|
+
],
|
|
59
|
+
reason: e.message
|
|
51
60
|
})));
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"diff",
|
|
61
|
-
"--name-only",
|
|
62
|
-
`${base}...HEAD`
|
|
63
|
-
],
|
|
64
|
-
reason: e.message
|
|
65
|
-
})));
|
|
66
|
-
const ensureTurboRepo = (cwd) => fs.exists(`${cwd}/turbo.json`).pipe(Effect.catch(() => Effect.succeed(false)), Effect.flatMap((ok) => ok ? Effect.void : Effect.fail(new NotATurboRepoError({ cwd }))));
|
|
67
|
-
const dryRun = (task, cwd, args, env) => ensureTurboRepo(cwd).pipe(Effect.flatMap(() => runTurbo(cwd, args, env)), Effect.flatMap((stdout) => Effect.try({
|
|
68
|
-
try: () => JSON.parse(stdout),
|
|
69
|
-
catch: (e) => new DryRunParseError({
|
|
70
|
-
task,
|
|
71
|
-
reason: `invalid JSON: ${String(e)}`
|
|
72
|
-
})
|
|
73
|
-
})), Effect.flatMap((json) => Schema.decodeUnknownEffect(TurboDryRun)(json).pipe(Effect.mapError((e) => new DryRunParseError({
|
|
74
|
-
task,
|
|
75
|
-
reason: String(e)
|
|
76
|
-
})))));
|
|
77
|
-
return {
|
|
78
|
-
diagnoseCache: (task, cwd) => dryRun(task, cwd, [
|
|
79
|
-
"run",
|
|
61
|
+
const ensureTurboRepo = (cwd) => fs.exists(`${cwd}/turbo.json`).pipe(Effect.catch(() => Effect.succeed(false)), Effect.flatMap((ok) => ok ? Effect.void : Effect.fail(new NotATurboRepoError({ cwd }))));
|
|
62
|
+
const dryRun = (task, cwd, args, env) => ensureTurboRepo(cwd).pipe(Effect.flatMap(() => runTurbo(cwd, args, env)), Effect.flatMap((stdout) => Effect.try({
|
|
63
|
+
try: () => JSON.parse(stdout),
|
|
64
|
+
catch: (e) => new DryRunParseError({
|
|
65
|
+
task,
|
|
66
|
+
reason: `invalid JSON: ${String(e)}`
|
|
67
|
+
})
|
|
68
|
+
})), Effect.flatMap((json) => Schema.decodeUnknownEffect(TurboDryRun)(json).pipe(Effect.mapError((e) => new DryRunParseError({
|
|
80
69
|
task,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return dryRun(t, cwd, [
|
|
70
|
+
reason: String(e)
|
|
71
|
+
})))));
|
|
72
|
+
return {
|
|
73
|
+
diagnoseCache: (task, cwd) => dryRun(task, cwd, [
|
|
86
74
|
"run",
|
|
87
|
-
|
|
75
|
+
task,
|
|
88
76
|
"--dry=json"
|
|
89
|
-
]).pipe(Effect.map((dry) => TurboDigest.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return Effect.all({
|
|
94
|
-
changedFiles: changedPaths(cwd, ref),
|
|
95
|
-
dry: dryRun(`${DEFAULT_BUILD_TASK} --affected`, cwd, [
|
|
77
|
+
]).pipe(Effect.map((dry) => TurboDigest.cacheDiagnosis(task, dry))),
|
|
78
|
+
taskGraph: (cwd, task) => {
|
|
79
|
+
const t = task ?? DEFAULT_BUILD_TASK;
|
|
80
|
+
return dryRun(t, cwd, [
|
|
96
81
|
"run",
|
|
97
|
-
|
|
98
|
-
"--affected",
|
|
82
|
+
t,
|
|
99
83
|
"--dry=json"
|
|
100
|
-
]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
84
|
+
]).pipe(Effect.map((dry) => TurboDigest.taskGraph(dry, task)));
|
|
85
|
+
},
|
|
86
|
+
affected: (cwd, base) => {
|
|
87
|
+
const ref = base ?? DEFAULT_AFFECTED_BASE;
|
|
88
|
+
return Effect.all({
|
|
89
|
+
changedFiles: changedPaths(cwd, ref),
|
|
90
|
+
dry: dryRun(`${DEFAULT_BUILD_TASK} --affected`, cwd, [
|
|
91
|
+
"run",
|
|
92
|
+
DEFAULT_BUILD_TASK,
|
|
93
|
+
"--affected",
|
|
94
|
+
"--dry=json"
|
|
95
|
+
], { TURBO_SCM_BASE: ref })
|
|
96
|
+
}).pipe(Effect.map(({ changedFiles, dry }) => TurboDigest.affected(ref, changedFiles, dry)));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}));
|
|
100
|
+
};
|
|
101
|
+
const TURBO = Tool.named("turbo");
|
|
102
|
+
/** Default task used by {@link TurboInspector.taskGraph} and {@link TurboInspector.affected}. */
|
|
103
|
+
const DEFAULT_BUILD_TASK = "build:dev";
|
|
104
|
+
/** Default git ref `affected` compares against — matches Turborepo's own `--affected` default. */
|
|
105
|
+
const DEFAULT_AFFECTED_BASE = "main";
|
|
105
106
|
|
|
106
107
|
//#endregion
|
|
107
|
-
export { TurboInspector
|
|
108
|
+
export { TurboInspector };
|