-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshfmt.mts
97 lines (88 loc) · 2.41 KB
/
shfmt.mts
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
/**
* @file dprint - shfmt
* @module dprint/shfmt
*/
import { ok } from 'devlop'
import editorconfig from 'editorconfig'
import { Transform } from 'node:stream'
import * as sh from 'sh-syntax'
declare module 'editorconfig' {
interface KnownProps {
binary_next_line?: boolean | undefined
function_next_line?: boolean | undefined
keep_comments?: boolean | undefined
keep_padding?: boolean | undefined
shell_variant?: sh.LangVariant | undefined
space_redirects?: boolean | undefined
switch_case_indent?: boolean | undefined
}
}
process.stdin.pipe(new Transform({
/**
* Formats a file using `sh-syntax`.
*
* @see https://github.com/un-ts/sh-syntax
* @see https://github.com/mvdan/sh/blob/master/cmd/shfmt/shfmt.1.scd
*
* @async
*
* @param {Buffer} buffer
* Data buffer
* @return {Promise<string>}
* Formatted file content
*/
async transform(buffer: Buffer): Promise<string> {
const [filepath] = process.argv.slice(2)
ok(typeof filepath === 'string', 'expected `filepath`')
const {
binary_next_line = true,
function_next_line = false,
indent_size = 2,
indent_style = 'space',
keep_comments = true,
keep_padding = false,
shell_variant = 0,
space_redirects = false,
switch_case_indent = true,
tab_width = 2
} = await editorconfig.parse(filepath)
/**
* Shell formatting options.
*
* @const {sh.ShOptions} options
*/
const options: sh.ShOptions = {
binaryNextLine: binary_next_line,
filepath,
functionNextLine: function_next_line,
indent: typeof indent_size === 'string' ? 2 : indent_size,
keepComments: keep_comments,
keepPadding: keep_padding,
minify: false,
spaceRedirects: space_redirects,
switchCaseIndent: switch_case_indent,
tabWidth: tab_width === 'unset' ? 2 : tab_width,
useTabs: indent_style === 'tab',
variant: shell_variant
}
/**
* Text to format.
*
* @const {string} originalText
*/
const originalText: string = buffer.toString()
/**
* Formatted text AST.
*
* @const {sh.File} ast
*/
const ast: sh.File = await sh.parse(originalText, options)
/**
* Formatted text.
*
* @const {string} text
*/
const text: string = await sh.print(ast, { ...options, originalText })
return process.stdout.write(text), text
}
}))