UNPKG

dockerfile-ast

Version:

Parse a Dockerfile into an array of instructions and comments.

238 lines (237 loc) 8.04 kB
/* -------------------------------------------------------------------------------------------- * Copyright (c) Remy Suen. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageTemplate = void 0; const vscode_languageserver_types_1 = require("vscode-languageserver-types"); const arg_1 = require("./instructions/arg"); const cmd_1 = require("./instructions/cmd"); const copy_1 = require("./instructions/copy"); const env_1 = require("./instructions/env"); const entrypoint_1 = require("./instructions/entrypoint"); const from_1 = require("./instructions/from"); const healthcheck_1 = require("./instructions/healthcheck"); const onbuild_1 = require("./instructions/onbuild"); const util_1 = require("./util"); const workdir_1 = require("./instructions/workdir"); class ImageTemplate { constructor() { this.comments = []; this.instructions = []; } addComment(comment) { this.comments.push(comment); } getComments() { return this.comments; } addInstruction(instruction) { this.instructions.push(instruction); } getInstructions() { return this.instructions; } getInstructionAt(line) { for (let instruction of this.instructions) { if (util_1.Util.isInsideRange(vscode_languageserver_types_1.Position.create(line, 0), instruction.getRange())) { return instruction; } } return null; } /** * Gets all the ARG instructions that are defined in this image. */ getARGs() { let args = []; for (let instruction of this.instructions) { if (instruction instanceof arg_1.Arg) { args.push(instruction); } } return args; } /** * Gets all the CMD instructions that are defined in this image. */ getCMDs() { let cmds = []; for (let instruction of this.instructions) { if (instruction instanceof cmd_1.Cmd) { cmds.push(instruction); } } return cmds; } /** * Gets all the COPY instructions that are defined in this image. */ getCOPYs() { let copies = []; for (let instruction of this.instructions) { if (instruction instanceof copy_1.Copy) { copies.push(instruction); } } return copies; } /** * Gets all the ENTRYPOINT instructions that are defined in this image. */ getENTRYPOINTs() { let froms = []; for (let instruction of this.instructions) { if (instruction instanceof entrypoint_1.Entrypoint) { froms.push(instruction); } } return froms; } /** * Gets all the ENV instructions that are defined in this image. */ getENVs() { let args = []; for (let instruction of this.instructions) { if (instruction instanceof env_1.Env) { args.push(instruction); } } return args; } getFROM() { for (const instruction of this.instructions) { if (instruction instanceof from_1.From) { return instruction; } } return null; } /** * Gets all the FROM instructions that are defined in this image. */ getFROMs() { let froms = []; for (let instruction of this.instructions) { if (instruction instanceof from_1.From) { froms.push(instruction); } } return froms; } /** * Gets all the HEALTHCHECK instructions that are defined in this image. */ getHEALTHCHECKs() { let froms = []; for (let instruction of this.instructions) { if (instruction instanceof healthcheck_1.Healthcheck) { froms.push(instruction); } } return froms; } getWORKDIRs() { const workdirs = []; for (const instruction of this.instructions) { if (instruction instanceof workdir_1.Workdir) { workdirs.push(instruction); } } return workdirs; } getOnbuildTriggers() { let triggers = []; for (let instruction of this.instructions) { if (instruction instanceof onbuild_1.Onbuild) { let trigger = instruction.getTriggerInstruction(); if (trigger) { triggers.push(trigger); } } } return triggers; } getAvailableVariables(currentLine) { const variables = []; for (const arg of this.getARGs()) { if (arg.isBefore(currentLine)) { const property = arg.getProperty(); if (property) { const variable = property.getName(); if (variables.indexOf(variable) === -1) { variables.push(variable); } } } } for (const env of this.getENVs()) { if (env.isBefore(currentLine)) { for (const property of env.getProperties()) { const variable = property.getName(); if (variables.indexOf(variable) === -1) { variables.push(variable); } } } } return variables; } /** * Resolves a variable with the given name at the specified line * to its value. If null is returned, then the variable has been * defined but no value was given. If undefined is returned, then * a variable with the given name has not been defined yet as of * the given line. * * @param variable the name of the variable to resolve * @param line the line number that the variable is on, zero-based * @return the value of the variable as defined by an ARG or ENV * instruction, or null if no value has been specified, or * undefined if a variable with the given name has not * been defined */ resolveVariable(variable, line) { let envs = this.getENVs(); for (let i = envs.length - 1; i >= 0; i--) { if (envs[i].isBefore(line)) { for (let property of envs[i].getProperties()) { if (property.getName() === variable) { return property.getValue(); } } } } let args = this.getARGs(); for (let i = args.length - 1; i >= 0; i--) { if (args[i].isBefore(line)) { let property = args[i].getProperty(); if (property && property.getName() === variable) { return property.getValue(); } } } return undefined; } getRange() { const instructions = this.getInstructions(); if (instructions.length === 0) { // all templates should have instructions, this only happens for // the initial set of instruction return vscode_languageserver_types_1.Range.create(0, 0, 0, 0); } const instructionStart = instructions[0].getRange().start; const instructionEnd = instructions[instructions.length - 1].getRange().end; return vscode_languageserver_types_1.Range.create(instructionStart, instructionEnd); } contains(position) { const range = this.getRange(); if (range === null) { return false; } return util_1.Util.isInsideRange(position, range); } } exports.ImageTemplate = ImageTemplate;