Skip to content

Commit 654450d

Browse files
committed
[FEATURE] AbstractBuilder: Allow adding custom tasks for types that have no standard tasks
Types like "module" do not define any standard tasks. Hence custom tasks can't reference anything in their "beforeTask" and "afterTask" configuration. With this change, the first custom task that a project of such type defines can omit the before- or afterTask configuration and will be automatically added as the first tasks. Resolves https://github.com/SAP/ui5-builder/issues/368
1 parent 0b47505 commit 654450d

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

lib/types/AbstractBuilder.js

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ class AbstractBuilder {
7272
throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` +
7373
`defines both "beforeTask" and "afterTask" parameters. Only one must be defined.`);
7474
}
75-
if (!taskDef.beforeTask && !taskDef.afterTask) {
75+
if (this.taskExecutionOrder.length && !taskDef.beforeTask && !taskDef.afterTask) {
76+
// Iff there are tasks configured, beforeTask or afterTask must be given
7677
throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` +
7778
`defines neither a "beforeTask" nor an "afterTask" parameter. One must be defined.`);
7879
}
@@ -115,17 +116,23 @@ class AbstractBuilder {
115116

116117
this.tasks[newTaskName] = execTask;
117118

118-
const refTaskName = taskDef.beforeTask || taskDef.afterTask;
119-
let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName);
120-
if (refTaskIdx === -1) {
121-
throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` +
122-
`to be scheduled for project ${project.metadata.name}`);
123-
}
124-
if (taskDef.afterTask) {
125-
// Insert after index of referenced task
126-
refTaskIdx++;
119+
if (this.taskExecutionOrder.length) {
120+
// There is at least one task configured. Use before- and afterTask to add the custom task
121+
const refTaskName = taskDef.beforeTask || taskDef.afterTask;
122+
let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName);
123+
if (refTaskIdx === -1) {
124+
throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` +
125+
`to be scheduled for project ${project.metadata.name}`);
126+
}
127+
if (taskDef.afterTask) {
128+
// Insert after index of referenced task
129+
refTaskIdx++;
130+
}
131+
this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName);
132+
} else {
133+
// There is no task configured so far. Just add the custom task
134+
this.taskExecutionOrder.push(newTaskName);
127135
}
128-
this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName);
129136
}
130137
}
131138

test/lib/types/AbstractBuilder.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ class CustomBuilder extends AbstractBuilder {
7777
}
7878
}
7979

80+
class EmptyBuilder extends AbstractBuilder {
81+
constructor({project, resourceCollections}) {
82+
super({parentLogger, project, resourceCollections});
83+
}
84+
85+
addStandardTasks({resourceCollections, project}) {
86+
// None - like the ModuleBuilder
87+
}
88+
}
89+
8090
test("Instantiation with standard tasks only", (t) => {
8191
const project = clone(applicationBTree);
8292

@@ -178,6 +188,46 @@ test.serial("Instantiation with custom task", (t) => {
178188
"Order of tasks is correct");
179189
});
180190

191+
test.serial("Instantiation of empty builder with custom tasks", (t) => {
192+
const customTask = function() {};
193+
sinon.stub(taskRepository, "getTask").returns(customTask);
194+
195+
const project = clone(applicationBTree);
196+
project.builder = {
197+
customTasks: [{
198+
name: "myTask"
199+
}, {
200+
name: "myTask2",
201+
beforeTask: "myTask"
202+
}]
203+
};
204+
const customBuilder = new EmptyBuilder({project});
205+
t.truthy(customBuilder.tasks["myTask"], "Custom task has been added to task array");
206+
t.truthy(customBuilder.tasks["myTask2"], "Custom task 2 has been added to task array");
207+
t.deepEqual(customBuilder.taskExecutionOrder,
208+
["myTask2", "myTask"],
209+
"Order of tasks is correct");
210+
});
211+
212+
test.serial("Instantiation of empty builder with 2nd custom tasks defining neither beforeTask nor afterTask", (t) => {
213+
const customTask = function() {};
214+
sinon.stub(taskRepository, "getTask").returns(customTask);
215+
216+
const project = clone(applicationBTree);
217+
project.builder = {
218+
customTasks: [{
219+
name: "myTask"
220+
}, {
221+
name: "myTask2" // should define before- or afterTask
222+
}]
223+
};
224+
const error = t.throws(() => {
225+
new EmptyBuilder({project});
226+
}, Error);
227+
t.deepEqual(error.message, `Custom task definition myTask2 of project application.b defines ` +
228+
`neither a "beforeTask" nor an "afterTask" parameter. One must be defined.`, "Correct exception thrown");
229+
});
230+
181231
test.serial("Instantiation with custom task defined three times", (t) => {
182232
const customTask = function() {};
183233
sinon.stub(taskRepository, "getTask").returns(customTask);

0 commit comments

Comments
 (0)