From 9608c5177f86494ba689d2e799b4378fec9ed6fa Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Wed, 19 Jan 2022 14:21:17 +0100 Subject: [PATCH] [FIX] generateResourcesJson: Don't list resources omitted from build result Resources that are tagged to be omitted from the build result should not be listed in the resources.json as it should represent a listing of files that are part of the build output. Resources of dependencies should also not be used for dependency lookups if they are omitted from the results as they also won't be listed in the resources.json of that dependency. --- lib/tasks/generateResourcesJson.js | 17 ++++- lib/types/application/ApplicationBuilder.js | 1 + lib/types/library/LibraryBuilder.js | 1 + lib/types/themeLibrary/ThemeLibraryBuilder.js | 1 + test/lib/tasks/generateResourcesJson.js | 67 +++++++++++++++++++ 5 files changed, 85 insertions(+), 2 deletions(-) diff --git a/lib/tasks/generateResourcesJson.js b/lib/tasks/generateResourcesJson.js index fcc1d2692..f405b25d1 100644 --- a/lib/tasks/generateResourcesJson.js +++ b/lib/tasks/generateResourcesJson.js @@ -97,12 +97,13 @@ function getCreatorOptions(projectName) { * @param {object} parameters Parameters * @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files * @param {module:@ui5/fs.AbstractReader} [parameters.dependencies] Reader or Collection to read dependency files + * @param {module:@ui5/builder.tasks.TaskUtil|object} [parameters.taskUtil] TaskUtil * @param {object} parameters.options Options * @param {string} parameters.options.projectName Project name * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = async function({workspace, dependencies, options: {projectName}}) { - const resources = await workspace.byGlob(["/resources/**/*"].concat(DEFAULT_EXCLUDES)); +module.exports = async function({workspace, dependencies, taskUtil, options: {projectName}}) { + let resources = await workspace.byGlob(["/resources/**/*"].concat(DEFAULT_EXCLUDES)); // TODO 3.0: Make dependencies parameter mandatory let dependencyResources; @@ -111,6 +112,18 @@ module.exports = async function({workspace, dependencies, options: {projectName} await dependencies.byGlob("/resources/**/*.{js,json,xml,html,properties,library}"); } + if (taskUtil) { + // Filter out resources that will be omitted from the build results + resources = resources.filter((resource) => { + return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult); + }); + if (dependencyResources) { + dependencyResources = dependencyResources.filter((resource) => { + return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.OmitFromBuildResult); + }); + } + } + const resourceLists = await resourceListCreator({ resources, dependencyResources, diff --git a/lib/types/application/ApplicationBuilder.js b/lib/types/application/ApplicationBuilder.js index 444ebce64..d82d05a8b 100644 --- a/lib/types/application/ApplicationBuilder.js +++ b/lib/types/application/ApplicationBuilder.js @@ -199,6 +199,7 @@ class ApplicationBuilder extends AbstractBuilder { return getTask("generateResourcesJson").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name } diff --git a/lib/types/library/LibraryBuilder.js b/lib/types/library/LibraryBuilder.js index d31148e36..57f96baa2 100644 --- a/lib/types/library/LibraryBuilder.js +++ b/lib/types/library/LibraryBuilder.js @@ -219,6 +219,7 @@ class LibraryBuilder extends AbstractBuilder { return getTask("generateResourcesJson").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name } diff --git a/lib/types/themeLibrary/ThemeLibraryBuilder.js b/lib/types/themeLibrary/ThemeLibraryBuilder.js index 2f49912af..1404357a1 100644 --- a/lib/types/themeLibrary/ThemeLibraryBuilder.js +++ b/lib/types/themeLibrary/ThemeLibraryBuilder.js @@ -51,6 +51,7 @@ class ThemeLibraryBuilder extends AbstractBuilder { return getTask("generateResourcesJson").task({ workspace: resourceCollections.workspace, dependencies: resourceCollections.dependencies, + taskUtil, options: { projectName: project.metadata.name } diff --git a/test/lib/tasks/generateResourcesJson.js b/test/lib/tasks/generateResourcesJson.js index c46a330de..af8b7b064 100644 --- a/test/lib/tasks/generateResourcesJson.js +++ b/test/lib/tasks/generateResourcesJson.js @@ -51,6 +51,7 @@ test.serial("empty resources (sap.ui.core)", async (t) => { }); t.deepEqual(result, undefined, "no resources returned"); t.is(resourceListCreatorStub.callCount, 1); + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].resources, [], "no resources are passed"); const expectedOptions = { externalResources: { "sap/ui/core": [ @@ -75,6 +76,7 @@ test.serial("empty resources (my.lib)", async (t) => { }); t.deepEqual(result, undefined, "no resources returned"); t.is(t.context.resourceListCreatorStub.callCount, 1); + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].resources, [], "no resources are passed"); const expectedOptions = {}; t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match"); }); @@ -96,8 +98,73 @@ test.serial("empty resources (my.lib with dependencies)", async (t) => { }); t.deepEqual(result, undefined, "no resources returned"); t.is(t.context.resourceListCreatorStub.callCount, 1); + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].resources, [], "no resources are passed"); const expectedOptions = {}; t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match"); t.is(t.context.resourceListCreatorStub.getCall(0).args[0].dependencyResources, dependencyResources, "dependencyResources reference should be passed to resourceListCreator"); }); + +test.serial("Resources omitted from build result should be ignored", async (t) => { + const generateResourcesJson = require("../../../lib/tasks/generateResourcesJson"); + + const resource1 = {}; + const resource2 = {}; + const resource3 = {}; + + const workspace = createWorkspace(); + workspace.byGlob = sinon.stub().resolves([ + resource1, + resource2, + resource3, + ]); + + const dependencyResource1 = {}; + const dependencyResource2 = {}; + const dependencies = { + byGlob: sinon.stub().resolves([dependencyResource1, dependencyResource2]) + }; + + const taskUtil = { + getTag: sinon.stub(), + STANDARD_TAGS: { + OmitFromBuildResult: "TEST-OmitFromBuildResult-TEST" + } + }; + + // resources + taskUtil.getTag + .onCall(0).returns(false) + .onCall(1).returns(true) // second resource should be filtered out + .onCall(2).returns(false); + + // dependencyResources + taskUtil.getTag + .onCall(3).returns(true) // first dependencyResource should be filtered out + .onCall(4).returns(false); + + const result = await generateResourcesJson({ + workspace, + dependencies, + taskUtil, + options: { + projectName: "my.lib" + } + }); + + t.is(taskUtil.getTag.callCount, 5); + t.deepEqual(taskUtil.getTag.getCall(0).args, [resource1, "TEST-OmitFromBuildResult-TEST"]); + t.deepEqual(taskUtil.getTag.getCall(1).args, [resource2, "TEST-OmitFromBuildResult-TEST"]); + t.deepEqual(taskUtil.getTag.getCall(2).args, [resource3, "TEST-OmitFromBuildResult-TEST"]); + t.deepEqual(taskUtil.getTag.getCall(3).args, [dependencyResource1, "TEST-OmitFromBuildResult-TEST"]); + t.deepEqual(taskUtil.getTag.getCall(4).args, [dependencyResource2, "TEST-OmitFromBuildResult-TEST"]); + + t.deepEqual(result, undefined, "no resources returned"); + t.is(t.context.resourceListCreatorStub.callCount, 1); + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].resources, + [resource1, resource3], "only resources 1 and 3 are passed"); + const expectedOptions = {}; + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match"); + t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].dependencyResources, [dependencyResource2], + "dependencyResources reference should be passed to resourceListCreator"); +});