@atomist/sdm-pack-docker
Version:
Extension Pack for an Atomist SDM to integrate Docker
152 lines • 5.5 kB
JavaScript
"use strict";
/*
* Copyright © 2019 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.
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const dockerfile_ast_1 = require("dockerfile-ast");
class DockerFileParserClass {
toAst(f) {
return __awaiter(this, void 0, void 0, function* () {
try {
const dockerfile = dockerfile_ast_1.DockerfileParser.parse(yield f.getContent());
// console.log(stringify(dockerfile));
const doc = dockerfile.document;
const $children = dockerfile.getInstructions().map(i => instructionToTreeNode(i, doc));
return {
$name: f.name,
$children,
};
}
catch (err) {
automation_client_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