Skip to content

Commit 80343cb

Browse files
committed
Fixes error with fast-glob and lack of dir access
When the read permissions are missing from a directory, `fast-glob` throws a EACCES error and if you try and suppress it, it ends up with a race condition. This is most likely a bug and I have opened an issue. In the meantime, we are using `glob` which is noticeably slower to recover.
1 parent 8e29811 commit 80343cb

File tree

3 files changed

+39
-27
lines changed

3 files changed

+39
-27
lines changed

package-lock.json

Lines changed: 8 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@
264264
"eslint-plugin-import": "^2.25.3",
265265
"eslint-plugin-jsdoc": "^37.0.3",
266266
"eslint-plugin-prettier": "^4.0.0",
267-
"glob": "^7.2.0",
268267
"husky": "^7.0.0",
269268
"lint-staged": "^11.2.6",
270269
"mocha": "^9.1.3",
@@ -281,6 +280,7 @@
281280
},
282281
"dependencies": {
283282
"fast-glob": "^3.2.7",
283+
"glob": "^7.2.0",
284284
"vscode-languageclient": "^7.0.0",
285285
"which": "^2.0.2"
286286
}

src/features/linter-provider.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as vscode from 'vscode';
88
import { LoggingService } from '../services/logging-service';
99
import { resolveVariables } from '../lib/tools';
1010
import * as fg from 'fast-glob';
11+
import { glob } from 'glob';
1112

1213
export default class FortranLintingProvider {
1314
constructor(private loggingService: LoggingService) {}
@@ -174,13 +175,38 @@ export default class FortranLintingProvider {
174175
private getIncludePaths(): string[] {
175176
const config = vscode.workspace.getConfiguration('fortran');
176177
const includePaths: string[] = config.get('includePaths', []);
178+
// Output the original include paths
179+
this.loggingService.logInfo(`Linter.include:\n${includePaths.join('\r\n')}`);
177180
// Resolve internal variables and expand glob patterns
178181
const resIncludePaths = includePaths.map(e => resolveVariables(e));
179182
// This needs to be after the resolvevariables since {} are used in globs
180-
const globIncPaths: string[] = fg.sync(resIncludePaths, { onlyDirectories: true });
181-
// Output the original include paths
182-
this.loggingService.logInfo(`Linter.include:\n${includePaths.join('\r\n')}`);
183-
return globIncPaths;
183+
try {
184+
const globIncPaths: string[] = fg.sync(resIncludePaths, {
185+
onlyDirectories: true,
186+
suppressErrors: false,
187+
});
188+
return globIncPaths;
189+
// Try to recover from fast-glob failing due to EACCES using slower more
190+
// robust glob.
191+
} catch (eacces) {
192+
this.loggingService.logWarning(`You lack read permissions for an include directory
193+
or more likely a glob match from the input 'includePaths' list. This can happen when
194+
using overly broad root level glob patters e.g. /usr/lib/** .
195+
No reason to worry. I will attempt to recover.
196+
You should consider adjusting your 'includePaths' if linting performance is slow.`);
197+
this.loggingService.logWarning(`${eacces.message}`);
198+
try {
199+
const globIncPaths: string[] = [];
200+
for (const i of resIncludePaths) {
201+
// use '/' to match only directories and not files
202+
globIncPaths.push(...glob.sync(i + '/', { strict: false }));
203+
}
204+
return globIncPaths;
205+
// if we failed again then our includes are somehow wrong. Abort
206+
} catch (error) {
207+
this.loggingService.logError(`Failed to recover: ${error}`);
208+
}
209+
}
184210
}
185211

186212
private getGfortranPath(): string {

0 commit comments

Comments
 (0)