Skip to content

Commit a4a606d

Browse files
committed
Switch to fast-glob instead of glob + limit files analyzed
This should ensure that the LSP server does not crash and yield a major performance increase for large repositories. fast-glob returns the same results and is around 10x faster.
1 parent 42542c5 commit a4a606d

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

server/src/analyser.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { promisify } from 'util'
77
import * as LSP from 'vscode-languageserver'
88
import * as Parser from 'web-tree-sitter'
99

10-
import { getGlobPattern } from './config'
10+
import * as config from './config'
1111
import { flattenArray, flattenObjectValues } from './util/flatten'
1212
import { getFilePaths } from './util/fs'
1313
import { getShebang, isBashShebang } from './util/shebang'
@@ -84,7 +84,8 @@ export default class Analyzer {
8484
connection: LSP.Connection
8585
rootPath: string
8686
}) {
87-
const globPattern = getGlobPattern()
87+
const globPattern = config.getGlobPattern()
88+
const backgroundAnalysisMaxFiles = config.getBackgroundAnalysisMaxFiles()
8889
connection.console.log(
8990
`BackgroundAnalysis: resolving glob "${globPattern}" inside "${rootPath}"...`,
9091
)
@@ -97,6 +98,7 @@ export default class Analyzer {
9798
filePaths = await getFilePaths({
9899
globPattern,
99100
rootPath,
101+
maxItems: backgroundAnalysisMaxFiles,
100102
})
101103
} catch (error) {
102104
const errorMessage = error instanceof Error ? error.message : error

server/src/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const DEFAULT_GLOB_PATTERN = '**/*@(.sh|.inc|.bash|.command)'
2+
export const DEFAULT_BACKGROUND_ANALYSIS_MAX_FILES = 5000
23

34
export function getShellcheckPath(): string | null {
45
const { SHELLCHECK_PATH } = process.env
@@ -26,3 +27,9 @@ export function getHighlightParsingError(): boolean {
2627
? HIGHLIGHT_PARSING_ERRORS === 'true' || HIGHLIGHT_PARSING_ERRORS === '1'
2728
: false
2829
}
30+
31+
export function getBackgroundAnalysisMaxFiles(): number {
32+
const { BACKGROUND_ANALYSIS_MAX_FILES } = process.env
33+
const parsed = parseInt(BACKGROUND_ANALYSIS_MAX_FILES || '', 10)
34+
return !isNaN(parsed) ? parsed : DEFAULT_BACKGROUND_ANALYSIS_MAX_FILES
35+
}

server/src/util/fs.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import * as glob from 'glob'
2-
import * as Os from 'os'
1+
import * as fastGlob from 'fast-glob'
2+
import * as os from 'os'
33

44
// from https://github.com/sindresorhus/untildify/blob/f85a087418aeaa2beb56fe2684fe3b64fc8c588d/index.js#L11
55
export function untildify(pathWithTilde: string): string {
6-
const homeDirectory = Os.homedir()
6+
const homeDirectory = os.homedir()
77
return homeDirectory
88
? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory)
99
: pathWithTilde
@@ -12,21 +12,33 @@ export function untildify(pathWithTilde: string): string {
1212
export async function getFilePaths({
1313
globPattern,
1414
rootPath,
15+
maxItems,
1516
}: {
1617
globPattern: string
1718
rootPath: string
19+
maxItems: number
1820
}): Promise<string[]> {
19-
return new Promise((resolve, reject) => {
20-
glob(
21-
globPattern,
22-
{ cwd: rootPath, nodir: true, absolute: true, strict: false },
23-
function (err, files) {
24-
if (err) {
25-
return reject(err)
26-
}
27-
28-
resolve(files)
29-
},
30-
)
21+
const stream = fastGlob.stream([globPattern], {
22+
absolute: true,
23+
onlyFiles: true,
24+
cwd: rootPath,
25+
followSymbolicLinks: true,
26+
suppressErrors: true,
3127
})
28+
29+
// NOTE: we use a stream here to not block the event loop
30+
// and ensure that we stop reading files if the glob returns
31+
// too many files.
32+
const files = []
33+
let i = 0
34+
for await (const fileEntry of stream) {
35+
if (i >= maxItems) {
36+
break
37+
}
38+
39+
files.push(fileEntry.toString())
40+
i++
41+
}
42+
43+
return files
3244
}

0 commit comments

Comments
 (0)