Add support for shell fragments separated by comments
This commit is contained in:
parent
74e7f4c3e6
commit
3693a2fd05
|
@ -8,7 +8,8 @@ CMD echo "test"
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(cmd_instruction
|
(cmd_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Shell command multiline
|
Shell command multiline
|
||||||
|
@ -23,7 +24,12 @@ CMD echo "test" \
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(cmd_instruction
|
(cmd_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Run with shell empty array
|
Run with shell empty array
|
||||||
|
|
|
@ -19,3 +19,22 @@ COPY libsqlite3-pcre-install-alpine.sh /libsqlite3-pcre-install-alpine.sh
|
||||||
(path)
|
(path)
|
||||||
(path)))
|
(path)))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Run interrupted with comment
|
||||||
|
==================
|
||||||
|
|
||||||
|
RUN echo hello \
|
||||||
|
# comment
|
||||||
|
# comment2
|
||||||
|
world
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(run_instruction
|
||||||
|
(shell_command
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(comment)
|
||||||
|
(comment)
|
||||||
|
(shell_fragment))))
|
||||||
|
|
|
@ -8,10 +8,11 @@ ENTRYPOINT echo "test"
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(entrypoint_instruction
|
(entrypoint_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Shell command multiline
|
Entrypoint Shell command multiline
|
||||||
==================
|
==================
|
||||||
|
|
||||||
ENTRYPOINT echo "test" \
|
ENTRYPOINT echo "test" \
|
||||||
|
@ -23,7 +24,12 @@ ENTRYPOINT echo "test" \
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(entrypoint_instruction
|
(entrypoint_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Run with shell empty array
|
Run with shell empty array
|
||||||
|
|
|
@ -57,6 +57,7 @@ ENV TEST1="foo" \
|
||||||
(env_pair
|
(env_pair
|
||||||
name: (unquoted_string)
|
name: (unquoted_string)
|
||||||
value: (double_quoted_string))
|
value: (double_quoted_string))
|
||||||
|
(line_continuation)
|
||||||
(env_pair
|
(env_pair
|
||||||
name: (unquoted_string)
|
name: (unquoted_string)
|
||||||
value: (unquoted_string))))
|
value: (unquoted_string))))
|
||||||
|
|
|
@ -20,7 +20,8 @@ HEALTHCHECK CMD echo "test"
|
||||||
(source_file
|
(source_file
|
||||||
(healthcheck_instruction
|
(healthcheck_instruction
|
||||||
(cmd_instruction
|
(cmd_instruction
|
||||||
(shell_command))))
|
(shell_command
|
||||||
|
(shell_fragment)))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
With options
|
With options
|
||||||
|
@ -35,5 +36,6 @@ HEALTHCHECK --interval=10s --retries=10 CMD echo "test"
|
||||||
(param)
|
(param)
|
||||||
(param)
|
(param)
|
||||||
(cmd_instruction
|
(cmd_instruction
|
||||||
(shell_command))))
|
(shell_command
|
||||||
|
(shell_fragment)))))
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ LABEL key.1="value1" \
|
||||||
(label_pair
|
(label_pair
|
||||||
key: (unquoted_string)
|
key: (unquoted_string)
|
||||||
value: (double_quoted_string))
|
value: (double_quoted_string))
|
||||||
|
(line_continuation)
|
||||||
(label_pair
|
(label_pair
|
||||||
key: (unquoted_string)
|
key: (unquoted_string)
|
||||||
value: (double_quoted_string))))
|
value: (double_quoted_string))))
|
||||||
|
|
|
@ -23,4 +23,5 @@ ONBUILD RUN /usr/local/bin/python-build --dir /app/src
|
||||||
(source_file
|
(source_file
|
||||||
(onbuild_instruction
|
(onbuild_instruction
|
||||||
(run_instruction
|
(run_instruction
|
||||||
(shell_command))))
|
(shell_command
|
||||||
|
(shell_fragment)))))
|
||||||
|
|
|
@ -8,7 +8,8 @@ RUN echo "test"
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(run_instruction
|
(run_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Shell command multiline
|
Shell command multiline
|
||||||
|
@ -23,7 +24,12 @@ RUN echo "test" \
|
||||||
|
|
||||||
(source_file
|
(source_file
|
||||||
(run_instruction
|
(run_instruction
|
||||||
(shell_command)))
|
(shell_command
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment)
|
||||||
|
(line_continuation)
|
||||||
|
(shell_fragment))))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Run with shell empty array
|
Run with shell empty array
|
||||||
|
|
|
@ -56,8 +56,7 @@ Env
|
||||||
ENV TEST="foo$BAR" \
|
ENV TEST="foo$BAR" \
|
||||||
TEST_2=foo\ bar$BAZ \
|
TEST_2=foo\ bar$BAZ \
|
||||||
TEST_3="foo${bar}" \
|
TEST_3="foo${bar}" \
|
||||||
TEST_4=foo\ ${baz}bar \
|
TEST_4=foo\ ${baz}bar
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -68,16 +67,19 @@ ENV TEST="foo$BAR" \
|
||||||
value: (double_quoted_string
|
value: (double_quoted_string
|
||||||
(expansion
|
(expansion
|
||||||
(variable))))
|
(variable))))
|
||||||
|
(line_continuation)
|
||||||
(env_pair
|
(env_pair
|
||||||
name: (unquoted_string)
|
name: (unquoted_string)
|
||||||
value: (unquoted_string
|
value: (unquoted_string
|
||||||
(expansion
|
(expansion
|
||||||
(variable))))
|
(variable))))
|
||||||
|
(line_continuation)
|
||||||
(env_pair
|
(env_pair
|
||||||
name: (unquoted_string)
|
name: (unquoted_string)
|
||||||
value: (double_quoted_string
|
value: (double_quoted_string
|
||||||
(expansion
|
(expansion
|
||||||
(variable))))
|
(variable))))
|
||||||
|
(line_continuation)
|
||||||
(env_pair
|
(env_pair
|
||||||
name: (unquoted_string)
|
name: (unquoted_string)
|
||||||
value: (unquoted_string
|
value: (unquoted_string
|
||||||
|
|
|
@ -36,6 +36,7 @@ VOLUME /myvol1 \
|
||||||
(source_file
|
(source_file
|
||||||
(volume_instruction
|
(volume_instruction
|
||||||
(path)
|
(path)
|
||||||
|
(line_continuation)
|
||||||
(path)))
|
(path)))
|
||||||
|
|
||||||
==================
|
==================
|
||||||
|
@ -64,4 +65,5 @@ VOLUME ["/test/myvol", \
|
||||||
(volume_instruction
|
(volume_instruction
|
||||||
(string_array
|
(string_array
|
||||||
(double_quoted_string)
|
(double_quoted_string)
|
||||||
|
(line_continuation)
|
||||||
(double_quoted_string))))
|
(double_quoted_string))))
|
||||||
|
|
21
grammar.js
21
grammar.js
|
@ -283,10 +283,27 @@ module.exports = grammar({
|
||||||
),
|
),
|
||||||
|
|
||||||
shell_command: $ => seq(
|
shell_command: $ => seq(
|
||||||
/[^\[\s].*[^\\\n]/, // TODO allow escape sequences
|
$.shell_fragment,
|
||||||
repeat(seq("\\\n", /.*[^\\\n]/)),
|
repeat(seq(
|
||||||
|
$.line_continuation,
|
||||||
|
repeat($._comment_line),
|
||||||
|
$.shell_fragment,
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
shell_fragment: $ => repeat1(choice(
|
||||||
|
/[^\\\[\n#\s][^\\\[\n]*/, // non-escape or newline character
|
||||||
|
/\\[^\n]/, // non-line-continuation escape
|
||||||
|
)),
|
||||||
|
|
||||||
|
line_continuation: $ => '\\\n',
|
||||||
|
|
||||||
|
_comment_line: $ => seq(
|
||||||
|
alias($._anon_comment, $.comment), '\n'
|
||||||
|
),
|
||||||
|
|
||||||
|
_anon_comment: $ => seq('#', /.*/),
|
||||||
|
|
||||||
double_quoted_string: $ => seq(
|
double_quoted_string: $ => seq(
|
||||||
'"',
|
'"',
|
||||||
repeat(choice(
|
repeat(choice(
|
||||||
|
|
|
@ -1198,8 +1198,8 @@
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "SYMBOL",
|
||||||
"value": "[^\\[\\s].*[^\\\\\\n]"
|
"name": "shell_fragment"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "REPEAT",
|
"type": "REPEAT",
|
||||||
|
@ -1207,18 +1207,76 @@
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "SYMBOL",
|
||||||
"value": "\\\n"
|
"name": "line_continuation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "REPEAT",
|
||||||
"value": ".*[^\\\\\\n]"
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_comment_line"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "shell_fragment"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"shell_fragment": {
|
||||||
|
"type": "REPEAT1",
|
||||||
|
"content": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "PATTERN",
|
||||||
|
"value": "[^\\\\\\[\\n#\\s][^\\\\\\[\\n]*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PATTERN",
|
||||||
|
"value": "\\\\[^\\n]"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"line_continuation": {
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "\\\n"
|
||||||
|
},
|
||||||
|
"_comment_line": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "ALIAS",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_anon_comment"
|
||||||
|
},
|
||||||
|
"named": true,
|
||||||
|
"value": "comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "\n"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_anon_comment": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "#"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PATTERN",
|
||||||
|
"value": ".*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"double_quoted_string": {
|
"double_quoted_string": {
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
|
|
|
@ -530,6 +530,29 @@
|
||||||
{
|
{
|
||||||
"type": "shell_command",
|
"type": "shell_command",
|
||||||
"named": true,
|
"named": true,
|
||||||
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": true,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "comment",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "line_continuation",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell_fragment",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shell_fragment",
|
||||||
|
"named": true,
|
||||||
"fields": {}
|
"fields": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -855,10 +878,6 @@
|
||||||
"type": "[",
|
"type": "[",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "\\\n",
|
|
||||||
"named": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "\\ ",
|
"type": "\\ ",
|
||||||
"named": false
|
"named": false
|
||||||
|
@ -871,6 +890,10 @@
|
||||||
"type": "escape_sequence",
|
"type": "escape_sequence",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "line_continuation",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "variable",
|
"type": "variable",
|
||||||
"named": true
|
"named": true
|
||||||
|
|
8511
src/parser.c
8511
src/parser.c
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue