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",