@visulima/task-runner 1.0.0-alpha.2 → 1.0.0-alpha.20
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/CHANGELOG.md +310 -0
- package/README.md +198 -52
- package/dist/index.d.ts +3795 -34
- package/dist/index.js +1 -20
- package/dist/packem_chunks/index.js +31 -0
- package/dist/packem_shared/Cache-C8FfeXpg.js +2 -0
- package/dist/packem_shared/CompositeLifeCycle-C6aee9GK.js +1 -0
- package/dist/packem_shared/FileAccessTracker-DBz_w4wl.js +50 -0
- package/dist/packem_shared/FingerprintManager-CYW2EwLc.js +2 -0
- package/dist/packem_shared/HttpRemoteCache-CpPl6lzE.js +1 -0
- package/dist/packem_shared/INPUT_URI_SCHEMES-Csrd0tlg.js +1 -0
- package/dist/packem_shared/IncrementalFileHasher-B-V3i2x-.js +1 -0
- package/dist/packem_shared/LogReporter-3R3oWj-Q.js +13 -0
- package/dist/packem_shared/ReapiRemoteCache-BXJip5wH.js +251 -0
- package/dist/packem_shared/TaskOrchestrator-CYj5MLwz.js +6 -0
- package/dist/packem_shared/TerminalBuffer-BtZy7TpT.js +3 -0
- package/dist/packem_shared/TrackedTaskExecutor-CtYLL3vS.js +1 -0
- package/dist/packem_shared/V2_ROOT-injxWBrl.js +1 -0
- package/dist/packem_shared/actionDigestForTaskHash-BOL4fZ9v.js +1 -0
- package/dist/packem_shared/archive-CDfGy5Lm.js +1 -0
- package/dist/packem_shared/buildForwardDependencyMap-DudUDFze.js +3 -0
- package/dist/packem_shared/collectFiles-W4bnBRpb.js +1 -0
- package/dist/packem_shared/collectNodeModulesBinDirs-CD-eDrtO.js +1 -0
- package/dist/packem_shared/computeTaskHash-CaPdG1BA.js +1 -0
- package/dist/packem_shared/containsBlob-DAU8R7GH.js +1 -0
- package/dist/packem_shared/createInputHandler-CkDCpPYy.js +1 -0
- package/dist/packem_shared/createTaskGraph-D8Jn_Dn9.js +1 -0
- package/dist/packem_shared/defaultTaskRunner-DMHpavzm.js +2 -0
- package/dist/packem_shared/detectFrameworks-WVZJOPgN.js +1 -0
- package/dist/packem_shared/detectScriptShell-CaTDk5cW.js +1 -0
- package/dist/packem_shared/digestBuffer-g11aCaDx.js +1 -0
- package/dist/packem_shared/enforceProjectConstraints-dNc1SwRi.js +1 -0
- package/dist/packem_shared/expandArguments-D7qvc6Rp.js +1 -0
- package/dist/packem_shared/expandShortcut-BErNHNXZ.js +1 -0
- package/dist/packem_shared/expandTokensInString-DVSFEdWu.js +1 -0
- package/dist/packem_shared/expandWildcard-DE0dOOZF.js +1 -0
- package/dist/packem_shared/extractPackageName-BeL6Gc3a.js +1 -0
- package/dist/packem_shared/findCycle-BY8-jmzB.js +1 -0
- package/dist/packem_shared/formatTimingTable-CP3rsDwf.js +7 -0
- package/dist/packem_shared/generateRunSummary-L9Z2NfWn.js +1 -0
- package/dist/packem_shared/getCurrentBranch-D-qoZByx.js +1 -0
- package/dist/packem_shared/getMainWorktreeRoot-DB9P2wDL.js +1 -0
- package/dist/packem_shared/isNativeAvailable-CkTjxb7P.js +1 -0
- package/dist/packem_shared/parseCommands-BHsXoUCd.js +1 -0
- package/dist/packem_shared/parsePartition-Bt1jBjZH.js +1 -0
- package/dist/packem_shared/projectGraphToDot-FN6oHDGH.js +250 -0
- package/dist/packem_shared/resolveCacheMode--4y60ODd.js +1 -0
- package/dist/packem_shared/resolveOutputs-CzGGEbcP.js +1 -0
- package/dist/packem_shared/runConcurrentFallback-BhJCT2LA.js +3 -0
- package/dist/packem_shared/runConcurrently-D1Ytsjaj.js +1 -0
- package/dist/packem_shared/runTeardown-DAn1xFWJ.js +1 -0
- package/dist/packem_shared/shell-quote-BhmqDUL1.js +1 -0
- package/dist/packem_shared/stripQuotes-jkZb0CL9.js +1 -0
- package/dist/packem_shared/toChromeTrace-DxN5NQIU.js +1 -0
- package/dist/packem_shared/tracked-executor-B90U4Um3.js +3 -0
- package/dist/packem_shared/utils-BH2W5Wml.js +1 -0
- package/dist/packem_shared/withRestart-DKtEGsQA.js +1 -0
- package/index.js +603 -0
- package/package.json +31 -19
- package/binding.js +0 -204
- package/dist/affected.d.ts +0 -48
- package/dist/cache.d.ts +0 -103
- package/dist/default-task-runner.d.ts +0 -44
- package/dist/file-access-tracker.d.ts +0 -53
- package/dist/fingerprint.d.ts +0 -45
- package/dist/framework-inference.d.ts +0 -35
- package/dist/graph-visualizer.d.ts +0 -74
- package/dist/incremental-hasher.d.ts +0 -58
- package/dist/life-cycle.d.ts +0 -36
- package/dist/lockfile-hasher.d.ts +0 -73
- package/dist/native-binding.d.ts +0 -64
- package/dist/packem_shared/Cache-IYpTYVUC.js +0 -298
- package/dist/packem_shared/CompositeLifeCycle-7AtYw1dv.js +0 -112
- package/dist/packem_shared/FileAccessTracker-CrtBAt5D.js +0 -239
- package/dist/packem_shared/FingerprintManager-D6Y0erg-.js +0 -227
- package/dist/packem_shared/IncrementalFileHasher-Ds3J6dgb.js +0 -151
- package/dist/packem_shared/RemoteCache-BDqrnDEi.js +0 -179
- package/dist/packem_shared/TaskOrchestrator-BvYs3ONw.js +0 -342
- package/dist/packem_shared/TaskScheduler-CJilHDta.js +0 -111
- package/dist/packem_shared/TrackedTaskExecutor-BGUKFE-7.js +0 -164
- package/dist/packem_shared/collectFiles-ClXHnHhg.js +0 -22
- package/dist/packem_shared/computeTaskHash-BoCnnvIJ.js +0 -356
- package/dist/packem_shared/createTaskGraph-CcsFaSrz.js +0 -164
- package/dist/packem_shared/defaultTaskRunner-CrW4v5Ye.js +0 -79
- package/dist/packem_shared/detectFrameworks-CeFzKE6J.js +0 -101
- package/dist/packem_shared/extractPackageName-CbVNW-dr.js +0 -189
- package/dist/packem_shared/filterAffectedTasks-I-18zPg6.js +0 -135
- package/dist/packem_shared/findCycle-DF4_BRdO.js +0 -212
- package/dist/packem_shared/generateRunSummary-qn-_jKwt.js +0 -134
- package/dist/packem_shared/isNativeAvailable-BWhnZ4ES.js +0 -19
- package/dist/packem_shared/projectGraphToDot-VdTjHcVp.js +0 -202
- package/dist/packem_shared/utils-zO0ZRgtf.js +0 -390
- package/dist/remote-cache.d.ts +0 -55
- package/dist/run-summary.d.ts +0 -89
- package/dist/task-graph-utils.d.ts +0 -39
- package/dist/task-graph.d.ts +0 -22
- package/dist/task-hasher.d.ts +0 -67
- package/dist/task-orchestrator.d.ts +0 -38
- package/dist/task-scheduler.d.ts +0 -18
- package/dist/tracked-executor.d.ts +0 -46
- package/dist/types.d.ts +0 -385
- package/dist/utils.d.ts +0 -39
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
const getTaskId = (target) => {
|
|
2
|
-
const parts = [target.project, target.target];
|
|
3
|
-
if (target.configuration) {
|
|
4
|
-
parts.push(target.configuration);
|
|
5
|
-
}
|
|
6
|
-
return parts.join(":");
|
|
7
|
-
};
|
|
8
|
-
const parseTaskId = (taskId) => {
|
|
9
|
-
const parts = taskId.split(":");
|
|
10
|
-
if (parts.length < 2) {
|
|
11
|
-
throw new Error(`Invalid task ID: ${taskId}`);
|
|
12
|
-
}
|
|
13
|
-
return {
|
|
14
|
-
configuration: parts[2],
|
|
15
|
-
project: parts[0],
|
|
16
|
-
target: parts[1]
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
const getTaskOutputs = (projectName, targetName, workspace, targetDefaults) => {
|
|
20
|
-
const project = workspace.projects[projectName];
|
|
21
|
-
const targetConfig = project?.targets?.[targetName];
|
|
22
|
-
const defaultConfig = targetDefaults?.[targetName];
|
|
23
|
-
const outputs = targetConfig?.outputs ?? defaultConfig?.outputs ?? [];
|
|
24
|
-
return outputs.map((output) => output.replace("{projectRoot}", project?.root ?? "").replace("{projectName}", projectName));
|
|
25
|
-
};
|
|
26
|
-
const getSameProjectTask = (projectName, targetName, overrides, workspace, targetDefaults) => {
|
|
27
|
-
const project = workspace.projects[projectName];
|
|
28
|
-
if (!project) {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
const hasTarget = project.targets?.[targetName] !== void 0 || targetDefaults?.[targetName] !== void 0;
|
|
32
|
-
if (!hasTarget) {
|
|
33
|
-
return [];
|
|
34
|
-
}
|
|
35
|
-
const target = {
|
|
36
|
-
project: projectName,
|
|
37
|
-
target: targetName
|
|
38
|
-
};
|
|
39
|
-
return [
|
|
40
|
-
{
|
|
41
|
-
cache: project.targets?.[targetName]?.cache ?? targetDefaults?.[targetName]?.cache,
|
|
42
|
-
id: getTaskId(target),
|
|
43
|
-
outputs: getTaskOutputs(projectName, targetName, workspace, targetDefaults),
|
|
44
|
-
overrides,
|
|
45
|
-
parallelism: project.targets?.[targetName]?.parallelism ?? targetDefaults?.[targetName]?.parallelism,
|
|
46
|
-
projectRoot: project.root,
|
|
47
|
-
target
|
|
48
|
-
}
|
|
49
|
-
];
|
|
50
|
-
};
|
|
51
|
-
const getDependencyProjectTasks = (projectName, targetName, overrides, workspace, projectGraph, targetDefaults) => {
|
|
52
|
-
const tasks = [];
|
|
53
|
-
const deps = projectGraph.dependencies[projectName] ?? [];
|
|
54
|
-
for (const dep of deps) {
|
|
55
|
-
const depProject = workspace.projects[dep.target];
|
|
56
|
-
if (!depProject) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const hasTarget = depProject.targets?.[targetName] !== void 0 || targetDefaults?.[targetName] !== void 0;
|
|
60
|
-
if (hasTarget) {
|
|
61
|
-
const target = {
|
|
62
|
-
project: dep.target,
|
|
63
|
-
target: targetName
|
|
64
|
-
};
|
|
65
|
-
tasks.push({
|
|
66
|
-
cache: depProject.targets?.[targetName]?.cache ?? targetDefaults?.[targetName]?.cache,
|
|
67
|
-
id: getTaskId(target),
|
|
68
|
-
outputs: getTaskOutputs(dep.target, targetName, workspace, targetDefaults),
|
|
69
|
-
overrides,
|
|
70
|
-
parallelism: depProject.targets?.[targetName]?.parallelism ?? targetDefaults?.[targetName]?.parallelism,
|
|
71
|
-
projectRoot: depProject.root,
|
|
72
|
-
target
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return tasks;
|
|
77
|
-
};
|
|
78
|
-
const resolveStringDependency = (task, dep, workspace, projectGraph, targetDefaults) => {
|
|
79
|
-
if (dep.startsWith("^")) {
|
|
80
|
-
const targetName = dep.slice(1);
|
|
81
|
-
return getDependencyProjectTasks(task.target.project, targetName, task.overrides, workspace, projectGraph, targetDefaults);
|
|
82
|
-
}
|
|
83
|
-
return getSameProjectTask(task.target.project, dep, task.overrides, workspace, targetDefaults);
|
|
84
|
-
};
|
|
85
|
-
const resolveConfigDependency = (task, dep, workspace, projectGraph, targetDefaults) => {
|
|
86
|
-
const tasks = [];
|
|
87
|
-
if (dep.dependencies) {
|
|
88
|
-
tasks.push(
|
|
89
|
-
...getDependencyProjectTasks(
|
|
90
|
-
task.target.project,
|
|
91
|
-
dep.target,
|
|
92
|
-
dep.params === "forward" ? task.overrides : {},
|
|
93
|
-
workspace,
|
|
94
|
-
projectGraph,
|
|
95
|
-
targetDefaults
|
|
96
|
-
)
|
|
97
|
-
);
|
|
98
|
-
} else if (dep.projects) {
|
|
99
|
-
const projects = Array.isArray(dep.projects) ? dep.projects : [dep.projects];
|
|
100
|
-
for (const projectName of projects) {
|
|
101
|
-
tasks.push(...getSameProjectTask(projectName, dep.target, dep.params === "forward" ? task.overrides : {}, workspace, targetDefaults));
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
tasks.push(...getSameProjectTask(task.target.project, dep.target, dep.params === "forward" ? task.overrides : {}, workspace, targetDefaults));
|
|
105
|
-
}
|
|
106
|
-
return tasks;
|
|
107
|
-
};
|
|
108
|
-
const resolveDependency = (task, dep, workspace, projectGraph, targetDefaults) => {
|
|
109
|
-
if (typeof dep === "string") {
|
|
110
|
-
return resolveStringDependency(task, dep, workspace, projectGraph, targetDefaults);
|
|
111
|
-
}
|
|
112
|
-
return resolveConfigDependency(task, dep, workspace, projectGraph, targetDefaults);
|
|
113
|
-
};
|
|
114
|
-
const resolveTaskDependencies = (task, options) => {
|
|
115
|
-
const { projectGraph, targetDefaults, workspace } = options;
|
|
116
|
-
const project = workspace.projects[task.target.project];
|
|
117
|
-
if (!project) {
|
|
118
|
-
return [];
|
|
119
|
-
}
|
|
120
|
-
const targetConfig = project.targets?.[task.target.target];
|
|
121
|
-
const defaultConfig = targetDefaults?.[task.target.target];
|
|
122
|
-
const dependsOn = targetConfig?.dependsOn ?? defaultConfig?.dependsOn ?? [];
|
|
123
|
-
const depTasks = [];
|
|
124
|
-
for (const dep of dependsOn) {
|
|
125
|
-
const resolved = resolveDependency(task, dep, workspace, projectGraph, targetDefaults);
|
|
126
|
-
depTasks.push(...resolved);
|
|
127
|
-
}
|
|
128
|
-
return depTasks;
|
|
129
|
-
};
|
|
130
|
-
const createTaskGraph = (initialTasks, options) => {
|
|
131
|
-
const tasks = {};
|
|
132
|
-
const dependencies = {};
|
|
133
|
-
const visited = /* @__PURE__ */ new Set();
|
|
134
|
-
const queue = [...initialTasks];
|
|
135
|
-
while (queue.length > 0) {
|
|
136
|
-
const task = queue.shift();
|
|
137
|
-
if (!task) {
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
if (visited.has(task.id)) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
visited.add(task.id);
|
|
144
|
-
tasks[task.id] = task;
|
|
145
|
-
dependencies[task.id] = [];
|
|
146
|
-
const deps = resolveTaskDependencies(task, options);
|
|
147
|
-
for (const depTask of deps) {
|
|
148
|
-
dependencies[task.id]?.push(depTask.id);
|
|
149
|
-
if (!visited.has(depTask.id)) {
|
|
150
|
-
queue.push(depTask);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
const allDeps = /* @__PURE__ */ new Set();
|
|
155
|
-
for (const deps of Object.values(dependencies)) {
|
|
156
|
-
for (const dep of deps) {
|
|
157
|
-
allDeps.add(dep);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
const roots = Object.keys(tasks).filter((taskId) => !allDeps.has(taskId));
|
|
161
|
-
return { dependencies, roots, tasks };
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
export { createTaskGraph, getTaskId, parseTaskId };
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Cache } from './Cache-IYpTYVUC.js';
|
|
2
|
-
import { inferFrameworkEnvPatterns } from './detectFrameworks-CeFzKE6J.js';
|
|
3
|
-
import { EmptyLifeCycle } from './CompositeLifeCycle-7AtYw1dv.js';
|
|
4
|
-
import { RemoteCache } from './RemoteCache-BDqrnDEi.js';
|
|
5
|
-
import { InProcessTaskHasher } from './computeTaskHash-BoCnnvIJ.js';
|
|
6
|
-
import { TaskOrchestrator } from './TaskOrchestrator-BvYs3ONw.js';
|
|
7
|
-
import { TaskScheduler } from './TaskScheduler-CJilHDta.js';
|
|
8
|
-
|
|
9
|
-
const resolveParallel = (parallel) => {
|
|
10
|
-
if (typeof parallel === "number") {
|
|
11
|
-
return Math.max(1, parallel);
|
|
12
|
-
}
|
|
13
|
-
if (parallel === false) {
|
|
14
|
-
return 1;
|
|
15
|
-
}
|
|
16
|
-
return 3;
|
|
17
|
-
};
|
|
18
|
-
const defaultTaskRunner = async (_tasks, options, context) => {
|
|
19
|
-
const { lifeCycle = new EmptyLifeCycle(), projectGraph, taskExecutor, taskGraph, workspaceRoot } = context;
|
|
20
|
-
const cache = new Cache({
|
|
21
|
-
cacheDirectory: options.cacheDirectory,
|
|
22
|
-
maxCacheAge: options.maxCacheAge,
|
|
23
|
-
maxCacheSize: options.maxCacheSize,
|
|
24
|
-
workspaceRoot
|
|
25
|
-
});
|
|
26
|
-
cache.removeOldEntries().catch(() => {
|
|
27
|
-
});
|
|
28
|
-
const projects = {};
|
|
29
|
-
for (const [name, node] of Object.entries(projectGraph.nodes)) {
|
|
30
|
-
projects[name] = node.data;
|
|
31
|
-
}
|
|
32
|
-
const taskHasher = new InProcessTaskHasher({
|
|
33
|
-
envVars: options.envVars,
|
|
34
|
-
frameworkInference: options.frameworkInference,
|
|
35
|
-
globalEnv: options.globalEnv,
|
|
36
|
-
globalInputs: options.globalInputs,
|
|
37
|
-
namedInputs: options.namedInputs,
|
|
38
|
-
projects,
|
|
39
|
-
smartLockfileHashing: options.smartLockfileHashing,
|
|
40
|
-
targetDefaults: options.targetDefaults,
|
|
41
|
-
workspaceRoot
|
|
42
|
-
});
|
|
43
|
-
const maxParallel = resolveParallel(options.parallel);
|
|
44
|
-
const scheduler = new TaskScheduler(taskGraph, projectGraph, maxParallel);
|
|
45
|
-
const resolveCommand = (task) => {
|
|
46
|
-
const project = projectGraph.nodes[task.target.project];
|
|
47
|
-
const targetConfig = project?.data.targets?.[task.target.target];
|
|
48
|
-
const defaultConfig = options.targetDefaults?.[task.target.target];
|
|
49
|
-
return targetConfig?.command ?? defaultConfig?.command;
|
|
50
|
-
};
|
|
51
|
-
const remoteCache = options.remoteCache ? new RemoteCache(options.remoteCache) : void 0;
|
|
52
|
-
let fingerprintEnvPatterns = options.fingerprintEnvPatterns ?? [];
|
|
53
|
-
if (options.frameworkInference && options.autoFingerprint) {
|
|
54
|
-
const inferredPatterns = await inferFrameworkEnvPatterns(workspaceRoot, projects);
|
|
55
|
-
fingerprintEnvPatterns = [.../* @__PURE__ */ new Set([...fingerprintEnvPatterns, ...inferredPatterns])];
|
|
56
|
-
}
|
|
57
|
-
const orchestrator = new TaskOrchestrator({
|
|
58
|
-
autoFingerprint: options.autoFingerprint,
|
|
59
|
-
cache,
|
|
60
|
-
cacheDiagnostics: options.cacheDiagnostics,
|
|
61
|
-
captureOutput: true,
|
|
62
|
-
dryRun: options.dryRun,
|
|
63
|
-
fingerprintEnvPatterns,
|
|
64
|
-
lifeCycle,
|
|
65
|
-
remoteCache,
|
|
66
|
-
resolveCommand: options.autoFingerprint ? resolveCommand : void 0,
|
|
67
|
-
scheduler,
|
|
68
|
-
skipCache: options.skipNxCache,
|
|
69
|
-
summarize: options.summarize,
|
|
70
|
-
taskExecutor,
|
|
71
|
-
taskGraph,
|
|
72
|
-
taskHasher,
|
|
73
|
-
untrackedEnvVars: options.untrackedEnvVars,
|
|
74
|
-
workspaceRoot
|
|
75
|
-
});
|
|
76
|
-
return orchestrator.run();
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export { defaultTaskRunner };
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { join } from '@visulima/path';
|
|
2
|
-
import { r as readPackageDeps } from './utils-zO0ZRgtf.js';
|
|
3
|
-
|
|
4
|
-
const FRAMEWORK_DEFINITIONS = [
|
|
5
|
-
{
|
|
6
|
-
envPrefixes: ["NEXT_PUBLIC_"],
|
|
7
|
-
name: "Next.js",
|
|
8
|
-
packages: ["next"]
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
envPrefixes: ["VITE_"],
|
|
12
|
-
name: "Vite",
|
|
13
|
-
packages: ["vite"]
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
envPrefixes: ["REACT_APP_"],
|
|
17
|
-
name: "Create React App",
|
|
18
|
-
packages: ["react-scripts"]
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
envPrefixes: ["GATSBY_"],
|
|
22
|
-
name: "Gatsby",
|
|
23
|
-
packages: ["gatsby"]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
envPrefixes: ["NUXT_PUBLIC_"],
|
|
27
|
-
name: "Nuxt",
|
|
28
|
-
packages: ["nuxt", "nuxt3"]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
envPrefixes: ["EXPO_PUBLIC_"],
|
|
32
|
-
name: "Expo",
|
|
33
|
-
packages: ["expo"]
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
envPrefixes: ["REMIX_PUBLIC_"],
|
|
37
|
-
name: "Remix",
|
|
38
|
-
packages: ["@remix-run/react", "@remix-run/node"]
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
envPrefixes: ["PUBLIC_"],
|
|
42
|
-
name: "Astro",
|
|
43
|
-
packages: ["astro"]
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
envPrefixes: ["PUBLIC_"],
|
|
47
|
-
name: "SvelteKit",
|
|
48
|
-
packages: ["@sveltejs/kit"]
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
envPrefixes: ["VITE_"],
|
|
52
|
-
name: "Solid Start",
|
|
53
|
-
packages: ["@solidjs/start", "solid-start"]
|
|
54
|
-
}
|
|
55
|
-
];
|
|
56
|
-
const detectFrameworks = async (packageJsonPath) => {
|
|
57
|
-
const allDeps = await readPackageDeps(packageJsonPath, { optional: false, peer: false });
|
|
58
|
-
if (!allDeps) {
|
|
59
|
-
return [];
|
|
60
|
-
}
|
|
61
|
-
const detected = [];
|
|
62
|
-
for (const framework of FRAMEWORK_DEFINITIONS) {
|
|
63
|
-
if (framework.packages.some((pkg) => allDeps.has(pkg))) {
|
|
64
|
-
detected.push({
|
|
65
|
-
envPrefixes: framework.envPrefixes,
|
|
66
|
-
name: framework.name
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return detected;
|
|
71
|
-
};
|
|
72
|
-
const inferFrameworkEnvPatterns = async (workspaceRoot, projects) => {
|
|
73
|
-
const allPrefixes = /* @__PURE__ */ new Set();
|
|
74
|
-
const detectionPromises = Object.values(projects).map(async (project) => {
|
|
75
|
-
const packageJsonPath = join(workspaceRoot, project.root, "package.json");
|
|
76
|
-
const frameworks = await detectFrameworks(packageJsonPath);
|
|
77
|
-
for (const fw of frameworks) {
|
|
78
|
-
for (const prefix of fw.envPrefixes) {
|
|
79
|
-
allPrefixes.add(prefix);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
await Promise.all(detectionPromises);
|
|
84
|
-
return [...allPrefixes].toSorted().map((prefix) => `${prefix}*`);
|
|
85
|
-
};
|
|
86
|
-
const getFrameworkEnvVariables = async (packageJsonPath, env = process.env) => {
|
|
87
|
-
const frameworks = await detectFrameworks(packageJsonPath);
|
|
88
|
-
const result = {};
|
|
89
|
-
for (const framework of frameworks) {
|
|
90
|
-
for (const prefix of framework.envPrefixes) {
|
|
91
|
-
for (const [key, value] of Object.entries(env)) {
|
|
92
|
-
if (key.startsWith(prefix) && value !== void 0) {
|
|
93
|
-
result[key] = value;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return result;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export { detectFrameworks, getFrameworkEnvVariables, inferFrameworkEnvPatterns };
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
|
-
|
|
3
|
-
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
4
|
-
|
|
5
|
-
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
|
|
6
|
-
|
|
7
|
-
const __cjs_getBuiltinModule = (module) => {
|
|
8
|
-
// Check if we're in Node.js and version supports getBuiltinModule
|
|
9
|
-
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
|
|
10
|
-
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
|
|
11
|
-
// Node.js 20.16.0+ and 22.3.0+
|
|
12
|
-
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
|
|
13
|
-
return __cjs_getProcess.getBuiltinModule(module);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
// Fallback to createRequire
|
|
17
|
-
return __cjs_require(module);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const {
|
|
21
|
-
readFile
|
|
22
|
-
} = __cjs_getBuiltinModule("node:fs/promises");
|
|
23
|
-
import { r as readPackageDeps, e as createXxh3Hasher } from './utils-zO0ZRgtf.js';
|
|
24
|
-
import { join } from '@visulima/path';
|
|
25
|
-
|
|
26
|
-
const extractPackageName = (path) => {
|
|
27
|
-
const match = /.*node_modules\/((?:@[^/]+\/)?[^/]+)/.exec(path);
|
|
28
|
-
if (!match?.[1]) {
|
|
29
|
-
return void 0;
|
|
30
|
-
}
|
|
31
|
-
const name = match[1];
|
|
32
|
-
if (name.startsWith(".")) {
|
|
33
|
-
return void 0;
|
|
34
|
-
}
|
|
35
|
-
return name;
|
|
36
|
-
};
|
|
37
|
-
const parseNpmLockfile = (content) => {
|
|
38
|
-
const versions = /* @__PURE__ */ new Map();
|
|
39
|
-
try {
|
|
40
|
-
const lockfile = JSON.parse(content);
|
|
41
|
-
if (lockfile.packages) {
|
|
42
|
-
for (const [path, entry] of Object.entries(lockfile.packages)) {
|
|
43
|
-
if (!path || !entry.version) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
const name = extractPackageName(path);
|
|
47
|
-
if (name && !versions.has(name)) {
|
|
48
|
-
versions.set(name, entry.version);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (versions.size === 0 && lockfile.dependencies) {
|
|
53
|
-
for (const [name, entry] of Object.entries(lockfile.dependencies)) {
|
|
54
|
-
if (entry.version) {
|
|
55
|
-
versions.set(name, entry.version);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
} catch {
|
|
60
|
-
}
|
|
61
|
-
return versions;
|
|
62
|
-
};
|
|
63
|
-
const parsePnpmLockfile = (content) => {
|
|
64
|
-
const versions = /* @__PURE__ */ new Map();
|
|
65
|
-
const depVersionRegex = /^\s{4,}(\S+):\n\s+specifier:.*\n\s+version:\s*'?([^'\n(]+)/gm;
|
|
66
|
-
let match;
|
|
67
|
-
while ((match = depVersionRegex.exec(content) ?? void 0) !== void 0) {
|
|
68
|
-
const name = match[1].replaceAll(/^['"]|['"]$/g, "");
|
|
69
|
-
let version = match[2].trim();
|
|
70
|
-
const parenIndex = version.indexOf("(");
|
|
71
|
-
if (parenIndex > 0) {
|
|
72
|
-
version = version.slice(0, parenIndex).trim();
|
|
73
|
-
}
|
|
74
|
-
if (!versions.has(name)) {
|
|
75
|
-
versions.set(name, version);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (versions.size === 0) {
|
|
79
|
-
const packagesRegex = /^\s{2}[/'"]?(?:@([^/@']+)\/)?([^@']+)@(\d[^:'"\s]*)/gm;
|
|
80
|
-
while ((match = packagesRegex.exec(content) ?? void 0) !== void 0) {
|
|
81
|
-
const scope = match[1];
|
|
82
|
-
const name = scope ? `@${scope}/${match[2]}` : match[2];
|
|
83
|
-
const version = match[3];
|
|
84
|
-
if (!versions.has(name)) {
|
|
85
|
-
versions.set(name, version);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return versions;
|
|
90
|
-
};
|
|
91
|
-
const parseYarnLockfile = (content) => {
|
|
92
|
-
const versions = /* @__PURE__ */ new Map();
|
|
93
|
-
const entryRegex = /^["']?(?:@([^/@"']+)\/)?([^@"']+)@[^"'\n]+["']?:?[\t\v\f\r \u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*\n\s+version:?\s+"?([^"\n]+)"?/gm;
|
|
94
|
-
let match;
|
|
95
|
-
while ((match = entryRegex.exec(content) ?? void 0) !== void 0) {
|
|
96
|
-
const scope = match[1];
|
|
97
|
-
const name = scope ? `@${scope}/${match[2]}` : match[2];
|
|
98
|
-
const version = match[3].trim();
|
|
99
|
-
if (!versions.has(name)) {
|
|
100
|
-
versions.set(name, version);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return versions;
|
|
104
|
-
};
|
|
105
|
-
class LockfileHasher {
|
|
106
|
-
#workspaceRoot;
|
|
107
|
-
#lockfileCache;
|
|
108
|
-
#lockfileType;
|
|
109
|
-
constructor(workspaceRoot) {
|
|
110
|
-
this.#workspaceRoot = workspaceRoot;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Computes a hash based only on the resolved dependency versions
|
|
114
|
-
* relevant to a specific package.
|
|
115
|
-
* @param packageJsonPath Path to the package.json (relative to workspace root)
|
|
116
|
-
* @returns Hash of the relevant lockfile entries, or undefined if no lockfile found
|
|
117
|
-
*/
|
|
118
|
-
async hashForPackage(packageJsonPath) {
|
|
119
|
-
const fullPath = join(this.#workspaceRoot, packageJsonPath);
|
|
120
|
-
const deps = await readPackageDeps(fullPath);
|
|
121
|
-
if (!deps || deps.size === 0) {
|
|
122
|
-
return void 0;
|
|
123
|
-
}
|
|
124
|
-
const resolvedVersions = await this.#getResolvedVersions();
|
|
125
|
-
if (!resolvedVersions) {
|
|
126
|
-
return void 0;
|
|
127
|
-
}
|
|
128
|
-
const resolved = [];
|
|
129
|
-
for (const depName of deps) {
|
|
130
|
-
const version = resolvedVersions.get(depName);
|
|
131
|
-
if (version) {
|
|
132
|
-
resolved.push({ name: depName, version });
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (resolved.length === 0) {
|
|
136
|
-
return void 0;
|
|
137
|
-
}
|
|
138
|
-
resolved.sort((a, b) => a.name.localeCompare(b.name));
|
|
139
|
-
const hash = createXxh3Hasher();
|
|
140
|
-
for (const dependency of resolved) {
|
|
141
|
-
hash.update(`${dependency.name}@${dependency.version}`);
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
dependencies: resolved,
|
|
145
|
-
hash: hash.digest()
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Returns the type of lockfile detected, or undefined if none found.
|
|
150
|
-
*/
|
|
151
|
-
get lockfileType() {
|
|
152
|
-
return this.#lockfileType;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Clears the cached lockfile data.
|
|
156
|
-
*/
|
|
157
|
-
clearCache() {
|
|
158
|
-
this.#lockfileCache = void 0;
|
|
159
|
-
this.#lockfileType = void 0;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Parses the workspace lockfile and returns a map of package name → resolved version.
|
|
163
|
-
* Results are cached for subsequent calls.
|
|
164
|
-
*/
|
|
165
|
-
async #getResolvedVersions() {
|
|
166
|
-
if (this.#lockfileCache !== void 0) {
|
|
167
|
-
return this.#lockfileCache.size > 0 ? this.#lockfileCache : void 0;
|
|
168
|
-
}
|
|
169
|
-
const parsers = [
|
|
170
|
-
{ file: "package-lock.json", parser: parseNpmLockfile, type: "npm" },
|
|
171
|
-
{ file: "pnpm-lock.yaml", parser: parsePnpmLockfile, type: "pnpm" },
|
|
172
|
-
{ file: "yarn.lock", parser: parseYarnLockfile, type: "yarn" }
|
|
173
|
-
];
|
|
174
|
-
for (const { file, parser, type } of parsers) {
|
|
175
|
-
try {
|
|
176
|
-
const content = await readFile(join(this.#workspaceRoot, file), "utf8");
|
|
177
|
-
const versions = parser(content);
|
|
178
|
-
this.#lockfileCache = versions;
|
|
179
|
-
this.#lockfileType = type;
|
|
180
|
-
return versions;
|
|
181
|
-
} catch {
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
this.#lockfileCache = /* @__PURE__ */ new Map();
|
|
185
|
-
return void 0;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export { LockfileHasher, extractPackageName, parseNpmLockfile, parsePnpmLockfile, parseYarnLockfile };
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
|
-
|
|
3
|
-
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
4
|
-
|
|
5
|
-
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
|
|
6
|
-
|
|
7
|
-
const __cjs_getBuiltinModule = (module) => {
|
|
8
|
-
// Check if we're in Node.js and version supports getBuiltinModule
|
|
9
|
-
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
|
|
10
|
-
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
|
|
11
|
-
// Node.js 20.16.0+ and 22.3.0+
|
|
12
|
-
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
|
|
13
|
-
return __cjs_getProcess.getBuiltinModule(module);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
// Fallback to createRequire
|
|
17
|
-
return __cjs_require(module);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const {
|
|
21
|
-
execFile
|
|
22
|
-
} = __cjs_getBuiltinModule("node:child_process");
|
|
23
|
-
|
|
24
|
-
const validateGitRef = (ref) => {
|
|
25
|
-
if (!/^[a-zA-Z0-9._\-/~^@{}]+$/.test(ref)) {
|
|
26
|
-
throw new Error(`Invalid git ref: "${ref}". Only alphanumeric characters, dots, dashes, underscores, slashes, tildes, carets, and @ are allowed.`);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
const findProjectForFile = (filePath, projects) => {
|
|
30
|
-
let bestMatch;
|
|
31
|
-
let bestLength = 0;
|
|
32
|
-
for (const [name, config] of Object.entries(projects)) {
|
|
33
|
-
const { root } = config;
|
|
34
|
-
if ((filePath.startsWith(`${root}/`) || filePath === root) && root.length > bestLength) {
|
|
35
|
-
bestMatch = name;
|
|
36
|
-
bestLength = root.length;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return bestMatch;
|
|
40
|
-
};
|
|
41
|
-
const expandAffected = (affectedProjects, projectGraph) => {
|
|
42
|
-
const reverseDependencies = /* @__PURE__ */ new Map();
|
|
43
|
-
for (const [project, dependencies] of Object.entries(projectGraph.dependencies)) {
|
|
44
|
-
for (const dependency of dependencies) {
|
|
45
|
-
let set = reverseDependencies.get(dependency.target);
|
|
46
|
-
if (!set) {
|
|
47
|
-
set = /* @__PURE__ */ new Set();
|
|
48
|
-
reverseDependencies.set(dependency.target, set);
|
|
49
|
-
}
|
|
50
|
-
set.add(project);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
const queue = [...affectedProjects];
|
|
54
|
-
while (queue.length > 0) {
|
|
55
|
-
const project = queue.shift();
|
|
56
|
-
if (project === void 0) {
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const dependents = reverseDependencies.get(project);
|
|
60
|
-
if (dependents) {
|
|
61
|
-
for (const dependent of dependents) {
|
|
62
|
-
if (!affectedProjects.has(dependent)) {
|
|
63
|
-
affectedProjects.add(dependent);
|
|
64
|
-
queue.push(dependent);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const getMergeBase = (workspaceRoot, base, head) => new Promise((resolve, reject) => {
|
|
71
|
-
execFile("git", ["merge-base", base, head], { cwd: workspaceRoot }, (error, stdout) => {
|
|
72
|
-
if (error) {
|
|
73
|
-
reject(error);
|
|
74
|
-
} else {
|
|
75
|
-
resolve(stdout.trim());
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
const getChangedFiles = async (workspaceRoot, base, head) => {
|
|
80
|
-
validateGitRef(base);
|
|
81
|
-
validateGitRef(head);
|
|
82
|
-
try {
|
|
83
|
-
const mergeBase = await getMergeBase(workspaceRoot, base, head);
|
|
84
|
-
return await new Promise((resolve, reject) => {
|
|
85
|
-
execFile("git", ["diff", "--name-only", mergeBase, head], { cwd: workspaceRoot }, (error, stdout) => {
|
|
86
|
-
if (error) {
|
|
87
|
-
reject(error);
|
|
88
|
-
} else {
|
|
89
|
-
resolve(stdout.trim().split("\n").filter(Boolean));
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
} catch {
|
|
94
|
-
return new Promise((resolve, reject) => {
|
|
95
|
-
execFile("git", ["diff", "--name-only", `${base}...${head}`], { cwd: workspaceRoot }, (error, stdout) => {
|
|
96
|
-
if (error) {
|
|
97
|
-
reject(error);
|
|
98
|
-
} else {
|
|
99
|
-
resolve(stdout.trim().split("\n").filter(Boolean));
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
const getAffectedProjects = async (options) => {
|
|
106
|
-
const { base = "main", head = "HEAD", projectGraph, projects, workspaceRoot } = options;
|
|
107
|
-
const changedFiles = await getChangedFiles(workspaceRoot, base, head);
|
|
108
|
-
const changedProjects = /* @__PURE__ */ new Set();
|
|
109
|
-
for (const file of changedFiles) {
|
|
110
|
-
const project = findProjectForFile(file, projects);
|
|
111
|
-
if (project) {
|
|
112
|
-
changedProjects.add(project);
|
|
113
|
-
} else {
|
|
114
|
-
return {
|
|
115
|
-
affectedProjects: Object.keys(projects),
|
|
116
|
-
changedFiles,
|
|
117
|
-
changedProjects: Object.keys(projects)
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
const affectedProjects = new Set(changedProjects);
|
|
122
|
-
expandAffected(affectedProjects, projectGraph);
|
|
123
|
-
return {
|
|
124
|
-
affectedProjects: [...affectedProjects],
|
|
125
|
-
changedFiles,
|
|
126
|
-
changedProjects: [...changedProjects]
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
const filterAffectedTasks = (taskIds, affectedProjects) => taskIds.filter((taskId) => {
|
|
130
|
-
const parts = taskId.split(":");
|
|
131
|
-
const project = parts[0];
|
|
132
|
-
return affectedProjects.has(project);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
export { filterAffectedTasks, getAffectedProjects, getChangedFiles };
|