1111// SPDX-License-Identifier: Apache-2.0
1212//
1313//===----------------------------------------------------------------------===//
14+ import * as fs from "fs/promises" ;
15+ import * as path from "path" ;
1416import { basename } from "path" ;
1517import * as vscode from "vscode" ;
1618
1719import { globDirectory , pathExists } from "./filesystem" ;
20+ import { Version } from "./version" ;
1821
1922export async function searchForPackages (
2023 folder : vscode . Uri ,
2124 disableSwiftPMIntegration : boolean ,
22- searchSubfoldersForPackages : boolean
25+ searchSubfoldersForPackages : boolean ,
26+ swiftVersion : Version
2327) : Promise < Array < vscode . Uri > > {
2428 const folders : Array < vscode . Uri > = [ ] ;
2529
2630 async function search ( folder : vscode . Uri ) {
2731 // add folder if Package.swift/compile_commands.json/compile_flags.txt/buildServer.json exists
28- if ( await isValidWorkspaceFolder ( folder . fsPath , disableSwiftPMIntegration ) ) {
32+ if ( await isValidWorkspaceFolder ( folder . fsPath , disableSwiftPMIntegration , swiftVersion ) ) {
2933 folders . push ( folder ) ;
3034 }
3135 // should I search sub-folders for more Swift Packages
@@ -47,16 +51,61 @@ export async function searchForPackages(
4751 return folders ;
4852}
4953
54+ export async function hasBSPConfigurationFile (
55+ folder : string ,
56+ swiftVersion : Version
57+ ) : Promise < boolean > {
58+ // buildServer.json
59+ const buildServerPath = path . join ( folder , "buildServer.json" ) ;
60+ const buildServerStat = await fs . stat ( buildServerPath ) . catch ( ( ) => undefined ) ;
61+ if ( buildServerStat && buildServerStat . isFile ( ) ) {
62+ return true ;
63+ }
64+ // .bsp/*.json for Swift >= 6.1.0
65+ if ( swiftVersion . isGreaterThanOrEqual ( new Version ( 6 , 1 , 0 ) ) ) {
66+ const bspDir = path . join ( folder , ".bsp" ) ;
67+ const bspStat = await fs . stat ( bspDir ) . catch ( ( ) => undefined ) ;
68+ if ( bspStat && bspStat . isDirectory ( ) ) {
69+ const files = await fs . readdir ( bspDir ) . catch ( ( ) => [ ] ) ;
70+ if ( files . some ( ( f : string ) => f . endsWith ( ".json" ) ) ) {
71+ return true ;
72+ }
73+ }
74+ }
75+ return false ;
76+ }
77+
5078export async function isValidWorkspaceFolder (
5179 folder : string ,
52- disableSwiftPMIntegration : boolean
80+ disableSwiftPMIntegration : boolean ,
81+ swiftVersion : Version
5382) : Promise < boolean > {
54- return (
55- ( ! disableSwiftPMIntegration && ( await pathExists ( folder , "Package.swift" ) ) ) ||
56- ( await pathExists ( folder , "compile_commands.json" ) ) ||
57- ( await pathExists ( folder , "compile_flags.txt" ) ) ||
58- ( await pathExists ( folder , "buildServer.json" ) ) ||
59- ( await pathExists ( folder , "build" ) ) ||
60- ( await pathExists ( folder , "out" ) )
61- ) ;
83+ // Check Package.swift first (most common case)
84+ if ( ! disableSwiftPMIntegration && ( await pathExists ( folder , "Package.swift" ) ) ) {
85+ return true ;
86+ }
87+
88+ // Check other common build files
89+ if ( await pathExists ( folder , "compile_commands.json" ) ) {
90+ return true ;
91+ }
92+
93+ if ( await pathExists ( folder , "compile_flags.txt" ) ) {
94+ return true ;
95+ }
96+
97+ if ( await pathExists ( folder , "build" ) ) {
98+ return true ;
99+ }
100+
101+ if ( await pathExists ( folder , "out" ) ) {
102+ return true ;
103+ }
104+
105+ // Check BSP configuration last (potentially more expensive)
106+ if ( await hasBSPConfigurationFile ( folder , swiftVersion ) ) {
107+ return true ;
108+ }
109+
110+ return false ;
62111}
0 commit comments