Skip to content

Commit

Permalink
[FEATURE] TaskUtil: Add 'force' flag to cleanup task callback (#677)
Browse files Browse the repository at this point in the history
JIRA: CPOUI5FOUNDATION-751
\@ui5/builder PR that depends on this change:
SAP/ui5-builder#953

When cleaning up after tasks run, it can happen in couple cases:
- When the project is build
- When there's a SIGTERM signal
- (Maybe) on some error

We need to be able to distinguish between those cases as in some places
we rely on graceful termination and cleanup. Especially, after the
project has been build successfully. On the other hand when the user
presses `Ctrl + C`, for example, we need to enforce the termination.

This cahnge provides this context.

---------

Co-authored-by: Merlin Beutlberger <[email protected]>
Co-authored-by: Günter Klatt <[email protected]>
  • Loading branch information
3 people authored Nov 15, 2023
1 parent 7824bef commit a0a21b7
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 10 deletions.
7 changes: 4 additions & 3 deletions lib/build/ProjectBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,18 @@ class ProjectBuilder {
}));
}

async _executeCleanupTasks() {
async _executeCleanupTasks(force) {
this.#log.info("Executing cleanup tasks...");
await this._buildContext.executeCleanupTasks();

await this._buildContext.executeCleanupTasks(force);
}

_registerCleanupSigHooks() {
const that = this;
function createListener(exitCode) {
return function() {
// Asynchronously cleanup resources, then exit
that._executeCleanupTasks().then(() => {
that._executeCleanupTasks(true).then(() => {
process.exit(exitCode);
});
};
Expand Down
4 changes: 2 additions & 2 deletions lib/build/helpers/BuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ class BuildContext {
return projectBuildContext;
}

async executeCleanupTasks() {
async executeCleanupTasks(force = false) {
await Promise.all(this._projectBuildContexts.map((ctx) => {
return ctx.executeCleanupTasks();
return ctx.executeCleanupTasks(force);
}));
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/build/helpers/ProjectBuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class ProjectBuildContext {
this._queues.cleanup.push(callback);
}

async executeCleanupTasks() {
async executeCleanupTasks(force) {
await Promise.all(this._queues.cleanup.map((callback) => {
return callback();
return callback(force);
}));
}

Expand Down
13 changes: 12 additions & 1 deletion lib/build/helpers/TaskUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ class TaskUtil {
return this._projectBuildContext.getOption(key);
}

/**
* Callback that is executed once the build has finished
*
* @public
* @callback @ui5/project/build/helpers/TaskUtil~cleanupTaskCallback
* @param {boolean} force Whether the cleanup callback should
* gracefully wait for certain jobs to be completed (<code>false</code>)
* or enforce immediate termination (<code>true</code>)
*/

/**
* Register a function that must be executed once the build is finished. This can be used to, for example,
* clean up files temporarily created on the file system. If the callback returns a Promise, it will be waited for.
Expand All @@ -172,7 +182,8 @@ class TaskUtil {
* This method is only available to custom task extensions defining
* <b>Specification Version 2.2 and above</b>.
*
* @param {Function} callback Callback to register. If it returns a Promise, it will be waited for
* @param {@ui5/project/build/helpers/TaskUtil~cleanupTaskCallback} callback Callback to
* register; it will be waited for if it returns a Promise
* @public
*/
registerCleanupTask(callback) {
Expand Down
12 changes: 10 additions & 2 deletions test/lib/build/ProjectBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -727,8 +727,16 @@ test("_executeCleanupTasks", async (t) => {
const executeCleanupTasksStub = sinon.stub(builder._buildContext, "executeCleanupTasks");
await builder._executeCleanupTasks();
t.is(executeCleanupTasksStub.callCount, 1, "BuildContext#executeCleanupTasks got called once");
t.deepEqual(executeCleanupTasksStub.getCall(0).args, [],
"BuildContext#executeCleanupTasks got called with no arguments");
t.deepEqual(executeCleanupTasksStub.getCall(0).args, [undefined],
"BuildContext#executeCleanupTasks got called with correct arguments");

// reset stub
executeCleanupTasksStub.reset();
// Call with enforcement flag
await builder._executeCleanupTasks(true);
t.is(executeCleanupTasksStub.callCount, 1, "BuildContext#executeCleanupTasks got called once");
t.deepEqual(executeCleanupTasksStub.getCall(0).args, [true],
"BuildContext#executeCleanupTasks got called with correct arguments");
});

test("instantiate new logger for every ProjectBuilder", async (t) => {
Expand Down
11 changes: 11 additions & 0 deletions test/lib/build/helpers/BuildContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,15 @@ test("executeCleanupTasks", async (t) => {

t.is(executeCleanupTasks.callCount, 2,
"Project context executeCleanupTasks got called twice");
t.is(executeCleanupTasks.getCall(0).firstArg, false,
"Project context executeCleanupTasks got called with expected arguments");


executeCleanupTasks.reset();
await buildContext.executeCleanupTasks(true);

t.is(executeCleanupTasks.callCount, 2,
"Project context executeCleanupTasks got called twice");
t.is(executeCleanupTasks.getCall(0).firstArg, true,
"Project context executeCleanupTasks got called with expected arguments");
});

0 comments on commit a0a21b7

Please sign in to comment.