Warning, /frameworks/syntax-highlighting/data/syntax/earthfile.xml is written in an unsupported language. File is not indexed.

0001 <?xml version="1.0" encoding="UTF-8"?>
0002 <!DOCTYPE language
0003 [
0004   <!ENTITY var_name_re "[A-Za-z_][_0-9A-Za-z]*">
0005   <!ENTITY unary_operators  "\B-[abcdefghkprstuwxGLNOSovRnz]\b">
0006   <!ENTITY binary_operators "\B(?:-(?:e[fq]|[nolg]t|[nlg]e)|==?|!=)\b">
0007 ]>
0008 <!--
0009     This file is part of KDE's kate project.
0010 
0011     SPDX-FileCopyrightText: 2022-2023 Alex Turbov <i.zaufi@gmail.com>
0012 
0013     SPDX-License-Identifier: MIT
0014  -->
0015 <language
0016     name="Earthfile"
0017     section="Other"
0018     version="2"
0019     kateversion="5.79"
0020     extensions="Earthfile"
0021     author="Alex Turbov (i.zaufi@gmail.com)"
0022     license="MIT"
0023   >
0024   <highlighting>
0025 
0026     <!-- https://docs.earthly.dev/docs/earthfile/builtin-args -->
0027     <list name="variables">
0028       <item>EARTHLY_BUILD_SHA</item>
0029       <item>EARTHLY_CI</item>
0030       <item>EARTHLY_GIT_AUTHOR</item>
0031       <item>EARTHLY_GIT_CO_AUTHORS</item>
0032       <item>EARTHLY_GIT_COMMIT_AUTHOR_TIMESTAMP</item>
0033       <item>EARTHLY_GIT_COMMIT_TIMESTAMP</item>
0034       <item>EARTHLY_GIT_BRANCH</item>
0035       <item>EARTHLY_GIT_HASH</item>
0036       <item>EARTHLY_GIT_ORIGIN_URL</item>
0037       <item>EARTHLY_GIT_PROJECT_NAME</item>
0038       <item>EARTHLY_GIT_SHORT_HASH</item>
0039       <item>EARTHLY_LOCALLY</item>
0040       <item>EARTHLY_SOURCE_DATE_EPOCH</item>
0041       <item>EARTHLY_TARGET_NAME</item>
0042       <item>EARTHLY_TARGET_PROJECT_NO_TAG</item>
0043       <item>EARTHLY_TARGET_PROJECT</item>
0044       <item>EARTHLY_TARGET_TAG_DOCKER</item>
0045       <item>EARTHLY_TARGET_TAG</item>
0046       <item>EARTHLY_TARGET</item>
0047       <item>EARTHLY_VERSION</item>
0048       <item>TARGETARCH</item>
0049       <item>TARGETOS</item>
0050       <item>TARGETPLATFORM</item>
0051       <item>TARGETVARIANT</item>
0052       <item>USERPLATFORM</item>
0053       <item>USEROS</item>
0054       <item>USERARCH</item>
0055       <item>USERVARIANT</item>
0056     </list>
0057 
0058     <list name="commands-top-level-only">
0059       <item>VERSION</item>
0060       <item>PROJECT</item>
0061     </list>
0062 
0063     <list name="commands">
0064       <item>FROM</item>
0065       <item>DOCKERFILE</item>
0066       <item>RUN</item>
0067       <item>COPY</item>
0068       <item>ARG</item>
0069       <item>SAVE</item>
0070       <item>ARTIFACT</item>
0071       <item>AS</item>
0072       <item>LOCAL</item>
0073       <item>IMAGE</item>
0074       <item>BUILD</item>
0075       <item>GIT</item>
0076       <item>CLONE</item>
0077       <item>WITH</item>
0078       <item>DOCKER</item>
0079       <item>IF</item>
0080       <item>FOR</item>
0081       <item>WAIT</item>
0082       <item>TRY</item>
0083       <item>CACHE</item>
0084       <item>LOCALLY</item>
0085       <item>COMMAND</item>
0086       <item>DO</item>
0087       <item>IMPORT</item>
0088       <item>CMD</item>
0089       <item>LABEL</item>
0090       <item>EXPOSE</item>
0091       <item>ENV</item>
0092       <item>ENTRYPOINT</item>
0093       <item>VOLUME</item>
0094       <item>WORKDIR</item>
0095       <item>HEALTHCHECK</item>
0096       <item>HOST</item>
0097       <item>PIPELINE</item>
0098       <item>TRIGGER</item>
0099     </list>
0100 
0101     <!--
0102       See `RUN` and `mount` option description
0103       https://docs.earthly.dev/docs/earthfile#run
0104     -->
0105     <list name="mount_keys">
0106       <item>type</item>
0107       <item>target</item>
0108       <item>mode</item>
0109       <item>id</item>
0110       <item>sharing</item>
0111     </list>
0112 
0113     <list name="trigger_events">
0114       <item>manual</item>
0115       <item>pr</item>
0116       <item>push</item>
0117     </list>
0118 
0119     <contexts>
0120       <context name="Global" attribute="Normal Text" lineEndContext="#stay">
0121         <DetectSpaces />
0122         <!-- Switch from global to recipe mode -->
0123         <RegExpr
0124             String="^[A-Za-z_][A-Za-z_\-0-9]+:"
0125             column="0"
0126             lookAhead="true"
0127             context="Recipe"
0128           />
0129 
0130         <!-- NOTE The following commands valid only at global level -->
0131         <WordDetect String="VERSION" attribute="Command" context="VERSION_ctx" />
0132         <WordDetect String="PROJECT" attribute="Command" context="PROJECT_ctx" />
0133 
0134         <IncludeRules context="RecipeCommands" />
0135       </context>
0136 
0137       <!-- As soon as the first recipe found stay in this context 'till EOF -->
0138       <context name="Recipe" attribute="Normal Text" lineEndContext="#stay">
0139         <RegExpr
0140             String="^[A-Z_][A-Z_0-9]+:"
0141             column="0"
0142             context="#stay"
0143             attribute="User Defined Command"
0144             endRegion="Recipe"
0145             beginRegion="Recipe"
0146           />
0147         <RegExpr
0148             String="^[a-z][a-z\-_0-9]+:"
0149             column="0"
0150             context="#stay"
0151             attribute="Target Name"
0152             endRegion="Recipe"
0153             beginRegion="Recipe"
0154           />
0155         <DetectSpaces />
0156         <!-- NOTE Any commands at global level (at column 0) are inappropriate now -->
0157         <keyword String="commands" column="0" attribute="Error" />
0158         <IncludeRules context="RecipeCommands" />
0159       </context>
0160 
0161       <context name="RecipeCommands" attribute="Normal Text" lineEndContext="#pop">
0162         <DetectSpaces />
0163         <DetectChar char="#" attribute="Comment" context="Comment" />
0164         <!-- The whole file is a collection of recipes -->
0165         <WordDetect String="ARG" attribute="Command" context="ARG_ctx" />
0166         <WordDetect String="FROM" attribute="Command" context="FROM_ctx" />
0167         <WordDetect String="BUILD" attribute="Command" context="BUILD_ctx" />
0168         <WordDetect String="GIT" attribute="Command" context="GIT_ctx" />
0169         <WordDetect String="CACHE" attribute="Command" context="CACHE_ctx" />
0170         <WordDetect String="LOCALLY" attribute="Command" context="#stay" />
0171         <WordDetect String="COMMAND" attribute="Command" context="#stay" />
0172         <WordDetect String="IMPORT" attribute="Command" context="IMPORT_ctx" />
0173         <WordDetect String="CMD" attribute="Command" context="CMD_ctx" />
0174         <WordDetect String="LABEL" attribute="Command" context="LABEL_ctx" />
0175         <WordDetect String="EXPOSE" attribute="Command" context="EXPOSE_ctx" />
0176         <WordDetect String="ENV" attribute="Command" context="BashOneLine##Bash" />
0177         <WordDetect String="ENTRYPOINT" attribute="Command" context="ENTRYPOINT_ctx" />
0178         <WordDetect String="VOLUME" attribute="Command" context="VOLUME_ctx" />
0179         <WordDetect String="USER" attribute="Command" context="USER_ctx" />
0180         <WordDetect String="WORKDIR" attribute="Command" context="WORKDIR_ctx" />
0181         <WordDetect String="HEALTHCHECK" attribute="Command" context="HEALTHCHECK_ctx" />
0182         <WordDetect String="HOST" attribute="Command" context="HOST_ctx" />
0183         <WordDetect String="DO" attribute="Command" context="DO_ctx" />
0184         <WordDetect String="COPY" attribute="Command" context="COPY_ctx" />
0185         <WordDetect String="WAIT" attribute="Command" context="WAIT_ctx" beginRegion="WAIT" />
0186         <WordDetect String="WITH" attribute="Command" context="WITH_ctx" beginRegion="WITH" />
0187         <WordDetect String="FOR" attribute="Command" context="FOR_ctx" beginRegion="FOR" />
0188         <WordDetect String="IF" attribute="Command" context="IF_ctx" beginRegion="IF" />
0189         <WordDetect String="TRIGGER" attribute="Command" context="TRIGGER_ctx" />
0190         <WordDetect String="PIPELINE" attribute="Command" context="PIPELINE_ctx" />
0191         <WordDetect String="TRY" attribute="Command" context="TRY_ctx" beginRegion="TRY" />
0192         <IncludeRules context="RecipeCommandsOnlyRUN" />
0193         <IncludeRules context="RecipeCommandsOnlySAVE" />
0194         <keyword String="commands-top-level-only" attribute="Error" />
0195       </context>
0196 
0197       <context name="RecipeCommandsOnlyRUN" attribute="Normal Text" lineEndContext="#pop">
0198         <WordDetect String="RUN" attribute="Command" context="RUN_ctx" />
0199       </context>
0200 
0201       <context name="RecipeCommandsOnlySAVE" attribute="Normal Text" lineEndContext="#pop">
0202         <WordDetect String="SAVE" attribute="Command" context="SAVE_ctx" />
0203       </context>
0204 
0205       <context name="RecipeContent" attribute="Normal Text" lineEndContext="#pop">
0206         <LineContinue />
0207         <IncludeRules context="RecipeCommandsNoLineCont" />
0208       </context>
0209 
0210       <context name="RecipeCommandsNoLineCont" attribute="Normal Text" lineEndContext="#pop">
0211         <DetectChar char="'" attribute="String SingleQ" context="StringSQ" />
0212         <DetectChar char="&quot;" attribute="String DoubleQ" context="StringDQ" />
0213 
0214         <!-- See https://docs.earthly.dev/docs/guides/target-ref#target-reference -->
0215         <RegExpr
0216           context="DetectReference"
0217           lookAhead="true"
0218           String="([a-z0-9_\-\./]+(:[A-Za-z0-9_\-\./]+)?)?(\+[A-Za-z0-9_\-]+)(/[^ ,]*)?"
0219           />
0220         <RegExpr String="--&var_name_re;=" lookAhead="true" context="BuildArg" />
0221         <DetectChar char="$" lookAhead="1" context="DispatchVariables" />
0222         <Int attribute="Integer" />
0223       </context>
0224 
0225       <context name="BuildArg" attribute="Normal Text" lineEndContext="#pop">
0226         <DetectChar char="=" attribute="Operator" context="#pop" />
0227         <RegExpr String="--&var_name_re;" attribute="Build Arg" />
0228       </context>
0229 
0230       <context name="DispatchVariables" attribute="Normal Text" lineEndContext="#pop">
0231         <IncludeRules context="DispatchVariablesBase" />
0232         <DetectChar char="$" context="#pop" />
0233       </context>
0234 
0235       <context name="DispatchVariablesBase" attribute="Normal Text" lineEndContext="#pop">
0236         <Detect2Chars char="$" char1="$" attribute="Variable" context="#pop" />
0237         <Detect2Chars char="$" char1="?" attribute="Variable" context="#pop" />
0238         <Detect2Chars char="$" char1="*" attribute="Variable" context="#pop" />
0239         <Detect2Chars char="$" char1="@" attribute="Variable" context="#pop" />
0240         <Detect2Chars char="$" char1="{" attribute="Variable" context="VarSubst" />
0241         <Detect2Chars char="$" char1="(" attribute="Variable" context="CommandSubst" />
0242         <RegExpr String="\$&var_name_re;" lookAhead="true" context="VarName" />
0243       </context>
0244 
0245       <context name="VarName" attribute="Normal Text" lineEndContext="#pop">
0246         <DetectChar char="$" attribute="Variable" context="#stay" />
0247         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#pop" />
0248         <keyword String="variables" attribute="Builtin Variable" context="#pop" />
0249         <DetectIdentifier attribute="Variable" context="#pop" />
0250       </context>
0251 
0252       <context name="VarSubst" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0253         <DetectChar char="}" attribute="Variable" context="#pop#pop" />
0254         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#stay" />
0255         <keyword String="variables" attribute="Builtin Variable" context="#stay" />
0256         <DetectIdentifier attribute="Variable" />
0257         <Detect2Chars char=":" char1="+" attribute="Variable" context="#stay" />
0258         <Detect2Chars char=":" char1="-" attribute="Variable" context="#stay" />
0259       </context>
0260 
0261       <context name="DetectReference" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0262         <StringDetect String="%1" dynamic="true" attribute="Reference" context="#stay" />
0263         <StringDetect String="%3" lookAhead="true" dynamic="true" context="TargetOrCommand" />
0264         <StringDetect String="%4" dynamic="true" attribute="Artifact Name" context="#stay" />
0265       </context>
0266 
0267       <context name="TargetOrCommand" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0268         <RegExpr String="\+[A-Z_][A-Z_0-9]+" context="#pop" attribute="User Defined Command" />
0269         <RegExpr String="\+[a-z][a-z\-_0-9]+" context="#pop" attribute="Target Name" />
0270       </context>
0271 
0272       <!-- StringSQ consumes anything till ' -->
0273       <context name="StringSQ" attribute="String SingleQ" lineEndContext="#stay">
0274         <DetectSpaces />
0275         <DetectIdentifier />
0276         <LineContinue context="#stay" />
0277         <DetectChar char="'" attribute="String SingleQ" context="#pop" />
0278       </context>
0279 
0280       <!-- StringDQ consumes anything till ", substitutes vars and expressions -->
0281       <context name="StringDQ" attribute="String DoubleQ" lineEndContext="#stay">
0282         <DetectSpaces />
0283         <DetectIdentifier />
0284         <DetectChar char="&quot;" attribute="String DoubleQ" context="#pop" />
0285         <LineContinue context="#stay" />
0286         <DetectChar char="\" lookAhead="1" context="StringDQEscape" />
0287         <DetectChar char="$" lookAhead="1" context="StringDQDispatchVariables" />
0288       </context>
0289 
0290       <context name="StringDQEscape" attribute="String DoubleQ" lineEndContext="#pop">
0291         <Detect2Chars char="\" char1="&quot;" attribute="String Escape" context="#pop" />
0292         <Detect2Chars char="\" char1="$" attribute="String Escape" context="#pop" />
0293         <Detect2Chars char="\" char1="n" attribute="String Escape" context="#pop" />
0294         <Detect2Chars char="\" char1="r" attribute="String Escape" context="#pop" />
0295         <Detect2Chars char="\" char1="t" attribute="String Escape" context="#pop" />
0296         <Detect2Chars char="\" char1="\" attribute="String Escape" context="#pop" />
0297         <!-- TODO REALLY? -->
0298         <LineContinue attribute="String Escape" context="#pop" />
0299         <DetectChar char="\" attribute="String DoubleQ" context="#pop" />
0300       </context>
0301 
0302       <context name="StringDQDispatchVariables" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0303         <IncludeRules context="DispatchVariablesBase" />
0304         <DetectChar char="$" attribute="String DoubleQ" context="#pop" />
0305       </context>
0306 
0307       <!-- SubstCommand is called after a $( is encountered -->
0308       <context name="CommandSubst" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop">
0309         <LineContinue context="#stay" />
0310         <DetectChar char=")" attribute="Variable" context="#pop" />
0311         <!-- TODO Need a FIX for this:
0312 
0313             ARG _python_ver = $(${python_bin} -c \"import sys; print(\'{}.{}\'.format(*sys.version_info))\")
0314         -->
0315         <IncludeRules context="BashOneLine##Bash" />
0316       </context>
0317 
0318       <context name="Comment" attribute="Comment" lineEndContext="#pop">
0319         <LineContinue context="#stay" />
0320         <IncludeRules context="##Comments" />
0321       </context>
0322 
0323       <!--
0324           Earthly Commands
0325       -->
0326 
0327       <!-- https://docs.earthly.dev/docs/earthfile#arg -->
0328       <context name="ARG_ctx" attribute="Normal Text" lineEndContext="#pop">
0329         <StringDetect String="--required" attribute="Command Option" context="#stay" />
0330         <StringDetect String="--global" attribute="Command Option" context="#stay" />
0331         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#stay" />
0332         <keyword String="variables" attribute="Builtin Variable" context="#stay" />
0333         <DetectIdentifier attribute="Variable" context="#stay" />
0334         <DetectChar char="=" attribute="Operator" context="#pop!RecipeContent" />
0335       </context>
0336 
0337       <!-- https://docs.earthly.dev/docs/earthfile#build -->
0338       <context name="BUILD_ctx" attribute="Normal Text" lineEndContext="#pop">
0339         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0340         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0341         <IncludeRules context="RecipeContent" />
0342       </context>
0343 
0344       <!-- https://docs.earthly.dev/docs/earthfile#do -->
0345       <context name="DO_ctx" attribute="Normal Text" lineEndContext="#pop">
0346         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0347         <IncludeRules context="RecipeContent" />
0348       </context>
0349 
0350       <!-- https://docs.earthly.dev/docs/earthfile#copy -->
0351       <context name="COPY_ctx" attribute="Normal Text" lineEndContext="#pop">
0352         <StringDetect String="--dir" attribute="Command Option" context="#stay" />
0353         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0354         <StringDetect String="--keep-own" attribute="Command Option" context="#stay" />
0355         <StringDetect String="--chmod" attribute="Command Option" context="#stay" />
0356         <StringDetect String="--if-exists" attribute="Command Option" context="#stay" />
0357         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0358         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0359         <IncludeRules context="RecipeContent" />
0360       </context>
0361 
0362       <!-- https://docs.earthly.dev/docs/earthfile#cache-beta -->
0363       <context name="CACHE_ctx" attribute="Normal Text" lineEndContext="#pop">
0364         <StringDetect String="--sharing" attribute="Command Option" context="#stay" />
0365         <IncludeRules context="RecipeContent" />
0366       </context>
0367 
0368       <!-- https://docs.earthly.dev/docs/earthfile#expose-same-as-dockerfile-expose -->
0369       <context name="EXPOSE_ctx" attribute="Normal Text" lineEndContext="#pop">
0370         <IncludeRules context="RecipeContent" />
0371       </context>
0372 
0373       <!-- https://docs.earthly.dev/docs/earthfile#user-same-as-dockerfile-user -->
0374       <context name="USER_ctx" attribute="Normal Text" lineEndContext="#pop">
0375         <IncludeRules context="RecipeContent" />
0376       </context>
0377 
0378       <!-- https://docs.earthly.dev/docs/earthfile#workdir-same-as-dockerfile-workdir -->
0379       <context name="WORKDIR_ctx" attribute="Normal Text" lineEndContext="#pop">
0380         <IncludeRules context="RecipeContent" />
0381       </context>
0382 
0383       <!-- https://docs.earthly.dev/docs/earthfile#healthcheck-same-as-dockerfile-workdir -->
0384       <context name="HEALTHCHECK_ctx" attribute="Normal Text" lineEndContext="#pop">
0385         <IncludeRules context="RecipeContent" />
0386       </context>
0387 
0388       <!-- https://docs.earthly.dev/docs/earthfile#host-same-as-dockerfile-workdir -->
0389       <context name="HOST_ctx" attribute="Normal Text" lineEndContext="#pop">
0390         <IncludeRules context="RecipeContent" />
0391       </context>
0392 
0393       <!-- https://docs.earthly.dev/docs/earthfile#cmd-same-as-dockerfile-cmd -->
0394       <context name="CMD_ctx" attribute="Normal Text" lineEndContext="#pop">
0395         <AnyChar String="[," attribute="Operator" context="#stay" />
0396         <DetectChar attribute="Operator" context="#pop" char="]" />
0397         <IncludeRules context="RecipeContent" />
0398       </context>
0399 
0400       <!-- https://docs.earthly.dev/docs/earthfile#entrypoint-same-as-dockerfile-entrypoint -->
0401       <!-- TODO Deduplicate? -->
0402       <context name="ENTRYPOINT_ctx" attribute="Normal Text" lineEndContext="#pop">
0403         <AnyChar String="[," attribute="Operator" context="#stay" />
0404         <DetectChar char="]" attribute="Operator" context="#pop" />
0405         <IncludeRules context="RecipeContent" />
0406       </context>
0407 
0408       <!-- https://docs.earthly.dev/docs/earthfile#volume-same-as-dockerfile-volume -->
0409       <!-- TODO Deduplicate? -->
0410       <context name="VOLUME_ctx" attribute="Normal Text" lineEndContext="#pop">
0411         <AnyChar String="[," attribute="Operator" context="#stay" />
0412         <DetectChar char="]" attribute="Operator" context="#pop" />
0413         <IncludeRules context="RecipeContent" />
0414       </context>
0415 
0416       <!-- https://docs.earthly.dev/docs/earthfile#label-same-as-dockerfile-label -->
0417       <context name="LABEL_ctx" attribute="Normal Text" lineEndContext="#pop">
0418         <DetectChar char="=" attribute="Operator" context="#stay" />
0419         <IncludeRules context="RecipeContent" />
0420         <LineContinue context="#stay" />
0421       </context>
0422 
0423       <!-- https://docs.earthly.dev/docs/earthfile#import -->
0424       <context name="IMPORT_ctx" attribute="Normal Text" lineEndContext="#pop">
0425         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0426         <WordDetect String="AS" attribute="Command" context="#stay" />
0427         <IncludeRules context="RecipeContent" />
0428       </context>
0429 
0430       <!-- https://docs.earthly.dev/docs/earthfile#version -->
0431       <context name="VERSION_ctx" attribute="Normal Text" lineEndContext="#pop">
0432         <!-- https://docs.earthly.dev/docs/earthfile/features#feature-flags -->
0433         <StringDetect String="--use-registry-for-with-docker" attribute="Command Option" context="#stay" />
0434         <StringDetect String="--use-copy-include-patterns" attribute="Command Option" context="#stay" />
0435         <StringDetect String="--referenced-save-only" attribute="Command Option" context="#stay" />
0436         <StringDetect String="--for-in" attribute="Command Option" context="#stay" />
0437         <StringDetect String="--require-force-for-unsafe-saves" attribute="Command Option" context="#stay" />
0438         <StringDetect String="--no-implicit-ignore" attribute="Command Option" context="#stay" />
0439         <StringDetect String="--earthly-version-arg" attribute="Command Option" context="#stay" />
0440         <StringDetect String="--shell-out-anywhere" attribute="Command Option" context="#stay" />
0441         <StringDetect String="--explicit-global" attribute="Command Option" context="#stay" />
0442         <StringDetect String="--check-duplicate-images" attribute="Command Option" context="#stay" />
0443         <StringDetect String="--use-cache-command" attribute="Command Option" context="#stay" />
0444         <StringDetect String="--use-host-command" attribute="Command Option" context="#stay" />
0445         <StringDetect String="--use-copy-link" attribute="Command Option" context="#stay" />
0446         <StringDetect String="--new-platform" attribute="Command Option" context="#stay" />
0447         <StringDetect String="--no-tar-build-output" attribute="Command Option" context="#stay" />
0448         <StringDetect String="--use-no-manifest-list" attribute="Command Option" context="#stay" />
0449         <StringDetect String="--use-chmod" attribute="Command Option" context="#stay" />
0450         <StringDetect String="--earthly-locally-arg" attribute="Command Option" context="#stay" />
0451         <StringDetect String="--use-project-secrets" attribute="Command Option" context="#stay" />
0452         <StringDetect String="--use-pipelines" attribute="Command Option" context="#stay" />
0453         <StringDetect String="--earthly-git-author-args" attribute="Command Option" context="#stay" />
0454         <StringDetect String="--wait-block" attribute="Command Option" context="#stay" />
0455         <StringDetect String="--try" attribute="Command Option" context="#stay" />
0456         <StringDetect String="--git-branch" attribute="Command Option" context="#stay" />
0457         <RegExpr String="[0-9](\.[0-9])*" context="#pop" />
0458       </context>
0459 
0460       <!-- https://docs.earthly.dev/docs/earthfile#git-clone -->
0461       <context name="GIT_ctx" attribute="Normal Text" lineEndContext="#pop">
0462         <WordDetect String="CLONE" attribute="Command" context="#stay" />
0463         <StringDetect String="--branch" attribute="Command Option" context="#stay" />
0464         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0465         <IncludeRules context="RecipeContent" />
0466       </context>
0467 
0468       <!-- https://docs.earthly.dev/docs/earthfile#wait -->
0469       <context name="WAIT_ctx" attribute="Normal Text" lineEndContext="#stay">
0470         <WordDetect String="END" attribute="Command" context="#pop" endRegion="WAIT" />
0471         <IncludeRules context="RecipeCommands" />
0472       </context>
0473 
0474       <!-- https://docs.earthly.dev/docs/earthfile#with-docker -->
0475       <context name="WITH_ctx" attribute="Normal Text" lineEndContext="#stay">
0476         <WordDetect String="DOCKER" attribute="Command" context="#stay" />
0477         <WordDetect String="END" attribute="Command" context="#pop" endRegion="WITH" />
0478         <StringDetect String="--pull" attribute="Command Option" context="#stay" />
0479         <StringDetect String="--load" attribute="Command Option" context="WITH_load_arg" />
0480         <StringDetect String="--compose" attribute="Command Option" context="#stay" />
0481         <StringDetect String="--service" attribute="Command Option" context="#stay" />
0482         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0483         <IncludeRules context="RecipeCommandsOnlyRUN" />
0484         <DetectChar char="#" attribute="Comment" context="Comment" />
0485         <IncludeRules context="InappropriateCommands" />
0486       </context>
0487 
0488       <context name="WITH_load_arg" attribute="Normal Text" lineEndContext="#stay">
0489         <DetectSpaces context="#stay" />
0490         <DetectIdentifier attribute="Command Option" />
0491         <DetectChar char="=" attribute="Operator" context="#pop!WITH_load_arg_target_ref" />
0492       </context>
0493 
0494       <context name="WITH_load_arg_target_ref" attribute="Normal Text" lineEndContext="#stay">
0495         <Detect2Chars char="-" char1="-" context="#pop" />
0496         <DetectSpaces context="#pop" />
0497         <DetectChar char="(" attribute="Normal Text" context="WITH_load_arg_target_ref_with_args" />
0498         <IncludeRules context="RecipeCommandsNoLineCont" includeAttrib="true" />
0499       </context>
0500 
0501       <context name="WITH_load_arg_target_ref_with_args" attribute="Normal Text" lineEndContext="#stay">
0502         <DetectChar char=")" attribute="Normal Text" context="#pop#pop" />
0503         <IncludeRules context="RecipeCommandsNoLineCont" includeAttrib="true" />
0504       </context>
0505 
0506       <!-- https://docs.earthly.dev/docs/earthfile#for -->
0507       <context name="FOR_ctx" attribute="Normal Text" lineEndContext="#stay">
0508         <WordDetect String="IN" attribute="Command" context="#stay" />
0509         <WordDetect String="END" attribute="Command" context="#pop" endRegion="FOR" />
0510         <StringDetect String="--sep" attribute="Command Option" context="#stay" />
0511         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0512         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0513         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0514         <StringDetect String="--secret" attribute="Command Option" context="secret_opt" />
0515         <IncludeRules context="RecipeCommands" />
0516       </context>
0517 
0518       <!--
0519         FROM DOCKERFILE ... or FROM ... -->
0520       <context name="FROM_ctx" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop!FROM_image_ctx">
0521         <DetectSpaces />
0522         <WordDetect String="DOCKERFILE" attribute="Command" context="#pop!FROM_DOCKERFILE_ctx" />
0523       </context>
0524 
0525       <!--
0526         FROM [options] <target> [build-args]
0527 
0528         https://docs.earthly.dev/docs/earthfile#from
0529       -->
0530       <context name="FROM_image_ctx" attribute="Normal Text" lineEndContext="#pop">
0531         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0532         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0533         <IncludeRules context="RecipeContent" />
0534       </context>
0535 
0536       <!--
0537         FROM DOCKERFILE [options] <context>
0538 
0539         https://docs.earthly.dev/docs/earthfile#from-dockerfile
0540       -->
0541       <context name="FROM_DOCKERFILE_ctx" attribute="Normal Text" lineEndContext="#pop">
0542         <!-- Options for the second form -->
0543         <StringDetect String="-f" attribute="Command Option" context="#stay" />
0544         <StringDetect String="--target" attribute="Command Option" context="#stay" />
0545         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0546         <StringDetect String="--build-arg" attribute="Command Option" context="secret_opt" />
0547 
0548         <IncludeRules context="RecipeContent" />
0549       </context>
0550 
0551       <!-- SAVE ARTIFACT or SAVE IMAGE -->
0552       <context name="SAVE_ctx" attribute="Normal Text" lineEndContext="#pop">
0553         <DetectSpaces />
0554         <WordDetect String="ARTIFACT" attribute="Command" context="#pop!SAVE_ARTIFACT_ctx" />
0555         <WordDetect String="IMAGE" attribute="Command" context="#pop!SAVE_IMAGE_ctx" />
0556       </context>
0557 
0558       <!-- https://docs.earthly.dev/docs/earthfile#save-artifact -->
0559       <context name="SAVE_ARTIFACT_ctx" attribute="Normal Text" lineEndContext="#pop">
0560         <WordDetect String="AS" attribute="Command" context="#stay" />
0561         <WordDetect String="LOCAL" attribute="Command" context="#stay" />
0562         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0563         <StringDetect String="--keep-own" attribute="Command Option" context="#stay" />
0564         <StringDetect String="--if-exists" attribute="Command Option" context="#stay" />
0565         <StringDetect String="--force" attribute="Command Option" context="#stay" />
0566         <IncludeRules context="RecipeContent" />
0567       </context>
0568 
0569       <!-- https://docs.earthly.dev/docs/earthfile#save-image -->
0570       <context name="SAVE_IMAGE_ctx" attribute="Normal Text" lineEndContext="#pop">
0571         <StringDetect String="--cache-hint" attribute="Command Option" context="#stay" />
0572         <StringDetect String="--cache-from" attribute="Command Option" context="#stay" />
0573         <StringDetect String="--push" attribute="Command Option" context="#stay" />
0574         <StringDetect String="--no-manifest-list" attribute="Command Option" context="#stay" />
0575         <IncludeRules context="RecipeContent" />
0576       </context>
0577 
0578       <!-- https://docs.earthly.dev/docs/earthfile#run -->
0579       <context name="RUN_ctx" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop!BashOneLine##Bash">
0580         <DetectSpaces />
0581         <LineContinue context="#stay" />
0582         <DetectChar char="[" attribute="Operator" context="#pop!RUN_exec" />
0583         <StringDetect String="--push" attribute="Command Option" context="#stay" />
0584         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0585         <StringDetect String="--entrypoint" attribute="Command Option" context="#stay" />
0586         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0587         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0588         <StringDetect String="--secret" attribute="Command Option" context="secret_opt" />
0589         <StringDetect String="--mount" attribute="Command Option" context="mount_opt" />
0590         <StringDetect String="--interactive-keep" attribute="Command Option" context="#stay" />
0591         <StringDetect String="--interactive" attribute="Command Option" context="#stay" />
0592         <StringDetect String="--network" attribute="Command Option" context="#stay" />
0593         <Detect2Chars char="-" char1="-" attribute="Command Option" context="#pop!BashOneLine##Bash" />
0594       </context>
0595       <!-- Second form of `RUN` -->
0596       <context name="RUN_exec" attribute="Normal Text" lineEndContext="#pop">
0597         <DetectChar char="]" attribute="Operator" context="#pop" />
0598         <IncludeRules context="RecipeContent" />
0599       </context>
0600 
0601       <!-- https://docs.earthly.dev/docs/earthfile#if -->
0602       <context name="IF_ctx" attribute="Normal Text" lineEndContext="#stay">
0603         <DetectSpaces />
0604         <LineContinue context="#stay" />
0605 
0606         <StringDetect String="ELSE IF" attribute="Command" context="#stay" />
0607         <WordDetect String="ELSE" attribute="Command" context="#stay" />
0608         <WordDetect String="END" attribute="Command" context="#pop" endRegion="IF" />
0609 
0610         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0611         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0612         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0613         <StringDetect String="--entrypoint" attribute="Command Option" context="#stay" />
0614         <StringDetect String="--mount" attribute="Command Option" context="mount_opt" />
0615         <StringDetect String="--secret" attribute="Command Option" context="secret_opt" />
0616         <!-- start expression in single brackets -->
0617         <DetectChar char="[" attribute="Operator" context="BracketExpression" />
0618         <IncludeRules context="RecipeCommands" />
0619       </context>
0620 
0621       <!-- https://docs.earthly.dev/docs/earthfile#project -->
0622       <context name="PROJECT_ctx" attribute="Normal Text" lineEndContext="#pop">
0623         <IncludeRules context="RecipeContent" />
0624       </context>
0625 
0626       <!-- https://docs.earthly.dev/docs/earthfile#trigger-beta -->
0627       <context name="TRIGGER_ctx" attribute="Normal Text" lineEndContext="#pop">
0628         <keyword String="trigger_events" attribute="Command Option" context="#stay" />
0629         <IncludeRules context="RecipeContent" />
0630       </context>
0631 
0632       <!-- https://docs.earthly.dev/docs/earthfile#pipeline-beta -->
0633       <context name="PIPELINE_ctx" attribute="Normal Text" lineEndContext="#pop">
0634         <StringDetect String="--push" attribute="Command Option" context="#stay" />
0635         <IncludeRules context="RecipeContent" />
0636       </context>
0637 
0638       <!-- https://docs.earthly.dev/docs/earthfile#try-experimental -->
0639       <context name="TRY_ctx" attribute="Normal Text" lineEndContext="#stay">
0640         <WordDetect String="FINALLY" attribute="Command" context="#pop!FINALLY_ctx" />
0641         <WordDetect String="END" attribute="Command" context="#pop" endRegion="TRY" />
0642         <IncludeRules context="RecipeCommandsOnlyRUN" />
0643         <DetectChar char="#" attribute="Comment" context="Comment" />
0644         <IncludeRules context="InappropriateCommands" />
0645       </context>
0646       <context name="FINALLY_ctx" attribute="Normal Text" lineEndContext="#stay">
0647         <WordDetect String="END" attribute="Command" context="#pop" endRegion="TRY" />
0648         <IncludeRules context="RecipeCommandsOnlySAVE" />
0649         <DetectChar char="#" attribute="Comment" context="Comment" />
0650         <IncludeRules context="InappropriateCommands" />
0651       </context>
0652 
0653       <context name="BracketExpression" attribute="Normal Text" lineEndContext="#pop">
0654         <DetectChar char="]" attribute="Operator" context="#pop" />
0655         <AnyChar String="!=" attribute="Operator" context="#stay" />
0656         <RegExpr String="(&binary_operators;|&unary_operators;)" attribute="Operator" context="#stay" />
0657         <DetectSpaces />
0658         <IncludeRules context="RecipeContent" />
0659       </context>
0660 
0661       <context name="mount_opt" attribute="Command Option" lineEndContext="#stay" fallthroughContext="#pop!mount_arg">
0662         <DetectSpaces context="#stay" />
0663       </context>
0664 
0665       <context name="mount_arg" attribute="Command Option" lineEndContext="#stay" fallthroughContext="#pop">
0666         <keyword String="mount_keys" attribute="Command Option" context="#stay" />
0667         <AnyChar String=",=" attribute="Operator" context="#stay" />
0668         <!--
0669             ALERT A mount option arg must consume characters up to the next space
0670             and stay in this context to match other rules. Typically there are characters
0671             that could be found in file paths...
0672 
0673             NOTE If you see "Normal Text" in the `mount` options, update the String below.
0674 
0675             TODO Any better way?
0676         -->
0677         <AnyChar String="/.-" attribute="Command Option" context="#stay" />
0678         <DetectIdentifier attribute="Command Option" />
0679         <IncludeRules context="RecipeContent" includeAttrib="true" />
0680         <DetectSpaces context="#pop" />
0681       </context>
0682 
0683       <context name="secret_opt" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop!secret_arg">
0684         <DetectSpaces context="#stay" />
0685       </context>
0686 
0687       <context name="secret_arg" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop">
0688         <DetectIdentifier attribute="Command Option" />
0689         <DetectChar char="=" attribute="Operator" context="#stay" />
0690         <IncludeRules context="RecipeContent" />
0691         <DetectSpaces context="#pop" />
0692       </context>
0693 
0694       <context name="InappropriateCommands" attribute="Normal Text">
0695         <keyword String="commands" attribute="Error" />
0696       </context>
0697 
0698     </contexts>
0699 
0700     <itemDatas>
0701       <itemData name="Normal Text"              defStyleNum="dsNormal" spellChecking="false" />
0702       <itemData name="Command"                  defStyleNum="dsKeyword" bold="true" spellChecking="false" />
0703       <itemData name="User Defined Command"     defStyleNum="dsFunction" spellChecking="false" />
0704       <itemData name="Command Option"           defStyleNum="dsAttribute" italic="true" spellChecking="false" />
0705       <itemData name="Build Arg"                defStyleNum="dsAttribute" italic="true" spellChecking="false" />
0706       <itemData name="Reference"                defStyleNum="dsExtension" spellChecking="false" />
0707       <itemData name="Target Name"              defStyleNum="dsImport" spellChecking="false" />
0708       <itemData name="Operator"                 defStyleNum="dsOperator" spellChecking="false" />
0709       <itemData name="Artifact Name"            defStyleNum="dsExtension" spellChecking="false" />
0710       <itemData name="Variable"                 defStyleNum="dsVariable" spellChecking="false" />
0711       <itemData name="Builtin Variable"         defStyleNum="dsVariable" spellChecking="false" color="#c09050" selColor="#c09050" />
0712       <itemData name="Internal/Local Variable"  defStyleNum="dsVariable" spellChecking="false" />
0713       <itemData name="Comment"                  defStyleNum="dsComment" />
0714       <itemData name="String SingleQ"           defStyleNum="dsString" />
0715       <itemData name="String DoubleQ"           defStyleNum="dsString" />
0716       <itemData name="String Escape"            defStyleNum="dsSpecialChar" />
0717       <itemData name="Integer"                  defStyleNum="dsDecVal" />
0718       <itemData name="Error"                    defStyleNum="dsError" />
0719     </itemDatas>
0720 
0721   </highlighting>
0722 
0723   <general>
0724     <comments>
0725       <comment name="singleLine" start="#" position="afterwhitespace"/>
0726     </comments>
0727   </general>
0728 
0729 </language>