diff --git a/lib/build/TaskRunner.js b/lib/build/TaskRunner.js index cd9a251e2..c4782c6f7 100644 --- a/lib/build/TaskRunner.js +++ b/lib/build/TaskRunner.js @@ -111,7 +111,9 @@ class TaskRunner { // This would require a more robust contract to identify task executions // (e.g. via an 'id' that can be assigned to a specific execution in the configuration). const taskWithoutSuffixCounter = taskName.replace(/--\d+$/, ""); - return tasksToRun.includes(taskWithoutSuffixCounter); + return tasksToRun.includes(taskWithoutSuffixCounter) && + // Task can be explicitly excluded by making its taskFunction = null + this._tasks[taskName].task !== null; }); this._log.setTasks(allTasks); @@ -176,25 +178,31 @@ class TaskRunner { `It has already been scheduled for execution`); } - const task = async (log) => { - options.projectName = this._project.getName(); - options.projectNamespace = this._project.getNamespace(); + let task; + if (taskFunction === null) { + this._log.verbose(`Task ${taskName} is set to be explicitly skipped in definitions.`); + task = null; + } else { + task = async (log) => { + options.projectName = this._project.getName(); + options.projectNamespace = this._project.getNamespace(); + + const params = { + workspace: this._project.getWorkspace(), + taskUtil: this._taskUtil, + options + }; + + if (requiresDependencies) { + params.dependencies = this._allDependenciesReader; + } - const params = { - workspace: this._project.getWorkspace(), - taskUtil: this._taskUtil, - options + if (!taskFunction) { + taskFunction = (await this._taskRepository.getTask(taskName)).task; + } + return taskFunction(params); }; - - if (requiresDependencies) { - params.dependencies = this._allDependenciesReader; - } - - if (!taskFunction) { - taskFunction = (await this._taskRepository.getTask(taskName)).task; - } - return taskFunction(params); - }; + } this._tasks[taskName] = { task, requiredDependencies: requiresDependencies ? this._directDependencies : new Set() diff --git a/lib/build/definitions/application.js b/lib/build/definitions/application.js index 5a21557fc..cb55a2a06 100644 --- a/lib/build/definitions/application.js +++ b/lib/build/definitions/application.js @@ -100,6 +100,11 @@ export default function({project, taskUtil, getTask}) { }, Promise.resolve()); } }); + } else { + // No bundles defined. Just set task so that it can be referenced by custom tasks + tasks.set("generateBundle", { + taskFunction: null + }); } tasks.set("generateVersionInfo", { diff --git a/lib/build/definitions/library.js b/lib/build/definitions/library.js index 7ff35d01d..2e8808498 100644 --- a/lib/build/definitions/library.js +++ b/lib/build/definitions/library.js @@ -103,6 +103,8 @@ export default function({project, taskUtil, getTask}) { skipBundles: existingBundleDefinitionNames } }); + } else { + tasks.set("generateComponentPreload", {taskFunction: null}); } tasks.set("generateLibraryPreload", { @@ -133,6 +135,8 @@ export default function({project, taskUtil, getTask}) { }, Promise.resolve()); } }); + } else { + tasks.set("generateBundle", {taskFunction: null}); } tasks.set("buildThemes", { @@ -153,6 +157,8 @@ export default function({project, taskUtil, getTask}) { version: project.getVersion() } }); + } else { + tasks.set("generateThemeDesignerResources", {taskFunction: null}); } tasks.set("generateResourcesJson", { diff --git a/lib/build/definitions/themeLibrary.js b/lib/build/definitions/themeLibrary.js index e1cbc7703..2acf03927 100644 --- a/lib/build/definitions/themeLibrary.js +++ b/lib/build/definitions/themeLibrary.js @@ -42,6 +42,8 @@ export default function({project, taskUtil, getTask}) { version: project.getVersion() } }); + } else { + tasks.set("generateThemeDesignerResources", {taskFunction: null}); } tasks.set("generateResourcesJson", {requiresDependencies: true}); diff --git a/test/lib/build/TaskRunner.js b/test/lib/build/TaskRunner.js index e215957a9..e27aeffa7 100644 --- a/test/lib/build/TaskRunner.js +++ b/test/lib/build/TaskRunner.js @@ -246,6 +246,7 @@ test("_initTasks: Project of type 'library'", async (t) => { "generateLibraryPreload", "generateBundle", "buildThemes", + "generateThemeDesignerResources", "generateResourcesJson" ], "Correct standard tasks"); }); @@ -290,6 +291,7 @@ test("_initTasks: Project of type 'theme-library'", async (t) => { "replaceCopyright", "replaceVersion", "buildThemes", + "generateThemeDesignerResources", "generateResourcesJson" ], "Correct standard tasks"); }); @@ -1248,6 +1250,45 @@ test("Custom task: requiredDependenciesCallback returns Array instead of Set", a }, "Threw with expected error message"); }); +test("Custom task attached to a disabled task", async (t) => { + const {graph, taskUtil, taskRepository, TaskRunner, projectBuildLogger, sinon, customTask} = t.context; + + const project = getMockProject("application"); + const customTaskFnStub = sinon.stub(); + project.getBundles = emptyarray; + project.getCustomTasks = () => [ + {name: "myTask", afterTask: "generateBundle", configuration: "dog"} + ]; + + taskRepository.getTask = sinon.stub().returns({task: sinon.stub()}); + customTask.getTask = () => customTaskFnStub; + + const taskRunner = new TaskRunner({ + project, graph, taskUtil, taskRepository, log: projectBuildLogger, buildConfig + }); + + await taskRunner.runTasks(); + + const setTasksArgs = projectBuildLogger.setTasks.firstCall.args[0]; + t.true(setTasksArgs.includes("myTask"), "Custom task 'myTask' is queried"); + t.is(customTaskFnStub.calledOnce, true, "Custom task 'myTask' is executed"); + t.false(setTasksArgs.includes("generateBundle"), + "generateBundle standard task is excluded from the execution list"); + + t.deepEqual( + setTasksArgs, + [ + "escapeNonAsciiCharacters", + "replaceCopyright", + "replaceVersion", + "minify", + "generateFlexChangesBundle", + "generateComponentPreload", + "myTask", + ], + "Correct tasks execution"); +}); + test.serial("_addTask", async (t) => { const {sinon, graph, taskUtil, taskRepository, TaskRunner, projectBuildLogger} = t.context; diff --git a/test/lib/build/definitions/application.js b/test/lib/build/definitions/application.js index 4fe95a23a..d78f9313d 100644 --- a/test/lib/build/definitions/application.js +++ b/test/lib/build/definitions/application.js @@ -83,6 +83,9 @@ test("Standard build", (t) => { requiresDependencies: true }, transformBootstrapHtml: {}, + generateBundle: { + taskFunction: null + }, generateVersionInfo: { requiresDependencies: true, options: { @@ -159,6 +162,9 @@ test("Standard build with legacy spec version", (t) => { requiresDependencies: true }, transformBootstrapHtml: {}, + generateBundle: { + taskFunction: null + }, generateVersionInfo: { requiresDependencies: true, options: { diff --git a/test/lib/build/definitions/library.js b/test/lib/build/definitions/library.js index 040f1caa8..510ecb548 100644 --- a/test/lib/build/definitions/library.js +++ b/test/lib/build/definitions/library.js @@ -114,6 +114,15 @@ test("Standard build", async (t) => { cssVariables: undefined } }, + generateBundle: { + taskFunction: null + }, + generateComponentPreload: { + taskFunction: null + }, + generateThemeDesignerResources: { + taskFunction: null + }, generateResourcesJson: { requiresDependencies: true } @@ -241,6 +250,15 @@ test("Standard build with legacy spec version", (t) => { cssVariables: undefined } }, + generateBundle: { + taskFunction: null + }, + generateComponentPreload: { + taskFunction: null + }, + generateThemeDesignerResources: { + taskFunction: null + }, generateResourcesJson: { requiresDependencies: true } @@ -361,6 +379,12 @@ test("Custom bundles", async (t) => { cssVariables: undefined } }, + generateComponentPreload: { + taskFunction: null + }, + generateThemeDesignerResources: { + taskFunction: null + }, generateResourcesJson: { requiresDependencies: true } @@ -606,3 +630,89 @@ test("buildThemes: CSS Variables enabled", (t) => { t.is(taskUtil.getBuildOption.getCall(0).args[0], "cssVariables", "taskUtil#getBuildOption got called with correct argument"); }); + +test("Standard build: nulled taskFunction to skip tasks", (t) => { + const {project, taskUtil, getTask} = t.context; + project.getJsdocExcludes = () => ["**.html"]; + + const tasks = library({ + project, taskUtil, getTask + }); + const generateComponentPreloadTaskDefinition = tasks.get("generateComponentPreload"); + const generateBundleTaskDefinition = tasks.get("generateBundle"); + const generateThemeDesignerResourcesTaskDefinition = tasks.get("generateThemeDesignerResources"); + t.deepEqual(Object.fromEntries(tasks), { + escapeNonAsciiCharacters: { + options: { + encoding: "UTF-412", pattern: "/**/*.properties" + } + }, + replaceCopyright: { + options: { + copyright: "copyright", + pattern: "/**/*.{js,library,css,less,theme,html}" + } + }, + replaceVersion: { + options: { + version: "version", + pattern: "/**/*.{js,json,library,css,less,theme,html}" + } + }, + replaceBuildtime: { + options: { + pattern: "/resources/sap/ui/Global.js" + } + }, + generateJsdoc: { + requiresDependencies: true, + taskFunction: async () => {}, + }, + executeJsdocSdkTransformation: { + requiresDependencies: true, + options: { + dotLibraryPattern: "/resources/**/*.library" + } + }, + minify: { + options: { + pattern: [ + "/resources/**/*.js", + "!**/*.support.js", + ] + } + }, + generateLibraryManifest: {}, + generateLibraryPreload: { + options: { + excludes: [], skipBundles: [] + } + }, + buildThemes: { + requiresDependencies: true, + options: { + projectName: "project.b", + librariesPattern: undefined, + themesPattern: undefined, + inputPattern: "/resources/project/b/themes/*/library.source.less", + cssVariables: undefined + } + }, + generateBundle: { + taskFunction: null + }, + generateComponentPreload: { + taskFunction: null + }, + generateThemeDesignerResources: { + taskFunction: null + }, + generateResourcesJson: { + requiresDependencies: true + } + }, "Correct task definitions"); + + t.is(generateComponentPreloadTaskDefinition.taskFunction, null, "taskFunction is explicitly set to null"); + t.is(generateBundleTaskDefinition.taskFunction, null, "taskFunction is explicitly set to null"); + t.is(generateThemeDesignerResourcesTaskDefinition.taskFunction, null, "taskFunction is explicitly set to null"); +}); diff --git a/test/lib/build/definitions/themeLibrary.js b/test/lib/build/definitions/themeLibrary.js index c57c7f38c..2da2457b5 100644 --- a/test/lib/build/definitions/themeLibrary.js +++ b/test/lib/build/definitions/themeLibrary.js @@ -47,6 +47,7 @@ test("Standard build", (t) => { const tasks = themeLibrary({ project, taskUtil, getTask }); + const generateThemeDesignerResourcesTaskFunction = tasks.get("generateThemeDesignerResources"); t.deepEqual(Object.fromEntries(tasks), { replaceCopyright: { options: { @@ -72,12 +73,17 @@ test("Standard build", (t) => { }, generateResourcesJson: { requiresDependencies: true + }, + generateThemeDesignerResources: { + taskFunction: null } }, "Correct task definitions"); t.is(taskUtil.getBuildOption.callCount, 1, "taskUtil#getBuildOption got called once"); t.is(taskUtil.getBuildOption.getCall(0).args[0], "cssVariables", "taskUtil#getBuildOption got called with correct argument"); + + t.is(generateThemeDesignerResourcesTaskFunction.taskFunction, null, "taskFunction is explicitly set to null"); }); test("Standard build (framework project)", (t) => { @@ -128,6 +134,9 @@ test("Standard build for non root project", (t) => { }, generateResourcesJson: { requiresDependencies: true + }, + generateThemeDesignerResources: { + taskFunction: null } }, "Correct task definitions");