From a8edff4cf63547cc1fc1d1c0ddfe958104fcb801 Mon Sep 17 00:00:00 2001 From: dstork <50145142+dstork@users.noreply.github.com> Date: Wed, 28 Aug 2019 08:26:06 +0200 Subject: [PATCH] [FIX] Add 'sap.ui.fl' dependency to manifest.json (#318) If changes are present during runtime, the 'sap.ui.fl' dependency should be added to the manifest.json so the changes contained in the changes bundled can be applied to the application An already declared lazy dependency will be converted to an eager (non-lazy) dependency. --- .../bundlers/generateFlexChangesBundle.js | 47 +++++++++++++++++- .../application.i/dest/Component-preload.js | 2 +- .../build/application.i/dest/manifest.json | 14 +----- .../application.j/dest/Component-preload.js | 11 +++++ .../build/application.j/dest/Component.js | 1 + .../dest/changes/changes-bundle.json | 1 + .../dest/changes/coding/MyExtension.js | 1 + .../changes/fragments/MyFragment.fragment.xml | 3 ++ .../dest/changes/id_123_addField.change | 20 ++++++++ .../dest/changes/id_456_addField.change | 20 ++++++++ .../build/application.j/dest/manifest.json | 1 + .../application.i/webapp/manifest.json | 9 ++++ test/fixtures/application.j/package.json | 10 ++++ test/fixtures/application.j/ui5.yaml | 25 ++++++++++ .../application.j/webapp/Component.js | 8 +++ .../webapp/changes/coding/MyExtension.js | 3 ++ .../changes/fragments/MyFragment.fragment.xml | 3 ++ .../webapp/changes/id_123_addField.change | 20 ++++++++ .../webapp/changes/id_456_addField.change | 20 ++++++++ .../application.j/webapp/manifest.json | 25 ++++++++++ test/lib/builder/builder.js | 49 +++++++++++++++++++ 21 files changed, 277 insertions(+), 16 deletions(-) create mode 100644 test/expected/build/application.j/dest/Component-preload.js create mode 100644 test/expected/build/application.j/dest/Component.js create mode 100644 test/expected/build/application.j/dest/changes/changes-bundle.json create mode 100644 test/expected/build/application.j/dest/changes/coding/MyExtension.js create mode 100644 test/expected/build/application.j/dest/changes/fragments/MyFragment.fragment.xml create mode 100644 test/expected/build/application.j/dest/changes/id_123_addField.change create mode 100644 test/expected/build/application.j/dest/changes/id_456_addField.change create mode 100644 test/expected/build/application.j/dest/manifest.json create mode 100644 test/fixtures/application.j/package.json create mode 100644 test/fixtures/application.j/ui5.yaml create mode 100644 test/fixtures/application.j/webapp/Component.js create mode 100644 test/fixtures/application.j/webapp/changes/coding/MyExtension.js create mode 100644 test/fixtures/application.j/webapp/changes/fragments/MyFragment.fragment.xml create mode 100644 test/fixtures/application.j/webapp/changes/id_123_addField.change create mode 100644 test/fixtures/application.j/webapp/changes/id_456_addField.change create mode 100644 test/fixtures/application.j/webapp/manifest.json diff --git a/lib/tasks/bundlers/generateFlexChangesBundle.js b/lib/tasks/bundlers/generateFlexChangesBundle.js index ad245b8c4..e6604077f 100644 --- a/lib/tasks/bundlers/generateFlexChangesBundle.js +++ b/lib/tasks/bundlers/generateFlexChangesBundle.js @@ -1,8 +1,12 @@ const log = require("@ui5/logger").getLogger("builder:tasks:bundlers:generateFlexChangesBundle"); const flexChangesBundler = require("../../processors/bundlers/flexChangesBundler"); +const resourceFactory = require("@ui5/fs").resourceFactory; /** - * Task to create changesBundle.json file containing all changes stored in the /changes folder for easier consumption at runtime. + * Task to create changesBundle.json file containing all changes stored in the /changes folder for easier consumption + * at runtime. + * If a change bundle is created, "sap.ui.fl" is added as a dependency to the manifest.json if not already present - + * if the dependency is already listed but lazy-loaded, lazy loading is disabled. * * @public * @alias module:@ui5/builder.tasks.generateFlexChangesBundle @@ -20,6 +24,44 @@ module.exports = function({workspace, options}) { pathPrefix = `/resources/${options.namespace}`; } + function updateJson(data) { + // ensure the existence of the libs section in the dependencies + data["sap.ui5"].dependencies.libs = data["sap.ui5"].dependencies.libs || {}; + const mLibs = data["sap.ui5"].dependencies.libs; + + if ("sap.ui.fl" in mLibs) { + log.verbose("sap.ui.fl found in manifest.json"); + if ("lazy" in mLibs["sap.ui.fl"]) { + log.verbose("sap.ui.fl 'lazy' attribute found in manifest.json, setting it to false..."); + if (mLibs["sap.ui.fl"].lazy === true) { + mLibs["sap.ui.fl"].lazy = false; + } + } + } else { + log.verbose("sap.ui.fl not found in manifest.json, inserting it..."); + mLibs["sap.ui.fl"] = {}; + } + + return data; + } + + function updateFLdependency() { + return workspace.byPath(`${pathPrefix}/manifest.json`) + .then((manifestData) => { + return manifestData.getBuffer().then((buffer) => { + return JSON.parse(buffer.toString()); + }); + }) + .then((manifestContent) => { + let updatedContent = updateJson(manifestContent); + updatedContent = JSON.stringify(updatedContent); + return workspace.write(resourceFactory.createResource({ + path: `${pathPrefix}/manifest.json`, + string: updatedContent + })); + }); + } + log.verbose("Collecting flexibility changes"); return workspace.byGlob(`${pathPrefix}/changes/*.change`) .then((allResources) => { @@ -32,8 +74,9 @@ module.exports = function({workspace, options}) { }); }) .then((processedResources) => { - return Promise.all(processedResources.map((resource) => { + return Promise.all(processedResources.map(async (resource) => { log.verbose("Writing flexibility changes bundle"); + await updateFLdependency(); return workspace.write(resource); })); }); diff --git a/test/expected/build/application.i/dest/Component-preload.js b/test/expected/build/application.i/dest/Component-preload.js index 8a88b6c69..647a1e8ea 100644 --- a/test/expected/build/application.i/dest/Component-preload.js +++ b/test/expected/build/application.i/dest/Component-preload.js @@ -7,5 +7,5 @@ jQuery.sap.registerPreloadedModules({ "application/i/changes/coding/MyExtension.js":function(){sap.ui.define([],function(){return{}}); }, "application/i/changes/fragments/MyFragment.fragment.xml":'', - "application/i/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.i","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"}}' + "application/i/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.i","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{}}}}}' }}); diff --git a/test/expected/build/application.i/dest/manifest.json b/test/expected/build/application.i/dest/manifest.json index 91f21cb85..e89fa6598 100644 --- a/test/expected/build/application.i/dest/manifest.json +++ b/test/expected/build/application.i/dest/manifest.json @@ -1,13 +1 @@ -{ - "_version": "1.1.0", - "sap.app": { - "_version": "1.1.0", - "id": "application.i", - "type": "application", - "applicationVersion": { - "version": "1.2.2" - }, - "embeds": ["embedded"], - "title": "{{title}}" - } -} +{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.i","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{}}}}} \ No newline at end of file diff --git a/test/expected/build/application.j/dest/Component-preload.js b/test/expected/build/application.j/dest/Component-preload.js new file mode 100644 index 000000000..688870a2c --- /dev/null +++ b/test/expected/build/application.j/dest/Component-preload.js @@ -0,0 +1,11 @@ +jQuery.sap.registerPreloadedModules({ +"version":"2.0", +"modules":{ + "application/j/Component.js":function(){sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})}); +}, + "application/j/changes/changes-bundle.json":'[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}]', + "application/j/changes/coding/MyExtension.js":function(){sap.ui.define([],function(){return{}}); +}, + "application/j/changes/fragments/MyFragment.fragment.xml":'', + "application/j/manifest.json":'{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}}' +}}); diff --git a/test/expected/build/application.j/dest/Component.js b/test/expected/build/application.j/dest/Component.js new file mode 100644 index 000000000..984f96eaf --- /dev/null +++ b/test/expected/build/application.j/dest/Component.js @@ -0,0 +1 @@ +sap.ui.define(["sap/ui/core/UIComponent"],function(n){"use strict";return n.extend("application.j.Component",{metadata:{manifest:"json"}})}); \ No newline at end of file diff --git a/test/expected/build/application.j/dest/changes/changes-bundle.json b/test/expected/build/application.j/dest/changes/changes-bundle.json new file mode 100644 index 000000000..0e270c459 --- /dev/null +++ b/test/expected/build/application.j/dest/changes/changes-bundle.json @@ -0,0 +1 @@ +[{"fileName":"id_456_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2023-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}},{"fileName":"id_123_addField","fileType":"change","changeType":"hideControl","component":"application.j.Component","content":{},"selector":{"id":"control1"},"layer":"VENDOR","texts":{},"namespace":"apps/application.j.Component/changes","creation":"2025-10-30T13:52:40.4754350Z","originalLanguage":"","conditions":{},"support":{"generator":"did it","user":"Max Mustermann"}}] \ No newline at end of file diff --git a/test/expected/build/application.j/dest/changes/coding/MyExtension.js b/test/expected/build/application.j/dest/changes/coding/MyExtension.js new file mode 100644 index 000000000..b9e475d8e --- /dev/null +++ b/test/expected/build/application.j/dest/changes/coding/MyExtension.js @@ -0,0 +1 @@ +sap.ui.define([],function(){return{}}); \ No newline at end of file diff --git a/test/expected/build/application.j/dest/changes/fragments/MyFragment.fragment.xml b/test/expected/build/application.j/dest/changes/fragments/MyFragment.fragment.xml new file mode 100644 index 000000000..39ce6859b --- /dev/null +++ b/test/expected/build/application.j/dest/changes/fragments/MyFragment.fragment.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/expected/build/application.j/dest/changes/id_123_addField.change b/test/expected/build/application.j/dest/changes/id_123_addField.change new file mode 100644 index 000000000..41d9bb61c --- /dev/null +++ b/test/expected/build/application.j/dest/changes/id_123_addField.change @@ -0,0 +1,20 @@ +{ + "fileName": "id_123_addField", + "fileType": "change", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2025-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + } +} diff --git a/test/expected/build/application.j/dest/changes/id_456_addField.change b/test/expected/build/application.j/dest/changes/id_456_addField.change new file mode 100644 index 000000000..4d4c73b51 --- /dev/null +++ b/test/expected/build/application.j/dest/changes/id_456_addField.change @@ -0,0 +1,20 @@ +{ + "fileName": "id_456_addField", + "fileType": "change", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2023-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + } +} diff --git a/test/expected/build/application.j/dest/manifest.json b/test/expected/build/application.j/dest/manifest.json new file mode 100644 index 000000000..ecde3d174 --- /dev/null +++ b/test/expected/build/application.j/dest/manifest.json @@ -0,0 +1 @@ +{"_version":"1.1.0","sap.app":{"_version":"1.1.0","id":"application.j","type":"application","applicationVersion":{"version":"1.2.2"},"embeds":["embedded"],"title":"{{title}}"},"sap.ui5":{"dependencies":{"libs":{"sap.ui.layout":{},"sap.ui.core":{},"sap.m":{},"sap.ui.fl":{"lazy":false}}}}} \ No newline at end of file diff --git a/test/fixtures/application.i/webapp/manifest.json b/test/fixtures/application.i/webapp/manifest.json index 91f21cb85..557627fd4 100644 --- a/test/fixtures/application.i/webapp/manifest.json +++ b/test/fixtures/application.i/webapp/manifest.json @@ -9,5 +9,14 @@ }, "embeds": ["embedded"], "title": "{{title}}" + }, + "sap.ui5": { + "dependencies": { + "libs": { + "sap.ui.layout": {}, + "sap.ui.core": {}, + "sap.m": {} + } + } } } diff --git a/test/fixtures/application.j/package.json b/test/fixtures/application.j/package.json new file mode 100644 index 000000000..e1dfbba6d --- /dev/null +++ b/test/fixtures/application.j/package.json @@ -0,0 +1,10 @@ +{ + "name": "application.j", + "version": "1.0.0", + "description": "Simple SAPUI5 based application", + "main": "index.html", + "dependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + } +} diff --git a/test/fixtures/application.j/ui5.yaml b/test/fixtures/application.j/ui5.yaml new file mode 100644 index 000000000..5cc8b006d --- /dev/null +++ b/test/fixtures/application.j/ui5.yaml @@ -0,0 +1,25 @@ +--- +specVersion: "0.1" +type: application +metadata: + name: application.j +builder: + bundles: + - name: sap/ushell/bootstrap/cdm.js + defaultFileTypes: + - ".js" + sections: + - mode: raw + filters: + - ui5loader.js + - ui5loader-autoconfig.js + declareModules: false + resolve: true + - mode: preload + name: sap/ushell/bootstrap/common + filters: + - sap/ushell/bootstrap/cdm/cdm-def.js + resolve: true + - mode: require + filters: + - sap/ushell/bootstrap/cdm/cdm-def.js diff --git a/test/fixtures/application.j/webapp/Component.js b/test/fixtures/application.j/webapp/Component.js new file mode 100644 index 000000000..e40d21d9a --- /dev/null +++ b/test/fixtures/application.j/webapp/Component.js @@ -0,0 +1,8 @@ +sap.ui.define(["sap/ui/core/UIComponent"], function(UIComponent){ + "use strict"; + return UIComponent.extend('application.j.Component', { + metadata: { + manifest: "json" + } + }); +}); diff --git a/test/fixtures/application.j/webapp/changes/coding/MyExtension.js b/test/fixtures/application.j/webapp/changes/coding/MyExtension.js new file mode 100644 index 000000000..dfb3da014 --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/coding/MyExtension.js @@ -0,0 +1,3 @@ +sap.ui.define([],function () { + return {}; +}); diff --git a/test/fixtures/application.j/webapp/changes/fragments/MyFragment.fragment.xml b/test/fixtures/application.j/webapp/changes/fragments/MyFragment.fragment.xml new file mode 100644 index 000000000..39ce6859b --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/fragments/MyFragment.fragment.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/test/fixtures/application.j/webapp/changes/id_123_addField.change b/test/fixtures/application.j/webapp/changes/id_123_addField.change new file mode 100644 index 000000000..41d9bb61c --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/id_123_addField.change @@ -0,0 +1,20 @@ +{ + "fileName": "id_123_addField", + "fileType": "change", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2025-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + } +} diff --git a/test/fixtures/application.j/webapp/changes/id_456_addField.change b/test/fixtures/application.j/webapp/changes/id_456_addField.change new file mode 100644 index 000000000..4d4c73b51 --- /dev/null +++ b/test/fixtures/application.j/webapp/changes/id_456_addField.change @@ -0,0 +1,20 @@ +{ + "fileName": "id_456_addField", + "fileType": "change", + "changeType": "hideControl", + "component": "application.j.Component", + "content": {}, + "selector": { + "id": "control1" + }, + "layer": "VENDOR", + "texts": {}, + "namespace": "apps/application.j.Component/changes", + "creation": "2023-10-30T13:52:40.4754350Z", + "originalLanguage": "", + "conditions": {}, + "support": { + "generator": "did it", + "user": "Max Mustermann" + } +} diff --git a/test/fixtures/application.j/webapp/manifest.json b/test/fixtures/application.j/webapp/manifest.json new file mode 100644 index 000000000..476ebb972 --- /dev/null +++ b/test/fixtures/application.j/webapp/manifest.json @@ -0,0 +1,25 @@ +{ + "_version": "1.1.0", + "sap.app": { + "_version": "1.1.0", + "id": "application.j", + "type": "application", + "applicationVersion": { + "version": "1.2.2" + }, + "embeds": ["embedded"], + "title": "{{title}}" + }, + "sap.ui5": { + "dependencies": { + "libs": { + "sap.ui.layout": {}, + "sap.ui.core": {}, + "sap.m": {}, + "sap.ui.fl": { + "lazy": true + } + } + } + } +} diff --git a/test/lib/builder/builder.js b/test/lib/builder/builder.js index 8aefda317..63bb671d1 100644 --- a/test/lib/builder/builder.js +++ b/test/lib/builder/builder.js @@ -15,6 +15,7 @@ const applicationAPath = path.join(__dirname, "..", "..", "fixtures", "applicati const applicationGPath = path.join(__dirname, "..", "..", "fixtures", "application.g"); const applicationHPath = path.join(__dirname, "..", "..", "fixtures", "application.h"); const applicationIPath = path.join(__dirname, "..", "..", "fixtures", "application.i"); +const applicationJPath = path.join(__dirname, "..", "..", "fixtures", "application.j"); const libraryDPath = path.join(__dirname, "..", "..", "fixtures", "library.d"); const libraryEPath = path.join(__dirname, "..", "..", "fixtures", "library.e"); const libraryHPath = path.join(__dirname, "..", "..", "fixtures", "library.h"); @@ -259,6 +260,26 @@ test("Build application.i", (t) => { }); }); +test("Build application.j", (t) => { + const destPath = "./test/tmp/build/application.j/dest"; + const expectedPath = path.join("test", "expected", "build", "application.j", "dest"); + + return builder.build({ + tree: applicationJTree, + destPath, + excludedTasks: ["createDebugFiles", "generateStandaloneAppBundle", "generateVersionInfo"] + }).then(() => { + return findFiles(expectedPath); + }).then((expectedFiles) => { + // Check for all directories and files + assert.directoryDeepEqual(destPath, expectedPath); + // Check for all file contents + return checkFileContentsIgnoreLineFeeds(expectedFiles, expectedPath, destPath); + }).then(() => { + t.pass(); + }); +}); + test("Build library.d with copyright from .library file", (t) => { const destPath = "./test/tmp/build/library.d/dest"; const expectedPath = path.join("test", "expected", "build", "library.d", "dest"); @@ -787,6 +808,34 @@ const applicationITree = { } }; +const applicationJTree = { + "id": "application.j", + "version": "1.0.0", + "path": applicationJPath, + "_level": 0, + "specVersion": "0.1", + "type": "application", + "metadata": { + "name": "application.j", + "namespace": "application/j" + }, + "dependencies": [], + "resources": { + "configuration": { + "paths": { + "webapp": "webapp" + }, + "propertiesFileSourceEncoding": "ISO-8859-1" + }, + "pathMappings": { + "/": "webapp" + } + }, + "builder": { + "bundles": [] + } +}; + const libraryDTree = { "id": "library.d", "version": "1.0.0",