@@ -324,6 +324,26 @@ async function stampProjects(
324324 return { projectsMap, mavenMetadataMap, gradleMetadataMap } ;
325325}
326326
327+ /**
328+ * Sorts root projects to match the order of workspace folders in the Explorer view.
329+ * Projects not under any workspace folder are sorted last.
330+ */
331+ export function sortByWorkspaceOrder ( roots : LibertyProject [ ] ) : LibertyProject [ ] {
332+ const wsFolders = vscode . workspace . workspaceFolders ?? [ ] ;
333+ const folderIndex = ( project : LibertyProject ) : number => {
334+ const idx = wsFolders . findIndex ( f => {
335+ const folderPath = f . uri . fsPath . endsWith ( vscodePath . sep ) ? f . uri . fsPath : f . uri . fsPath + vscodePath . sep ;
336+ return project . path . startsWith ( folderPath ) ;
337+ } ) ;
338+ return idx === - 1 ? wsFolders . length : idx ;
339+ } ;
340+ return [ ...roots ] . sort ( ( a , b ) => {
341+ const diff = folderIndex ( a ) - folderIndex ( b ) ;
342+ if ( diff !== 0 ) { return diff ; }
343+ return a . path . localeCompare ( b . path ) ;
344+ } ) ;
345+ }
346+
327347/**
328348 * Wires parent-child relationships and computes rootProjects.
329349 */
@@ -333,33 +353,6 @@ async function linkProjects(
333353 gradleMetadataMap : Map < string , gradleUtil . GradleProjectMetadata >
334354) : Promise < LibertyProject [ ] > {
335355 const t0 = Date . now ( ) ;
336- const mavenProjectsByArtifactId = new Map < string , LibertyProject > ( ) ;
337- const gradleProjectsByName = new Map < string , LibertyProject > ( ) ;
338-
339- for ( const [ path , metadata ] of mavenMetadataMap . entries ( ) ) {
340- const project = projectsMap . get ( path ) ;
341- if ( project ) { mavenProjectsByArtifactId . set ( metadata . artifactId , project ) ; }
342- }
343- for ( const [ path , metadata ] of gradleMetadataMap . entries ( ) ) {
344- const project = projectsMap . get ( path ) ;
345- if ( project ) { gradleProjectsByName . set ( metadata . projectName , project ) ; }
346- }
347-
348- for ( const project of projectsMap . values ( ) ) {
349- if ( ! project . parentArtifactId ) { continue ; }
350- const parent = project . path . endsWith ( "pom.xml" )
351- ? mavenProjectsByArtifactId . get ( project . parentArtifactId )
352- : gradleProjectsByName . get ( project . parentArtifactId ) ;
353- console . log ( `[link] ${ project . artifactId } parentArtifactId=${ project . parentArtifactId } -> parent found=${ ! ! parent } ` ) ;
354- if ( parent && ! parent . children . includes ( project ) ) {
355- project . parent = parent ;
356- parent . children . push ( project ) ;
357- if ( ! project . isLibertyEnabled && parent . isLibertyEnabled ) {
358- project . isLibertyEnabled = true ;
359- console . debug ( `${ project . artifactId } inherits Liberty plugin from parent ${ parent . artifactId } ` ) ;
360- }
361- }
362- }
363356
364357 for ( const [ parentPath , parentMetadata ] of mavenMetadataMap . entries ( ) ) {
365358 if ( ! parentMetadata . isAggregator || parentMetadata . modules . length === 0 ) { continue ; }
@@ -382,6 +375,28 @@ async function linkProjects(
382375 }
383376 }
384377
378+ for ( const [ parentPath , parentMetadata ] of gradleMetadataMap . entries ( ) ) {
379+ if ( ! parentMetadata . isAggregator || parentMetadata . subprojects . length === 0 ) { continue ; }
380+ const parentProject = projectsMap . get ( parentPath ) ;
381+ if ( ! parentProject ) { continue ; }
382+ const parentDir = vscodePath . dirname ( parentPath ) ;
383+ for ( const subproject of parentMetadata . subprojects ) {
384+ const fsPath = subproject . replace ( / : / g, "/" ) . replace ( / ^ \/ / , "" ) ;
385+ const childBuildPath = vscodePath . resolve ( parentDir , fsPath , "build.gradle" ) ;
386+ const childProject = projectsMap . get ( childBuildPath ) ;
387+ if ( childProject && ! childProject . parent ) {
388+ childProject . parent = parentProject ;
389+ if ( ! parentProject . children . includes ( childProject ) ) {
390+ parentProject . children . push ( childProject ) ;
391+ }
392+ if ( ! childProject . isLibertyEnabled && parentProject . isLibertyEnabled ) {
393+ childProject . isLibertyEnabled = true ;
394+ }
395+ console . debug ( `Linked gradle subproject ${ subproject } to parent ${ parentMetadata . projectName } via filesystem path` ) ;
396+ }
397+ }
398+ }
399+
385400 // Stamp aggregator contextValue
386401 for ( const project of projectsMap . values ( ) ) {
387402 if ( project . isAggregator ) {
@@ -398,9 +413,11 @@ async function linkProjects(
398413 return project . children . some ( child => hasLibertyDescendants ( child ) ) ;
399414 } ;
400415
401- const rootProjects = Array . from ( projectsMap . values ( ) )
402- . filter ( p => ! p . parent )
403- . filter ( p => p . isLibertyEnabled || hasLibertyDescendants ( p ) ) ;
416+ const rootProjects = sortByWorkspaceOrder (
417+ Array . from ( projectsMap . values ( ) )
418+ . filter ( p => ! p . parent )
419+ . filter ( p => p . isLibertyEnabled || hasLibertyDescendants ( p ) )
420+ ) ;
404421 console . log ( `[perf] linkProjects: ${ Date . now ( ) - t0 } ms (${ rootProjects . length } roots)` ) ;
405422 return rootProjects ;
406423}
0 commit comments