Skip to content

Commit a81c063

Browse files
committed
add template processing builtin
1 parent b7af7d9 commit a81c063

13 files changed

Lines changed: 157 additions & 35 deletions

File tree

builtin/builtin.go

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codegen/chain.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package codegen
22

33
import (
4+
"bytes"
45
"context"
56
"fmt"
67
"os"
78
"strings"
9+
"text/template"
810

911
shellquote "github.com/kballard/go-shellquote"
1012
"github.com/moby/buildkit/client/llb"
@@ -35,7 +37,7 @@ func (cg *CodeGen) EmitChainStmt(ctx context.Context, scope *parser.Scope, typ p
3537
return chain(v.(llb.State))
3638
}, nil
3739
case parser.Str:
38-
chain, err := cg.EmitStringChainStmt(ctx, scope, call.Func, call.Args, chainStart)
40+
chain, err := cg.EmitStringChainStmt(ctx, scope, call.Func, call.Args, call.WithOpt, chainStart)
3941
if err != nil {
4042
return nil, err
4143
}
@@ -585,7 +587,16 @@ func (cg *CodeGen) EmitFilesystemBuiltinChainStmt(ctx context.Context, scope *pa
585587
return fc, nil
586588
}
587589

588-
func (cg *CodeGen) EmitStringChainStmt(ctx context.Context, scope *parser.Scope, expr *parser.Expr, args []*parser.Expr, chainStart interface{}) (StringChain, error) {
590+
func (cg *CodeGen) EmitStringChainStmt(ctx context.Context, scope *parser.Scope, expr *parser.Expr, args []*parser.Expr, with *parser.WithOpt, chainStart interface{}) (StringChain, error) {
591+
var iopts []interface{}
592+
var err error
593+
if with != nil {
594+
iopts, err = cg.EmitOptionExpr(ctx, scope, with.Expr, nil, expr.Name())
595+
if err != nil {
596+
return nil, err
597+
}
598+
}
599+
589600
switch expr.Name() {
590601
case "value":
591602
val, err := cg.EmitStringExpr(ctx, scope, args[0])
@@ -619,6 +630,28 @@ func (cg *CodeGen) EmitStringChainStmt(ctx context.Context, scope *parser.Scope,
619630
return func(_ string) (string, error) {
620631
return os.Getenv(key), nil
621632
}, nil
633+
case "template":
634+
text, err := cg.EmitStringExpr(ctx, scope, args[0])
635+
if err != nil {
636+
return nil, err
637+
}
638+
639+
t, err := template.New(expr.Pos.String()).Parse(text)
640+
if err != nil {
641+
return nil, err
642+
}
643+
644+
data := map[string]interface{}{}
645+
for _, iopt := range iopts {
646+
opt := iopt.(*TemplateField)
647+
data[opt.Name] = opt.Value
648+
}
649+
650+
return func(_ string) (string, error) {
651+
buf := bytes.NewBufferString("")
652+
err = t.Execute(buf, data)
653+
return buf.String(), err
654+
}, nil
622655
default:
623656
// Must be a named reference.
624657
obj := scope.Lookup(expr.Name())

codegen/codegen.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ func (cg *CodeGen) EmitOptions(ctx context.Context, scope *parser.Scope, op stri
422422
return cg.EmitRmOptions(ctx, scope, op, stmts)
423423
case "copy":
424424
return cg.EmitCopyOptions(ctx, scope, op, stmts)
425+
case "template":
426+
return cg.EmitTemplateOptions(ctx, scope, op, stmts)
425427
default:
426428
return opts, errors.Errorf("call stmt does not support options: %s", op)
427429
}
@@ -811,6 +813,40 @@ func (cg *CodeGen) EmitCopyOptions(ctx context.Context, scope *parser.Scope, op
811813
return
812814
}
813815

816+
type TemplateField struct {
817+
Name string
818+
Value interface{}
819+
}
820+
821+
func (cg *CodeGen) EmitTemplateOptions(ctx context.Context, scope *parser.Scope, op string, stmts []*parser.Stmt) (opts []interface{}, err error) {
822+
for _, stmt := range stmts {
823+
if stmt.Call != nil {
824+
args := stmt.Call.Args
825+
switch stmt.Call.Func.Ident.Name {
826+
case "stringField":
827+
name, err := cg.EmitStringExpr(ctx, scope, args[0])
828+
if err != nil {
829+
return opts, err
830+
}
831+
832+
value, err := cg.EmitStringExpr(ctx, scope, args[1])
833+
if err != nil {
834+
return opts, err
835+
}
836+
837+
opts = append(opts, &TemplateField{Name: name, Value: value})
838+
default:
839+
iopts, err := cg.EmitOptionLookup(ctx, scope, stmt.Call.Func, args, op)
840+
if err != nil {
841+
return opts, err
842+
}
843+
opts = append(opts, iopts...)
844+
}
845+
}
846+
}
847+
return opts, nil
848+
}
849+
814850
func (cg *CodeGen) EmitExecOptions(ctx context.Context, scope *parser.Scope, op string, stmts []*parser.Stmt, ac aliasCallback) (opts []interface{}, err error) {
815851
for _, stmt := range stmts {
816852
if stmt.Call != nil {

codegen/codegen_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,30 @@ func TestCodeGen(t *testing.T) {
240240
llb.Shlex("\techo hi"),
241241
).Root())
242242
},
243+
}, {
244+
"templates",
245+
[]string{"default"},
246+
`
247+
string cmd() {
248+
template <<-EOM
249+
echo hi {{.user}}
250+
EOM with option {
251+
stringField "user" string {
252+
localEnv "USER"
253+
}
254+
}
255+
}
256+
257+
fs default() {
258+
image "busybox"
259+
run cmd
260+
}
261+
`,
262+
func(t *testing.T, cg *CodeGen) solver.Request {
263+
return Expect(t, llb.Image("busybox").Run(
264+
llb.Shlexf("echo hi %s", os.Getenv("USER")),
265+
).Root())
266+
},
243267
}} {
244268
tc := tc
245269
t.Run(tc.name, func(t *testing.T) {

language/builtin.hlb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,26 @@ string format(string formatString, variadic string values)
496496

497497
# An environment variable from the client's local environment.
498498
#
499-
# @param the environment variable's key.
499+
# @param key the environment variable's key.
500500
# @return the environment variable's value
501501
string localEnv(string key)
502502

503+
# Process text as a Go text template.
504+
# For template syntax documentation see:
505+
# https://golang.org/pkg/text/template/
506+
#
507+
# @param text the text of the template
508+
# @return the text resulting from the processed template
509+
string template(string text)
510+
511+
# Add a string field with provided name to be available
512+
# inside the template.
513+
#
514+
# @param name the name of the field inside the template
515+
# @param value the value of the field inside the template
516+
# @return an option to add a field to the template
517+
option::template stringField(string name, string value)
518+
503519
# Execute groups in parallel.
504520
#
505521
# @param groups the groups to run in parallel

language/hlb-ace.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ define(function (require, exports, module) {
3131
},
3232
{
3333
"token": "entity.name.type",
34-
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)"
34+
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)"
3535
},
3636
{
3737
"token": ["keyword", "punctuation"],
@@ -85,12 +85,12 @@ define(function (require, exports, module) {
8585
},
8686
{
8787
"token": ["entity.name.type", "punctuation"],
88-
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)(?:[\\t ]+)(\\{)",
88+
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)(?:[\\t ]+)(\\{)",
8989
"push": "block"
9090
},
9191
{
9292
"token": "variable",
93-
"regex": "(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|target|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))"
93+
"regex": "(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|stringField|target|template|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))"
9494
},
9595
{
9696
defaultToken: "text",
@@ -124,7 +124,7 @@ define(function (require, exports, module) {
124124
},
125125
{
126126
"token": "entity.name.type",
127-
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)"
127+
"regex": "(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)"
128128
},
129129
{
130130
"token": "variable",

language/hlb-atom.coffee

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
'include' : '#common'
1717
}
1818
{
19-
'match' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)'
19+
'match' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)'
2020
'name' : 'entity.name.type.hlb'
2121
}
2222
{
@@ -80,7 +80,7 @@
8080
'name' : 'variable.language.hlb'
8181
}
8282
{
83-
'begin' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)(?:[\\t\\x{0020}]+)(\\{)'
83+
'begin' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)(?:[\\t\\x{0020}]+)(\\{)'
8484
'beginCaptures' : {
8585
'1' : {
8686
'name' : 'entity.name.type.hlb'
@@ -102,7 +102,7 @@
102102
}
103103
}
104104
{
105-
'match' : '(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|target|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))'
105+
'match' : '(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|stringField|target|template|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))'
106106
'name' : 'variable.hlb'
107107
}
108108
]
@@ -163,7 +163,7 @@
163163
'params' : {
164164
'patterns' : [
165165
{
166-
'match' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)'
166+
'match' : '(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)'
167167
'name' : 'entity.name.type.hlb'
168168
}
169169
{

language/hlb-pygments.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class HlbLexer(RegexLexer):
1717
(u'((\\b(0(b|B|o|O|x|X)[a-fA-F0-9]+)\\b)|(\\b(0|[1-9][0-9]*)\\b)|(\\b(true|false)\\b))', bygroups(Name.Constant)),
1818
(u'(\")', bygroups(Punctuation), 'common__1'),
1919
(u'(<<[-~]?)([A-Z]+)', bygroups(Punctuation, Name.Constant), 'common__2'),
20-
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)', bygroups(Keyword.Type)),
20+
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)', bygroups(Keyword.Type)),
2121
(u'(\\b[a-zA-Z_][a-zA-Z0-9]*\\b)(\\()', bygroups(Keyword, Punctuation), 'params'),
2222
(u'(\\))', bygroups(Generic.Error)),
2323
(u'(\\{)', bygroups(Punctuation), 'block'),
@@ -31,8 +31,8 @@ class HlbLexer(RegexLexer):
3131
(u'(\")', bygroups(Punctuation), 'common__1'),
3232
(u'(<<[-~]?)([A-Z]+)', bygroups(Punctuation, Name.Constant), 'common__2'),
3333
(u'(\\b(with|as|variadic)\\b)', bygroups(Name.Builtin)),
34-
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)(?:[\\t ]+)(\\{)', bygroups(Keyword.Type, Punctuation), 'block'),
35-
(u'(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|target|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))', bygroups(Name.Variable)),
34+
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)(?:[\\t ]+)(\\{)', bygroups(Keyword.Type, Punctuation), 'block'),
35+
(u'(\\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|stringField|target|template|tmpfs|uid|unix|unpack|unset|user|value)\\b)[a-zA-Z_][a-zA-Z0-9]*\\b))', bygroups(Name.Variable)),
3636
('(\n|\r|\r\n)', String),
3737
('.', String),
3838
],
@@ -45,7 +45,7 @@ class HlbLexer(RegexLexer):
4545
('.', String),
4646
],
4747
'params' : [
48-
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\\b)', bygroups(Keyword.Type)),
48+
(u'(\\bstring\\b|\\bint\\b|\\bbool\\b|\\bfs\\b|\\bgroup\\b|\\boption(?!::)\\b|\\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\\b)', bygroups(Keyword.Type)),
4949
(u'(\\b[a-zA-Z_][a-zA-Z0-9]*\\b)', bygroups(Name.Variable)),
5050
('(\n|\r|\r\n)', String),
5151
('.', String),

language/hlb-rouge.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Hlb < RegexLexer
1616
groups Punctuation, Name::Constant
1717
push :common__2
1818
end
19-
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\b)/, Keyword::Type
19+
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\b)/, Keyword::Type
2020
rule /(\b[a-zA-Z_][a-zA-Z0-9]*\b)(\()/ do
2121
groups Keyword, Punctuation
2222
push :params
@@ -37,11 +37,11 @@ class Hlb < RegexLexer
3737
push :common__2
3838
end
3939
rule /(\b(with|as|variadic)\b)/, Name::Builtin
40-
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\b)(?:[\t ]+)(\{)/ do
40+
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\b)(?:[\t ]+)(\{)/ do
4141
groups Keyword::Type, Punctuation
4242
push :block
4343
end
44-
rule /(\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|target|tmpfs|uid|unix|unpack|unset|user|value)\b)[a-zA-Z_][a-zA-Z0-9]*\b))/, Name::Variable
44+
rule /(\b((?!(allowEmptyWildcard|allowNotFound|allowWildcard|cache|checksum|chmod|chown|contentsOnly|copy|createDestPath|createParents|createdTime|dir|dockerLoad|dockerPush|download|downloadDockerTarball|downloadOCITarball|downloadTarball|env|excludePatterns|filename|followPaths|followSymlinks|format|forward|frontend|gid|git|host|http|id|ignoreCache|image|includePatterns|input|insecure|keepGitDir|local|localEnv|localPaths|locked|mkdir|mkfile|mode|mount|network|node|opt|parallel|private|readonly|readonlyRootfs|resolve|rm|run|sandbox|scratch|secret|security|shared|sourcePath|ssh|stringField|target|template|tmpfs|uid|unix|unpack|unset|user|value)\b)[a-zA-Z_][a-zA-Z0-9]*\b))/, Name::Variable
4545
rule /(\n|\r|\r\n)/, String
4646
rule /./, String
4747
end
@@ -57,7 +57,7 @@ class Hlb < RegexLexer
5757
end
5858

5959
state:params do
60-
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh)\b)/, Keyword::Type
60+
rule /(\bstring\b|\bint\b|\bbool\b|\bfs\b|\bgroup\b|\boption(?!::)\b|\boption::(?:copy|frontend|git|http|image|local|mkdir|mkfile|mount|rm|run|secret|ssh|template)\b)/, Keyword::Type
6161
rule /(\b[a-zA-Z_][a-zA-Z0-9]*\b)/, Name::Variable
6262
rule /(\n|\r|\r\n)/, String
6363
rule /./, String

0 commit comments

Comments
 (0)