-
Notifications
You must be signed in to change notification settings - Fork 143
Expand file tree
/
Copy pathconfig.ts
More file actions
131 lines (103 loc) · 5.54 KB
/
config.ts
File metadata and controls
131 lines (103 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { z } from 'zod'
import { DEFAULT_LOG_LEVEL, LOG_LEVEL_ENV_VAR, LOG_LEVELS } from './util/logger'
export const ConfigSchema = z.object({
// Maximum number of files to analyze in the background. Set to 0 to disable background analysis.
backgroundAnalysisMaxFiles: z.number().int().min(0).default(500),
// Enable diagnostics for source errors. Ignored if includeAllWorkspaceSymbols is true.
enableSourceErrorDiagnostics: z.boolean().default(false),
// Glob pattern for finding and parsing shell script files in the workspace. Used by the background analysis features across files.
globPattern: z.string().trim().default('**/*@(.sh|.inc|.bash|.command)'),
// Configure explainshell server endpoint in order to get hover documentation on flags and options.
// And empty string will disable the feature.
explainshellEndpoint: z.string().trim().default(''),
// Log level for the server. To set the right log level from the start please also use the environment variable 'BASH_IDE_LOG_LEVEL'.
logLevel: z.enum(LOG_LEVELS).default(DEFAULT_LOG_LEVEL),
// Controls how symbols (e.g. variables and functions) are included and used for completion, documentation, and renaming.
// If false, then we only include symbols from sourced files (i.e. using non dynamic statements like 'source file.sh' or '. file.sh' or following ShellCheck directives).
// If true, then all symbols from the workspace are included.
includeAllWorkspaceSymbols: z.boolean().default(false),
// Controls whether ShellCheck is invoked with --external-sources. When enabled (default),
// ShellCheck follows source directives to lint referenced files. On projects with many
// cross-sourcing scripts this can cause unbounded memory growth. Set to false to disable.
shellcheckExternalSources: z.boolean().default(true),
// Additional ShellCheck arguments. Note that we already add the following arguments: --shell, --format, and --external-sources (if shellcheckExternalSources is true).
shellcheckArguments: z
.preprocess((arg) => {
let argsList: string[] = []
if (typeof arg === 'string') {
argsList = arg.split(' ')
} else if (Array.isArray(arg)) {
argsList = arg as string[]
}
return argsList.map((s) => s.trim()).filter((s) => s.length > 0)
}, z.array(z.string()))
.default([]),
// Controls the executable used for ShellCheck linting information. An empty string will disable linting.
shellcheckPath: z.string().trim().default('shellcheck'),
shfmt: z
.object({
// Controls the executable used for Shfmt formatting. An empty string will disable formatting
path: z.string().trim().default('shfmt'),
// Ignore shfmt config options in .editorconfig (always use language server config)
ignoreEditorconfig: z.boolean().default(false),
// Language dialect to use when parsing (bash/posix/mksh/bats).
languageDialect: z.enum(['auto', 'bash', 'posix', 'mksh', 'bats']).default('auto'),
// Allow boolean operators (like && and ||) to start a line.
binaryNextLine: z.boolean().default(false),
// Indent patterns in case statements.
caseIndent: z.boolean().default(false),
// Place function opening braces on a separate line.
funcNextLine: z.boolean().default(false),
// (Deprecated) Keep column alignment padding.
keepPadding: z.boolean().default(false),
// Simplify code before formatting.
simplifyCode: z.boolean().default(false),
// Follow redirection operators with a space.
spaceRedirects: z.boolean().default(false),
})
.default({}),
})
export type Config = z.infer<typeof ConfigSchema>
export function getConfigFromEnvironmentVariables(): {
config: Config
environmentVariablesUsed: string[]
} {
const rawConfig = {
backgroundAnalysisMaxFiles: toNumber(process.env.BACKGROUND_ANALYSIS_MAX_FILES),
enableSourceErrorDiagnostics: toBoolean(process.env.ENABLE_SOURCE_ERROR_DIAGNOSTICS),
explainshellEndpoint: process.env.EXPLAINSHELL_ENDPOINT,
globPattern: process.env.GLOB_PATTERN,
includeAllWorkspaceSymbols: toBoolean(process.env.INCLUDE_ALL_WORKSPACE_SYMBOLS),
logLevel: process.env[LOG_LEVEL_ENV_VAR],
shellcheckArguments: process.env.SHELLCHECK_ARGUMENTS,
shellcheckExternalSources: toBoolean(process.env.SHELLCHECK_EXTERNAL_SOURCES),
shellcheckPath: process.env.SHELLCHECK_PATH,
shfmt: {
path: process.env.SHFMT_PATH,
ignoreEditorconfig: toBoolean(process.env.SHFMT_IGNORE_EDITORCONFIG),
languageDialect: process.env.SHFMT_LANGUAGE_DIALECT,
binaryNextLine: toBoolean(process.env.SHFMT_BINARY_NEXT_LINE),
caseIndent: toBoolean(process.env.SHFMT_CASE_INDENT),
funcNextLine: toBoolean(process.env.SHFMT_FUNC_NEXT_LINE),
keepPadding: toBoolean(process.env.SHFMT_KEEP_PADDING),
simplifyCode: toBoolean(process.env.SHFMT_SIMPLIFY_CODE),
spaceRedirects: toBoolean(process.env.SHFMT_SPACE_REDIRECTS),
},
}
const environmentVariablesUsed = Object.entries(rawConfig)
.filter(
([key, value]) =>
!['undefined', 'object'].includes(typeof value) &&
![null, 'logLevel'].includes(key),
)
.map(([key]) => key)
const config = ConfigSchema.parse(rawConfig)
return { config, environmentVariablesUsed }
}
export function getDefaultConfiguration(): Config {
return ConfigSchema.parse({})
}
const toBoolean = (s?: string): boolean | undefined =>
typeof s !== 'undefined' ? s === 'true' || s === '1' : undefined
const toNumber = (s?: string): number | undefined =>
typeof s !== 'undefined' ? parseInt(s, 10) : undefined