File: /home/frenchy/www/french-american.org/current/node_modules/dockerfile-ast/lib/instructions/from.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/* --------------------------------------------------------------------------------------------
* Copyright (c) Remy Suen. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const instruction_1 = require("../instruction");
class From extends instruction_1.Instruction {
constructor(document, range, dockerfile, escapeChar, instruction, instructionRange) {
super(document, range, dockerfile, escapeChar, instruction, instructionRange);
}
getImage() {
return this.getRangeContent(this.getImageRange());
}
/**
* Returns the name of the image that will be used as the base image.
*
* @return the base image's name, or null if unspecified
*/
getImageName() {
return this.getRangeContent(this.getImageNameRange());
}
/**
* Returns the range that covers the name of the image used by
* this instruction.
*
* @return the range of the name of this instruction's argument,
* or null if no image has been specified
*/
getImageNameRange() {
let range = this.getImageRange();
if (range) {
let registryRange = this.getRegistryRange();
if (registryRange) {
range.start = this.document.positionAt(this.document.offsetAt(registryRange.end) + 1);
}
let tagRange = this.getImageTagRange();
let digestRange = this.getImageDigestRange();
if (tagRange === null) {
if (digestRange !== null) {
range.end = this.document.positionAt(this.document.offsetAt(digestRange.start) - 1);
}
}
else {
range.end = this.document.positionAt(this.document.offsetAt(tagRange.start) - 1);
}
return range;
}
return null;
}
/**
* Returns the range that covers the image argument of this
* instruction. This includes the tag or digest of the image if
* it has been specified by the instruction.
*
* @return the range of the image argument, or null if no image
* has been specified
*/
getImageRange() {
let args = this.getArguments();
return args.length !== 0 ? args[0].getRange() : null;
}
getImageTag() {
return this.getRangeContent(this.getImageTagRange());
}
/**
* Returns the range in the document that the tag of the base
* image encompasses.
*
* @return the base image's tag's range in the document, or null
* if no tag has been specified
*/
getImageTagRange() {
const range = this.getImageRange();
if (range) {
if (this.getImageDigestRange() === null) {
let content = this.getRangeContent(range);
let index = this.lastIndexOf(this.document.offsetAt(range.start), content, ':');
// the colon might be for a private registry's port and not a tag
if (index > content.indexOf('/')) {
return vscode_languageserver_types_1.Range.create(range.start.line, range.start.character + index + 1, range.end.line, range.end.character);
}
}
}
return null;
}
getImageDigest() {
return this.getRangeContent(this.getImageDigestRange());
}
/**
* Returns the range in the document that the digest of the base
* image encompasses.
*
* @return the base image's digest's range in the document, or null
* if no digest has been specified
*/
getImageDigestRange() {
let range = this.getImageRange();
if (range) {
let content = this.getRangeContent(range);
let index = this.lastIndexOf(this.document.offsetAt(range.start), content, '@');
if (index !== -1) {
return vscode_languageserver_types_1.Range.create(range.start.line, range.start.character + index + 1, range.end.line, range.end.character);
}
}
return null;
}
indexOf(documentOffset, content, searchString) {
let index = content.indexOf(searchString);
const variables = this.getVariables();
for (let i = 0; i < variables.length; i++) {
const position = documentOffset + index;
const variableRange = variables[i].getRange();
if (this.document.offsetAt(variableRange.start) < position && position < this.document.offsetAt(variableRange.end)) {
const offset = this.document.offsetAt(variableRange.end) - documentOffset;
const substring = content.substring(offset);
const subIndex = substring.indexOf(searchString);
if (subIndex === -1) {
return -1;
}
index = subIndex + offset;
i = -1;
continue;
}
}
return index;
}
lastIndexOf(documentOffset, content, searchString) {
let index = content.lastIndexOf(searchString);
const variables = this.getVariables();
for (let i = 0; i < variables.length; i++) {
const position = documentOffset + index;
const variableRange = variables[i].getRange();
if (this.document.offsetAt(variableRange.start) < position && position < this.document.offsetAt(variableRange.end)) {
index = content.substring(0, index).lastIndexOf(searchString);
if (index === -1) {
return -1;
}
i = -1;
continue;
}
}
return index;
}
getRegistry() {
return this.getRangeContent(this.getRegistryRange());
}
getRegistryRange() {
const range = this.getImageRange();
if (range) {
const tagRange = this.getImageTagRange();
const digestRange = this.getImageDigestRange();
if (tagRange === null) {
if (digestRange !== null) {
range.end = this.document.positionAt(this.document.offsetAt(digestRange.start) - 1);
}
}
else {
range.end = this.document.positionAt(this.document.offsetAt(tagRange.start) - 1);
}
const content = this.getRangeContent(range);
const portIndex = this.indexOf(this.document.offsetAt(range.start), content, ':');
const startingSlashIndex = this.indexOf(this.document.offsetAt(range.start), content, '/');
const endingSlashIndex = this.lastIndexOf(this.document.offsetAt(range.start), content, '/');
// check if two slashes have been detected or if there is a port defined
if ((startingSlashIndex !== -1 && startingSlashIndex !== endingSlashIndex) || portIndex !== -1) {
// registry detected, return its range
const rangeStart = this.document.offsetAt(range.start);
return vscode_languageserver_types_1.Range.create(range.start, this.document.positionAt(rangeStart + startingSlashIndex));
}
}
return null;
}
getBuildStage() {
let range = this.getBuildStageRange();
return range === null ? null : this.getRangeContent(range);
}
getBuildStageRange() {
let args = this.getArguments();
if (args.length === 3 && args[1].getValue().toUpperCase() === "AS") {
return args[2].getRange();
}
return null;
}
}
exports.From = From;