UNPKG

8.97 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.From = void 0;
4const vscode_languageserver_types_1 = require("vscode-languageserver-types");
5const modifiableInstruction_1 = require("../modifiableInstruction");
6class From extends modifiableInstruction_1.ModifiableInstruction {
7 constructor(document, range, dockerfile, escapeChar, instruction, instructionRange) {
8 super(document, range, dockerfile, escapeChar, instruction, instructionRange);
9 }
10 stopSearchingForFlags(argument) {
11 return argument.indexOf("--") === -1;
12 }
13 getImage() {
14 return this.getRangeContent(this.getImageRange());
15 }
16 /**
17 * Returns the name of the image that will be used as the base image.
18 *
19 * @return the base image's name, or null if unspecified
20 */
21 getImageName() {
22 return this.getRangeContent(this.getImageNameRange());
23 }
24 /**
25 * Returns the range that covers the name of the image used by
26 * this instruction.
27 *
28 * @return the range of the name of this instruction's argument,
29 * or null if no image has been specified
30 */
31 getImageNameRange() {
32 let range = this.getImageRange();
33 if (range) {
34 let registryRange = this.getRegistryRange();
35 if (registryRange) {
36 range.start = this.document.positionAt(this.document.offsetAt(registryRange.end) + 1);
37 }
38 let tagRange = this.getImageTagRange();
39 let digestRange = this.getImageDigestRange();
40 if (tagRange === null) {
41 if (digestRange !== null) {
42 range.end = this.document.positionAt(this.document.offsetAt(digestRange.start) - 1);
43 }
44 }
45 else {
46 range.end = this.document.positionAt(this.document.offsetAt(tagRange.start) - 1);
47 }
48 return range;
49 }
50 return null;
51 }
52 /**
53 * Returns the range that covers the image argument of this
54 * instruction. This includes the tag or digest of the image if
55 * it has been specified by the instruction.
56 *
57 * @return the range of the image argument, or null if no image
58 * has been specified
59 */
60 getImageRange() {
61 let args = this.getArguments();
62 return args.length !== 0 ? args[0].getRange() : null;
63 }
64 getImageTag() {
65 return this.getRangeContent(this.getImageTagRange());
66 }
67 /**
68 * Returns the range in the document that the tag of the base
69 * image encompasses.
70 *
71 * @return the base image's tag's range in the document, or null
72 * if no tag has been specified
73 */
74 getImageTagRange() {
75 const range = this.getImageRange();
76 if (range) {
77 const rangeStartOffset = this.document.offsetAt(range.start);
78 const content = this.getRangeContent(range);
79 const atIndex = this.indexOf(rangeStartOffset, content, '@');
80 const slashIndex = content.indexOf('/');
81 if (atIndex === -1) {
82 const colonIndex = this.lastIndexOf(rangeStartOffset, content, ':');
83 if (colonIndex > slashIndex) {
84 return vscode_languageserver_types_1.Range.create(range.start.line, range.start.character + colonIndex + 1, range.end.line, range.end.character);
85 }
86 }
87 const subcontent = content.substring(0, atIndex);
88 const subcolonIndex = subcontent.indexOf(':');
89 if (subcolonIndex === -1) {
90 return null;
91 }
92 if (slashIndex === -1) {
93 // slash not found suggests no registry and no namespace defined
94 return vscode_languageserver_types_1.Range.create(this.document.positionAt(rangeStartOffset + subcolonIndex + 1), this.document.positionAt(rangeStartOffset + atIndex));
95 }
96 // both colon and slash found, check if it is a port
97 if (subcolonIndex < slashIndex) {
98 return null;
99 }
100 return vscode_languageserver_types_1.Range.create(this.document.positionAt(rangeStartOffset + subcolonIndex + 1), this.document.positionAt(rangeStartOffset + subcontent.length));
101 }
102 return null;
103 }
104 getImageDigest() {
105 return this.getRangeContent(this.getImageDigestRange());
106 }
107 /**
108 * Returns the range in the document that the digest of the base
109 * image encompasses.
110 *
111 * @return the base image's digest's range in the document, or null
112 * if no digest has been specified
113 */
114 getImageDigestRange() {
115 let range = this.getImageRange();
116 if (range) {
117 let content = this.getRangeContent(range);
118 let index = this.lastIndexOf(this.document.offsetAt(range.start), content, '@');
119 if (index !== -1) {
120 return vscode_languageserver_types_1.Range.create(range.start.line, range.start.character + index + 1, range.end.line, range.end.character);
121 }
122 }
123 return null;
124 }
125 indexOf(documentOffset, content, searchString) {
126 let index = content.indexOf(searchString);
127 const variables = this.getVariables();
128 for (let i = 0; i < variables.length; i++) {
129 const position = documentOffset + index;
130 const variableRange = variables[i].getRange();
131 if (this.document.offsetAt(variableRange.start) < position && position < this.document.offsetAt(variableRange.end)) {
132 const offset = this.document.offsetAt(variableRange.end) - documentOffset;
133 const substring = content.substring(offset);
134 const subIndex = substring.indexOf(searchString);
135 if (subIndex === -1) {
136 return -1;
137 }
138 index = subIndex + offset;
139 i = -1;
140 continue;
141 }
142 }
143 return index;
144 }
145 lastIndexOf(documentOffset, content, searchString) {
146 let index = content.lastIndexOf(searchString);
147 const variables = this.getVariables();
148 for (let i = 0; i < variables.length; i++) {
149 const position = documentOffset + index;
150 const variableRange = variables[i].getRange();
151 if (this.document.offsetAt(variableRange.start) < position && position < this.document.offsetAt(variableRange.end)) {
152 index = content.substring(0, index).lastIndexOf(searchString);
153 if (index === -1) {
154 return -1;
155 }
156 i = -1;
157 continue;
158 }
159 }
160 return index;
161 }
162 getRegistry() {
163 return this.getRangeContent(this.getRegistryRange());
164 }
165 getRegistryRange() {
166 const range = this.getImageRange();
167 if (range) {
168 const tagRange = this.getImageTagRange();
169 const digestRange = this.getImageDigestRange();
170 if (tagRange === null) {
171 if (digestRange !== null) {
172 range.end = this.document.positionAt(this.document.offsetAt(digestRange.start) - 1);
173 }
174 }
175 else {
176 range.end = this.document.positionAt(this.document.offsetAt(tagRange.start) - 1);
177 }
178 const content = this.getRangeContent(range);
179 const rangeStart = this.document.offsetAt(range.start);
180 const startingSlashIndex = this.indexOf(rangeStart, content, '/');
181 if (startingSlashIndex === -1) {
182 return null;
183 }
184 const portIndex = this.indexOf(rangeStart, content, ':');
185 const dotIndex = this.indexOf(rangeStart, content, '.');
186 // hostname detected
187 if (portIndex !== -1 || dotIndex !== -1) {
188 return vscode_languageserver_types_1.Range.create(range.start, this.document.positionAt(rangeStart + startingSlashIndex));
189 }
190 const registry = content.substring(0, startingSlashIndex);
191 // localhost registry detected
192 if (registry === 'localhost') {
193 return vscode_languageserver_types_1.Range.create(range.start, this.document.positionAt(rangeStart + startingSlashIndex));
194 }
195 }
196 return null;
197 }
198 getBuildStage() {
199 let range = this.getBuildStageRange();
200 return range === null ? null : this.getRangeContent(range);
201 }
202 getBuildStageRange() {
203 let args = this.getArguments();
204 if (args.length > 2 && args[1].getValue().toUpperCase() === "AS") {
205 return args[2].getRange();
206 }
207 return null;
208 }
209 getPlatformFlag() {
210 let flags = super.getFlags();
211 return flags.length === 1 && flags[0].getName() === "platform" ? flags[0] : null;
212 }
213}
214exports.From = From;