scripts/CodeMirror/mode/dockerfile/dockerfile.js (view raw)
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://codemirror.net/LICENSE
3
4(function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror"), require("../../addon/mode/simple"));
7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror", "../../addon/mode/simple"], mod);
9 else // Plain browser env
10 mod(CodeMirror);
11})(function(CodeMirror) {
12 "use strict";
13
14 var from = "from";
15 var fromRegex = new RegExp("^(\\s*)\\b(" + from + ")\\b", "i");
16
17 var shells = ["run", "cmd", "entrypoint", "shell"];
18 var shellsAsArrayRegex = new RegExp("^(\\s*)(" + shells.join('|') + ")(\\s+\\[)", "i");
19
20 var expose = "expose";
21 var exposeRegex = new RegExp("^(\\s*)(" + expose + ")(\\s+)", "i");
22
23 var others = [
24 "arg", "from", "maintainer", "label", "env",
25 "add", "copy", "volume", "user",
26 "workdir", "onbuild", "stopsignal", "healthcheck", "shell"
27 ];
28
29 // Collect all Dockerfile directives
30 var instructions = [from, expose].concat(shells).concat(others),
31 instructionRegex = "(" + instructions.join('|') + ")",
32 instructionOnlyLine = new RegExp("^(\\s*)" + instructionRegex + "(\\s*)(#.*)?$", "i"),
33 instructionWithArguments = new RegExp("^(\\s*)" + instructionRegex + "(\\s+)", "i");
34
35 CodeMirror.defineSimpleMode("dockerfile", {
36 start: [
37 // Block comment: This is a line starting with a comment
38 {
39 regex: /^\s*#.*$/,
40 sol: true,
41 token: "comment"
42 },
43 {
44 regex: fromRegex,
45 token: [null, "keyword"],
46 sol: true,
47 next: "from"
48 },
49 // Highlight an instruction without any arguments (for convenience)
50 {
51 regex: instructionOnlyLine,
52 token: [null, "keyword", null, "error"],
53 sol: true
54 },
55 {
56 regex: shellsAsArrayRegex,
57 token: [null, "keyword", null],
58 sol: true,
59 next: "array"
60 },
61 {
62 regex: exposeRegex,
63 token: [null, "keyword", null],
64 sol: true,
65 next: "expose"
66 },
67 // Highlight an instruction followed by arguments
68 {
69 regex: instructionWithArguments,
70 token: [null, "keyword", null],
71 sol: true,
72 next: "arguments"
73 },
74 {
75 regex: /./,
76 token: null
77 }
78 ],
79 from: [
80 {
81 regex: /\s*$/,
82 token: null,
83 next: "start"
84 },
85 {
86 // Line comment without instruction arguments is an error
87 regex: /(\s*)(#.*)$/,
88 token: [null, "error"],
89 next: "start"
90 },
91 {
92 regex: /(\s*\S+\s+)(as)/i,
93 token: [null, "keyword"],
94 next: "start"
95 },
96 // Fail safe return to start
97 {
98 token: null,
99 next: "start"
100 }
101 ],
102 single: [
103 {
104 regex: /(?:[^\\']|\\.)/,
105 token: "string"
106 },
107 {
108 regex: /'/,
109 token: "string",
110 pop: true
111 }
112 ],
113 double: [
114 {
115 regex: /(?:[^\\"]|\\.)/,
116 token: "string"
117 },
118 {
119 regex: /"/,
120 token: "string",
121 pop: true
122 }
123 ],
124 array: [
125 {
126 regex: /\]/,
127 token: null,
128 next: "start"
129 },
130 {
131 regex: /"(?:[^\\"]|\\.)*"?/,
132 token: "string"
133 }
134 ],
135 expose: [
136 {
137 regex: /\d+$/,
138 token: "number",
139 next: "start"
140 },
141 {
142 regex: /[^\d]+$/,
143 token: null,
144 next: "start"
145 },
146 {
147 regex: /\d+/,
148 token: "number"
149 },
150 {
151 regex: /[^\d]+/,
152 token: null
153 },
154 // Fail safe return to start
155 {
156 token: null,
157 next: "start"
158 }
159 ],
160 arguments: [
161 {
162 regex: /^\s*#.*$/,
163 sol: true,
164 token: "comment"
165 },
166 {
167 regex: /"(?:[^\\"]|\\.)*"?$/,
168 token: "string",
169 next: "start"
170 },
171 {
172 regex: /"/,
173 token: "string",
174 push: "double"
175 },
176 {
177 regex: /'(?:[^\\']|\\.)*'?$/,
178 token: "string",
179 next: "start"
180 },
181 {
182 regex: /'/,
183 token: "string",
184 push: "single"
185 },
186 {
187 regex: /[^#"']+[\\`]$/,
188 token: null
189 },
190 {
191 regex: /[^#"']+$/,
192 token: null,
193 next: "start"
194 },
195 {
196 regex: /[^#"']+/,
197 token: null
198 },
199 // Fail safe return to start
200 {
201 token: null,
202 next: "start"
203 }
204 ],
205 meta: {
206 lineComment: "#"
207 }
208 });
209
210 CodeMirror.defineMIME("text/x-dockerfile", "dockerfile");
211});