Merge pull request #28 from returntocorp/mj-run-param

Support options after RUN
This commit is contained in:
Camden Cheek 2023-02-21 21:09:31 -07:00 committed by GitHub
commit 8ee3a0f758
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 5424 additions and 4700 deletions

View file

@ -57,3 +57,24 @@ run ["echo", "test"]
(double_quoted_string) (double_quoted_string)
(double_quoted_string)))) (double_quoted_string))))
==================
Run with options
==================
run --mount=type=secret,id=aws,target=/root/.aws/credentials \
--security=insecure \
aws s3 cp s3://example.com
---
(source_file
(run_instruction
(mount_param
(mount_param_param)
(mount_param_param)
(mount_param_param))
(line_continuation)
(param)
(line_continuation)
(shell_command
(shell_fragment))))

View file

@ -40,6 +40,12 @@ module.exports = grammar({
run_instruction: ($) => run_instruction: ($) =>
seq( seq(
alias(/[rR][uU][nN]/, "RUN"), alias(/[rR][uU][nN]/, "RUN"),
repeat(
choice(
$.param,
$.mount_param
)
),
choice($.string_array, $.shell_command) choice($.string_array, $.shell_command)
), ),
@ -266,6 +272,7 @@ module.exports = grammar({
repeat1(choice(token.immediate(/[a-zA-Z0-9:]+/), $._immediate_expansion)) repeat1(choice(token.immediate(/[a-zA-Z0-9:]+/), $._immediate_expansion))
), ),
// Generic parsing of options passed right after an instruction name.
param: ($) => param: ($) =>
seq( seq(
"--", "--",
@ -274,6 +281,31 @@ module.exports = grammar({
field("value", token.immediate(/[^\s]+/)) field("value", token.immediate(/[^\s]+/))
), ),
// Specific parsing of the --mount option e.g.
//
// --mount=type=cache,target=/root/.cache/go-build
//
mount_param: ($) => seq(
"--",
field("name", token.immediate("mount")),
token.immediate("="),
field(
"value",
seq(
$.mount_param_param,
repeat(
seq(token.immediate(","), $.mount_param_param)
)
)
)
),
mount_param_param: ($) => seq(
token.immediate(/[^\s=,]+/),
token.immediate("="),
token.immediate(/[^\s=,]+/)
),
image_alias: ($) => seq( image_alias: ($) => seq(
choice(/[-a-zA-Z0-9_]+/, $.expansion), choice(/[-a-zA-Z0-9_]+/, $.expansion),
repeat(choice(token.immediate(/[-a-zA-Z0-9_]+/), $._immediate_expansion)) repeat(choice(token.immediate(/[-a-zA-Z0-9_]+/), $._immediate_expansion))
@ -301,7 +333,24 @@ module.exports = grammar({
) )
), ),
shell_fragment: ($) => repeat1(choice(/[^\\\[\n#\s][^\\\n]*/, /\\[^\n]/)), shell_fragment: ($) => repeat1(
choice(
// A shell fragment is broken into the same tokens as other
// constructs because the lexer prefers the longer tokens
// when it has a choice. The example below shows the tokenization
// of the --mount parameter.
//
// RUN --mount=foo=bar,baz=42 ls --all
// ^^ ^ ^ ^ ^
// ^^^^^ ^^^ ^^^ ^^^ ^^
// |--------param-------|
// |--shell_command--|
//
/[,=-]/,
/[^\\\[\n#\s,=-][^\\\n]*/,
/\\[^\n,=-]/
)
),
line_continuation: ($) => "\\\n", line_continuation: ($) => "\\\n",
required_line_continuation: ($) => "\\\n", required_line_continuation: ($) => "\\\n",

View file

@ -179,6 +179,22 @@
"named": false, "named": false,
"value": "RUN" "value": "RUN"
}, },
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "param"
},
{
"type": "SYMBOL",
"name": "mount_param"
}
]
}
},
{ {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -1302,6 +1318,91 @@
} }
] ]
}, },
"mount_param": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "--"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "mount"
}
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "="
}
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "mount_param_param"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": ","
}
},
{
"type": "SYMBOL",
"name": "mount_param_param"
}
]
}
}
]
}
}
]
},
"mount_param_param": {
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^\\s=,]+"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "="
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^\\s=,]+"
}
}
]
},
"image_alias": { "image_alias": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@ -1436,11 +1537,15 @@
"members": [ "members": [
{ {
"type": "PATTERN", "type": "PATTERN",
"value": "[^\\\\\\[\\n#\\s][^\\\\\\n]*" "value": "[,=-]"
}, },
{ {
"type": "PATTERN", "type": "PATTERN",
"value": "\\\\[^\\n]" "value": "[^\\\\\\[\\n#\\s,=-][^\\\\\\n]*"
},
{
"type": "PATTERN",
"value": "\\\\[^\\n,=-]"
} }
] ]
} }

View file

@ -418,6 +418,41 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "mount_param",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": true,
"types": [
{
"type": "mount",
"named": false
}
]
},
"value": {
"multiple": true,
"required": true,
"types": [
{
"type": ",",
"named": false
},
{
"type": "mount_param_param",
"named": true
}
]
}
}
},
{
"type": "mount_param_param",
"named": true,
"fields": {}
},
{ {
"type": "onbuild_instruction", "type": "onbuild_instruction",
"named": true, "named": true,
@ -530,9 +565,17 @@
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
"multiple": false, "multiple": true,
"required": true, "required": true,
"types": [ "types": [
{
"type": "mount_param",
"named": true
},
{
"type": "param",
"named": true
},
{ {
"type": "shell_command", "type": "shell_command",
"named": true "named": true
@ -931,6 +974,10 @@
"type": "escape_sequence", "type": "escape_sequence",
"named": true "named": true
}, },
{
"type": "mount",
"named": false
},
{ {
"type": "variable", "type": "variable",
"named": true "named": true

File diff suppressed because it is too large Load diff