@@ -43,6 +43,7 @@ const processManifest = async (manifestResource) => {
4343 if ( manifestEmbeds ) {
4444 result . embeds = manifestEmbeds ;
4545 }
46+ result . id = manifestObject [ "sap.app" ] [ "id" ] ;
4647 return result ;
4748} ;
4849
@@ -52,6 +53,8 @@ const processManifest = async (manifestResource) => {
5253 * @public
5354 * @typedef {object } DependencyInfos
5455 * @property {object } libs The library object
56+ * @property {string[] } embeds embedded components
57+ * @property {string } id id
5558 *
5659 *
5760 * @example
@@ -76,50 +79,98 @@ const processManifest = async (manifestResource) => {
7679 * @property {module:@ui5/fs.Resource[] } manifestResources list of corresponding manifest resources
7780 */
7881
82+ const getManifestPath = ( filePath , subPath ) => {
83+ if ( filePath . endsWith ( "manifest.json" ) ) {
84+ return filePath . substr ( 0 , filePath . length - "manifest.json" . length ) + subPath + "/manifest.json" ;
85+ }
86+ return filePath ;
87+ } ;
7988
8089/**
8190 *
8291 * @param {Map<string, DependencyInfos> } manifestHints
8392 */
8493const resolveTransitiveDependencies = ( manifestHints ) => {
85- manifestHints . forEach ( ( manifestHint , key ) => {
86- const resolvedLibs = { } ;
87- Object . keys ( manifestHint . libs ) . forEach ( ( libName ) => {
88- resolvedLibs [ libName ] = manifestHint . libs [ libName ] ;
89- const resolved = resolve ( libName , manifestHints , resolvedLibs ) ;
90- Object . keys ( resolved ) . forEach ( ( nestedKey ) => {
91- manifestHint . libs [ nestedKey ] = resolved [ nestedKey ] ;
92- } ) ;
93- } ) ;
94+ // top level libraries
95+ // // lib.a => lib.c, lib.b
96+ // // lib.b => lib.d
97+ // // lib.c => lib.e, lib.b (true)
98+ // // lib.d => lib.e (true)
99+ // // lib.e =>
100+ // TODO optimize duplicate resolve (e.g. cache)
101+
102+ // lib.c => lib.e, lib.b (true), lib.d
103+ // lib.a => lib.c, lib.b, lib.d, lib.e
104+ // lib.b => lib.d, lib.e (true)
105+ // lib.d => lib.e (true)
106+ // lib.e =>
107+ const keys = [ ...manifestHints . keys ( ) ] ;
108+ keys . sort ( ) ;
109+ const resolvedCache = new Map ( ) ;
110+ keys . forEach ( ( libName ) => {
111+ resolve ( libName , manifestHints , resolvedCache ) ;
94112 } ) ;
95113} ;
96114
97- const isLazy = ( obj1 , obj2 ) => {
98- return obj1 . lazy && obj2 . lazy ;
115+ const clone = ( obj ) => {
116+ return JSON . parse ( JSON . stringify ( obj ) ) ;
99117} ;
100118
101119/**
102120 *
103- * @param {string } libName
104121 * @param {Map<string, DependencyInfos> } manifestHints
105- * @param {object } resolvedLibs
122+ * @param {string } libName
123+ * @param {object } newObject
106124 */
107- const resolve = ( libName , manifestHints , resolvedLibs ) => {
108- const manifestHint = manifestHints . get ( libName ) ;
109- Object . keys ( manifestHint . libs ) . forEach ( ( childLibName ) => {
110- if ( resolvedLibs [ childLibName ] && ! isLazy ( manifestHint . libs [ childLibName ] , resolvedLibs [ childLibName ] ) ) {
111- resolvedLibs [ childLibName ] = { } ;
112- } else {
113- resolvedLibs [ childLibName ] = manifestHint . libs [ childLibName ] ;
114- }
125+ const setManifestHints = ( manifestHints , libName , newObject ) => {
126+ const existingEntry = manifestHints . get ( libName ) ;
127+ const newLibs = merge ( existingEntry && existingEntry , newObject ) ;
128+ console . log ( ` setting ${ libName } ==> ${ Object . keys ( newLibs ) . join ( ", " ) } ` ) ;
129+ manifestHints . set ( libName , newLibs ) ;
130+ } ;
115131
116- const nested = resolve ( childLibName , manifestHints , resolvedLibs ) ;
117- Object . keys ( nested ) . forEach ( ( nestedKey ) => {
118- resolvedLibs [ nestedKey ] = resolvedLibs [ nestedKey ] || { } ;
132+ const merge = ( existingEntry , newObject ) => {
133+ const newLibs = clone ( newObject ) ;
134+ if ( existingEntry ) {
135+ Object . keys ( existingEntry ) . forEach ( ( libName ) => {
136+ if ( ! existingEntry [ libName ] . lazy && newLibs [ libName ] && newLibs [ libName ] . lazy ) {
137+ newLibs [ libName ] = { } ;
138+ }
139+ if ( ! newLibs [ libName ] ) {
140+ newLibs [ libName ] = existingEntry [ libName ] ;
141+ }
119142 } ) ;
120- } ) ;
143+ }
144+ return newLibs ;
145+ } ;
121146
122- return resolvedLibs ;
147+ /**
148+ *
149+ * @param {string } libName
150+ * @param {Map<string, DependencyInfos> } manifestHints
151+ * @param {Map<string, DependencyInfos> } resolvedCache
152+ * @returns {DependencyInfos } resolved dependencies
153+ */
154+ const resolve = ( libName , manifestHints , resolvedCache ) => {
155+ // lib.c get entries
156+ // lib.c => lib.b (true)
157+ // lib.b =>
158+ if ( resolvedCache . has ( libName ) ) {
159+ return resolvedCache . get ( libName ) ;
160+ }
161+ const manifestHint = manifestHints . get ( libName ) ; // lib.c
162+ console . log ( `:processing: ${ libName } ` ) ;
163+ const keys = Object . keys ( manifestHint ) ; // [lib.b]
164+ let resolved = { } ;
165+ keys . forEach ( ( childLibName ) => {
166+ const childResolved = resolve ( childLibName , manifestHints , resolvedCache ) ;
167+ resolved = merge ( resolved , childResolved ) ;
168+ console . log ( `resolved ${ childLibName } with ${ Object . keys ( resolved ) . join ( ", " ) } ` ) ;
169+ } ) ;
170+ resolved = merge ( resolved , manifestHint ) ;
171+ setManifestHints ( manifestHints , libName , resolved ) ;
172+ resolvedCache . set ( libName , resolved ) ;
173+ return resolved ;
123174} ;
124175
125176
@@ -155,7 +206,7 @@ module.exports = async function({options}) {
155206 const buildTimestamp = getTimestamp ( ) ;
156207 // TODO filter manifest.json if sap/embeds (we expect it contains the correct information)
157208
158- const components = [ ] ;
209+ const components = { } ;
159210 /**
160211 * @example
161212 * "sap.ui.integration": {
@@ -168,27 +219,52 @@ module.exports = async function({options}) {
168219 * @type {Map<string, DependencyInfos> }
169220 */
170221 const dependencyInfoMap = new Map ( ) ;
222+ const embeddedInfoMap = new Map ( ) ;
171223
172224 // gather all manifestHints
173225 const librariesPromises = options . libraryInfos . map ( ( libraryInfo ) => {
226+ // TODO use proper async await!
174227 return processManifest ( libraryInfo . mainManifest ) . then ( ( manifestHint ) => {
175- dependencyInfoMap . set ( libraryInfo . name , manifestHint ) ;
228+ dependencyInfoMap . set ( libraryInfo . name , manifestHint . libs ) ;
229+ return manifestHint . embeds ;
230+ } ) . then ( ( embeds ) => {
231+ // filter
232+ embeds . forEach ( ( embed ) => {
233+ embeddedInfoMap . set ( embed , {
234+ library : libraryInfo . name
235+ } ) ;
236+ } ) ;
237+ const embeddedPaths = embeds . map ( ( embed ) => {
238+ return getManifestPath ( libraryInfo . mainManifest . getPath ( ) , embed ) ;
239+ } ) ;
240+ const relevantManifests = libraryInfo . manifestResources . filter ( ( manifestResource ) => {
241+ return embeddedPaths . includes ( manifestResource . getPath ( ) ) ;
242+ } ) ;
243+
244+ // get all embeds manifests
245+ return Promise . all ( relevantManifests . map ( ( relevantManifest ) => {
246+ return processManifest ( relevantManifest ) . then ( ( result ) => {
247+ dependencyInfoMap . set ( result . id , result . libs ) ;
248+ } ) ;
249+ } ) ) ;
176250 } ) ;
177251 } ) ;
178252
253+ // gather embeds' manifest and do the same
254+
179255 await Promise . all ( librariesPromises ) ;
180256
181257 console . log ( "before:" ) ;
182258 dependencyInfoMap . forEach ( ( manifestHint , key ) => {
183- console . log ( `${ key } => ${ out ( manifestHint . libs ) . join ( ", " ) } ` ) ;
259+ console . log ( `${ key } => ${ out ( manifestHint ) . join ( ", " ) } ` ) ;
184260 } ) ;
185261
186262 // resolve nested dependencies (transitive)
187263 resolveTransitiveDependencies ( dependencyInfoMap ) ;
188264
189265 console . log ( "\nafter:" ) ;
190266 dependencyInfoMap . forEach ( ( manifestHint , key ) => {
191- console . log ( `${ key } => ${ out ( manifestHint . libs ) . join ( ", " ) } ` ) ;
267+ console . log ( `${ key } => ${ out ( manifestHint ) . join ( ", " ) } ` ) ;
192268 } ) ;
193269
194270
@@ -200,7 +276,8 @@ module.exports = async function({options}) {
200276 scmRevision : "" // TODO: insert current library scm revision here
201277 } ;
202278
203- const libs = dependencyInfoMap . get ( libraryInfo . name ) . libs ;
279+ const libs = dependencyInfoMap . get ( libraryInfo . name ) ;
280+ // TODO: sort the libs
204281 if ( Object . keys ( libs ) . length ) {
205282 result . manifestHints = {
206283 dependencies : {
@@ -211,10 +288,29 @@ module.exports = async function({options}) {
211288 return result ;
212289 } ) ;
213290
291+ // TODO sort!
292+ embeddedInfoMap . forEach ( ( embeddedInfo , libName ) => {
293+ components [ libName ] = {
294+ library : embeddedInfo . library
295+ } ;
296+ const libs = dependencyInfoMap . get ( libName ) ;
297+ if ( libs && Object . keys ( libs ) . length ) {
298+ components [ libName ] . manifestHints = {
299+ dependencies : {
300+ libs : libs
301+ }
302+ } ;
303+ }
304+ } ) ;
305+
306+ // sort alphabetically
307+ libraries . sort ( ( a , b ) => {
308+ return a . name . localeCompare ( b . name ) ;
309+ } ) ;
310+
214311
215312 // TODO enrich components
216313
217-
218314 const versionJson = {
219315 name : options . rootProjectName ,
220316 version : options . rootProjectVersion , // TODO: insert current application version here
0 commit comments