dockerfileLanguage top-level constant
Grammar
const dockerfileLanguage
Dockerfile (and Containerfile).
Each instruction is a region that runs to the end of its logical line,
following \ continuations. Heredocs (RUN <<EOF … EOF) are strings.
Implementation
const dockerfileLanguage = Grammar(
name: 'dockerfile',
aliases: ['docker', 'containerfile'],
fileExtensions: ['dockerfile'],
fileNames: ['Dockerfile', 'Containerfile'],
caseInsensitive: true,
signatures: [
r'^FROM\s+[\w./:@${}-]+(?:\s+AS\s+\w+)?\s*$',
r'^(?:RUN|COPY|WORKDIR|ENTRYPOINT|EXPOSE|HEALTHCHECK)\s',
r'^CMD\s+\[\s*"',
],
rules: [
// Parser directives such as `# syntax=docker/dockerfile:1`.
TokenRule(r'^#[ \t]*(?:syntax|escape|check)[ \t]*=.*$', scope: Scopes.meta),
TokenRule(r'^[ \t]*#.*$', scope: Scopes.comment),
RegionRule(
begin:
r'^[ \t]*(?:ONBUILD[ \t]+)?(?:FROM|RUN|CMD|LABEL|MAINTAINER|EXPOSE|'
r'ENV|ADD|COPY|ENTRYPOINT|VOLUME|USER|WORKDIR|ARG|ONBUILD|'
r'STOPSIGNAL|HEALTHCHECK|SHELL)\b',
// The instruction ends at a line end not preceded by `\`.
end: r'(?<!\\)$',
beginScope: Scopes.keyword,
rules: [IncludeRule('arguments')],
),
],
repository: {
'arguments': [
// Comment lines inside a continued instruction.
TokenRule(r'^[ \t]*#.*$', scope: Scopes.comment),
// Heredocs: `<<EOF`, `<<-EOF`, `<<"EOF"`.
RegionRule(
begin: r'''<<-?(["']?)([A-Za-z_]\w*)\1''',
end: r'^[ \t]*\2$',
beginScope: Scopes.operator,
endScope: Scopes.operator,
endReferencesBegin: true,
rules: [TokenRule(r'[^\n]+', scope: Scopes.string)],
),
QuotedString('"', rules: [IncludeRule('variables')]),
QuotedString("'", escape: null),
IncludeRule('variables'),
// Flags such as `--from=build` or `--chown=app`.
TokenRule(r'(?<=\s)--[A-Za-z][\w-]*', scope: Scopes.attribute),
// `HEALTHCHECK … CMD [...]` and `HEALTHCHECK NONE`.
TokenRule(
r'(?<=\s)(?:CMD|NONE)(?=[ \t]+\[|[ \t]*$)',
scope: Scopes.keyword,
),
// `FROM image AS name`.
TokenRule(r'(?<=\s)AS(?=[ \t]+[\w.-]+[ \t]*$)', scope: Scopes.keyword),
TokenRule(r'&&|\|\||[|;=]', scope: Scopes.operator),
TokenRule(
r'(?<![\w$.:/-])\d+(?:/(?:tcp|udp))?(?![\w.:/-])',
scope: Scopes.number,
),
// A trailing `\` continues the instruction.
TokenRule(r'\\(?=[ \t]*$)', scope: Scopes.operator),
],
'variables': [
TokenRule(r'\$\{[^}\n]*\}', scope: Scopes.variable),
TokenRule(r'\$[A-Za-z_]\w*', scope: Scopes.variable),
],
},
);