🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

dockerfile-language-server-nodejs

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dockerfile-language-server-nodejs - npm Package Compare versions

Comparing version

to
0.0.12

18

CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file.
## [0.0.12] - 2018-0-11
### Added
- textDocument/completion
- documentation for ADD and COPY's --chown flag ([#181](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/181))
- textDocument/hover
- ADD and COPY's --chown flag ([#181](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/181))
### Changed
- create dependency on the dockerfile-ast NPM module ([#196](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/196))
### Fixed
- prevent signature help from showing in a multiline instruction's embedded comment ([#195](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/195))
- publish the docker-langserver binary with \n line endings for OS X ([#198](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/198))
### Removed
- remove Dockerfile parsing code in src/parser ([#196](https://github.com/rcjsuen/dockerfile-language-server-nodejs/issues/196))
## [0.0.11] - 2017-11-15

@@ -252,2 +269,3 @@ ### Added

[0.0.12]: https://github.com/rcjsuen/dockerfile-language-server-nodejs/compare/v0.0.11...v0.0.12
[0.0.11]: https://github.com/rcjsuen/dockerfile-language-server-nodejs/compare/v0.0.10...v0.0.11

@@ -254,0 +272,0 @@ [0.0.10]: https://github.com/rcjsuen/dockerfile-language-server-nodejs/compare/v0.0.9...v0.0.10

33

lib/docker.js

@@ -27,3 +27,2 @@ /* --------------------------------------------------------------------------------------------

];
exports.DIRECTIVE_ESCAPE = "escape";
class Util {

@@ -36,34 +35,2 @@ static isWhitespace(char) {

}
static findLeadingNonWhitespace(content, escapeChar) {
whitespaceCheck: for (let i = 0; i < content.length; i++) {
switch (content.charAt(i)) {
case ' ':
case '\t':
continue;
case escapeChar:
for (let j = i + 1; j < content.length; j++) {
switch (content.charAt(j)) {
case ' ':
case '\t':
continue;
case '\r':
if (content.charAt(j + 1) === '\n') {
i = j + 1;
continue whitespaceCheck;
}
case '\n':
i = j;
continue whitespaceCheck;
default:
return i;
}
}
return i;
default:
return i;
}
}
// only possible if the content is the empty string
return -1;
}
/**

@@ -70,0 +37,0 @@ * Determines if the given position is contained within the given range.

68

lib/dockerAssist.js

@@ -17,3 +17,3 @@ /* --------------------------------------------------------------------------------------------

const docker_1 = require("./docker");
const dockerfileParser_1 = require("./parser/dockerfileParser");
const dockerfile_ast_1 = require("dockerfile-ast");
class DockerAssist {

@@ -35,4 +35,3 @@ /**

let offset = document.offsetAt(position);
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(buffer);
let escapeCharacter = dockerfile.getEscapeCharacter();

@@ -44,7 +43,7 @@ let directive = dockerfile.getDirective();

// in whitespace before the directive's name
return [this.createEscape(0, offset, docker_1.DIRECTIVE_ESCAPE)];
return [this.createEscape(0, offset, dockerfile_ast_1.Directive.escape)];
}
else if (position.character <= range.end.character) {
// in the name
return [this.createEscape(position.character - range.start.character, offset, docker_1.DIRECTIVE_ESCAPE)];
return [this.createEscape(position.character - range.start.character, offset, dockerfile_ast_1.Directive.escape)];
}

@@ -65,3 +64,3 @@ return [];

// in whitespace
return [this.createEscape(0, offset, docker_1.DIRECTIVE_ESCAPE)];
return [this.createEscape(0, offset, dockerfile_ast_1.Directive.escape)];
}

@@ -73,4 +72,4 @@ let comment = comments[0].getContent();

// substring check
if (docker_1.DIRECTIVE_ESCAPE.indexOf(prefix.toLowerCase()) === 0) {
return [this.createEscape(prefix.length, offset, docker_1.DIRECTIVE_ESCAPE)];
if (dockerfile_ast_1.Directive.escape.indexOf(prefix.toLowerCase()) === 0) {
return [this.createEscape(prefix.length, offset, dockerfile_ast_1.Directive.escape)];
}

@@ -104,10 +103,13 @@ }

let prefixLength = variablePrefix.length + 1;
const items = [];
if (variablePrefix === "") {
// empty prefix, return all variables
const items = [];
for (let variable of dockerfile.getVariableNames(position.line)) {
let doc = dockerfile.getVariableValue(variable, position.line);
for (let variable of dockerfile.getAvailableVariables(position.line)) {
let doc = dockerfile.resolveVariable(variable, position.line);
items.push(this.createVariableCompletionItem(variable, prefixLength, offset, true, doc));
}
return items;
for (let variable of dockerfile_ast_1.DefaultVariables) {
let doc = dockerfile.resolveVariable(variable, position.line);
items.push(this.createVariableCompletionItem(variable, prefixLength, offset, true, doc));
}
}

@@ -120,11 +122,23 @@ else {

}
const items = [];
for (let variable of dockerfile.getVariableNames(position.line)) {
for (let variable of dockerfile.getAvailableVariables(position.line)) {
if (variable.toLowerCase().indexOf(variablePrefix) === 0) {
let doc = dockerfile.getVariableValue(variable, position.line);
let doc = dockerfile.resolveVariable(variable, position.line);
items.push(this.createVariableCompletionItem(variable, prefixLength, offset, brace, doc));
}
}
return items;
for (let variable of dockerfile_ast_1.DefaultVariables) {
if (variable.toLowerCase().indexOf(variablePrefix) === 0) {
let doc = dockerfile.resolveVariable(variable, position.line);
items.push(this.createVariableCompletionItem(variable, prefixLength, offset, brace, doc));
}
}
}
items.sort((a, b) => {
if (a.label.toLowerCase() === b.label.toLowerCase()) {
// put uppercase variables first
return a.label.localeCompare(b.label) * -1;
}
return a.label.localeCompare(b.label);
});
return items;
}

@@ -240,13 +254,13 @@ }

if (copyArgs.length === 0 && add.getFlags().length === 0) {
return [this.createCOPY_FlagChown(0, offset)];
return [this.createADD_FlagChown(0, offset)];
}
else if (copyArgs.length > 0 && docker_1.Util.isInsideRange(position, copyArgs[0].getRange()) && prefix === "-") {
return [this.createCOPY_FlagChown(prefix.length, offset)];
return [this.createADD_FlagChown(prefix.length, offset)];
}
else if (flags.length > 0 && flags[0].toString() === "--") {
return [this.createCOPY_FlagChown(prefix.length, offset)];
return [this.createADD_FlagChown(prefix.length, offset)];
}
else if ((copyArgs.length > 0 && docker_1.Util.isInsideRange(position, copyArgs[0].getRange()) && "--chown=".indexOf(prefix) === 0)
|| (flags.length > 0 && "--chown=".indexOf(flags[0].toString()) === 0)) {
return [this.createCOPY_FlagChown(prefix.length, offset)];
return [this.createADD_FlagChown(prefix.length, offset)];
}

@@ -256,5 +270,5 @@ return [];

createCopyProposals(dockerfile, copy, position, offset, prefix) {
let range = copy.getFromValueRange();
let flag = copy.getFromFlag();
// is the user in the --from= area
if (range && docker_1.Util.isInsideRange(position, range)) {
if (flag && docker_1.Util.isInsideRange(position, flag.getValueRange())) {
const names = {};

@@ -266,3 +280,3 @@ const items = [];

// get the prefix
let stagePrefix = this.document.getText().substring(this.document.offsetAt(range.start), offset).toLowerCase();
let stagePrefix = this.document.getText().substring(this.document.offsetAt(flag.getValueRange().start), offset).toLowerCase();
for (let from of dockerfile.getFROMs()) {

@@ -522,2 +536,8 @@ if (copy.isAfter(from)) {

}
createADD_FlagChown(prefixLength, offset) {
if (this.snippetSupport) {
return this.createFlagCompletionItem("--chown=user:group", prefixLength, offset, "--chown=${1:user\:group}", "ADD_FlagChown");
}
return this.createFlagCompletionItem("--chown=", prefixLength, offset, "--chown=", "ADD_FlagChown");
}
createCOPY_FlagChown(prefixLength, offset) {

@@ -593,3 +613,3 @@ if (this.snippetSupport) {

createEscape(prefixLength, offset, markdown) {
return this.createKeywordCompletionItem(docker_1.DIRECTIVE_ESCAPE, "escape=`", prefixLength, offset, "escape=${1:`}", markdown);
return this.createKeywordCompletionItem(dockerfile_ast_1.Directive.escape, "escape=`", prefixLength, offset, "escape=${1:`}", markdown);
}

@@ -596,0 +616,0 @@ createKeywordCompletionItem(keyword, label, prefixLength, offset, insertText, markdown) {

@@ -9,5 +9,3 @@ /* --------------------------------------------------------------------------------------------

const docker_1 = require("./docker");
const dockerfileParser_1 = require("./parser/dockerfileParser");
const arg_1 = require("./parser/instructions/arg");
const env_1 = require("./parser/instructions/env");
const dockerfile_ast_1 = require("dockerfile-ast");
class DockerDefinition {

@@ -17,6 +15,9 @@ computeBuildStageDefinition(uri, dockerfile, position) {

for (let instruction of dockerfile.getCOPYs()) {
let range = instruction.getFromValueRange();
if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) {
source = instruction.getFromValue();
break;
let flag = instruction.getFromFlag();
if (flag) {
let range = flag.getValueRange();
if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) {
source = flag.getValue();
break;
}
}

@@ -69,3 +70,3 @@ }

for (let instruction of image.getInstructions()) {
if (instruction instanceof arg_1.Arg) {
if (instruction instanceof dockerfile_ast_1.Arg) {
let property = instruction.getProperty();

@@ -77,3 +78,3 @@ // might be an ARG with no arguments

}
else if (instruction instanceof env_1.Env) {
else if (instruction instanceof dockerfile_ast_1.Env) {
let properties = instruction.getProperties();

@@ -111,4 +112,3 @@ for (let property of properties) {

computeDefinition(document, position) {
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
let definition = this.computeBuildStageDefinition(document.uri, dockerfile, position);

@@ -115,0 +115,0 @@ if (definition !== null) {

@@ -8,3 +8,3 @@ /* --------------------------------------------------------------------------------------------

const vscode_languageserver_1 = require("vscode-languageserver");
const dockerfileParser_1 = require("./parser/dockerfileParser");
const dockerfile_ast_1 = require("dockerfile-ast");
class DockerFormatter {

@@ -45,4 +45,3 @@ getIndentation(formattingOptions) {

formatOnType(document, position, ch, options) {
const parser = new dockerfileParser_1.DockerfileParser();
const dockerfile = parser.parse(document);
const dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
// check that the inserted character is the escape character

@@ -106,5 +105,4 @@ if (dockerfile.getEscapeCharacter() === ch) {

format(document, lines, options) {
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let content = document.getText();
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
const indentedLines = [];

@@ -111,0 +109,0 @@ for (let i = 0; i < document.lineCount; i++) {

@@ -8,4 +8,3 @@ /* --------------------------------------------------------------------------------------------

const vscode_languageserver_1 = require("vscode-languageserver");
const dockerfileParser_1 = require("./parser/dockerfileParser");
const from_1 = require("./parser/instructions/from");
const dockerfile_ast_1 = require("dockerfile-ast");
const dockerDefinition_1 = require("./dockerDefinition");

@@ -15,4 +14,3 @@ const docker_1 = require("./docker");

computeHighlightRanges(document, position) {
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
let provider = new dockerDefinition_1.DockerDefinition();

@@ -24,12 +22,15 @@ let location = provider.computeDefinition(document, position);

for (let instruction of dockerfile.getCOPYs()) {
let range = instruction.getFromValueRange();
if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) {
let stage = instruction.getFromValue();
for (let instruction of dockerfile.getCOPYs()) {
let source = instruction.getFromValue();
if (source === stage) {
highlights.push(vscode_languageserver_1.DocumentHighlight.create(instruction.getFromValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
let flag = instruction.getFromFlag();
if (flag) {
let range = flag.getValueRange();
if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) {
let stage = flag.getValue();
for (let other of dockerfile.getCOPYs()) {
let otherFlag = other.getFromFlag();
if (otherFlag && otherFlag.getValue() === stage) {
highlights.push(vscode_languageserver_1.DocumentHighlight.create(otherFlag.getValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
}
}
return highlights;
}
return highlights;
}

@@ -57,3 +58,3 @@ }

for (let instruction of image.getInstructions()) {
if (!(instruction instanceof from_1.From)) {
if (!(instruction instanceof dockerfile_ast_1.From)) {
for (let variable of instruction.getVariables()) {

@@ -78,5 +79,7 @@ if (variable.getName() === name) {

for (let instruction of dockerfile.getCOPYs()) {
let source = instruction.getFromValue();
if (source === definition) {
highlights.push(vscode_languageserver_1.DocumentHighlight.create(instruction.getFromValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
let flag = instruction.getFromFlag();
if (flag) {
if (flag.getValue() === definition) {
highlights.push(vscode_languageserver_1.DocumentHighlight.create(flag.getValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
}
}

@@ -103,3 +106,3 @@ }

// only highlight variables in non-FROM instructions
if (!(instruction instanceof from_1.From)) {
if (!(instruction instanceof dockerfile_ast_1.From)) {
for (const variable of instruction.getVariables()) {

@@ -106,0 +109,0 @@ if (variable.getName() === definition) {

@@ -7,6 +7,3 @@ /* --------------------------------------------------------------------------------------------

Object.defineProperty(exports, "__esModule", { value: true });
const dockerfileParser_1 = require("./parser/dockerfileParser");
const arg_1 = require("./parser/instructions/arg");
const env_1 = require("./parser/instructions/env");
const onbuild_1 = require("./parser/instructions/onbuild");
const dockerfile_ast_1 = require("dockerfile-ast");
const docker_1 = require("./docker");

@@ -19,10 +16,9 @@ const dockerDefinition_1 = require("./dockerDefinition");

onHover(document, textDocumentPosition) {
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
let directive = dockerfile.getDirective();
let image = dockerfile.getContainingImage(textDocumentPosition.position);
if (textDocumentPosition.position.line === 0 && directive !== null && directive.getDirective() === docker_1.DIRECTIVE_ESCAPE) {
if (textDocumentPosition.position.line === 0 && directive !== null && directive.getDirective() === dockerfile_ast_1.Directive.escape) {
let range = directive.getNameRange();
if (docker_1.Util.isInsideRange(textDocumentPosition.position, range)) {
return this.markdown.getMarkdown(docker_1.DIRECTIVE_ESCAPE);
return this.markdown.getMarkdown(dockerfile_ast_1.Directive.escape);
}

@@ -37,3 +33,3 @@ }

// only look for variables defined before the current instruction
if (instruction.isAfter(instructions[i]) && instructions[i] instanceof env_1.Env) {
if (instruction.isAfter(instructions[i]) && instructions[i] instanceof dockerfile_ast_1.Env) {
for (let property of instructions[i].getProperties()) {

@@ -55,3 +51,3 @@ // check that the names match

}
if (instruction instanceof onbuild_1.Onbuild) {
if (instruction instanceof dockerfile_ast_1.Onbuild) {
// hovering over a trigger instruction of an ONBUILD

@@ -63,3 +59,3 @@ let range = instruction.getTriggerRange();

}
if (instruction instanceof arg_1.Arg) {
if (instruction instanceof dockerfile_ast_1.Arg) {
// hovering over an argument defined by ARG

@@ -73,3 +69,3 @@ let property = instruction.getProperty();

}
if (instruction instanceof env_1.Env) {
if (instruction instanceof dockerfile_ast_1.Env) {
// hovering over an argument defined by ENV

@@ -97,6 +93,24 @@ for (let property of instruction.getProperties()) {

switch (instruction.getKeyword()) {
case "ADD":
let addFlags = instruction.getFlags();
for (let flag of addFlags) {
if (docker_1.Util.isInsideRange(position, flag.getNameRange())) {
switch (flag.getName()) {
case "chown":
return this.markdown.getMarkdown("ADD_FlagChown");
}
}
}
break;
case "COPY":
let copyFlags = instruction.getFlags();
if (copyFlags.length > 0 && docker_1.Util.isInsideRange(position, copyFlags[0].getNameRange()) && copyFlags[0].getName() === "from") {
return this.markdown.getMarkdown("COPY_FlagFrom");
for (let flag of copyFlags) {
if (docker_1.Util.isInsideRange(position, flag.getNameRange())) {
switch (flag.getName()) {
case "chown":
return this.markdown.getMarkdown("COPY_FlagChown");
case "from":
return this.markdown.getMarkdown("COPY_FlagFrom");
}
}
}

@@ -103,0 +117,0 @@ break;

@@ -30,2 +30,4 @@ /* --------------------------------------------------------------------------------------------

"hoverOnlineDocumentationFooter": "\n\n[Online documentation](${0})",
"hoverAddFlagChown": "The username, groupname, or UID/GID combination to own the added content.",
"hoverCopyFlagChown": "The username, groupname, or UID/GID combination to own the copied content.",
"hoverCopyFlagFrom": "The previous build stage to use as the source location instead of the build's context.\n\nSince Docker 17.05.0-ce.",

@@ -50,2 +52,5 @@ "hoverHealthcheckFlagInterval": "The seconds to wait for the health check to run after the container has started, and then again the number of seconds to wait before running again after the previous check has completed.",

},
ADD_FlagChown: {
contents: this.dockerMessages["hoverAddFlagChown"]
},
ARG: {

@@ -74,2 +79,5 @@ contents: this.dockerMessages["hoverArg"] +

},
COPY_FlagChown: {
contents: this.dockerMessages["hoverCopyFlagChown"]
},
COPY_FlagFrom: {

@@ -76,0 +84,0 @@ contents: this.dockerMessages["hoverCopyFlagFrom"]

@@ -28,2 +28,4 @@ /* --------------------------------------------------------------------------------------------

"hoverWorkdir": "Set the working directory for any subsequent ADD, COPY, CMD, ENTRYPOINT, or RUN` instructions that follow it in the `Dockerfile`.\n\n",
"hoverAddFlagChown": "The username, groupname, or UID/GID combination to own the added content.",
"hoverCopyFlagChown": "The username, groupname, or UID/GID combination to own the copied content.",
"hoverCopyFlagFrom": "The previous build stage to use as the source location instead of the build's context.\n\nSince Docker 17.05.0-ce.",

@@ -109,2 +111,3 @@ "hoverHealthcheckFlagInterval": "The seconds to wait for the health check to run after the container has started, and then again the number of seconds to wait before running again after the previous check has completed.",

"ADD hello.txt relative/to/workdir",
ADD_FlagChown: this.dockerMessages["hoverAddFlagChown"],
ARG: this.dockerMessages["hoverArg"] +

@@ -122,2 +125,3 @@ "ARG userName\n" +

"COPY hello.txt relative/to/workdir",
COPY_FlagChown: this.dockerMessages["hoverCopyFlagChown"],
COPY_FlagFrom: this.dockerMessages["hoverCopyFlagFrom"],

@@ -124,0 +128,0 @@ ENTRYPOINT: this.dockerMessages["hoverEntrypoint"] +

@@ -8,3 +8,3 @@ /* --------------------------------------------------------------------------------------------

const vscode_languageserver_1 = require("vscode-languageserver");
const dockerfileParser_1 = require("./parser/dockerfileParser");
const dockerfile_ast_1 = require("dockerfile-ast");
class DockerSymbols {

@@ -22,4 +22,3 @@ createSymbolInformation(name, textDocumentURI, range, kind) {

parseSymbolInformation(document, textDocumentURI) {
let parser = new dockerfileParser_1.DockerfileParser();
let dockerfile = parser.parse(document);
let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
let directive = dockerfile.getDirective();

@@ -26,0 +25,0 @@ let symbols = [];

@@ -0,0 +0,0 @@ Copyright (c) 2017 Remy Suen

@@ -0,0 +0,0 @@ The code in this repository was originally based off of open source

@@ -11,3 +11,3 @@ {

],
"version": "0.0.11",
"version": "0.0.12",
"author": "Remy Suen",

@@ -24,2 +24,3 @@ "license": "MIT",

"dependencies": {
"dockerfile-ast": "0.0.1",
"vscode-languageserver": "^3.5.0-next.1"

@@ -26,0 +27,0 @@ },

@@ -22,2 +22,3 @@ # Dockerfile Language Server

- [vscode-docker](https://github.com/Microsoft/vscode-docker)
- [atom-ide-docker](https://github.com/josa42/atom-ide-docker)

@@ -53,3 +54,3 @@ ## Development Instructions

server with the `docker-langserver` binary. You should specify
the desired method of communciating with the language server via one
the desired method of communicating with the language server via one
of the three arguments shown below.

@@ -56,0 +57,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display