Skip to content

Commit 30c519b

Browse files
72636csamchungy
andauthored
Fix file descriptor warnings (#664)
Resolves #659. Co-authored-by: Sam Chung <[email protected]>
1 parent def7616 commit 30c519b

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

.changeset/shiny-cows-add.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"skuba": patch
3+
---
4+
5+
format, lint: Fix file descriptor warnings
6+
7+
This resolves the following warning when processing files that Prettier cannot parse:
8+
9+
```console
10+
(node:123) Warning: File descriptor 456 closed but not opened in unmanaged mode
11+
```

src/cli/adapter/prettier.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { inferParser } from './prettier';
2+
3+
describe('inferParser', () => {
4+
test.each`
5+
filepath | parser
6+
${'/usr/local/bin/secret.json'} | ${'json'}
7+
${'C:\\Users\\Devloper\\My CV.yml'} | ${'yaml'}
8+
${'CODEOWNERS'} | ${undefined}
9+
${'client.tsx'} | ${'typescript'}
10+
${'server.ts'} | ${'typescript'}
11+
${'vanilla.js'} | ${'babel'}
12+
`('inferParser($filepath) === $parser', ({ filepath, parser }) =>
13+
expect(inferParser(filepath)).toBe(parser),
14+
);
15+
});

src/cli/adapter/prettier.ts

+47-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,55 @@
11
import path from 'path';
22

33
import fs from 'fs-extra';
4-
import { Options, check, format, getFileInfo, resolveConfig } from 'prettier';
4+
import {
5+
Options,
6+
SupportLanguage,
7+
check,
8+
format,
9+
getSupportInfo,
10+
resolveConfig,
11+
} from 'prettier';
512

613
import { crawlDirectory } from '../../utils/dir';
714
import { Logger, pluralise } from '../../utils/logging';
815
import { getConsumerManifest } from '../../utils/manifest';
916

17+
let languages: SupportLanguage[] | undefined;
18+
19+
/**
20+
* Infers a parser for the specified filepath.
21+
*
22+
* This is a cut-down version of Prettier's built-in function of the same name;
23+
* ours operates purely on the `filepath` string and does not perform file I/O.
24+
* Prettier's internal `getInterpreter` function can open a file to read the
25+
* shebang, and its file descriptor usage can throw warnings on worker threads:
26+
*
27+
* ```console
28+
* Warning: File descriptor 123 closed but not opened in unmanaged mode
29+
* at Object.closeSync (node:fs:530:11)
30+
* at Object.closeSync (node_modules/graceful-fs/graceful-fs.js:74:20)
31+
* ...
32+
* ```
33+
*
34+
* References:
35+
*
36+
* - https://github.com/prettier/prettier/blob/2.4.1/src/main/options.js#L167
37+
* - seek-oss/skuba#659
38+
*/
39+
export const inferParser = (filepath: string): string | undefined => {
40+
const filename = path.basename(filepath).toLowerCase();
41+
42+
languages ??= getSupportInfo().languages.filter((language) => language.since);
43+
44+
const firstLanguage = languages.find(
45+
(language) =>
46+
language.extensions?.some((extension) => filename.endsWith(extension)) ||
47+
language.filenames?.some((name) => name.toLowerCase() === filename),
48+
);
49+
50+
return firstLanguage?.parsers[0];
51+
};
52+
1053
interface File {
1154
data: string;
1255
options: Options;
@@ -110,12 +153,12 @@ export const runPrettier = async (
110153

111154
for (const filepath of filepaths) {
112155
// Infer parser upfront so we can skip unsupported files.
113-
const fileInfo = await getFileInfo(filepath, { resolveConfig: false });
156+
const parser = inferParser(filepath);
114157

115158
logger.debug(filepath);
116-
logger.debug(' parser:', fileInfo.inferredParser ?? '-');
159+
logger.debug(' parser:', parser ?? '-');
117160

118-
if (!fileInfo.inferredParser) {
161+
if (!parser) {
119162
result.unparsed.push(filepath);
120163
continue;
121164
}

0 commit comments

Comments
 (0)