UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

150 lines 4.84 kB
"use strict"; /* * Copyright © 2020 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DockerFileParser = void 0; const logger_1 = require("@atomist/automation-client/lib/util/logger"); const dockerfile_ast_1 = require("dockerfile-ast"); class DockerFileParserClass { async toAst(f) { try { const dockerfile = dockerfile_ast_1.DockerfileParser.parse(await f.getContent()); const doc = dockerfile.document; const $children = dockerfile.getInstructions().map(i => instructionToTreeNode(i, doc)); return { $name: f.name, $children, }; } catch (err) { logger_1.logger.error("Error parsing Dockerfile", err); throw err; } } } /** * FileParser instance to use for Docker files. * Example path expressions, given "node:argon" as the image * //FROM/image/name - returns a node with the value "node" etc * //FROM/image/tag - returns a node with the value "argon" etc * @type {DockerFileParserClass} */ exports.DockerFileParser = new DockerFileParserClass(); function instructionToTreeNode(l, doc, parent) { const n = { $name: l.getKeyword(), $value: l.getTextContent(), $parent: parent, $offset: l.getRange() ? convertToOffset(l.getRange().start, doc) : undefined, }; // Deconstruct subelements. There is no generic tree structure in the // AST library, so we need to do this manually for subelements we care about. if (isFrom(l)) { addChildrenFromFromStructure(n, l, doc); } else if (isLabel(l)) { addChildrenFromLabelStructure(n, l, doc); } else { switch (l.getKeyword()) { case "MAINTAINER": addChildrenFromMaintainer(n, l, doc); break; case "EXPOSE": n.$children = [ { $name: "port", $value: l.getArgumentsContent(), }, ]; break; default: break; } } return n; } function isFrom(l) { const maybe = l; return !!maybe.getImageName; } function isLabel(l) { const maybe = l; return !!maybe.getProperties; } // Deconstruct FROM to add children. // We need to do this for all structures we want to see inside function addChildrenFromFromStructure(n, l, doc) { const nameChild = { $name: "name", $value: l.getImageName(), $offset: convertToOffset(l.getImageNameRange().start, doc), }; const $children = [nameChild]; if (!!l.getImageTag()) { $children.push({ $name: "tag", $value: l.getImageTag(), $offset: convertToOffset(l.getImageTagRange().start, doc), }); } n.$children = [ { $parent: n, $name: "image", $value: l.getImage(), $offset: convertToOffset(l.getImageRange().start, doc), $children, }, ]; } function addChildrenFromLabelStructure(n, l, doc) { n.$children = l.getProperties().map(prop => ({ $parent: n, $name: "pair", $value: l.getTextContent().slice("LABEL ".length), // Children are the name and value $children: [ { $name: "key", $value: prop.getName(), $offset: convertToOffset(prop.getNameRange().start, doc), }, { $name: "value", $value: prop.getValue(), $offset: prop.getValueRange() ? convertToOffset(prop.getValueRange().start, doc) : undefined, }, ], })); } function addChildrenFromMaintainer(n, m, doc) { const rest = n.$value.slice("MAINTAINER ".length); n.$children = [ { $parent: n, $name: "maintainer", $value: rest, $offset: n.$offset + "MAINTAINER ".length, $children: [], }, ]; } // Convert a position to an offset, given the document function convertToOffset(pos, doc) { return doc.offsetAt(pos); } //# sourceMappingURL=DockerFileParser.js.map