Skip to content

Commit bf53d49

Browse files
authored
Merge pull request #1081 from liljaylj/main
feat: handle shellcheck's `shell` directive
2 parents bd9ec9e + a23edab commit bf53d49

File tree

8 files changed

+76
-3
lines changed

8 files changed

+76
-3
lines changed

server/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Bash Language Server
22

3+
## 5.1.2
4+
5+
- Use shellcheck's shell directive for selecting the dialect https://github.com/bash-lsp/bash-language-server/pull/1081
6+
37
## 5.1.1
48

59
- Add --help fallback for documentation https://github.com/bash-lsp/bash-language-server/pull/1052

server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "A language server for Bash",
44
"author": "Mads Hartmann",
55
"license": "MIT",
6-
"version": "5.1.1",
6+
"version": "5.1.2",
77
"main": "./out/server.js",
88
"typings": "./out/server.d.ts",
99
"bin": {

server/src/__tests__/__snapshots__/server.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ exports[`server onRenameRequest Workspace-wide rename returns correct WorkspaceE
906906
},
907907
},
908908
],
909+
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/shell-directive.bash": [],
909910
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/source.sh": [],
910911
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/sourced.sh": [],
911912
"file://__REPO_ROOT_FOLDER__/testing/fixtures/sourcing.sh": [],
@@ -997,6 +998,7 @@ exports[`server onRenameRequest Workspace-wide rename returns correct WorkspaceE
997998
},
998999
},
9991000
],
1001+
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/shell-directive.bash": [],
10001002
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/source.sh": [],
10011003
"file://__REPO_ROOT_FOLDER__/testing/fixtures/shellcheck/sourced.sh": [],
10021004
"file://__REPO_ROOT_FOLDER__/testing/fixtures/sourcing.sh": [],

server/src/__tests__/analyzer.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { Logger } from '../util/logger'
1616
const CURRENT_URI = 'dummy-uri.sh'
1717

1818
// if you add a .sh file to testing/fixtures, update this value
19-
const FIXTURE_FILES_MATCHING_GLOB = 17
19+
const FIXTURE_FILES_MATCHING_GLOB = 18
2020

2121
const defaultConfig = getDefaultConfiguration()
2222

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { FIXTURE_DOCUMENT } from '../../../../testing/fixtures'
12
import { analyzeShebang } from '../shebang'
23

34
describe('analyzeShebang', () => {
@@ -35,4 +36,28 @@ describe('analyzeShebang', () => {
3536
expect(analyzeShebang(command).shellDialect).toBe(expectedDialect)
3637
expect(analyzeShebang(`${command} `).shellDialect).toBe(expectedDialect)
3738
})
39+
40+
it('returns shell dialect from shell directive', () => {
41+
expect(analyzeShebang('# shellcheck shell=dash')).toEqual({
42+
shellDialect: 'dash',
43+
shebang: null,
44+
})
45+
})
46+
47+
it('returns shell dialect when multiple directives are passed', () => {
48+
expect(
49+
analyzeShebang(
50+
'# shellcheck enable=require-variable-braces shell=dash disable=SC1000',
51+
),
52+
).toEqual({
53+
shellDialect: 'dash',
54+
shebang: null,
55+
})
56+
})
57+
58+
it('shell directive overrides file extension and shebang', () => {
59+
expect(
60+
analyzeShebang(FIXTURE_DOCUMENT.SHELLCHECK_SHELL_DIRECTIVE.getText()),
61+
).toHaveProperty('shellDialect', 'sh')
62+
})
3863
})

server/src/util/shebang.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ const SHELL_REGEXP = /bin[/](?:env )?(\w+)/
55
const BASH_DIALECTS = ['sh', 'bash', 'dash', 'ksh', 'zsh', 'csh', 'ash'] as const
66
type BashDialect = (typeof BASH_DIALECTS)[number]
77

8+
const SHELL_DIRECTIVE_REGEXP = new RegExp(
9+
`^\\s*#\\s*shellcheck.*shell=(${BASH_DIALECTS.join('|')}).*$|^\\s*#.*$|^\\s*$`,
10+
)
11+
812
export function getShebang(fileContent: string): string | null {
913
const match = SHEBANG_REGEXP.exec(fileContent)
1014
if (!match || !match[1]) {
@@ -26,13 +30,34 @@ export function getShellDialect(shebang: string): BashDialect | null {
2630
return null
2731
}
2832

33+
export function getShellDialectFromShellDirective(
34+
fileContent: string,
35+
): BashDialect | null {
36+
const contentLines = fileContent.split('\n')
37+
for (const line of contentLines) {
38+
const match = SHELL_DIRECTIVE_REGEXP.exec(line)
39+
if (match === null) {
40+
break
41+
}
42+
if (match[1]) {
43+
const bashDialect = match[1].trim() as any
44+
if (BASH_DIALECTS.includes(bashDialect)) {
45+
return bashDialect
46+
}
47+
}
48+
}
49+
return null
50+
}
51+
2952
export function analyzeShebang(fileContent: string): {
3053
shellDialect: BashDialect | null
3154
shebang: string | null
3255
} {
3356
const shebang = getShebang(fileContent)
3457
return {
3558
shebang,
36-
shellDialect: shebang ? getShellDialect(shebang) : null,
59+
shellDialect:
60+
getShellDialectFromShellDirective(fileContent) ??
61+
(shebang ? getShellDialect(shebang) : null),
3762
}
3863
}

testing/fixtures.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export const FIXTURE_URI = {
2929
PARSE_PROBLEMS: `file://${path.join(FIXTURE_FOLDER, 'parse-problems.sh')}`,
3030
SCOPE: `file://${path.join(FIXTURE_FOLDER, 'scope.sh')}`,
3131
SHELLCHECK_SOURCE: `file://${path.join(FIXTURE_FOLDER, 'shellcheck', 'source.sh')}`,
32+
SHELLCHECK_SHELL_DIRECTIVE: `file://${path.join(
33+
FIXTURE_FOLDER,
34+
'shellcheck',
35+
'shell-directive.bash',
36+
)}`,
3237
SOURCING: `file://${path.join(FIXTURE_FOLDER, 'sourcing.sh')}`,
3338
SOURCING2: `file://${path.join(FIXTURE_FOLDER, 'sourcing2.sh')}`,
3439
RENAMING: `file://${path.join(FIXTURE_FOLDER, 'renaming.sh')}`,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/env ksh
2+
# this shebang must be overriden by shell directive
3+
# this line must be ignored
4+
5+
# shellcheck disable=SC1072 shell=sh enable=require-variable-braces
6+
7+
8+
if [[ -n "$TERM" ]]; then
9+
echo "$TERM"
10+
fi
11+
12+
# shellcheck shell=dash

0 commit comments

Comments
 (0)