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 SYSTEM "language.dtd"
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="1"
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_TARGET_TAG</item>
0029       <item>EARTHLY_TARGET_PROJECT</item>
0030       <item>EARTHLY_TARGET_PROJECT_NO_TAG</item>
0031       <item>EARTHLY_TARGET_NAME</item>
0032       <item>EARTHLY_TARGET_TAG</item>
0033       <item>EARTHLY_TARGET_TAG_DOCKER</item>
0034       <item>EARTHLY_GIT_HASH</item>
0035       <item>EARTHLY_GIT_SHORT_HASH</item>
0036       <item>EARTHLY_GIT_ORIGIN_URL</item>
0037       <item>EARTHLY_GIT_PROJECT_NAME</item>
0038       <item>EARTHLY_GIT_COMMIT_TIMESTAMP</item>
0039       <item>EARTHLY_GIT_COMMIT_AUTHOR_TIMESTAMP</item>
0040       <item>EARTHLY_VERSION</item>
0041       <item>EARTHLY_BUILD_SHA</item>
0042       <item>TARGETPLATFORM</item>
0043       <item>TARGETOS</item>
0044       <item>TARGETARCH</item>
0045       <item>TARGETVARIANT</item>
0046       <item>EARTHLY_SOURCE_DATE_EPOCH</item>
0047       <item>USERPLATFORM</item>
0048       <item>USEROS</item>
0049       <item>USERARCH</item>
0050       <item>USERVARIANT</item>
0051     </list>
0052 
0053     <!--
0054       See `RUN` and `mount` option description
0055       https://docs.earthly.dev/docs/earthfile#run
0056     -->
0057     <list name="mount_keys">
0058       <item>type</item>
0059       <item>target</item>
0060       <item>mode</item>
0061       <item>id</item>
0062       <item>sharing</item>
0063     </list>
0064 
0065     <contexts>
0066       <context name="Base" attribute="Normal Text" lineEndContext="#stay">
0067         <RegExpr
0068             String="^[A-Z_][A-Z_0-9]+:"
0069             column="0"
0070             context="#stay"
0071             attribute="User Defined Command"
0072             endRegion="Recipe"
0073             beginRegion="Recipe"
0074           />
0075         <RegExpr
0076             String="^[a-z][a-z\-_0-9]+:"
0077             column="0"
0078             context="#stay"
0079             attribute="Target Name"
0080             endRegion="Recipe"
0081             beginRegion="Recipe"
0082           />
0083         <DetectSpaces />
0084         <IncludeRules context="RecipeCommands" />
0085       </context>
0086 
0087       <context name="RecipeCommands" attribute="Normal Text" lineEndContext="#pop">
0088         <DetectSpaces />
0089         <DetectChar char="#" attribute="Comment" context="Comment" />
0090         <!-- The whole file is a collection of recipes -->
0091         <WordDetect String="ARG" attribute="Command" context="ARG_ctx" />
0092         <WordDetect String="FROM" attribute="Command" context="FROM_ctx" />
0093         <WordDetect String="BUILD" attribute="Command" context="BUILD_ctx" />
0094         <WordDetect String="VERSION" attribute="Command" context="VERSION_ctx" />
0095         <WordDetect String="GIT" attribute="Command" context="GIT_ctx" />
0096         <WordDetect String="CACHE" attribute="Command" context="CACHE_ctx" />
0097         <WordDetect String="LOCALLY" attribute="Command" context="#stay" />
0098         <WordDetect String="COMMAND" attribute="Command" context="#stay" />
0099         <WordDetect String="IMPORT" attribute="Command" context="IMPORT_ctx" />
0100         <WordDetect String="CMD" attribute="Command" context="CMD_ctx" />
0101         <WordDetect String="LABEL" attribute="Command" context="LABEL_ctx" />
0102         <WordDetect String="EXPOSE" attribute="Command" context="EXPOSE_ctx" />
0103         <WordDetect String="ENV" attribute="Command" context="BashOneLine##Bash" />
0104         <WordDetect String="ENTRYPOINT" attribute="Command" context="ENTRYPOINT_ctx" />
0105         <WordDetect String="VOLUME" attribute="Command" context="VOLUME_ctx" />
0106         <WordDetect String="USER" attribute="Command" context="USER_ctx" />
0107         <WordDetect String="WORKDIR" attribute="Command" context="WORKDIR_ctx" />
0108         <WordDetect String="HEALTHCHECK" attribute="Command" context="HEALTHCHECK_ctx" />
0109         <WordDetect String="HOST" attribute="Command" context="HOST_ctx" />
0110         <WordDetect String="DO" attribute="Command" context="DO_ctx" />
0111         <WordDetect String="COPY" attribute="Command" context="COPY_ctx" />
0112         <WordDetect String="SAVE" attribute="Command" context="SAVE_ctx" />
0113         <WordDetect String="WAIT" attribute="Command" context="WAIT_ctx" beginRegion="WAIT" />
0114         <WordDetect String="WITH" attribute="Command" context="WITH_ctx" beginRegion="WITH" />
0115         <WordDetect String="FOR" attribute="Command" context="FOR_ctx" beginRegion="FOR" />
0116         <WordDetect String="RUN" attribute="Command" context="RUN_ctx" />
0117         <WordDetect String="IF" attribute="Command" context="IF_ctx" beginRegion="IF" />
0118       </context>
0119 
0120       <context name="RecipeContent" attribute="Normal Text" lineEndContext="#pop">
0121         <LineContinue />
0122 
0123         <DetectChar char="'" attribute="String SingleQ" context="StringSQ" />
0124         <DetectChar char="&quot;" attribute="String DoubleQ" context="StringDQ" />
0125 
0126         <!-- See https://docs.earthly.dev/docs/guides/target-ref#target-reference -->
0127         <RegExpr
0128           context="DetectReference"
0129           lookAhead="true"
0130           String="([a-z0-9_\-\./]+(:[A-Za-z0-9_\-\./]+)?)?(\+[A-Za-z0-9_\-]+)(/[^ ,]*)?"
0131           />
0132         <RegExpr String="--&var_name_re;=" lookAhead="true" context="BuildArg" />
0133         <DetectChar char="$" lookAhead="1" context="DispatchVariables" />
0134         <Int attribute="Integer" />
0135       </context>
0136 
0137       <context name="BuildArg" attribute="Normal Text" lineEndContext="#pop">
0138         <DetectChar char="=" attribute="Operator" context="#pop" />
0139         <RegExpr String="--&var_name_re;" attribute="Build Arg" />
0140       </context>
0141 
0142       <context name="DispatchVariables" attribute="Normal Text" lineEndContext="#pop">
0143         <IncludeRules context="DispatchVariablesBase" />
0144         <DetectChar char="$" context="#pop" />
0145       </context>
0146 
0147       <context name="DispatchVariablesBase" attribute="Normal Text" lineEndContext="#pop">
0148         <Detect2Chars char="$" char1="$" attribute="Variable" context="#pop" />
0149         <Detect2Chars char="$" char1="?" attribute="Variable" context="#pop" />
0150         <Detect2Chars char="$" char1="*" attribute="Variable" context="#pop" />
0151         <Detect2Chars char="$" char1="@" attribute="Variable" context="#pop" />
0152         <Detect2Chars char="$" char1="{" attribute="Variable" context="VarSubst" />
0153         <Detect2Chars char="$" char1="(" attribute="Variable" context="CommandSubst" />
0154         <RegExpr String="\$&var_name_re;" lookAhead="true" context="VarName" />
0155       </context>
0156 
0157       <context name="VarName" attribute="Normal Text" lineEndContext="#pop">
0158         <DetectChar char="$" attribute="Variable" context="#stay" />
0159         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#pop" />
0160         <keyword String="variables" insensitive="false" attribute="Builtin Variable" context="#pop" />
0161         <DetectIdentifier attribute="Variable" context="#pop" />
0162       </context>
0163 
0164       <context name="VarSubst" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0165         <DetectChar char="}" attribute="Variable" context="#pop#pop" />
0166         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#stay" />
0167         <keyword String="variables" insensitive="false" attribute="Builtin Variable" context="#stay" />
0168         <DetectIdentifier attribute="Variable" />
0169         <Detect2Chars char=":" char1="+" attribute="Variable" context="#stay" />
0170         <Detect2Chars char=":" char1="-" attribute="Variable" context="#stay" />
0171       </context>
0172 
0173       <context name="DetectReference" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0174         <StringDetect String="%1" dynamic="true" attribute="Reference" context="#stay" />
0175         <StringDetect String="%3" lookAhead="true" dynamic="true" context="TargetOrCommand" />
0176         <StringDetect String="%4" dynamic="true" attribute="Artifact Name" context="#stay" />
0177       </context>
0178 
0179       <context name="TargetOrCommand" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0180         <RegExpr String="\+[A-Z_][A-Z_0-9]+" context="#pop" attribute="User Defined Command" />
0181         <RegExpr String="\+[a-z][a-z\-_0-9]+" context="#pop" attribute="Target Name" />
0182       </context>
0183 
0184       <!-- StringSQ consumes anything till ' -->
0185       <context name="StringSQ" attribute="String SingleQ" lineEndContext="#stay">
0186         <DetectSpaces />
0187         <DetectIdentifier />
0188         <LineContinue context="#stay" />
0189         <DetectChar char="'" attribute="String SingleQ" context="#pop" />
0190       </context>
0191 
0192       <!-- StringDQ consumes anything till ", substitutes vars and expressions -->
0193       <context name="StringDQ" attribute="String DoubleQ" lineEndContext="#stay">
0194         <DetectSpaces />
0195         <DetectIdentifier />
0196         <DetectChar char="&quot;" attribute="String DoubleQ" context="#pop" />
0197         <LineContinue context="#stay" />
0198         <DetectChar char="\" lookAhead="1" context="StringDQEscape" />
0199         <DetectChar char="$" lookAhead="1" context="StringDQDispatchVariables" />
0200       </context>
0201 
0202       <context name="StringDQEscape" attribute="String DoubleQ" lineEndContext="#pop">
0203         <Detect2Chars char="\" char1="&quot;" attribute="String Escape" context="#pop" />
0204         <Detect2Chars char="\" char1="$" attribute="String Escape" context="#pop" />
0205         <Detect2Chars char="\" char1="n" attribute="String Escape" context="#pop" />
0206         <Detect2Chars char="\" char1="r" attribute="String Escape" context="#pop" />
0207         <Detect2Chars char="\" char1="t" attribute="String Escape" context="#pop" />
0208         <Detect2Chars char="\" char1="\" attribute="String Escape" context="#pop" />
0209         <!-- TODO REALLY? -->
0210         <LineContinue attribute="String Escape" context="#pop" />
0211         <DetectChar char="\" attribute="String DoubleQ" context="#pop" />
0212       </context>
0213 
0214       <context name="StringDQDispatchVariables" attribute="Normal Text" lineEndContext="#pop" fallthroughContext="#pop">
0215         <IncludeRules context="DispatchVariablesBase" />
0216         <DetectChar char="$" attribute="String DoubleQ" context="#pop" />
0217       </context>
0218 
0219       <!-- SubstCommand is called after a $( is encountered -->
0220       <context name="CommandSubst" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop">
0221         <LineContinue context="#stay" />
0222         <DetectChar char=")" attribute="Variable" context="#pop" />
0223         <!-- TODO Need a FIX for this:
0224 
0225             ARG _python_ver = $(${python_bin} -c \"import sys; print(\'{}.{}\'.format(*sys.version_info))\")
0226         -->
0227         <IncludeRules context="BashOneLine##Bash" />
0228       </context>
0229 
0230       <context name="Comment" attribute="Comment" lineEndContext="#pop">
0231         <LineContinue context="#stay" />
0232         <IncludeRules context="##Comments" />
0233       </context>
0234 
0235       <!--
0236           Earthly Commands
0237       -->
0238 
0239       <!-- https://docs.earthly.dev/docs/earthfile#arg -->
0240       <context name="ARG_ctx" attribute="Normal Text" lineEndContext="#pop">
0241         <StringDetect String="--required" attribute="Command Option" context="#stay" />
0242         <RegExpr String="_&var_name_re;" attribute="Internal/Local Variable" context="#stay" />
0243         <keyword String="variables" insensitive="false" attribute="Builtin Variable" context="#stay" />
0244         <DetectIdentifier attribute="Variable" context="#stay" />
0245         <DetectChar char="=" attribute="Operator" context="#pop!RecipeContent" />
0246       </context>
0247 
0248       <!-- https://docs.earthly.dev/docs/earthfile#build -->
0249       <context name="BUILD_ctx" attribute="Normal Text" lineEndContext="#pop">
0250         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0251         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0252         <IncludeRules context="RecipeContent" />
0253       </context>
0254 
0255       <!-- https://docs.earthly.dev/docs/earthfile#do -->
0256       <context name="DO_ctx" attribute="Normal Text" lineEndContext="#pop">
0257         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0258         <IncludeRules context="RecipeContent" />
0259       </context>
0260 
0261       <!-- https://docs.earthly.dev/docs/earthfile#copy -->
0262       <context name="COPY_ctx" attribute="Normal Text" lineEndContext="#pop">
0263         <StringDetect String="--dir" attribute="Command Option" context="#stay" />
0264         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0265         <StringDetect String="--keep-own" attribute="Command Option" context="#stay" />
0266         <StringDetect String="--if-exists" attribute="Command Option" context="#stay" />
0267         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0268         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0269         <IncludeRules context="RecipeContent" />
0270       </context>
0271 
0272       <!-- https://docs.earthly.dev/docs/earthfile#cache-beta -->
0273       <context name="CACHE_ctx" attribute="Normal Text" lineEndContext="#pop">
0274         <StringDetect String="--sharing" attribute="Command Option" context="#stay" />
0275         <IncludeRules context="RecipeContent" />
0276       </context>
0277 
0278       <!-- https://docs.earthly.dev/docs/earthfile#expose-same-as-dockerfile-expose -->
0279       <context name="EXPOSE_ctx" attribute="Normal Text" lineEndContext="#pop">
0280         <IncludeRules context="RecipeContent" />
0281       </context>
0282 
0283       <!-- https://docs.earthly.dev/docs/earthfile#user-same-as-dockerfile-user -->
0284       <context name="USER_ctx" attribute="Normal Text" lineEndContext="#pop">
0285         <IncludeRules context="RecipeContent" />
0286       </context>
0287 
0288       <!-- https://docs.earthly.dev/docs/earthfile#workdir-same-as-dockerfile-workdir -->
0289       <context name="WORKDIR_ctx" attribute="Normal Text" lineEndContext="#pop">
0290         <IncludeRules context="RecipeContent" />
0291       </context>
0292 
0293       <!-- https://docs.earthly.dev/docs/earthfile#healthcheck-same-as-dockerfile-workdir -->
0294       <context name="HEALTHCHECK_ctx" attribute="Normal Text" lineEndContext="#pop">
0295         <IncludeRules context="RecipeContent" />
0296       </context>
0297 
0298       <!-- https://docs.earthly.dev/docs/earthfile#host-same-as-dockerfile-workdir -->
0299       <context name="HOST_ctx" attribute="Normal Text" lineEndContext="#pop">
0300         <IncludeRules context="RecipeContent" />
0301       </context>
0302 
0303       <!-- https://docs.earthly.dev/docs/earthfile#cmd-same-as-dockerfile-cmd -->
0304       <context name="CMD_ctx" attribute="Normal Text" lineEndContext="#pop">
0305         <AnyChar String="[," attribute="Operator" context="#stay" />
0306         <DetectChar attribute="Operator" context="#pop" char="]" />
0307         <IncludeRules context="RecipeContent" />
0308       </context>
0309 
0310       <!-- https://docs.earthly.dev/docs/earthfile#entrypoint-same-as-dockerfile-entrypoint -->
0311       <!-- TODO Deduplicate? -->
0312       <context name="ENTRYPOINT_ctx" attribute="Normal Text" lineEndContext="#pop">
0313         <AnyChar String="[," attribute="Operator" context="#stay" />
0314         <DetectChar char="]" attribute="Operator" context="#pop" />
0315         <IncludeRules context="RecipeContent" />
0316       </context>
0317 
0318       <!-- https://docs.earthly.dev/docs/earthfile#volume-same-as-dockerfile-volume -->
0319       <!-- TODO Deduplicate? -->
0320       <context name="VOLUME_ctx" attribute="Normal Text" lineEndContext="#pop">
0321         <AnyChar String="[," attribute="Operator" context="#stay" />
0322         <DetectChar char="]" attribute="Operator" context="#pop" />
0323         <IncludeRules context="RecipeContent" />
0324       </context>
0325 
0326       <!-- https://docs.earthly.dev/docs/earthfile#label-same-as-dockerfile-label -->
0327       <context name="LABEL_ctx" attribute="Normal Text" lineEndContext="#pop">
0328         <DetectChar char="=" attribute="Operator" context="#stay" />
0329         <IncludeRules context="RecipeContent" />
0330         <LineContinue context="#stay" />
0331       </context>
0332 
0333       <!-- https://docs.earthly.dev/docs/earthfile#import -->
0334       <context name="IMPORT_ctx" attribute="Normal Text" lineEndContext="#pop">
0335         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0336         <WordDetect String="AS" attribute="Command" context="#stay" />
0337         <IncludeRules context="RecipeContent" />
0338       </context>
0339 
0340       <!-- https://docs.earthly.dev/docs/earthfile#version -->
0341       <context name="VERSION_ctx" attribute="Normal Text" lineEndContext="#pop">
0342         <!-- https://docs.earthly.dev/docs/earthfile/features#feature-flags -->
0343         <StringDetect String="--use-copy-include-patterns" attribute="Command Option" context="#stay" />
0344         <StringDetect String="--referenced-save-only" attribute="Command Option" context="#stay" />
0345         <StringDetect String="--for-in" attribute="Command Option" context="#stay" />
0346         <StringDetect String="--require-force-for-unsafe-saves" attribute="Command Option" context="#stay" />
0347         <StringDetect String="--no-implicit-ignore" attribute="Command Option" context="#stay" />
0348         <StringDetect String="--earthly-version-arg" attribute="Command Option" context="#stay" />
0349         <StringDetect String="--shell-out-anywhere" attribute="Command Option" context="#stay" />
0350         <StringDetect String="--use-registry-for-with-docker" attribute="Command Option" context="#stay" />
0351         <!--Other not from the list -->
0352         <StringDetect String="--wait-block" attribute="Command Option" context="#stay" />
0353         <StringDetect String="--use-cache-command" attribute="Command Option" context="#stay" />
0354         <RegExpr String="[0-9](\.[0-9])*" context="#pop" />
0355       </context>
0356 
0357       <!-- https://docs.earthly.dev/docs/earthfile#git-clone -->
0358       <context name="GIT_ctx" attribute="Normal Text" lineEndContext="#pop">
0359         <WordDetect String="CLONE" attribute="Command" context="#stay" />
0360         <StringDetect String="--branch" attribute="Command Option" context="#stay" />
0361         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0362         <IncludeRules context="RecipeContent" />
0363       </context>
0364 
0365       <!-- https://docs.earthly.dev/docs/earthfile#wait-experimental -->
0366       <context name="WAIT_ctx" attribute="Normal Text" lineEndContext="#stay">
0367         <WordDetect String="END" attribute="Command" context="#pop" endRegion="WAIT" />
0368         <IncludeRules context="RecipeCommands" />
0369       </context>
0370 
0371       <!-- https://docs.earthly.dev/docs/earthfile#with-docker -->
0372       <context name="WITH_ctx" attribute="Normal Text" lineEndContext="#stay">
0373         <WordDetect String="DOCKER" attribute="Command" context="#stay" />
0374         <WordDetect String="END" attribute="Command" context="#pop" endRegion="WITH" />
0375         <StringDetect String="--pull" attribute="Command Option" context="#stay" />
0376         <StringDetect String="--load" attribute="Command Option" context="#stay" />
0377         <StringDetect String="--compose" attribute="Command Option" context="#stay" />
0378         <StringDetect String="--service" attribute="Command Option" context="#stay" />
0379         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0380         <IncludeRules context="RecipeCommands" />
0381       </context>
0382 
0383       <!-- https://docs.earthly.dev/docs/earthfile#for -->
0384       <context name="FOR_ctx" attribute="Normal Text" lineEndContext="#stay">
0385         <WordDetect String="IN" attribute="Command" context="#stay" />
0386         <WordDetect String="END" attribute="Command" context="#pop" endRegion="FOR" />
0387         <StringDetect String="--sep" attribute="Command Option" context="#stay" />
0388         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0389         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0390         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0391         <StringDetect String="--secret" attribute="Command Option" context="#stay" />
0392         <IncludeRules context="RecipeCommands" />
0393       </context>
0394 
0395       <!--
0396         FROM [options] <target> [build-args]
0397         FROM DOCKERFILE [options] <context>
0398 
0399         https://docs.earthly.dev/docs/earthfile#from
0400         https://docs.earthly.dev/docs/earthfile#from-dockerfile
0401       -->
0402       <context name="FROM_ctx" attribute="Normal Text" lineEndContext="#pop">
0403         <WordDetect String="DOCKERFILE" attribute="Command" context="#stay" />
0404 
0405         <!-- Options for the first form -->
0406         <StringDetect String="--allow-privileged" attribute="Command Option" context="#stay" />
0407         <StringDetect String="--platform" attribute="Command Option" context="#stay" />
0408 
0409         <!-- Options for the second form -->
0410         <StringDetect String="-f" attribute="Command Option" context="#stay" />
0411         <StringDetect String="--target" attribute="Command Option" context="#stay" />
0412 
0413         <IncludeRules context="RecipeContent" />
0414       </context>
0415 
0416       <!--
0417         SAVE ARTIFACT
0418         https://docs.earthly.dev/docs/earthfile#save-artifact
0419 
0420         SAVE IMAGE
0421         https://docs.earthly.dev/docs/earthfile#save-image
0422       -->
0423       <context name="SAVE_ctx" attribute="Normal Text" lineEndContext="#pop">
0424         <WordDetect String="ARTIFACT" attribute="Command" context="#stay" />
0425         <WordDetect String="AS" attribute="Command" context="#stay" />
0426         <WordDetect String="LOCAL" attribute="Command" context="#stay" />
0427         <WordDetect String="IMAGE" attribute="Command" context="#stay" />
0428 
0429         <!-- Options for the first form -->
0430         <StringDetect String="--keep-ts" attribute="Command Option" context="#stay" />
0431         <StringDetect String="--keep-own" attribute="Command Option" context="#stay" />
0432         <StringDetect String="--if-exists" attribute="Command Option" context="#stay" />
0433         <StringDetect String="--force" attribute="Command Option" context="#stay" />
0434 
0435         <!-- Options for the second form -->
0436         <StringDetect String="--cache-hint" attribute="Command Option" context="#stay" />
0437         <StringDetect String="--cache-from" attribute="Command Option" context="#stay" />
0438         <StringDetect String="--push" attribute="Command Option" context="#stay" />
0439 
0440         <IncludeRules context="RecipeContent" />
0441       </context>
0442 
0443       <!-- https://docs.earthly.dev/docs/earthfile#run -->
0444       <context name="RUN_ctx" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop!BashOneLine##Bash">
0445         <DetectSpaces />
0446         <LineContinue context="#stay" />
0447         <DetectChar char="[" attribute="Operator" context="#pop!RUN_exec" />
0448         <StringDetect String="--push" attribute="Command Option" context="#stay" />
0449         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0450         <StringDetect String="--entrypoint" attribute="Command Option" context="#stay" />
0451         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0452         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0453         <StringDetect String="--secret" attribute="Command Option" context="secret_opt" />
0454         <StringDetect String="--mount" attribute="Command Option" context="mount_opt" />
0455         <StringDetect String="--interactive-keep" attribute="Command Option" context="#stay" />
0456         <StringDetect String="--interactive" attribute="Command Option" context="#stay" />
0457         <Detect2Chars char="-" char1="-" attribute="Command Option" context="#pop!BashOneLine##Bash" />
0458       </context>
0459       <!-- Second form of `RUN` -->
0460       <context name="RUN_exec" attribute="Normal Text" lineEndContext="#pop">
0461         <DetectChar char="]" attribute="Operator" context="#pop" />
0462         <IncludeRules context="RecipeContent" />
0463       </context>
0464 
0465       <!-- https://docs.earthly.dev/docs/earthfile#if -->
0466       <context name="IF_ctx" attribute="Normal Text" lineEndContext="#stay">
0467         <DetectSpaces />
0468         <LineContinue context="#stay" />
0469 
0470         <StringDetect String="ELSE IF" attribute="Command" context="#stay" />
0471         <WordDetect String="ELSE" attribute="Command" context="#stay" />
0472         <WordDetect String="END" attribute="Command" context="#pop" endRegion="IF" />
0473 
0474         <StringDetect String="--privileged" attribute="Command Option" context="#stay" />
0475         <StringDetect String="--ssh" attribute="Command Option" context="#stay" />
0476         <StringDetect String="--no-cache" attribute="Command Option" context="#stay" />
0477         <StringDetect String="--entrypoint" attribute="Command Option" context="#stay" />
0478         <StringDetect String="--mount" attribute="Command Option" context="mount_opt" />
0479         <StringDetect String="--secret" attribute="Command Option" context="secret_opt" />
0480         <!-- start expression in single brackets -->
0481         <DetectChar char="[" attribute="Operator" context="BracketExpression" />
0482         <IncludeRules context="RecipeCommands" />
0483       </context>
0484 
0485       <context name="BracketExpression" attribute="Normal Text" lineEndContext="#pop">
0486         <DetectChar char="]" attribute="Operator" context="#pop" />
0487         <AnyChar String="!=" attribute="Operator" context="#stay" />
0488         <RegExpr String="(&binary_operators;|&unary_operators;)" attribute="Operator" context="#stay" />
0489         <DetectSpaces />
0490         <IncludeRules context="RecipeContent" />
0491       </context>
0492 
0493       <context name="mount_opt" attribute="Command Option" lineEndContext="#stay" fallthroughContext="#pop!mount_arg">
0494         <DetectSpaces context="#stay" />
0495       </context>
0496 
0497       <context name="mount_arg" attribute="Command Option" lineEndContext="#stay" fallthroughContext="#pop">
0498         <keyword String="mount_keys" insensitive="false" attribute="Command Option" context="#stay" />
0499         <AnyChar String=",=" attribute="Operator" context="#stay" />
0500         <!--
0501             ALERT A mount option arg must consume characters up to the next space
0502             and stay in this context to match other rules. Typically there are characters
0503             that could be found in file paths...
0504 
0505             NOTE If you see "Normal Text" in the `mount` options, update the String below.
0506 
0507             TODO Any better way?
0508         -->
0509         <AnyChar String="/.-" attribute="Command Option" context="#stay" />
0510         <DetectIdentifier attribute="Command Option" />
0511         <IncludeRules context="RecipeContent" includeAttrib="true" />
0512         <DetectSpaces context="#pop" />
0513       </context>
0514 
0515       <context name="secret_opt" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop!secret_arg">
0516         <DetectSpaces context="#stay" />
0517       </context>
0518 
0519       <context name="secret_arg" attribute="Normal Text" lineEndContext="#stay" fallthroughContext="#pop">
0520         <DetectIdentifier attribute="Command Option" />
0521         <DetectChar char="=" attribute="Operator" context="#stay" />
0522         <IncludeRules context="RecipeContent" />
0523         <DetectSpaces context="#pop" />
0524       </context>
0525 
0526     </contexts>
0527 
0528     <itemDatas>
0529       <itemData name="Normal Text"              defStyleNum="dsNormal" spellChecking="false" />
0530       <itemData name="Command"                  defStyleNum="dsKeyword" bold="true" spellChecking="false" />
0531       <itemData name="User Defined Command"     defStyleNum="dsFunction" spellChecking="false" />
0532       <itemData name="Command Option"           defStyleNum="dsAttribute" italic="true" spellChecking="false" />
0533       <itemData name="Build Arg"                defStyleNum="dsAttribute" italic="true" spellChecking="false" />
0534       <itemData name="Reference"                defStyleNum="dsExtension" spellChecking="false" />
0535       <itemData name="Target Name"              defStyleNum="dsImport" spellChecking="false" />
0536       <itemData name="Operator"                 defStyleNum="dsOperator" spellChecking="false" />
0537       <itemData name="Artifact Name"            defStyleNum="dsExtension" spellChecking="false" />
0538       <itemData name="Variable"                 defStyleNum="dsVariable" spellChecking="false" />
0539       <itemData name="Builtin Variable"         defStyleNum="dsVariable" spellChecking="false" color="#c09050" selColor="#c09050" />
0540       <itemData name="Internal/Local Variable"  defStyleNum="dsVariable" spellChecking="false" />
0541       <itemData name="Comment"                  defStyleNum="dsComment" />
0542       <itemData name="String SingleQ"           defStyleNum="dsString" />
0543       <itemData name="String DoubleQ"           defStyleNum="dsString" />
0544       <itemData name="String Escape"            defStyleNum="dsSpecialChar" />
0545       <itemData name="Integer"                  defStyleNum="dsDecVal" />
0546     </itemDatas>
0547 
0548   </highlighting>
0549 
0550   <general>
0551     <comments>
0552       <comment name="singleLine" start="#" position="afterwhitespace"/>
0553     </comments>
0554   </general>
0555 
0556 </language>