UNPKG

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