Skip to content

Commit fd6a8e9

Browse files
committed
improve code
use typedef for ArtifactInfo instead of class because functionality could be extracted and it served then only as a data container. replaced Object.keys().forEach loops which Object.entries loop Use getResolvedLibraries for directly resolving transitive dependencies
1 parent b9da72d commit fd6a8e9

File tree

2 files changed

+51
-114
lines changed

2 files changed

+51
-114
lines changed

lib/processors/versionInfoGenerator.js

Lines changed: 49 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ const processManifest = async (manifestResource) => {
6060
const manifestDependencies = manifestObject["sap.ui5"]["dependencies"];
6161
if (manifestDependencies) {
6262
const libs = {};
63-
Object.keys(manifestDependencies.libs).forEach((libKey) => {
63+
for (const [libKey, libValue] of Object.entries(manifestDependencies.libs)) {
6464
libs[libKey] = {};
65-
if (manifestDependencies.libs[libKey].lazy) {
65+
if (libValue.lazy) {
6666
libs[libKey].lazy = true;
6767
}
68-
});
68+
}
6969
manifestInfo.libs = libs;
7070
}
7171
}
@@ -140,8 +140,8 @@ const getManifestPath = (filePath, subPath) => {
140140

141141
/**
142142
* Represents dependency information for a library.
143-
* Dependencies can be resolved recursively using <code>#resolve</code>
144-
* and are stored then in <code>libsResolved</code>
143+
* Dependencies can be retrieved using <code>#getResolvedLibraries</code>
144+
* and with that are resolved recursively
145145
*/
146146
class DependencyInfo {
147147
/**
@@ -152,14 +152,6 @@ class DependencyInfo {
152152
constructor(libs, name) {
153153
this.libs = libs;
154154
this.name = name;
155-
156-
/**
157-
* contains as key the library name and as value an object with an optional lazy property
158-
*
159-
* @type {ManifestLibraries}
160-
*/
161-
this.libsResolved = Object.create(null);
162-
this.wasResolved = false;
163155
}
164156

165157
/**
@@ -171,13 +163,13 @@ class DependencyInfo {
171163
* @returns {{lazy: boolean}} the added library
172164
*/
173165
addResolvedLibDependency(libName, lazy) {
174-
let alreadyResolved = this.libsResolved[libName];
166+
let alreadyResolved = this._libsResolved[libName];
175167
if (!alreadyResolved) {
176168
alreadyResolved = Object.create(null);
177169
if (lazy) {
178170
alreadyResolved.lazy = true;
179171
}
180-
this.libsResolved[libName] = alreadyResolved;
172+
this._libsResolved[libName] = alreadyResolved;
181173
} else {
182174
// siblings if sibling is eager only if one other sibling eager
183175
alreadyResolved.lazy = alreadyResolved.lazy && lazy;
@@ -186,38 +178,38 @@ class DependencyInfo {
186178
}
187179

188180
/**
189-
* Resolves dependencies recursively and stores them in libsResolved
190-
* with
181+
* Resolves dependencies recursively and retrieves them with
191182
* - resolved siblings a lazy and a eager dependency becomes eager
192183
* - resolved children become lazy if their parent is lazy
193184
*
194185
* @param {Map<string,DependencyInfo>} dependencyInfoMap
186+
* @returns {ManifestLibraries} resolved libraries
195187
*/
196-
resolve(dependencyInfoMap) {
197-
if (!this.wasResolved) {
188+
getResolvedLibraries(dependencyInfoMap) {
189+
if (!this._libsResolved) {
198190
// early set if there is a potential cycle
199-
this.wasResolved = true;
200-
Object.keys(this.libs).forEach((libName) => {
201-
const lazy = this.libs[libName].lazy;
191+
this._libsResolved = Object.create(null);
192+
for (const [libName, libValue] of Object.entries(this.libs)) {
193+
const lazy = libValue.lazy;
202194
const dependencyInfoObjectAdded = this.addResolvedLibDependency(libName, lazy);
203195
const dependencyInfo = dependencyInfoMap.get(libName);
204196
if (dependencyInfo) {
205-
dependencyInfo.resolve(dependencyInfoMap);
197+
const childLibsResolved = dependencyInfo.getResolvedLibraries(dependencyInfoMap);
206198

207199
// children if parent is lazy children become lazy
208-
Object.keys(dependencyInfo.libsResolved).forEach((resolvedLibName) => {
209-
const resolvedLib = dependencyInfo.libsResolved[resolvedLibName];
200+
for (const [resolvedLibName, resolvedLib] of Object.entries(childLibsResolved)) {
210201
this.addResolvedLibDependency(resolvedLibName,
211202
resolvedLib.lazy || dependencyInfoObjectAdded.lazy);
212-
});
203+
}
213204
} else {
214205
log.info(`Cannot find dependency '${libName}' `+
215206
`defined in the manifest.json or .library file of project '${this.name}'. ` +
216207
"This might prevent some UI5 runtime performance optimizations from taking effect. " +
217208
"Please double check your project's dependency configuration.");
218209
}
219-
});
210+
}
220211
}
212+
return this._libsResolved;
221213
}
222214
}
223215

@@ -226,7 +218,7 @@ class DependencyInfo {
226218
* Sorts the keys of a given object
227219
*
228220
* @param {object} obj the object
229-
* @returns {{}} the object with sorted keys
221+
* @returns {object} the object with sorted keys
230222
*/
231223
const sortObjectKeys = (obj) => {
232224
const sortedObject = {};
@@ -242,78 +234,33 @@ const sortObjectKeys = (obj) => {
242234
* Builds the manifestHints object from the dependencyInfo
243235
*
244236
* @param {DependencyInfo} dependencyInfo
237+
* @param {Map<string, DependencyInfo>} dependencyInfoMap
245238
* @returns {{dependencies: {libs: ManifestLibraries}}} manifestHints
246239
*/
247-
const getManifestHints = (dependencyInfo) => {
248-
if (dependencyInfo && Object.keys(dependencyInfo.libsResolved).length) {
249-
return {
250-
dependencies: {
251-
libs: sortObjectKeys(dependencyInfo.libsResolved)
252-
}
253-
};
240+
const getManifestHints = (dependencyInfo, dependencyInfoMap) => {
241+
if (dependencyInfo) {
242+
const libsResolved = dependencyInfo.getResolvedLibraries(dependencyInfoMap);
243+
if (libsResolved && Object.keys(libsResolved).length) {
244+
return {
245+
dependencies: {
246+
libs: sortObjectKeys(libsResolved)
247+
}
248+
};
249+
}
254250
}
255251
};
256252

257253
/**
258254
* Common type for Library and Component
259255
* embeds and bundled components makes only sense for library
256+
*
257+
* @typedef {object} ArtifactInfo
258+
* @property {string} componentName The library name, e.g. "lib.x"
259+
* @property {Set<string>} bundledComponents The embedded components which have a embeddedBy reference to the library
260+
* @property {DependencyInfo} dependencyInfo The dependency info object
261+
* @property {ArtifactInfo[]} embeds The embedded artifact infos
260262
*/
261-
class ArtifactInfo {
262-
/**
263-
* @param {string} componentName e.g. lib.x
264-
*/
265-
constructor(componentName) {
266-
this.componentName = componentName;
267-
this.artifactInfos = [];
268-
this.parentBundledComponents = new Set();
269-
}
270-
271-
/**
272-
*
273-
* @param {DependencyInfo} dependencyInfo
274-
*/
275-
setDependencyInfo(dependencyInfo) {
276-
this.dependencyInfo = dependencyInfo;
277-
}
278263

279-
/**
280-
* The embedded components which have a embeddedBy reference to the library
281-
*
282-
* @param {Set<string>} bundledComponents e.g. ["lib.x.sub"]
283-
*/
284-
setBundledComponents(bundledComponents) {
285-
this.bundledComponents = bundledComponents;
286-
}
287-
288-
/**
289-
* Set the embedded components of the library
290-
*
291-
* @param {ArtifactInfo[]} artifactInfos embedded components
292-
*/
293-
setEmbeds(artifactInfos) {
294-
this.artifactInfos = artifactInfos;
295-
this.artifactInfos.forEach((artifactInfo) => {
296-
artifactInfo._setParent(this);
297-
});
298-
}
299-
300-
/**
301-
* @returns {ArtifactInfo[]} get embedded components of this library
302-
*/
303-
getEmbeds() {
304-
return this.artifactInfos;
305-
}
306-
307-
/**
308-
* @param {ArtifactInfo} parent set the parent library
309-
* @private
310-
*/
311-
_setParent(parent) {
312-
this.parent = parent;
313-
this.parentBundledComponents = this.parent.bundledComponents;
314-
this.parentComponentName = this.parent.componentName;
315-
}
316-
}
317264

318265
/**
319266
* Processes the manifest and creates a ManifestInfo and an ArtifactInfo.
@@ -325,8 +272,9 @@ class ArtifactInfo {
325272
async function processManifestAndGetArtifactInfo(libraryManifest, name) {
326273
const manifestInfo = await processManifest(libraryManifest);
327274
name = name || manifestInfo.id;
328-
const libraryArtifactInfo = new ArtifactInfo(name);
329-
libraryArtifactInfo.setDependencyInfo(new DependencyInfo(manifestInfo.libs, name));
275+
const libraryArtifactInfo = Object.create(null);
276+
libraryArtifactInfo.componentName = name;
277+
libraryArtifactInfo.dependencyInfo = new DependencyInfo(manifestInfo.libs, name);
330278
return {manifestInfo, libraryArtifactInfo};
331279
}
332280

@@ -347,7 +295,7 @@ const processLibraryInfo = async (libraryInfo) => {
347295
await processManifestAndGetArtifactInfo(libraryInfo.libraryManifest, libraryInfo.name);
348296

349297
const bundledComponents = new Set();
350-
libraryArtifactInfo.setBundledComponents(bundledComponents);
298+
libraryArtifactInfo.bundledComponents = bundledComponents;
351299

352300
const embeds = manifestInfo.embeds; // e.g. ["sub"]
353301
// filter only embedded manifests
@@ -378,7 +326,7 @@ const processLibraryInfo = async (libraryInfo) => {
378326
});
379327

380328
const embeddedArtifactInfos = await Promise.all(embeddedManifestPromises);
381-
libraryArtifactInfo.setEmbeds(embeddedArtifactInfos);
329+
libraryArtifactInfo.embeds = embeddedArtifactInfos;
382330

383331
return libraryArtifactInfo;
384332
};
@@ -434,29 +382,18 @@ module.exports = async function({options}) {
434382

435383

436384
// process library infos
437-
const librariesPromises = options.libraryInfos.map((libraryInfo) => {
385+
const libraryInfosProcessPromises = options.libraryInfos.map((libraryInfo) => {
438386
return processLibraryInfo(libraryInfo);
439387
});
440388

441-
let artifactInfos = await Promise.all(librariesPromises);
389+
let artifactInfos = await Promise.all(libraryInfosProcessPromises);
442390
artifactInfos = artifactInfos.filter(Boolean);
443391

444392
// fill dependencyInfoMap
445393
artifactInfos.forEach((artifactInfo) => {
446394
dependencyInfoMap.set(artifactInfo.componentName, artifactInfo.dependencyInfo);
447395
});
448396

449-
// resolve library dependencies (transitive)
450-
dependencyInfoMap.forEach((dependencyInfo) => {
451-
dependencyInfo.resolve(dependencyInfoMap);
452-
});
453-
454-
// resolve dependencies of embedded components
455-
artifactInfos.forEach((artifactInfo) => {
456-
artifactInfo.getEmbeds().forEach((embeddedArtifactInfo) => {
457-
embeddedArtifactInfo.dependencyInfo.resolve(dependencyInfoMap);
458-
});
459-
});
460397

461398
const libraries = options.libraryInfos.map((libraryInfo) => {
462399
const library = {
@@ -467,7 +404,7 @@ module.exports = async function({options}) {
467404
};
468405

469406
const dependencyInfo = dependencyInfoMap.get(libraryInfo.name);
470-
const manifestHints = getManifestHints(dependencyInfo);
407+
const manifestHints = getManifestHints(dependencyInfo, dependencyInfoMap);
471408
if (manifestHints) {
472409
library.manifestHints = manifestHints;
473410
}
@@ -482,17 +419,16 @@ module.exports = async function({options}) {
482419
// components
483420
let components;
484421
artifactInfos.forEach((artifactInfo) => {
485-
artifactInfo.getEmbeds().forEach((embeddedArtifactInfo) => {
422+
artifactInfo.embeds.forEach((embeddedArtifactInfo) => {
486423
const componentObject = {
487-
library: embeddedArtifactInfo.parentComponentName
424+
library: artifactInfo.componentName
488425
};
489426
const componentName = embeddedArtifactInfo.componentName;
490-
const dependencyInfo = embeddedArtifactInfo.dependencyInfo;
491-
const manifestHints = getManifestHints(dependencyInfo);
427+
const manifestHints = getManifestHints(embeddedArtifactInfo.dependencyInfo, dependencyInfoMap);
492428
if (manifestHints) {
493429
componentObject.manifestHints = manifestHints;
494430
}
495-
const bundledComponents = embeddedArtifactInfo.parentBundledComponents;
431+
const bundledComponents = artifactInfo.bundledComponents;
496432
if (bundledComponents.has(componentName)) {
497433
componentObject.hasOwnPreload = true;
498434
}

test/lib/processors/versionInfoGenerator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ test.serial("versionInfoGenerator library infos with dependencies", async (t) =>
106106
"minUI5Version": "1.84",
107107
"libs": {
108108
"my.dep": {
109-
"minVersion": "1.84.0"
109+
"minVersion": "1.84.0",
110+
"lazy": false
110111
}
111112
}
112113
}

0 commit comments

Comments
 (0)