Skip to content

Commit 345d1c2

Browse files
committed
Decide for ourselves whether a file is a shell file
1 parent 54d6e0b commit 345d1c2

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

entry.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#!/usr/bin/env node
22

33
import { exec } from "child_process";
4-
import { readFile, writeFile } from "fs";
4+
import { createReadStream, readFile, writeFile } from "fs";
5+
import { createInterface } from "readline";
56

67
/**
78
* Path to an empty file that we can provide to linters/formatters as a config
@@ -39,6 +40,9 @@ const run = (...args: string[]) =>
3940
);
4041
});
4142

43+
/** Type guard that returns true iff the given value is truthy */
44+
export const isTruthy = <T>(value: T): value is NonNullable<T> => !!value;
45+
4246
/** Reads a file, transforms its contents, and writes the result if different */
4347
const transformFile = (path: string, transform: (before: string) => string) =>
4448
new Promise<void>((resolve, reject) => {
@@ -346,8 +350,32 @@ const HOOKS: Record<HookName, LockableHook> = {
346350
[HookName.Shfmt]: createLockableHook({
347351
action: async sources => {
348352
// Find source files that are Shell files
349-
const shellSources = (await run("/shfmt", "-f", ...sources)).trim();
350-
if (!shellSources) {
353+
const shellSources = (
354+
await Promise.all(
355+
sources.map(async source => {
356+
// Check file extension
357+
if (/\.(bash|sh|zsh)$/.test(source)) {
358+
return source;
359+
}
360+
361+
// Check shebang
362+
const firstLine = await new Promise<string>(resolve => {
363+
// https://stackoverflow.com/a/45556848
364+
const reader = createInterface({
365+
input: createReadStream(source),
366+
});
367+
reader.on("line", line => {
368+
reader.close();
369+
resolve(line);
370+
});
371+
});
372+
if (/^#!.*\b(bash|sh|zsh)\b/.test(firstLine)) {
373+
return source;
374+
}
375+
}),
376+
)
377+
).filter(isTruthy);
378+
if (!shellSources.length) {
351379
return;
352380
}
353381

@@ -360,7 +388,7 @@ const HOOKS: Record<HookName, LockableHook> = {
360388
"-s", // Simplify code
361389
"-sr", // Add space after redirect operators
362390
"-w", // Write
363-
...shellSources.split("\n"),
391+
...shellSources,
364392
);
365393
},
366394
// pre-commit's `types: [text]` config option sometimes has false positives,

0 commit comments

Comments
 (0)