diff --git a/lib/types/AbstractBuilder.js b/lib/types/AbstractBuilder.js index b7536c003..6361b1135 100644 --- a/lib/types/AbstractBuilder.js +++ b/lib/types/AbstractBuilder.js @@ -72,7 +72,8 @@ class AbstractBuilder { throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` + `defines both "beforeTask" and "afterTask" parameters. Only one must be defined.`); } - if (!taskDef.beforeTask && !taskDef.afterTask) { + if (this.taskExecutionOrder.length && !taskDef.beforeTask && !taskDef.afterTask) { + // Iff there are tasks configured, beforeTask or afterTask must be given throw new Error(`Custom task definition ${taskDef.name} of project ${project.metadata.name} ` + `defines neither a "beforeTask" nor an "afterTask" parameter. One must be defined.`); } @@ -115,17 +116,23 @@ class AbstractBuilder { this.tasks[newTaskName] = execTask; - const refTaskName = taskDef.beforeTask || taskDef.afterTask; - let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName); - if (refTaskIdx === -1) { - throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` + - `to be scheduled for project ${project.metadata.name}`); - } - if (taskDef.afterTask) { - // Insert after index of referenced task - refTaskIdx++; + if (this.taskExecutionOrder.length) { + // There is at least one task configured. Use before- and afterTask to add the custom task + const refTaskName = taskDef.beforeTask || taskDef.afterTask; + let refTaskIdx = this.taskExecutionOrder.indexOf(refTaskName); + if (refTaskIdx === -1) { + throw new Error(`Could not find task ${refTaskName}, referenced by custom task ${newTaskName}, ` + + `to be scheduled for project ${project.metadata.name}`); + } + if (taskDef.afterTask) { + // Insert after index of referenced task + refTaskIdx++; + } + this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName); + } else { + // There is no task configured so far. Just add the custom task + this.taskExecutionOrder.push(newTaskName); } - this.taskExecutionOrder.splice(refTaskIdx, 0, newTaskName); } } diff --git a/test/lib/types/AbstractBuilder.js b/test/lib/types/AbstractBuilder.js index 971a78b9a..c656ca89c 100644 --- a/test/lib/types/AbstractBuilder.js +++ b/test/lib/types/AbstractBuilder.js @@ -77,6 +77,16 @@ class CustomBuilder extends AbstractBuilder { } } +class EmptyBuilder extends AbstractBuilder { + constructor({project, resourceCollections}) { + super({parentLogger, project, resourceCollections}); + } + + addStandardTasks({resourceCollections, project}) { + // None - like the ModuleBuilder + } +} + test("Instantiation with standard tasks only", (t) => { const project = clone(applicationBTree); @@ -178,6 +188,46 @@ test.serial("Instantiation with custom task", (t) => { "Order of tasks is correct"); }); +test.serial("Instantiation of empty builder with custom tasks", (t) => { + const customTask = function() {}; + sinon.stub(taskRepository, "getTask").returns(customTask); + + const project = clone(applicationBTree); + project.builder = { + customTasks: [{ + name: "myTask" + }, { + name: "myTask2", + beforeTask: "myTask" + }] + }; + const customBuilder = new EmptyBuilder({project}); + t.truthy(customBuilder.tasks["myTask"], "Custom task has been added to task array"); + t.truthy(customBuilder.tasks["myTask2"], "Custom task 2 has been added to task array"); + t.deepEqual(customBuilder.taskExecutionOrder, + ["myTask2", "myTask"], + "Order of tasks is correct"); +}); + +test.serial("Instantiation of empty builder with 2nd custom tasks defining neither beforeTask nor afterTask", (t) => { + const customTask = function() {}; + sinon.stub(taskRepository, "getTask").returns(customTask); + + const project = clone(applicationBTree); + project.builder = { + customTasks: [{ + name: "myTask" + }, { + name: "myTask2" // should define before- or afterTask + }] + }; + const error = t.throws(() => { + new EmptyBuilder({project}); + }, Error); + t.deepEqual(error.message, `Custom task definition myTask2 of project application.b defines ` + + `neither a "beforeTask" nor an "afterTask" parameter. One must be defined.`, "Correct exception thrown"); +}); + test.serial("Instantiation with custom task defined three times", (t) => { const customTask = function() {}; sinon.stub(taskRepository, "getTask").returns(customTask);