Format grammar.js with prettier
This commit is contained in:
parent
6c1ef89aa8
commit
f3a88aa686
428
grammar.js
428
grammar.js
|
@ -1,16 +1,13 @@
|
|||
module.exports = grammar({
|
||||
name: 'dockerfile',
|
||||
name: "dockerfile",
|
||||
|
||||
extras: $ => [
|
||||
$.comment,
|
||||
/\s+/,
|
||||
'\\\n'
|
||||
],
|
||||
extras: ($) => [$.comment, /\s+/, "\\\n"],
|
||||
|
||||
rules: {
|
||||
source_file: $ => repeat(seq($._instruction, "\n")),
|
||||
source_file: ($) => repeat(seq($._instruction, "\n")),
|
||||
|
||||
_instruction: $ => choice(
|
||||
_instruction: ($) =>
|
||||
choice(
|
||||
$.from_instruction,
|
||||
$.run_instruction,
|
||||
$.cmd_instruction,
|
||||
|
@ -29,324 +26,295 @@ module.exports = grammar({
|
|||
$.healthcheck_instruction,
|
||||
$.shell_instruction,
|
||||
$.maintainer_instruction,
|
||||
$.cross_build_instruction,
|
||||
$.cross_build_instruction
|
||||
),
|
||||
|
||||
from_instruction: $ => seq(
|
||||
from_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[fF][rR][oO][mM]/, "FROM"),
|
||||
$._non_newline_whitespace,
|
||||
optional($.param),
|
||||
$.image_spec,
|
||||
optional(seq(
|
||||
alias(/[aA][sS]/, "AS"),
|
||||
field("as", $.image_alias),
|
||||
)),
|
||||
optional(seq(alias(/[aA][sS]/, "AS"), field("as", $.image_alias)))
|
||||
),
|
||||
|
||||
run_instruction: $ => seq(
|
||||
run_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[rR][uU][nN]/, "RUN"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
$.string_array,
|
||||
$.shell_command,
|
||||
),
|
||||
choice($.string_array, $.shell_command)
|
||||
),
|
||||
|
||||
cmd_instruction: $ => seq(
|
||||
cmd_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[cC][mM][dD]/, "CMD"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
$.string_array,
|
||||
$.shell_command,
|
||||
),
|
||||
choice($.string_array, $.shell_command)
|
||||
),
|
||||
|
||||
label_instruction: $ => seq(
|
||||
label_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[lL][aA][bB][eE][lL]/, "LABEL"),
|
||||
$._non_newline_whitespace,
|
||||
repeat1($.label_pair),
|
||||
repeat1($.label_pair)
|
||||
),
|
||||
|
||||
expose_instruction: $ => seq(
|
||||
expose_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[eE][xX][pP][oO][sS][eE]/, "EXPOSE"),
|
||||
repeat1(choice($.expose_port, $.expansion)),
|
||||
repeat1(choice($.expose_port, $.expansion))
|
||||
),
|
||||
|
||||
env_instruction: $ => seq(
|
||||
env_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[eE][nN][vV]/, "ENV"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
repeat1($.env_pair),
|
||||
alias($._spaced_env_pair, $.env_pair),
|
||||
)
|
||||
choice(repeat1($.env_pair), alias($._spaced_env_pair, $.env_pair))
|
||||
),
|
||||
|
||||
add_instruction: $ => seq(
|
||||
add_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[aA][dD][dD]/, "ADD"),
|
||||
$._non_newline_whitespace,
|
||||
optional($.param),
|
||||
$.path,
|
||||
$._non_newline_whitespace,
|
||||
$.path,
|
||||
$.path
|
||||
),
|
||||
|
||||
copy_instruction: $ => seq(
|
||||
copy_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[cC][oO][pP][yY]/, "COPY"),
|
||||
$._non_newline_whitespace,
|
||||
optional($.param),
|
||||
$.path,
|
||||
$._non_newline_whitespace,
|
||||
$.path,
|
||||
$.path
|
||||
),
|
||||
|
||||
entrypoint_instruction: $ => seq(
|
||||
entrypoint_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[eE][nN][tT][rR][yY][pP][oO][iI][nN][tT]/, "ENTRYPOINT"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
$.string_array,
|
||||
$.shell_command,
|
||||
),
|
||||
choice($.string_array, $.shell_command)
|
||||
),
|
||||
|
||||
volume_instruction: $ => seq(
|
||||
volume_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[vV][oO][lL][uU][mM][eE]/, "VOLUME"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
$.string_array,
|
||||
seq(
|
||||
$.path,
|
||||
repeat(seq($._non_newline_whitespace, $.path)),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
user_instruction: $ => seq(
|
||||
alias(/[uU][sS][eE][rR]/, "USER"),
|
||||
$._non_newline_whitespace,
|
||||
field("user", alias($._user_name_group, $.unquoted_string)),
|
||||
optional(seq(
|
||||
token.immediate(":"),
|
||||
field("group", alias($._user_name_group, $.unquoted_string)),
|
||||
)),
|
||||
),
|
||||
|
||||
_user_name_group: $ => repeat1(choice(
|
||||
token.immediate(/[a-z][-a-z0-9_]*/),
|
||||
$.expansion,
|
||||
)),
|
||||
|
||||
workdir_instruction: $ => seq(
|
||||
alias(/[wW][oO][rR][kK][dD][iI][rR]/, "WORKDIR"),
|
||||
$._non_newline_whitespace,
|
||||
$.path,
|
||||
),
|
||||
|
||||
arg_instruction: $ => seq(
|
||||
alias(/[aA][rR][gG]/, "ARG"),
|
||||
$._non_newline_whitespace,
|
||||
field("name", alias(/[a-zA-Z0-9_]+/, $.unquoted_string)),
|
||||
optional(seq(
|
||||
token.immediate("="),
|
||||
field("default", choice(
|
||||
$.double_quoted_string,
|
||||
$.unquoted_string,
|
||||
)),
|
||||
)),
|
||||
),
|
||||
|
||||
onbuild_instruction: $ => seq(
|
||||
alias(/[oO][nN][bB][uU][iI][lL][dD]/, "ONBUILD"),
|
||||
$._non_newline_whitespace,
|
||||
$._instruction,
|
||||
),
|
||||
|
||||
stopsignal_instruction: $ => seq(
|
||||
alias(/[sS][tT][oO][pP][sS][iI][gG][nN][aA][lL]/, "STOPSIGNAL"),
|
||||
$._non_newline_whitespace,
|
||||
$._stopsignal_value,
|
||||
),
|
||||
|
||||
_stopsignal_value: $ => repeat1(choice(
|
||||
/[A-Z0-9]+/,
|
||||
$.expansion,
|
||||
)),
|
||||
|
||||
healthcheck_instruction: $ => seq(
|
||||
alias(/[hH][eE][aA][lL][tT][hH][cC][hH][eE][cC][kK]/, "HEALTHCHECK"),
|
||||
$._non_newline_whitespace,
|
||||
choice(
|
||||
"NONE",
|
||||
seq(
|
||||
repeat($.param),
|
||||
$.cmd_instruction,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
shell_instruction: $ => seq(
|
||||
alias(/[sS][hH][eE][lL][lL]/, "SHELL"),
|
||||
$._non_newline_whitespace,
|
||||
$.string_array,
|
||||
),
|
||||
|
||||
maintainer_instruction: $ => seq(
|
||||
alias(/[mM][aA][iI][nN][tT][aA][iI][nN][eE][rR]/, "MAINTAINER"),
|
||||
/.*/,
|
||||
),
|
||||
|
||||
cross_build_instruction: $ => seq(
|
||||
alias(/[cC][rR][oO][sS][sS]_[bB][uU][iI][lL][dD][a-zA-Z_]*/, "CROSS_BUILD"),
|
||||
/.*/,
|
||||
),
|
||||
|
||||
path: $ => seq(
|
||||
choice(
|
||||
/[^-\s\$]/, // cannot start with a '-' to avoid conflicts with params
|
||||
$.expansion,
|
||||
),
|
||||
repeat(choice(
|
||||
/[^\s\$]+/,
|
||||
$.expansion,
|
||||
)),
|
||||
),
|
||||
|
||||
expansion: $ => seq(
|
||||
'$',
|
||||
choice(
|
||||
$.variable,
|
||||
seq('{', alias(/[^\}]+/, $.variable), '}'),
|
||||
seq($.path, repeat(seq($._non_newline_whitespace, $.path)))
|
||||
)
|
||||
),
|
||||
|
||||
variable: $ => /[a-zA-Z][a-zA-Z0-9_]*/,
|
||||
|
||||
env_pair: $ => seq(
|
||||
field("name", $._env_key),
|
||||
token.immediate("="),
|
||||
field("value", choice(
|
||||
$.double_quoted_string,
|
||||
$.unquoted_string,
|
||||
)),
|
||||
user_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[uU][sS][eE][rR]/, "USER"),
|
||||
$._non_newline_whitespace,
|
||||
field("user", alias($._user_name_group, $.unquoted_string)),
|
||||
optional(
|
||||
seq(
|
||||
token.immediate(":"),
|
||||
field("group", alias($._user_name_group, $.unquoted_string))
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
_spaced_env_pair: $ => seq(
|
||||
_user_name_group: ($) =>
|
||||
repeat1(choice(token.immediate(/[a-z][-a-z0-9_]*/), $.expansion)),
|
||||
|
||||
workdir_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[wW][oO][rR][kK][dD][iI][rR]/, "WORKDIR"),
|
||||
$._non_newline_whitespace,
|
||||
$.path
|
||||
),
|
||||
|
||||
arg_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[aA][rR][gG]/, "ARG"),
|
||||
$._non_newline_whitespace,
|
||||
field("name", alias(/[a-zA-Z0-9_]+/, $.unquoted_string)),
|
||||
optional(
|
||||
seq(
|
||||
token.immediate("="),
|
||||
field("default", choice($.double_quoted_string, $.unquoted_string))
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
onbuild_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[oO][nN][bB][uU][iI][lL][dD]/, "ONBUILD"),
|
||||
$._non_newline_whitespace,
|
||||
$._instruction
|
||||
),
|
||||
|
||||
stopsignal_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[sS][tT][oO][pP][sS][iI][gG][nN][aA][lL]/, "STOPSIGNAL"),
|
||||
$._non_newline_whitespace,
|
||||
$._stopsignal_value
|
||||
),
|
||||
|
||||
_stopsignal_value: ($) => repeat1(choice(/[A-Z0-9]+/, $.expansion)),
|
||||
|
||||
healthcheck_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[hH][eE][aA][lL][tT][hH][cC][hH][eE][cC][kK]/, "HEALTHCHECK"),
|
||||
$._non_newline_whitespace,
|
||||
choice("NONE", seq(repeat($.param), $.cmd_instruction))
|
||||
),
|
||||
|
||||
shell_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[sS][hH][eE][lL][lL]/, "SHELL"),
|
||||
$._non_newline_whitespace,
|
||||
$.string_array
|
||||
),
|
||||
|
||||
maintainer_instruction: ($) =>
|
||||
seq(
|
||||
alias(/[mM][aA][iI][nN][tT][aA][iI][nN][eE][rR]/, "MAINTAINER"),
|
||||
/.*/
|
||||
),
|
||||
|
||||
cross_build_instruction: ($) =>
|
||||
seq(
|
||||
alias(
|
||||
/[cC][rR][oO][sS][sS]_[bB][uU][iI][lL][dD][a-zA-Z_]*/,
|
||||
"CROSS_BUILD"
|
||||
),
|
||||
/.*/
|
||||
),
|
||||
|
||||
path: ($) =>
|
||||
seq(
|
||||
choice(
|
||||
/[^-\s\$]/, // cannot start with a '-' to avoid conflicts with params
|
||||
$.expansion
|
||||
),
|
||||
repeat(choice(/[^\s\$]+/, $.expansion))
|
||||
),
|
||||
|
||||
expansion: ($) =>
|
||||
seq("$", choice($.variable, seq("{", alias(/[^\}]+/, $.variable), "}"))),
|
||||
|
||||
variable: ($) => /[a-zA-Z][a-zA-Z0-9_]*/,
|
||||
|
||||
env_pair: ($) =>
|
||||
seq(
|
||||
field("name", $._env_key),
|
||||
token.immediate("="),
|
||||
field("value", choice($.double_quoted_string, $.unquoted_string))
|
||||
),
|
||||
|
||||
_spaced_env_pair: ($) =>
|
||||
seq(
|
||||
field("name", $._env_key),
|
||||
token.immediate(/\s+/),
|
||||
field("value", choice(
|
||||
$.double_quoted_string,
|
||||
$.unquoted_string,
|
||||
)),
|
||||
field("value", choice($.double_quoted_string, $.unquoted_string))
|
||||
),
|
||||
|
||||
_env_key: $ => alias(/[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]/, $.unquoted_string),
|
||||
_env_key: ($) =>
|
||||
alias(/[a-zA-Z][a-zA-Z0-9_]*[a-zA-Z0-9]/, $.unquoted_string),
|
||||
|
||||
expose_port: $ => seq(
|
||||
/\d+/,
|
||||
optional(choice(
|
||||
"/tcp",
|
||||
"/udp",
|
||||
)),
|
||||
),
|
||||
expose_port: ($) => seq(/\d+/, optional(choice("/tcp", "/udp"))),
|
||||
|
||||
label_pair: $ => seq(
|
||||
label_pair: ($) =>
|
||||
seq(
|
||||
field("key", alias(/[-a-zA-Z0-9\._]+/, $.unquoted_string)),
|
||||
token.immediate("="),
|
||||
field("value", choice(
|
||||
$.double_quoted_string,
|
||||
$.unquoted_string,
|
||||
)),
|
||||
field("value", choice($.double_quoted_string, $.unquoted_string))
|
||||
),
|
||||
|
||||
image_spec: $ => seq(
|
||||
image_spec: ($) =>
|
||||
seq(
|
||||
field("name", $.image_name),
|
||||
seq(
|
||||
field("tag", optional($.image_tag)),
|
||||
field("digest", optional($.image_digest)),
|
||||
),
|
||||
field("digest", optional($.image_digest))
|
||||
)
|
||||
),
|
||||
|
||||
image_name: $ => repeat1(choice(
|
||||
token.immediate(/[^@:\s\$]+/),
|
||||
$.expansion,
|
||||
)),
|
||||
image_name: ($) =>
|
||||
repeat1(choice(token.immediate(/[^@:\s\$]+/), $.expansion)),
|
||||
|
||||
image_tag: $ => seq(
|
||||
image_tag: ($) =>
|
||||
seq(
|
||||
token.immediate(":"),
|
||||
repeat1(choice(
|
||||
token.immediate(/[^@\s\$]+/),
|
||||
$.expansion,
|
||||
))
|
||||
repeat1(choice(token.immediate(/[^@\s\$]+/), $.expansion))
|
||||
),
|
||||
|
||||
image_digest: $ => seq(
|
||||
image_digest: ($) =>
|
||||
seq(
|
||||
token.immediate("@"),
|
||||
repeat1(choice(
|
||||
token.immediate(/[a-zA-Z0-9:]+/),
|
||||
$.expansion,
|
||||
)),
|
||||
repeat1(choice(token.immediate(/[a-zA-Z0-9:]+/), $.expansion))
|
||||
),
|
||||
|
||||
param: $ => seq(
|
||||
param: ($) =>
|
||||
seq(
|
||||
"--",
|
||||
field("name", token.immediate(/[a-z][-a-z]*/)),
|
||||
token.immediate("="),
|
||||
field("value", token.immediate(/[^\s]+/)),
|
||||
field("value", token.immediate(/[^\s]+/))
|
||||
),
|
||||
|
||||
image_alias: $ => repeat1(choice(
|
||||
/[-a-zA-Z0-9_]+/,
|
||||
$.expansion,
|
||||
)),
|
||||
image_alias: ($) => repeat1(choice(/[-a-zA-Z0-9_]+/, $.expansion)),
|
||||
|
||||
string_array: $ => seq(
|
||||
string_array: ($) =>
|
||||
seq(
|
||||
"[",
|
||||
optional(seq(
|
||||
$.double_quoted_string,
|
||||
repeat(seq(",", $.double_quoted_string)),
|
||||
)),
|
||||
"]",
|
||||
optional(
|
||||
seq($.double_quoted_string, repeat(seq(",", $.double_quoted_string)))
|
||||
),
|
||||
"]"
|
||||
),
|
||||
|
||||
shell_command: $ => seq(
|
||||
shell_command: ($) =>
|
||||
seq(
|
||||
$.shell_fragment,
|
||||
repeat(seq(
|
||||
$.line_continuation,
|
||||
repeat($._comment_line),
|
||||
$.shell_fragment,
|
||||
)),
|
||||
repeat(
|
||||
seq($.line_continuation, repeat($._comment_line), $.shell_fragment)
|
||||
)
|
||||
),
|
||||
|
||||
shell_fragment: $ => repeat1(choice(
|
||||
/[^\\\[\n#\s][^\\\n]*/,
|
||||
/\\[^\n]/,
|
||||
)),
|
||||
shell_fragment: ($) => repeat1(choice(/[^\\\[\n#\s][^\\\n]*/, /\\[^\n]/)),
|
||||
|
||||
line_continuation: $ => '\\\n',
|
||||
line_continuation: ($) => "\\\n",
|
||||
|
||||
_comment_line: $ => seq(
|
||||
alias($._anon_comment, $.comment), '\n'
|
||||
),
|
||||
_comment_line: ($) => seq(alias($._anon_comment, $.comment), "\n"),
|
||||
|
||||
_anon_comment: $ => seq('#', /.*/),
|
||||
_anon_comment: ($) => seq("#", /.*/),
|
||||
|
||||
double_quoted_string: $ => seq(
|
||||
double_quoted_string: ($) =>
|
||||
seq(
|
||||
'"',
|
||||
repeat(choice(
|
||||
repeat(
|
||||
choice(
|
||||
token.immediate(prec(1, /[^"\n\\\$]+/)),
|
||||
$.escape_sequence,
|
||||
$.expansion,
|
||||
)),
|
||||
$.expansion
|
||||
)
|
||||
),
|
||||
'"'
|
||||
),
|
||||
|
||||
unquoted_string: $ => repeat1(choice(
|
||||
unquoted_string: ($) =>
|
||||
repeat1(
|
||||
choice(
|
||||
token.immediate(/[^\s\n\"\\\$]+/),
|
||||
token.immediate("\\ "),
|
||||
$.expansion,
|
||||
)),
|
||||
$.expansion
|
||||
)
|
||||
),
|
||||
|
||||
escape_sequence: $ => token.immediate(seq(
|
||||
'\\',
|
||||
escape_sequence: ($) =>
|
||||
token.immediate(
|
||||
seq(
|
||||
"\\",
|
||||
choice(
|
||||
/[^xuU]/,
|
||||
/\d{2,3}/,
|
||||
|
@ -354,11 +322,11 @@ module.exports = grammar({
|
|||
/u[0-9a-fA-F]{4}/,
|
||||
/U[0-9a-fA-F]{8}/
|
||||
)
|
||||
)),
|
||||
)
|
||||
),
|
||||
|
||||
_non_newline_whitespace: $ => /[\t ]+/,
|
||||
_non_newline_whitespace: ($) => /[\t ]+/,
|
||||
|
||||
comment: $ => seq("#", /.*/),
|
||||
}
|
||||
comment: ($) => seq("#", /.*/),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue