Skip to content

Commit

Permalink
WIP #162 Add signature help for RUN
Browse files Browse the repository at this point in the history
Signed-off-by: Remy Suen <[email protected]>
  • Loading branch information
rcjsuen committed Sep 1, 2017
1 parent 35db4ea commit 0445be1
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file.
- LABEL
- MAINTAINER
- ONBUILD
- RUN
- SHELL
- STOPSIGNAL
- USER
Expand Down
12 changes: 12 additions & 0 deletions src/dockerPlainText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export class PlainTextDocumentation {
"signatureMaintainer_Param": "The name of this image's maintainer.",
"signatureOnbuild": "Register a build instruction as a trigger to be executed when this image is used as a base image for another build.",
"signatureOnbuild_Param": "The build instruction to register as a trigger instruction.",
"signatureRun_Signature0": "Execute commands inside a shell.",
"signatureRun_Signature0_Param0": "The command to run.",
"signatureRun_Signature0_Param1": "A parameter to the command.",
"signatureRun_Signature1": "Execute commands without invoking a command shell.",
"signatureShell": "Override default shell used for the shell form of commands.",
"signatureShell_Param1": "The shell executable to use.",
"signatureShell_Param2": "The parameters to the shell executable.",
Expand Down Expand Up @@ -276,6 +280,14 @@ export class PlainTextDocumentation {
signatureMaintainer_Param: this.dockerMessages["signatureMaintainer_Param"],
signatureOnbuild: this.dockerMessages["signatureOnbuild"],
signatureOnbuild_Param: this.dockerMessages["signatureOnbuild_Param"],
signatureRun_Signature0: this.dockerMessages["signatureRun_Signature0"],
signatureRun_Signature0_Param0: this.dockerMessages["signatureRun_Signature0_Param0"],
signatureRun_Signature0_Param1: this.dockerMessages["signatureRun_Signature0_Param1"],
signatureRun_Signature0_Param2: this.dockerMessages["signatureRun_Signature0_Param1"],
signatureRun_Signature1: this.dockerMessages["signatureRun_Signature1"],
signatureRun_Signature1_Param1: this.dockerMessages["signatureRun_Signature0_Param0"],
signatureRun_Signature1_Param2: this.dockerMessages["signatureRun_Signature0_Param1"],
signatureRun_Signature1_Param3: this.dockerMessages["signatureRun_Signature0_Param1"],
signatureShell: this.dockerMessages["signatureShell"],
signatureShell_Param1: this.dockerMessages["signatureShell_Param1"],
signatureShell_Param2: this.dockerMessages["signatureShell_Param2"],
Expand Down
129 changes: 83 additions & 46 deletions src/dockerSignatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,7 @@ export class DockerSignatures {
}
]
};
let entrypointActiveParameter = this.getJSONSignatureActiveParameter(entrypoint, position, false);
if (entrypointActiveParameter === -1) {
entrypointActiveParameter = this.getSignatureActiveParameter(entrypoint, position, 2);
return {
signatures: [ entrypointShellSignature ],
activeSignature: 0,
activeParameter: entrypointActiveParameter
}
} else if (entrypointActiveParameter === 0) {
return {
signatures: [
entrypointJsonSignature,
entrypointShellSignature
],
activeSignature: 0,
activeParameter: entrypointActiveParameter
}
}
return {
signatures: [ entrypointJsonSignature ],
activeSignature: 0,
activeParameter: entrypointActiveParameter
}
return this.getJSONInstructionSignatureHelp(entrypoint, position, entrypointJsonSignature, entrypointShellSignature, true, false);
case "ENV":
const envSignatures = [
{
Expand Down Expand Up @@ -478,6 +456,51 @@ export class DockerSignatures {
activeSignature: 0,
activeParameter: 0
};
case "RUN":
const run = instruction as JSONInstruction;
const runShellSignature = {
label: "RUN command parameter ...",
documentation: this.documentation.getDocumentation("signatureRun_Signature0"),
parameters: [
{
label: "command",
documentation: this.documentation.getDocumentation("signatureRun_Signature0_Param0")
},
{
label: "parameter",
documentation: this.documentation.getDocumentation("signatureRun_Signature0_Param1")
},
{
label: "...",
documentation: this.documentation.getDocumentation("signatureRun_Signature0_Param2")
}
]
};
const runJsonSignature = {
label: "RUN [ \"command\", \"parameter\", ... ]",
documentation: this.documentation.getDocumentation("signatureRun_Signature1"),
parameters: [
{
label: "["
},
{
label: "\"command\"",
documentation: this.documentation.getDocumentation("signatureRun_Signature1_Param1")
},
{
label: "\"parameter\"",
documentation: this.documentation.getDocumentation("signatureRun_Signature1_Param2")
},
{
label: "...",
documentation: this.documentation.getDocumentation("signatureRun_Signature1_Param3")
},
{
label: "]"
}
]
};
return this.getJSONInstructionSignatureHelp(run, position, runJsonSignature, runShellSignature, false, false);
case "SHELL":
let shell = instruction as JSONInstruction;
let shellSignatureHelp: SignatureHelp = {
Expand Down Expand Up @@ -662,29 +685,7 @@ export class DockerSignatures {
}
]
};
let volumeActiveParameter = this.getJSONSignatureActiveParameter(volume, position, true);
if (volumeActiveParameter === -1) {
volumeActiveParameter = this.getSignatureActiveParameter(volume, position, 1);
return {
signatures: [ volumeShellSignature ],
activeSignature: 0,
activeParameter: volumeActiveParameter
}
} else if (volumeActiveParameter === 0) {
return {
signatures: [
volumeJsonSignature,
volumeShellSignature
],
activeSignature: 0,
activeParameter: volumeActiveParameter
}
}
return {
signatures: [ volumeJsonSignature ],
activeSignature: 0,
activeParameter: volumeActiveParameter
}
return this.getJSONInstructionSignatureHelp(volume, position, volumeJsonSignature, volumeShellSignature, true, true);
case "WORKDIR":
return {
signatures: [
Expand Down Expand Up @@ -867,6 +868,42 @@ export class DockerSignatures {
return inTag || inDigest ? 1 : 0;
}

private getJSONInstructionSignatureHelp(instruction: JSONInstruction, position: Position, jsonSignature: SignatureInformation, shellSignature: SignatureInformation, jsonFirst: boolean, singleParameter: boolean): SignatureHelp {
let activeParameter = this.getJSONSignatureActiveParameter(instruction, position, singleParameter);
if (activeParameter === -1) {
activeParameter = this.getSignatureActiveParameter(instruction, position, singleParameter ? 1 : 2);
return {
signatures: [ shellSignature ],
activeSignature: 0,
activeParameter: activeParameter
}
} else if (activeParameter === 0) {
if (jsonFirst) {
return {
signatures: [
jsonSignature,
shellSignature
],
activeSignature: 0,
activeParameter: 0
}
}
return {
signatures: [
shellSignature,
jsonSignature
],
activeSignature: 0,
activeParameter: 0
}
}
return {
signatures: [ jsonSignature ],
activeSignature: 0,
activeParameter: activeParameter
}
}

private getJSONSignatureActiveParameter(instruction: JSONInstruction, position: Position, singleParameter: boolean): number {
const closingBracket = instruction.getClosingBracket();
if (closingBracket) {
Expand Down
3 changes: 3 additions & 0 deletions src/parser/dockerfileParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Comment } from './comment';
import { Directive } from './directive';
import { Instruction } from './instruction';
import { Line } from './line';
import { JSONInstruction } from './instructions/jsonInstruction';
import { Arg } from './instructions/arg';
import { Cmd } from './instructions/cmd';
import { Copy } from './instructions/copy';
Expand Down Expand Up @@ -50,6 +51,8 @@ export class DockerfileParser {
return new Label(document, lineRange, escapeChar, instruction, instructionRange);
case "ONBUILD":
return new Onbuild(document, lineRange, escapeChar, instruction, instructionRange);
case "RUN":
return new JSONInstruction(document, lineRange, escapeChar, instruction, instructionRange);
case "SHELL":
return new Shell(document, lineRange, escapeChar, instruction, instructionRange);
case "STOPSIGNAL":
Expand Down
65 changes: 65 additions & 0 deletions test/dockerSignatures.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,64 @@ function assertOnbuild(signatureHelp: SignatureHelp) {
assert.equal(signatureHelp.signatures[0].parameters[0].documentation, docs.getDocumentation("signatureOnbuild_Param"));
}

function assertRun_Shell(signature: SignatureInformation) {
assert.equal(signature.label, "RUN command parameter ...");
assert.notEqual(signature.documentation, null);
assert.equal(signature.documentation, docs.getDocumentation("signatureRun_Signature0"));
assert.equal(signature.parameters.length, 3);
assert.equal(signature.parameters[0].label, "command");
assert.notEqual(signature.parameters[0].documentation, null);
assert.equal(signature.parameters[0].documentation, docs.getDocumentation("signatureRun_Signature0_Param0"));
assert.equal(signature.parameters[1].label, "parameter");
assert.notEqual(signature.parameters[1].documentation, null);
assert.equal(signature.parameters[1].documentation, docs.getDocumentation("signatureRun_Signature0_Param1"));
assert.equal(signature.parameters[2].label, "...");
assert.notEqual(signature.parameters[2].documentation, null);
assert.equal(signature.parameters[2].documentation, docs.getDocumentation("signatureRun_Signature0_Param2"));
}

function assertRun_JSON(signature: SignatureInformation) {
assert.equal(signature.label, "RUN [ \"command\", \"parameter\", ... ]");
assert.notEqual(signature.documentation, null);
assert.equal(signature.documentation, docs.getDocumentation("signatureRun_Signature1"));
assert.equal(signature.parameters.length, 5);
assert.equal(signature.parameters[0].label, "[");
assert.equal(signature.parameters[0].documentation, null);
assert.equal(signature.parameters[1].label, "\"command\"");
assert.notEqual(signature.parameters[1].documentation, null);
assert.equal(signature.parameters[1].documentation, docs.getDocumentation("signatureRun_Signature1_Param1"));
assert.equal(signature.parameters[2].label, "\"parameter\"");
assert.notEqual(signature.parameters[2].documentation, null);
assert.equal(signature.parameters[2].documentation, docs.getDocumentation("signatureRun_Signature1_Param2"));
assert.equal(signature.parameters[3].label, "...");
assert.notEqual(signature.parameters[3].documentation, null);
assert.equal(signature.parameters[3].documentation, docs.getDocumentation("signatureRun_Signature1_Param3"));
assert.equal(signature.parameters[4].label, "]");
assert.equal(signature.parameters[4].documentation, null);
}

function assertRun(signatureHelp: SignatureHelp, activeParameter: number) {
assert.equal(signatureHelp.activeSignature, 0);
assert.equal(signatureHelp.activeParameter, activeParameter);
assert.equal(signatureHelp.signatures.length, 2);
assertRun_Shell(signatureHelp.signatures[0]);
assertRun_JSON(signatureHelp.signatures[1]);
}

function assertRun_JSONOnly(signatureHelp: SignatureHelp, activeParameter: number) {
assert.equal(signatureHelp.activeSignature, 0);
assert.equal(signatureHelp.activeParameter, activeParameter);
assert.equal(signatureHelp.signatures.length, 1);
assertRun_JSON(signatureHelp.signatures[0]);
}

function assertRun_ShellOnly(signatureHelp: SignatureHelp, activeParameter: number) {
assert.equal(signatureHelp.activeSignature, 0);
assert.equal(signatureHelp.activeParameter, activeParameter);
assert.equal(signatureHelp.signatures.length, 1);
assertRun_Shell(signatureHelp.signatures[0]);
}

function assertShell(signatureHelp: SignatureHelp, activeParameter: number) {
assert.equal(signatureHelp.activeSignature, 0);
assert.equal(signatureHelp.activeParameter, activeParameter);
Expand Down Expand Up @@ -1532,6 +1590,12 @@ describe("Dockerfile Signature Tests", function() {
});
});

function testRun(trigger: boolean) {
testParameterizedInstruction("RUN", trigger, false, assertRun, assertRun_JSONOnly, assertRun_ShellOnly);
}

testRun(false);

function testShell(trigger: boolean) {
let onbuild = trigger ? "ONBUILD " : "";
let triggerOffset = trigger ? 8 : 0;
Expand Down Expand Up @@ -1775,6 +1839,7 @@ describe("Dockerfile Signature Tests", function() {
testHealthcheck(true);
testLabel(true);
testMaintainer(true);
testRun(true);
testShell(true);
testStopsignal(true);
testUser(true);
Expand Down

0 comments on commit 0445be1

Please sign in to comment.