Skip to content

Commit e43b480

Browse files
committed
Skip linting zsh files
1 parent 0bd2212 commit e43b480

File tree

4 files changed

+59
-27
lines changed

4 files changed

+59
-27
lines changed

server/src/shellcheck/index.ts

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,37 +71,49 @@ export class Linter {
7171
sourcePaths: string[],
7272
additionalShellCheckArguments: string[] = [],
7373
): Promise<LintingResult> {
74+
const documentText = document.getText()
75+
76+
const shellDialect = guessShellDialect({
77+
documentText,
78+
uri: document.uri,
79+
})
80+
81+
if (shellDialect && !SUPPORTED_BASH_DIALECTS.includes(shellDialect)) {
82+
// We found a dialect that isn't supported by ShellCheck.
83+
return { diagnostics: [], codeActions: [] }
84+
}
85+
86+
// NOTE: that ShellCheck actually does shebang parsing, but we manually
87+
// do it here in order to fallback to bash for files without a shebang.
88+
// This enables parsing files with a bash syntax, but could yield false positives.
89+
const shellName =
90+
shellDialect && SUPPORTED_BASH_DIALECTS.includes(shellDialect)
91+
? shellDialect
92+
: 'bash'
93+
7494
const result = await this.runShellCheck(
75-
document,
95+
documentText,
96+
shellName,
7697
[...sourcePaths, dirname(fileURLToPath(document.uri))],
7798
additionalShellCheckArguments,
7899
)
100+
79101
if (!this._canLint) {
80102
return { diagnostics: [], codeActions: [] }
81103
}
82104

83105
// Clean up the debounced function
84106
delete this.uriToDebouncedExecuteLint[document.uri]
85107

86-
return mapShellCheckResult({ document, result })
108+
return mapShellCheckResult({ uri: document.uri, result })
87109
}
88110

89111
private async runShellCheck(
90-
document: TextDocument,
112+
documentText: string,
113+
shellName: string,
91114
sourcePaths: string[],
92115
additionalArgs: string[] = [],
93116
): Promise<ShellCheckResult> {
94-
const documentText = document.getText()
95-
96-
const { shellDialect } = analyzeShebang(documentText)
97-
// NOTE: that ShellCheck actually does shebang parsing, but we manually
98-
// do it here in order to fallback to bash. This enables parsing files
99-
// with a bash syntax.
100-
const shellName =
101-
shellDialect && SUPPORTED_BASH_DIALECTS.includes(shellDialect)
102-
? shellDialect
103-
: 'bash'
104-
105117
const sourcePathsArgs = sourcePaths
106118
.map((folder) => folder.trim())
107119
.filter((folderName) => folderName)
@@ -169,10 +181,10 @@ export class Linter {
169181
}
170182

171183
function mapShellCheckResult({
172-
document,
184+
uri,
173185
result,
174186
}: {
175-
document: TextDocument
187+
uri: string
176188
result: ShellCheckResult
177189
}): {
178190
diagnostics: LSP.Diagnostic[]
@@ -208,8 +220,8 @@ function mapShellCheckResult({
208220

209221
const codeAction = CodeActionProvider.getCodeAction({
210222
comment,
211-
document,
212223
diagnostics: [diagnostic],
224+
uri,
213225
})
214226

215227
if (codeAction) {
@@ -230,12 +242,12 @@ function mapShellCheckResult({
230242
class CodeActionProvider {
231243
public static getCodeAction({
232244
comment,
233-
document,
234245
diagnostics,
246+
uri,
235247
}: {
236248
comment: ShellCheckComment
237-
document: TextDocument
238249
diagnostics: LSP.Diagnostic[]
250+
uri: string
239251
}): LSP.CodeAction | null {
240252
const { code, fix } = comment
241253
if (!fix || fix.replacements.length === 0) {
@@ -257,7 +269,7 @@ class CodeActionProvider {
257269
diagnostics,
258270
edit: {
259271
changes: {
260-
[document.uri]: edits,
272+
[uri]: edits,
261273
},
262274
},
263275
kind: LSP.CodeActionKind.QuickFix,
@@ -283,3 +295,7 @@ class CodeActionProvider {
283295
}
284296
}
285297
}
298+
299+
function guessShellDialect({ documentText, uri }: { documentText: string; uri: string }) {
300+
return uri.endsWith('.zsh') ? 'zsh' : analyzeShebang(documentText).shellDialect
301+
}

server/src/util/__tests__/shebang.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ describe('analyzeShebang', () => {
1212
})
1313
})
1414

15-
it('returns no shell dialect for unsupported shell "#!/usr/bin/zsh"', () => {
16-
expect(analyzeShebang('#!/usr/bin/zsh')).toEqual({
15+
it('returns no shell dialect for unsupported shell "#!/usr/bin/fish"', () => {
16+
expect(analyzeShebang('#!/usr/bin/fish')).toEqual({
1717
shellDialect: null,
18-
shebang: '/usr/bin/zsh',
18+
shebang: '/usr/bin/fish',
1919
})
2020
})
2121

@@ -30,6 +30,7 @@ describe('analyzeShebang', () => {
3030
['#! /bin/bash', 'bash'],
3131
['#! /bin/dash', 'dash'],
3232
['#!/usr/bin/bash', 'bash'],
33+
['#!/usr/bin/zsh', 'zsh'],
3334
])('returns a bash dialect for %p', (command, expectedDialect) => {
3435
expect(analyzeShebang(command).shellDialect).toBe(expectedDialect)
3536
expect(analyzeShebang(`${command} `).shellDialect).toBe(expectedDialect)

server/src/util/shebang.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
const SHEBANG_REGEXP = /^#!(.*)/
22
const SHELL_REGEXP = /bin[/](?:env )?(\w+)/
33

4-
const BASH_DIALECTS = ['sh', 'bash', 'dash', 'ksh'] as const
5-
type SupportedBashDialect = (typeof BASH_DIALECTS)[number]
4+
// Non exhaustive list of bash dialects that we potentially could support and try to analyze.
5+
const BASH_DIALECTS = ['sh', 'bash', 'dash', 'ksh', 'zsh', 'csh', 'ash'] as const
6+
type BashDialect = (typeof BASH_DIALECTS)[number]
67

78
export function getShebang(fileContent: string): string | null {
89
const match = SHEBANG_REGEXP.exec(fileContent)
@@ -13,7 +14,7 @@ export function getShebang(fileContent: string): string | null {
1314
return match[1].trim()
1415
}
1516

16-
export function getShellDialect(shebang: string): SupportedBashDialect | null {
17+
export function getShellDialect(shebang: string): BashDialect | null {
1718
const match = SHELL_REGEXP.exec(shebang)
1819
if (match && match[1]) {
1920
const bashDialect = match[1].trim() as any
@@ -26,7 +27,7 @@ export function getShellDialect(shebang: string): SupportedBashDialect | null {
2627
}
2728

2829
export function analyzeShebang(fileContent: string): {
29-
shellDialect: SupportedBashDialect | null
30+
shellDialect: BashDialect | null
3031
shebang: string | null
3132
} {
3233
const shebang = getShebang(fileContent)

testing/fixtures/basic-zsh.zsh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env zsh
2+
# Path to your oh-my-zsh installation.
3+
export ZSH=~/.oh-my-zsh
4+
5+
# Uncomment the following line if you want to disable marking untracked files
6+
# under VCS as dirty. This makes repository status check for large repositories
7+
# much, much faster.
8+
DISABLE_UNTRACKED_FILES_DIRTY="true"
9+
10+
fpath=(/usr/local/share/zsh-completions $fpath)
11+
12+
export CLICOLOR=1
13+
14+
echo $DISABLE_UNTRACKED_FILES_DIRTY

0 commit comments

Comments
 (0)