bun-workspaces 1.8.2 → 1.10.0
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/AGENTS.md +537 -0
- package/README.md +51 -13
- package/package.json +1 -1
- package/src/2392.mjs +184 -3
- package/src/5166.mjs +1 -0
- package/src/8529.mjs +10 -0
- package/src/affected/affectedBaseRef.mjs +12 -0
- package/src/affected/externalDependencyChanges.mjs +47 -0
- package/src/affected/fileAffectedWorkspaces.mjs +152 -54
- package/src/affected/gitAffectedFiles.mjs +44 -1
- package/src/affected/gitAffectedWorkspaces.mjs +73 -3
- package/src/affected/index.mjs +2 -0
- package/src/ai/mcp/serverState.mjs +1 -1
- package/src/cli/commands/commandHandlerUtils.mjs +12 -7
- package/src/cli/commands/commands.mjs +4 -1
- package/src/cli/commands/handleSimpleCommands.mjs +2 -2
- package/src/cli/commands/listAffected.mjs +184 -0
- package/src/cli/commands/runScript/handleRunAffected.mjs +99 -0
- package/src/cli/commands/runScript/handleRunScript.mjs +19 -202
- package/src/cli/commands/runScript/index.mjs +1 -0
- package/src/cli/commands/runScript/scriptRunFlow.mjs +213 -0
- package/src/cli/index.d.ts +749 -134
- package/src/config/public.d.ts +66 -2
- package/src/config/rootConfig/rootConfig.mjs +9 -9
- package/src/config/rootConfig/rootConfigSchema.mjs +3 -0
- package/src/config/workspaceConfig/mergeWorkspaceConfig.mjs +33 -19
- package/src/config/workspaceConfig/workspaceConfig.mjs +3 -0
- package/src/config/workspaceConfig/workspaceConfigSchema.mjs +26 -0
- package/src/index.d.ts +307 -5
- package/src/index.mjs +1 -0
- package/src/internal/bun/bunLock.mjs +33 -0
- package/src/internal/generated/aiDocs/docs.mjs +169 -9
- package/src/internal/generated/ajv/validateRootConfig.mjs +1 -1
- package/src/internal/generated/ajv/validateWorkspaceConfig.mjs +1 -1
- package/src/project/implementations/fileSystemProject/affectedWorkspaces.mjs +227 -0
- package/src/project/implementations/{fileSystemProject.mjs → fileSystemProject/fileSystemProject.mjs} +169 -12
- package/src/project/implementations/fileSystemProject/index.mjs +4 -0
- package/src/project/implementations/memoryProject.mjs +1 -0
- package/src/project/implementations/projectBase.mjs +11 -17
- package/src/project/index.mjs +1 -1
- package/src/rslib-runtime.mjs +0 -31
- package/src/workspaces/applyWorkspacePatternConfigs.mjs +16 -2
- package/src/workspaces/dependencyGraph/resolveDependencies.mjs +68 -18
- package/src/workspaces/dependencyGraph/validateDependencyRules.mjs +14 -7
- package/src/workspaces/findWorkspaces.mjs +3 -0
- package/src/workspaces/workspace.mjs +8 -2
- package/src/workspaces/workspacePattern.mjs +134 -46
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import bun from "bun";
|
|
4
|
+
import { getFileAffectedWorkspaces } from "../../../affected/fileAffectedWorkspaces.mjs";
|
|
5
|
+
import { getGitAffectedWorkspaces } from "../../../affected/gitAffectedWorkspaces.mjs";
|
|
6
|
+
|
|
7
|
+
const isOptionsForDiffSource = (options, diffSource) =>
|
|
8
|
+
options.diffSource === diffSource;
|
|
9
|
+
const DEFAULT_INPUT_FILE_PATTERN = ".";
|
|
10
|
+
const DEFAULT_HEAD_REF = "HEAD";
|
|
11
|
+
const BUN_LOCK_PROJECT_RELATIVE_PATH = "bun.lock";
|
|
12
|
+
const FILE_PATTERN_NEGATION_PREFIX = "!";
|
|
13
|
+
const GLOB_CHARACTER_REGEX = /[*?[{]/;
|
|
14
|
+
const SKIPPED_DIR_NAMES = new Set(["node_modules", ".git"]);
|
|
15
|
+
const buildWorkspaceInputs = ({ project, script }) => {
|
|
16
|
+
const effectiveInputsByName = new Map();
|
|
17
|
+
const inputs = project.workspaces.map((workspace) => {
|
|
18
|
+
const workspaceConfig = project.config.workspaces[workspace.name];
|
|
19
|
+
const scriptInputs = script
|
|
20
|
+
? workspaceConfig?.scripts[script]?.inputs
|
|
21
|
+
: undefined;
|
|
22
|
+
const sourceInputs = scriptInputs ?? workspaceConfig?.defaultInputs ?? {};
|
|
23
|
+
const effectiveFiles = sourceInputs.files ?? [DEFAULT_INPUT_FILE_PATTERN];
|
|
24
|
+
const effectiveWorkspacePatterns = sourceInputs.workspacePatterns ?? [];
|
|
25
|
+
const effectiveExternalDependencies = sourceInputs.externalDependencies;
|
|
26
|
+
effectiveInputsByName.set(workspace.name, {
|
|
27
|
+
files: effectiveFiles,
|
|
28
|
+
workspacePatterns: effectiveWorkspacePatterns,
|
|
29
|
+
...(effectiveExternalDependencies !== undefined && {
|
|
30
|
+
externalDependencies: effectiveExternalDependencies,
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
workspace,
|
|
35
|
+
inputFilePatterns: effectiveFiles,
|
|
36
|
+
inputWorkspacePatterns: effectiveWorkspacePatterns,
|
|
37
|
+
...(effectiveExternalDependencies !== undefined && {
|
|
38
|
+
inputExternalDependencyNames: effectiveExternalDependencies,
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
inputs,
|
|
44
|
+
effectiveInputsByName,
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
const buildLockfileChangeSyntheticEntries = (workspaces) => {
|
|
48
|
+
const result = new Map();
|
|
49
|
+
for (const workspace of workspaces) {
|
|
50
|
+
if (!workspace.externalDependencies.length) continue;
|
|
51
|
+
result.set(
|
|
52
|
+
workspace.name,
|
|
53
|
+
workspace.externalDependencies.map(({ name, source }) => ({
|
|
54
|
+
name,
|
|
55
|
+
source,
|
|
56
|
+
baseVersion: null,
|
|
57
|
+
headVersion: null,
|
|
58
|
+
})),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
const normalizeChangedFilesPattern = (pattern) => {
|
|
64
|
+
let normalized = pattern.replaceAll("\\", "/");
|
|
65
|
+
while (normalized.startsWith("./")) normalized = normalized.slice(2);
|
|
66
|
+
normalized = normalized.replace(/^\/+/, "").replace(/\/+$/, "");
|
|
67
|
+
if (normalized === ".") return "";
|
|
68
|
+
return normalized;
|
|
69
|
+
};
|
|
70
|
+
const expandPatternToFiles = ({ rootDirectory, pattern }) => {
|
|
71
|
+
if (!pattern) return [];
|
|
72
|
+
const normalized = normalizeChangedFilesPattern(pattern);
|
|
73
|
+
if (normalized && GLOB_CHARACTER_REGEX.test(normalized)) {
|
|
74
|
+
return Array.from(
|
|
75
|
+
new bun.Glob(normalized).scanSync({
|
|
76
|
+
cwd: rootDirectory,
|
|
77
|
+
onlyFiles: true,
|
|
78
|
+
}),
|
|
79
|
+
).map((match) => match.replaceAll("\\", "/"));
|
|
80
|
+
}
|
|
81
|
+
// Empty `normalized` means the input resolved to the project root (e.g. ".")
|
|
82
|
+
const isProjectRoot = normalized === "";
|
|
83
|
+
const absolute = isProjectRoot
|
|
84
|
+
? rootDirectory
|
|
85
|
+
: path.join(rootDirectory, ...normalized.split("/"));
|
|
86
|
+
let stat;
|
|
87
|
+
try {
|
|
88
|
+
stat = fs.statSync(absolute);
|
|
89
|
+
} catch {
|
|
90
|
+
// Pass through paths that don't exist on disk (e.g. deleted files)
|
|
91
|
+
return isProjectRoot ? [] : [normalized];
|
|
92
|
+
}
|
|
93
|
+
if (stat.isFile()) return [normalized];
|
|
94
|
+
if (!stat.isDirectory()) return [];
|
|
95
|
+
const result = [];
|
|
96
|
+
const walk = (dir, baseRel) => {
|
|
97
|
+
for (const entry of fs.readdirSync(dir, {
|
|
98
|
+
withFileTypes: true,
|
|
99
|
+
})) {
|
|
100
|
+
if (entry.isDirectory() && SKIPPED_DIR_NAMES.has(entry.name)) continue;
|
|
101
|
+
const rel = baseRel ? `${baseRel}/${entry.name}` : entry.name;
|
|
102
|
+
if (entry.isDirectory()) {
|
|
103
|
+
walk(path.join(dir, entry.name), rel);
|
|
104
|
+
} else if (entry.isFile()) {
|
|
105
|
+
result.push(rel);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
walk(absolute, normalized);
|
|
110
|
+
return result;
|
|
111
|
+
};
|
|
112
|
+
const expandChangedFilesPatterns = ({ rootDirectory, patterns }) => {
|
|
113
|
+
const includes = new Set();
|
|
114
|
+
const excludes = new Set();
|
|
115
|
+
for (const pattern of patterns) {
|
|
116
|
+
const isExclude = pattern.startsWith(FILE_PATTERN_NEGATION_PREFIX);
|
|
117
|
+
const stripped = isExclude
|
|
118
|
+
? pattern.slice(FILE_PATTERN_NEGATION_PREFIX.length)
|
|
119
|
+
: pattern;
|
|
120
|
+
const target = isExclude ? excludes : includes;
|
|
121
|
+
for (const expanded of expandPatternToFiles({
|
|
122
|
+
rootDirectory,
|
|
123
|
+
pattern: stripped,
|
|
124
|
+
})) {
|
|
125
|
+
target.add(expanded);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const excluded of excludes) {
|
|
129
|
+
includes.delete(excluded);
|
|
130
|
+
}
|
|
131
|
+
return [...includes];
|
|
132
|
+
};
|
|
133
|
+
const toAffectedWorkspaceResult = (internal, effectiveInputsByName) => ({
|
|
134
|
+
workspace: internal.workspace,
|
|
135
|
+
inputs: effectiveInputsByName.get(internal.workspace.name) ?? {},
|
|
136
|
+
isAffected: internal.isAffected,
|
|
137
|
+
affectedReasons: {
|
|
138
|
+
changedFiles: internal.affectedReasons.changedFiles.map((file) => ({
|
|
139
|
+
projectFilePath: file.filePath,
|
|
140
|
+
inputMatch: file.inputPattern,
|
|
141
|
+
...(file.fileMetadata?.git && {
|
|
142
|
+
gitReasons: file.fileMetadata.git.reasons,
|
|
143
|
+
}),
|
|
144
|
+
})),
|
|
145
|
+
dependencies: internal.affectedReasons.dependencies,
|
|
146
|
+
externalDependencies: internal.affectedReasons.externalDependencies,
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const determineAffectedWorkspaces = async (project, options) => {
|
|
150
|
+
const ignoreWorkspaceDependencies =
|
|
151
|
+
options.ignoreWorkspaceDependencies ?? false;
|
|
152
|
+
const ignoreExternalDependencies =
|
|
153
|
+
options.ignoreExternalDependencies ?? false;
|
|
154
|
+
const { inputs: workspaceInputs, effectiveInputsByName } =
|
|
155
|
+
buildWorkspaceInputs({
|
|
156
|
+
project,
|
|
157
|
+
script: options.script,
|
|
158
|
+
});
|
|
159
|
+
if (isOptionsForDiffSource(options, "git")) {
|
|
160
|
+
const baseRef =
|
|
161
|
+
options.diffOptions?.baseRef ??
|
|
162
|
+
project.config.root.defaults.affectedBaseRef;
|
|
163
|
+
const headRef = options.diffOptions?.headRef ?? DEFAULT_HEAD_REF;
|
|
164
|
+
const { affectedWorkspaces, baseSha, headSha } =
|
|
165
|
+
await getGitAffectedWorkspaces({
|
|
166
|
+
rootDirectory: project.rootDirectory,
|
|
167
|
+
workspacesOptions: {
|
|
168
|
+
workspaceInputs,
|
|
169
|
+
workspaces: project.workspaces,
|
|
170
|
+
rootWorkspace: project.rootWorkspace,
|
|
171
|
+
ignoreWorkspaceDependencies,
|
|
172
|
+
ignoreExternalDependencies,
|
|
173
|
+
},
|
|
174
|
+
gitOptions: {
|
|
175
|
+
baseRef,
|
|
176
|
+
headRef,
|
|
177
|
+
ignoreUntracked: options.diffOptions?.ignoreUntracked,
|
|
178
|
+
ignoreStaged: options.diffOptions?.ignoreStaged,
|
|
179
|
+
ignoreUnstaged: options.diffOptions?.ignoreUnstaged,
|
|
180
|
+
ignoreUncommitted: options.diffOptions?.ignoreUncommitted,
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
return {
|
|
184
|
+
metadata: {
|
|
185
|
+
diffSource: "git",
|
|
186
|
+
git: {
|
|
187
|
+
baseRef,
|
|
188
|
+
headRef,
|
|
189
|
+
baseSha,
|
|
190
|
+
headSha,
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
workspaceResults: affectedWorkspaces.map((result) =>
|
|
194
|
+
toAffectedWorkspaceResult(result, effectiveInputsByName),
|
|
195
|
+
),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const expandedChangedFilePaths = expandChangedFilesPatterns({
|
|
199
|
+
rootDirectory: project.rootDirectory,
|
|
200
|
+
patterns: options.changedFiles,
|
|
201
|
+
});
|
|
202
|
+
const lockfileInChangedFiles = expandedChangedFilePaths.includes(
|
|
203
|
+
BUN_LOCK_PROJECT_RELATIVE_PATH,
|
|
204
|
+
);
|
|
205
|
+
const externalDepChangesByWorkspace =
|
|
206
|
+
!ignoreExternalDependencies && lockfileInChangedFiles
|
|
207
|
+
? buildLockfileChangeSyntheticEntries(project.workspaces)
|
|
208
|
+
: new Map();
|
|
209
|
+
const { affectedWorkspaces } = await getFileAffectedWorkspaces({
|
|
210
|
+
rootDirectory: project.rootDirectory,
|
|
211
|
+
workspaceInputs,
|
|
212
|
+
changedFilePaths: expandedChangedFilePaths,
|
|
213
|
+
rootWorkspace: project.rootWorkspace,
|
|
214
|
+
externalDepChangesByWorkspace,
|
|
215
|
+
ignoreWorkspaceDependencies,
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
metadata: {
|
|
219
|
+
diffSource: "fileList",
|
|
220
|
+
},
|
|
221
|
+
workspaceResults: affectedWorkspaces.map((result) =>
|
|
222
|
+
toAffectedWorkspaceResult(result, effectiveInputsByName),
|
|
223
|
+
),
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export { determineAffectedWorkspaces, isOptionsForDiffSource };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { loadRootConfig } from "
|
|
4
|
-
import { getUserEnvVar } from "
|
|
5
|
-
import { parse, quote } from "
|
|
3
|
+
import { loadRootConfig } from "../../../config/index.mjs";
|
|
4
|
+
import { getUserEnvVar } from "../../../config/userEnvVars/index.mjs";
|
|
5
|
+
import { parse, quote } from "../../../internal/bundledDeps/shellQuote.mjs";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_TEMP_DIR,
|
|
8
8
|
IS_WINDOWS,
|
|
@@ -11,25 +11,55 @@ import {
|
|
|
11
11
|
isPlainObject,
|
|
12
12
|
validateJSArray,
|
|
13
13
|
validateJSTypes,
|
|
14
|
-
} from "
|
|
15
|
-
import { logger } from "
|
|
14
|
+
} from "../../../internal/core/index.mjs";
|
|
15
|
+
import { logger } from "../../../internal/logger/index.mjs";
|
|
16
16
|
import {
|
|
17
17
|
createScriptRuntimeEnvVars,
|
|
18
18
|
interpolateWorkspaceScriptMetadata,
|
|
19
19
|
runScript,
|
|
20
20
|
runScripts,
|
|
21
|
-
} from "
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
21
|
+
} from "../../../runScript/index.mjs";
|
|
22
|
+
import { createMultiProcessOutput } from "../../../runScript/output/multiProcessOutput.mjs";
|
|
23
|
+
import { checkIsRecursiveScript } from "../../../runScript/recursion.mjs";
|
|
24
|
+
import { resolveScriptShell } from "../../../runScript/scriptShellOption.mjs";
|
|
25
|
+
import { findWorkspaces, sortWorkspaces } from "../../../workspaces/index.mjs";
|
|
26
|
+
import { preventDependencyCycles } from "../../../workspaces/dependencyGraph/index.mjs";
|
|
27
|
+
import { PROJECT_ERRORS } from "../../errors.mjs";
|
|
27
28
|
import {
|
|
28
29
|
ProjectBase,
|
|
29
30
|
resolveRootWorkspaceSelector,
|
|
30
31
|
resolveWorkspacePath,
|
|
31
|
-
} from "
|
|
32
|
+
} from "../projectBase.mjs";
|
|
33
|
+
import { determineAffectedWorkspaces } from "./affectedWorkspaces.mjs";
|
|
32
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Resolves the script name used to look up script-level inputs in
|
|
37
|
+
* `runAffectedWorkspaceScript`. Uses the inline-script name when running
|
|
38
|
+
* an inline command, or the script name otherwise.
|
|
39
|
+
*/ const resolveInputsLookupScriptName = (scriptOptions) => {
|
|
40
|
+
if (!scriptOptions.inline) return scriptOptions.script;
|
|
41
|
+
if (typeof scriptOptions.inline === "object") {
|
|
42
|
+
return scriptOptions.inline.scriptName;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
46
|
+
const createEmptyAffectedRunResult = () => {
|
|
47
|
+
const now = new Date().toISOString();
|
|
48
|
+
return {
|
|
49
|
+
output: createMultiProcessOutput([]),
|
|
50
|
+
summary: Promise.resolve({
|
|
51
|
+
totalCount: 0,
|
|
52
|
+
successCount: 0,
|
|
53
|
+
failureCount: 0,
|
|
54
|
+
allSuccess: true,
|
|
55
|
+
startTimeISO: now,
|
|
56
|
+
endTimeISO: now,
|
|
57
|
+
durationMs: 0,
|
|
58
|
+
scriptResults: [],
|
|
59
|
+
}),
|
|
60
|
+
workspaces: [],
|
|
61
|
+
};
|
|
62
|
+
};
|
|
33
63
|
const quoteArg = (arg, shell) =>
|
|
34
64
|
IS_WINDOWS && shell === "system"
|
|
35
65
|
? `"${arg.replace(/"/g, '""')}"`
|
|
@@ -497,6 +527,133 @@ class _FileSystemProject extends ProjectBase {
|
|
|
497
527
|
workspaces,
|
|
498
528
|
};
|
|
499
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Determine the affected workspaces based on the given options.
|
|
532
|
+
*
|
|
533
|
+
* Returns a summary of all workspaces, whether they are affected or not,
|
|
534
|
+
* and the reasons why they are affected.
|
|
535
|
+
*/ async determineAffectedWorkspaces(options) {
|
|
536
|
+
validateJSTypes(
|
|
537
|
+
{
|
|
538
|
+
"diffSource option": {
|
|
539
|
+
value: options.diffSource,
|
|
540
|
+
typeofName: "string",
|
|
541
|
+
},
|
|
542
|
+
"ignoreWorkspaceDependencies option": {
|
|
543
|
+
value: options.ignoreWorkspaceDependencies,
|
|
544
|
+
typeofName: "boolean",
|
|
545
|
+
optional: true,
|
|
546
|
+
},
|
|
547
|
+
"ignoreExternalDependencies option": {
|
|
548
|
+
value: options.ignoreExternalDependencies,
|
|
549
|
+
typeofName: "boolean",
|
|
550
|
+
optional: true,
|
|
551
|
+
},
|
|
552
|
+
"script option": {
|
|
553
|
+
value: options.script,
|
|
554
|
+
typeofName: "string",
|
|
555
|
+
optional: true,
|
|
556
|
+
},
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
throw: true,
|
|
560
|
+
},
|
|
561
|
+
);
|
|
562
|
+
if (options.diffSource !== "git" && options.diffSource !== "fileList") {
|
|
563
|
+
throw new InvalidJSTypeError(
|
|
564
|
+
`Type error: diffSource option expects "git" | "fileList", received ${JSON.stringify(options.diffSource)}`,
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
if (options.diffSource === "git") {
|
|
568
|
+
validateJSTypes(
|
|
569
|
+
{
|
|
570
|
+
"diffOptions option": {
|
|
571
|
+
value: options.diffOptions,
|
|
572
|
+
typeofName: "object",
|
|
573
|
+
optional: true,
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
throw: true,
|
|
578
|
+
},
|
|
579
|
+
);
|
|
580
|
+
if (options.diffOptions !== undefined) {
|
|
581
|
+
validateJSTypes(
|
|
582
|
+
{
|
|
583
|
+
"diffOptions.baseRef option": {
|
|
584
|
+
value: options.diffOptions.baseRef,
|
|
585
|
+
typeofName: "string",
|
|
586
|
+
optional: true,
|
|
587
|
+
},
|
|
588
|
+
"diffOptions.headRef option": {
|
|
589
|
+
value: options.diffOptions.headRef,
|
|
590
|
+
typeofName: "string",
|
|
591
|
+
optional: true,
|
|
592
|
+
},
|
|
593
|
+
"diffOptions.ignoreUntracked option": {
|
|
594
|
+
value: options.diffOptions.ignoreUntracked,
|
|
595
|
+
typeofName: "boolean",
|
|
596
|
+
optional: true,
|
|
597
|
+
},
|
|
598
|
+
"diffOptions.ignoreStaged option": {
|
|
599
|
+
value: options.diffOptions.ignoreStaged,
|
|
600
|
+
typeofName: "boolean",
|
|
601
|
+
optional: true,
|
|
602
|
+
},
|
|
603
|
+
"diffOptions.ignoreUnstaged option": {
|
|
604
|
+
value: options.diffOptions.ignoreUnstaged,
|
|
605
|
+
typeofName: "boolean",
|
|
606
|
+
optional: true,
|
|
607
|
+
},
|
|
608
|
+
"diffOptions.ignoreUncommitted option": {
|
|
609
|
+
value: options.diffOptions.ignoreUncommitted,
|
|
610
|
+
typeofName: "boolean",
|
|
611
|
+
optional: true,
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
throw: true,
|
|
616
|
+
},
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
} else {
|
|
620
|
+
validateJSTypes(
|
|
621
|
+
{
|
|
622
|
+
"changedFiles option": {
|
|
623
|
+
value: options.changedFiles,
|
|
624
|
+
array: true,
|
|
625
|
+
itemOptions: {
|
|
626
|
+
typeofName: "string",
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
throw: true,
|
|
632
|
+
},
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
return determineAffectedWorkspaces(this, options);
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Run the script across the affected workspaces.
|
|
639
|
+
*
|
|
640
|
+
* Similar to {@link runScriptAcrossWorkspaces}, but only runs the script across the affected workspaces.
|
|
641
|
+
*/ async runAffectedWorkspaceScript({ affectedOptions, scriptOptions }) {
|
|
642
|
+
const { workspaceResults } = await this.determineAffectedWorkspaces({
|
|
643
|
+
...affectedOptions,
|
|
644
|
+
script: resolveInputsLookupScriptName(scriptOptions),
|
|
645
|
+
});
|
|
646
|
+
const affectedNames = workspaceResults
|
|
647
|
+
.filter(({ isAffected }) => isAffected)
|
|
648
|
+
.map(({ workspace }) => workspace.name);
|
|
649
|
+
if (affectedNames.length === 0) {
|
|
650
|
+
return createEmptyAffectedRunResult();
|
|
651
|
+
}
|
|
652
|
+
return this.runScriptAcrossWorkspaces({
|
|
653
|
+
...scriptOptions,
|
|
654
|
+
workspacePatterns: affectedNames,
|
|
655
|
+
});
|
|
656
|
+
}
|
|
500
657
|
static #initialized = false;
|
|
501
658
|
}
|
|
502
659
|
/**
|
|
@@ -130,24 +130,18 @@ class ProjectBase {
|
|
|
130
130
|
return this.workspaces.filter((workspace) => workspace.tags.includes(tag));
|
|
131
131
|
}
|
|
132
132
|
findWorkspacesByPattern(...workspacePatterns) {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
workspaces.push(
|
|
146
|
-
...sortWorkspaces(
|
|
147
|
-
matchWorkspacesByPatterns(workspacePatterns, this.workspaces),
|
|
148
|
-
),
|
|
133
|
+
const matched = matchWorkspacesByPatterns(
|
|
134
|
+
workspacePatterns,
|
|
135
|
+
this.workspaces,
|
|
136
|
+
this.rootWorkspace,
|
|
137
|
+
);
|
|
138
|
+
// Preserve historical ordering: root workspace first, then sorted others.
|
|
139
|
+
const rootName = this.rootWorkspace.name;
|
|
140
|
+
const rootMatch = matched.find((workspace) => workspace.name === rootName);
|
|
141
|
+
const rest = sortWorkspaces(
|
|
142
|
+
matched.filter((workspace) => workspace.name !== rootName),
|
|
149
143
|
);
|
|
150
|
-
return
|
|
144
|
+
return rootMatch ? [rootMatch, ...rest] : rest;
|
|
151
145
|
}
|
|
152
146
|
createScriptCommand(options) {
|
|
153
147
|
validateJSTypes(
|
package/src/project/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./errors.mjs";
|
|
2
2
|
export * from "./implementations/projectBase.mjs";
|
|
3
|
-
export * from "./implementations/fileSystemProject.mjs";
|
|
3
|
+
export * from "./implementations/fileSystemProject/index.mjs";
|
|
4
4
|
export * from "./implementations/memoryProject.mjs";
|
|
5
5
|
|
|
6
6
|
export {};
|
package/src/rslib-runtime.mjs
CHANGED
|
@@ -21,42 +21,11 @@ function __webpack_require__(moduleId) {
|
|
|
21
21
|
// expose the modules object (__webpack_modules__)
|
|
22
22
|
__webpack_require__.m = __webpack_modules__;
|
|
23
23
|
|
|
24
|
-
// webpack/runtime/compat_get_default_export
|
|
25
|
-
(() => {
|
|
26
|
-
// getDefaultExport function for compatibility with non-ESM modules
|
|
27
|
-
__webpack_require__.n = (module) => {
|
|
28
|
-
var getter =
|
|
29
|
-
module && module.__esModule ? () => module["default"] : () => module;
|
|
30
|
-
__webpack_require__.d(getter, { a: getter });
|
|
31
|
-
return getter;
|
|
32
|
-
};
|
|
33
|
-
})();
|
|
34
|
-
// webpack/runtime/define_property_getters
|
|
35
|
-
(() => {
|
|
36
|
-
__webpack_require__.d = (exports, definition) => {
|
|
37
|
-
for (var key in definition) {
|
|
38
|
-
if (
|
|
39
|
-
__webpack_require__.o(definition, key) &&
|
|
40
|
-
!__webpack_require__.o(exports, key)
|
|
41
|
-
) {
|
|
42
|
-
Object.defineProperty(exports, key, {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
get: definition[key],
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
})();
|
|
50
24
|
// webpack/runtime/esm_register_module
|
|
51
25
|
(() => {
|
|
52
26
|
__webpack_require__.add = function registerModules(modules) {
|
|
53
27
|
Object.assign(__webpack_require__.m, modules);
|
|
54
28
|
};
|
|
55
29
|
})();
|
|
56
|
-
// webpack/runtime/has_own_property
|
|
57
|
-
(() => {
|
|
58
|
-
__webpack_require__.o = (obj, prop) =>
|
|
59
|
-
Object.prototype.hasOwnProperty.call(obj, prop);
|
|
60
|
-
})();
|
|
61
30
|
|
|
62
31
|
export { __webpack_require__ };
|
|
@@ -4,11 +4,20 @@ import {
|
|
|
4
4
|
} from "../config/index.mjs";
|
|
5
5
|
import { matchWorkspacesByPatterns } from "./workspacePattern.mjs";
|
|
6
6
|
|
|
7
|
-
const resolvedToWorkspaceConfig = ({
|
|
7
|
+
const resolvedToWorkspaceConfig = ({
|
|
8
|
+
aliases,
|
|
9
|
+
tags,
|
|
10
|
+
scripts,
|
|
11
|
+
rules,
|
|
12
|
+
defaultInputs,
|
|
13
|
+
}) => ({
|
|
8
14
|
alias: aliases,
|
|
9
15
|
tags,
|
|
10
16
|
scripts,
|
|
11
17
|
rules,
|
|
18
|
+
...(defaultInputs && {
|
|
19
|
+
defaultInputs,
|
|
20
|
+
}),
|
|
12
21
|
});
|
|
13
22
|
const makeContext = (workspace) => ({
|
|
14
23
|
name: workspace.name,
|
|
@@ -24,9 +33,14 @@ const applyWorkspacePatternConfigs = (
|
|
|
24
33
|
workspaceMap,
|
|
25
34
|
workspaceAliases,
|
|
26
35
|
patternConfigs,
|
|
36
|
+
rootWorkspace,
|
|
27
37
|
) => {
|
|
28
38
|
for (const entry of patternConfigs) {
|
|
29
|
-
const matched = matchWorkspacesByPatterns(
|
|
39
|
+
const matched = matchWorkspacesByPatterns(
|
|
40
|
+
entry.patterns,
|
|
41
|
+
workspaces,
|
|
42
|
+
rootWorkspace,
|
|
43
|
+
);
|
|
30
44
|
for (const workspace of matched) {
|
|
31
45
|
const mapEntry = workspaceMap[workspace.name];
|
|
32
46
|
const prevConfig = mapEntry.config;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { resolveCatalogDependencyVersion } from "../packageJson.mjs";
|
|
2
2
|
|
|
3
|
+
const parseCatalogRef = (rawVersion) => {
|
|
4
|
+
if (!rawVersion.startsWith("catalog:")) return undefined;
|
|
5
|
+
return {
|
|
6
|
+
name: rawVersion.slice("catalog:".length),
|
|
7
|
+
};
|
|
8
|
+
};
|
|
3
9
|
const resolveWorkspaceDependencies = (
|
|
4
10
|
workspaceMap,
|
|
5
11
|
includeRootWorkspace,
|
|
@@ -10,34 +16,78 @@ const resolveWorkspaceDependencies = (
|
|
|
10
16
|
);
|
|
11
17
|
const workspacesWithDependencies = workspacePackages.map(
|
|
12
18
|
({ workspace, packageJson }) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const externalAccumulator = new Map();
|
|
20
|
+
const dependencyMaps = [
|
|
21
|
+
{
|
|
22
|
+
map: packageJson.dependencies,
|
|
23
|
+
source: "dependencies",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
map: packageJson.devDependencies,
|
|
27
|
+
source: "devDependencies",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
map: packageJson.peerDependencies,
|
|
31
|
+
source: "peerDependencies",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
map: packageJson.optionalDependencies,
|
|
35
|
+
source: "optionalDependencies",
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
for (const { map, source } of dependencyMaps) {
|
|
39
|
+
for (const [dependencyName, dependencyVersion] of Object.entries(map)) {
|
|
40
|
+
const catalog = parseCatalogRef(dependencyVersion);
|
|
22
41
|
const resolvedVersion =
|
|
23
|
-
catalogs &&
|
|
42
|
+
catalogs && catalog
|
|
24
43
|
? (resolveCatalogDependencyVersion(
|
|
25
44
|
dependencyName,
|
|
26
45
|
dependencyVersion,
|
|
27
46
|
catalogs,
|
|
28
47
|
) ?? dependencyVersion)
|
|
29
48
|
: dependencyVersion;
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
if (resolvedVersion.startsWith("workspace:")) {
|
|
50
|
+
if (workspaceMap[dependencyName]) {
|
|
51
|
+
workspace.dependencies.push(dependencyName);
|
|
52
|
+
workspaceMap[dependencyName].workspace.dependents.push(
|
|
53
|
+
workspace.name,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// External dep — record. Source precedence: a non-`devDependencies`
|
|
59
|
+
// source overrides `devDependencies`; otherwise the first source
|
|
60
|
+
// seen wins. Version/catalog reflect the last entry seen for the name.
|
|
61
|
+
const existing = externalAccumulator.get(dependencyName);
|
|
62
|
+
if (!existing) {
|
|
63
|
+
externalAccumulator.set(dependencyName, {
|
|
64
|
+
source,
|
|
65
|
+
version: resolvedVersion,
|
|
66
|
+
catalog,
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
existing.version = resolvedVersion;
|
|
70
|
+
existing.catalog = catalog;
|
|
71
|
+
if (
|
|
72
|
+
existing.source === "devDependencies" &&
|
|
73
|
+
source !== "devDependencies"
|
|
74
|
+
) {
|
|
75
|
+
existing.source = source;
|
|
76
|
+
}
|
|
38
77
|
}
|
|
39
78
|
}
|
|
40
79
|
}
|
|
80
|
+
workspace.externalDependencies = [...externalAccumulator.entries()]
|
|
81
|
+
.map(([name, { source, version, catalog }]) => {
|
|
82
|
+
const entry = {
|
|
83
|
+
name,
|
|
84
|
+
version,
|
|
85
|
+
source,
|
|
86
|
+
};
|
|
87
|
+
if (catalog) entry.catalog = catalog;
|
|
88
|
+
return entry;
|
|
89
|
+
})
|
|
90
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
41
91
|
return workspace;
|
|
42
92
|
},
|
|
43
93
|
);
|