Skip to content

Commit 9e8f574

Browse files
committed
refactor(project): API refactoring
1 parent 73b1294 commit 9e8f574

File tree

14 files changed

+759
-367
lines changed

14 files changed

+759
-367
lines changed

packages/project/lib/build/ProjectBuilder.js

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import composeProjectList from "./helpers/composeProjectList.js";
55
import BuildContext from "./helpers/BuildContext.js";
66
import prettyHrtime from "pretty-hrtime";
77
import OutputStyleEnum from "./helpers/ProjectBuilderOutputStyle.js";
8+
import createBuildManifest from "./helpers/createBuildManifest.js";
89

910
/**
1011
* @public
@@ -140,7 +141,6 @@ class ProjectBuilder {
140141
destPath, cleanDest = false,
141142
includedDependencies = [], excludedDependencies = [],
142143
dependencyIncludes,
143-
cacheDir,
144144
watch,
145145
}) {
146146
if (!destPath && !watch) {
@@ -179,7 +179,7 @@ class ProjectBuilder {
179179
}
180180
}
181181

182-
const projectBuildContexts = await this._createRequiredBuildContexts(requestedProjects, cacheDir);
182+
const projectBuildContexts = await this._createRequiredBuildContexts(requestedProjects);
183183
const cleanupSigHooks = this._registerCleanupSigHooks();
184184
let fsTarget;
185185
if (destPath) {
@@ -274,9 +274,13 @@ class ProjectBuilder {
274274
pWrites.push(this._writeResults(projectBuildContext, fsTarget));
275275
}
276276

277-
if (cacheDir && !alreadyBuilt.includes(projectName)) {
278-
this.#log.verbose(`Serializing cache...`);
279-
pWrites.push(projectBuildContext.getBuildCache().serializeToDisk());
277+
if (!alreadyBuilt.includes(projectName)) {
278+
this.#log.verbose(`Saving cache...`);
279+
const metadata = await createBuildManifest(
280+
project,
281+
this._graph, this._buildContext.getBuildConfig(), this._buildContext.getTaskRepository(),
282+
projectBuildContext.getBuildSignature());
283+
pWrites.push(projectBuildContext.getBuildCache().saveToDisk(metadata));
280284
}
281285
}
282286
await Promise.all(pWrites);
@@ -294,7 +298,7 @@ class ProjectBuilder {
294298
return projectBuildContext.getProject();
295299
});
296300
const watchHandler = this._buildContext.initWatchHandler(relevantProjects, async () => {
297-
await this.#update(projectBuildContexts, requestedProjects, fsTarget, cacheDir);
301+
await this.#update(projectBuildContexts, requestedProjects, fsTarget);
298302
});
299303
return watchHandler;
300304

@@ -315,7 +319,7 @@ class ProjectBuilder {
315319
}
316320
}
317321

318-
async #update(projectBuildContexts, requestedProjects, fsTarget, cacheDir) {
322+
async #update(projectBuildContexts, requestedProjects, fsTarget) {
319323
const queue = [];
320324
await this._graph.traverseDepthFirst(async ({project}) => {
321325
const projectName = project.getName();
@@ -362,17 +366,14 @@ class ProjectBuilder {
362366
pWrites.push(this._writeResults(projectBuildContext, fsTarget));
363367
}
364368

365-
if (cacheDir) {
366-
this.#log.verbose(`Updating cache...`);
367-
// TODO: Only serialize if cache has changed
368-
// TODO: Serialize lazily, or based on memory pressure
369-
pWrites.push(projectBuildContext.getBuildCache().serializeToDisk());
370-
}
369+
this.#log.verbose(`Updating cache...`);
370+
// TODO: Serialize lazily, or based on memory pressure
371+
pWrites.push(projectBuildContext.getBuildCache().saveToDisk());
371372
}
372373
await Promise.all(pWrites);
373374
}
374375

375-
async _createRequiredBuildContexts(requestedProjects, cacheDir) {
376+
async _createRequiredBuildContexts(requestedProjects) {
376377
const requiredProjects = new Set(this._graph.getProjectNames().filter((projectName) => {
377378
return requestedProjects.includes(projectName);
378379
}));
@@ -382,8 +383,7 @@ class ProjectBuilder {
382383
for (const projectName of requiredProjects) {
383384
this.#log.verbose(`Creating build context for project ${projectName}...`);
384385
const projectBuildContext = await this._buildContext.createProjectContext({
385-
project: this._graph.getProject(projectName),
386-
cacheDir,
386+
project: this._graph.getProject(projectName)
387387
});
388388

389389
projectBuildContexts.set(projectName, projectBuildContext);
@@ -488,12 +488,9 @@ class ProjectBuilder {
488488

489489
if (createBuildManifest) {
490490
// Create and write a build manifest metadata file
491-
const {
492-
default: createBuildManifest
493-
} = await import("./helpers/createBuildManifest.js");
494491
const metadata = await createBuildManifest(
495492
project, this._graph, buildConfig, this._buildContext.getTaskRepository(),
496-
projectBuildContext.getBuildCache());
493+
projectBuildContext.getBuildSignature());
497494
await target.write(resourceFactory.createResource({
498495
path: `/.ui5/build-manifest.json`,
499496
string: JSON.stringify(metadata, null, "\t")

packages/project/lib/build/TaskRunner.js

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ class TaskRunner {
1616
* @param {object} parameters.graph
1717
* @param {object} parameters.project
1818
* @param {@ui5/logger/loggers/ProjectBuild} parameters.log Logger to use
19+
* @param {@ui5/project/build/cache/ProjectBuildCache} parameters.buildCache Build cache instance
1920
* @param {@ui5/project/build/helpers/TaskUtil} parameters.taskUtil TaskUtil instance
2021
* @param {@ui5/builder/tasks/taskRepository} parameters.taskRepository Task repository
2122
* @param {@ui5/project/build/ProjectBuilder~BuildConfiguration} parameters.buildConfig
2223
* Build configuration
2324
*/
24-
constructor({graph, project, log, cache, taskUtil, taskRepository, buildConfig}) {
25-
if (!graph || !project || !log || !cache || !taskUtil || !taskRepository || !buildConfig) {
25+
constructor({graph, project, log, buildCache, taskUtil, taskRepository, buildConfig}) {
26+
if (!graph || !project || !log || !buildCache || !taskUtil || !taskRepository || !buildConfig) {
2627
throw new Error("TaskRunner: One or more mandatory parameters not provided");
2728
}
2829
this._project = project;
@@ -31,7 +32,7 @@ class TaskRunner {
3132
this._taskRepository = taskRepository;
3233
this._buildConfig = buildConfig;
3334
this._log = log;
34-
this._cache = cache;
35+
this._buildCache = buildCache;
3536

3637
this._directDependencies = new Set(this._taskUtil.getDependencies());
3738
}
@@ -192,38 +193,35 @@ class TaskRunner {
192193
options.projectNamespace = this._project.getNamespace();
193194

194195
// TODO: Apply cache and stage handling for custom tasks as well
195-
this._project.useStage(taskName);
196-
197-
// Check whether any of the relevant resources have changed
198-
if (this._cache.hasCacheForTask(taskName)) {
199-
await this._cache.validateChangedProjectResources(
200-
taskName, this._project.getReader(), this._allDependenciesReader);
201-
if (this._cache.hasValidCacheForTask(taskName)) {
202-
this._log.skipTask(taskName);
203-
return;
204-
}
196+
const requiresRun = await this._buildCache.prepareTaskExecution(taskName, this._allDependenciesReader);
197+
if (!requiresRun) {
198+
this._log.skipTask(taskName);
199+
return;
205200
}
201+
202+
const expectedOutput = new Set(); // TODO: Determine expected output properly
203+
206204
this._log.info(
207205
`Executing task ${taskName} for project ${this._project.getName()}`);
208206
const workspace = createTracker(this._project.getWorkspace());
209207
const params = {
210208
workspace,
211209
taskUtil: this._taskUtil,
212-
options,
213-
buildCache: {
210+
cacheUtil: {
214211
// TODO: Create a proper interface for this
215212
hasCache: () => {
216-
return this._cache.hasCacheForTask(taskName);
213+
return this._buildCache.hasTaskCache(taskName);
217214
},
218215
getChangedProjectResourcePaths: () => {
219-
return this._cache.getChangedProjectResourcePaths(taskName);
216+
return this._buildCache.getChangedProjectResourcePaths(taskName);
220217
},
221218
getChangedDependencyResourcePaths: () => {
222-
return this._cache.getChangedDependencyResourcePaths(taskName);
219+
return this._buildCache.getChangedDependencyResourcePaths(taskName);
223220
},
224-
}
221+
},
222+
options,
225223
};
226-
// const invalidatedResources = this._cache.getDepsOfInvalidatedResourcesForTask(taskName);
224+
// const invalidatedResources = this._buildCache.getDepsOfInvalidatedResourcesForTask(taskName);
227225
// if (invalidatedResources) {
228226
// params.invalidatedResources = invalidatedResources;
229227
// }
@@ -246,7 +244,7 @@ class TaskRunner {
246244
`Task ${taskName} finished in ${Math.round((performance.now() - this._taskStart))} ms`);
247245
}
248246
this._log.endTask(taskName);
249-
await this._cache.updateTaskResult(taskName, workspace, dependencies);
247+
await this._buildCache.recordTaskResult(taskName, expectedOutput, workspace, dependencies);
250248
};
251249
}
252250
this._tasks[taskName] = {
@@ -319,6 +317,8 @@ class TaskRunner {
319317

320318
// Tasks can provide an optional callback to tell build process which dependencies they require
321319
const requiredDependenciesCallback = await task.getRequiredDependenciesCallback();
320+
const getBuildSignatureCallback = await task.getBuildSignatureCallback();
321+
const getExpectedOutputCallback = await task.getExpectedOutputCallback();
322322
const specVersion = task.getSpecVersion();
323323
let requiredDependencies;
324324

@@ -390,6 +390,8 @@ class TaskRunner {
390390
taskName: newTaskName,
391391
taskConfiguration: taskDef.configuration,
392392
provideDependenciesReader,
393+
getBuildSignatureCallback,
394+
getExpectedOutputCallback,
393395
getDependenciesReader: () => {
394396
// Create the dependencies reader on-demand
395397
return this._createDependenciesReader(requiredDependencies);
@@ -488,7 +490,7 @@ class TaskRunner {
488490
* @returns {Promise} Resolves when task has finished
489491
*/
490492
async _executeTask(taskName, taskFunction, taskParams) {
491-
if (this._cache.hasValidCacheForTask(taskName)) {
493+
if (this._buildCache.isTaskCacheValid(taskName)) {
492494
// Immediately skip task if cache is valid
493495
// Continue if cache is (potentially) invalid, in which case taskFunction will
494496
// validate the cache thoroughly

packages/project/lib/build/cache/BuildTaskCache.js

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import micromatch from "micromatch";
22
import {getLogger} from "@ui5/logger";
3+
import {createResourceIndex} from "./utils.js";
34
const log = getLogger("build:cache:BuildTaskCache");
45

56
/**
@@ -37,23 +38,23 @@ function unionObject(target, obj) {
3738
}
3839
}
3940

40-
async function createMetadataForResources(resourceMap) {
41-
const metadata = Object.create(null);
42-
await Promise.all(Object.keys(resourceMap).map(async (resourcePath) => {
43-
const resource = resourceMap[resourcePath];
44-
if (resource.hash) {
45-
// Metadata object
46-
metadata[resourcePath] = resource;
47-
return;
48-
}
49-
// Resource instance
50-
metadata[resourcePath] = {
51-
hash: await resource.getHash(),
52-
lastModified: resource.getStatInfo()?.mtimeMs,
53-
};
54-
}));
55-
return metadata;
56-
}
41+
// async function createMetadataForResources(resourceMap) {
42+
// const metadata = Object.create(null);
43+
// await Promise.all(Object.keys(resourceMap).map(async (resourcePath) => {
44+
// const resource = resourceMap[resourcePath];
45+
// if (resource.hash) {
46+
// // Metadata object
47+
// metadata[resourcePath] = resource;
48+
// return;
49+
// }
50+
// // Resource instance
51+
// metadata[resourcePath] = {
52+
// integrity: await resource.getIntegrity(),
53+
// lastModified: resource.getLastModified(),
54+
// };
55+
// }));
56+
// return metadata;
57+
// }
5758

5859
/**
5960
* Manages the build cache for a single task
@@ -89,7 +90,7 @@ export default class BuildTaskCache {
8990
* @param {string} taskName - Name of the task
9091
* @param {TaskCacheMetadata} metadata - Task cache metadata
9192
*/
92-
constructor(projectName, taskName, {projectRequests, dependencyRequests, resourcesRead, resourcesWritten}) {
93+
constructor(projectName, taskName, {projectRequests, dependencyRequests, input, output}) {
9394
this.#projectName = projectName;
9495
this.#taskName = taskName;
9596

@@ -102,8 +103,8 @@ export default class BuildTaskCache {
102103
pathsRead: [],
103104
patterns: [],
104105
};
105-
this.#resourcesRead = resourcesRead ?? Object.create(null);
106-
this.#resourcesWritten = resourcesWritten ?? Object.create(null);
106+
this.#resourcesRead = input ?? Object.create(null);
107+
this.#resourcesWritten = output ?? Object.create(null);
107108
}
108109

109110
// ===== METADATA ACCESS =====
@@ -122,8 +123,8 @@ export default class BuildTaskCache {
122123
*
123124
* @param {RequestMetadata} projectRequests - Project resource requests
124125
* @param {RequestMetadata} [dependencyRequests] - Dependency resource requests
125-
* @param {Object.<string, object>} resourcesRead - Resources read by task
126-
* @param {Object.<string, object>} resourcesWritten - Resources written by task
126+
* @param {Object<string, object>} resourcesRead - Resources read by task
127+
* @param {Object<string, object>} resourcesWritten - Resources written by task
127128
* @returns {void}
128129
*/
129130
updateMetadata(projectRequests, dependencyRequests, resourcesRead, resourcesWritten) {
@@ -144,15 +145,12 @@ export default class BuildTaskCache {
144145
*
145146
* @returns {Promise<object>} Serialized task cache data
146147
*/
147-
async toJSON() {
148+
async createMetadata() {
148149
return {
149-
taskName: this.#taskName,
150-
resourceMetadata: {
151-
projectRequests: this.#projectRequests,
152-
dependencyRequests: this.#dependencyRequests,
153-
resourcesRead: await createMetadataForResources(this.#resourcesRead),
154-
resourcesWritten: await createMetadataForResources(this.#resourcesWritten)
155-
}
150+
projectRequests: this.#projectRequests,
151+
dependencyRequests: this.#dependencyRequests,
152+
taskIndex: await createResourceIndex(Object.values(this.#resourcesRead)),
153+
// resourcesWritten: await createMetadataForResources(this.#resourcesWritten)
156154
};
157155
}
158156

0 commit comments

Comments
 (0)