Skip to content

Commit

Permalink
✨ : add HCL parsing for outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
juwit committed Nov 12, 2019
1 parent 27e5876 commit 812fe04
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 15 deletions.
44 changes: 38 additions & 6 deletions src/main/antlr4/io/codeka/gaia/hcl/antlr/hcl.g4
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,67 @@ file

directive
: variableDirective
| outputDirective
;

variableDirective
: 'variable' identifier variableBlock
;

variableBlock
: '{' type? description? r_default? '}'
: '{' type? variableDescription? r_default? '}'
;

outputDirective
: 'output' identifier outputBlock
;

outputBlock
: '{' outputValue? outputDescription? sensitive? '}'
;

outputValue
: 'value' '=' expression
;

outputDescription
: 'description' '=' STRING
;

sensitive
: 'sensitive' '=' BOOLEAN
;

type
: 'type' '=' TYPE
;

description
variableDescription
: 'description' '=' STRING
;

r_default
: 'default' '=' defaultValue
: 'default' '=' expression
;

defaultValue
expression
: STRING
| NUMBER
| 'true'
| 'false'
| BOOLEAN
| UNQUOTED_STRING
;

identifier
: STRING
;

BOOLEAN
: 'true'
| '"true"'
| 'false'
| '"false"'
;

TYPE
: 'string'
| '"string"'
Expand All @@ -48,6 +76,10 @@ TYPE
| '"bool"'
;

UNQUOTED_STRING
: [a-zA-Z0-9_.[\]-]+
;

/**
* STRING Lexer Rule comes from the JSON grammar
* https://github.com/antlr/grammars-v4/blob/master/json/JSON.g4
Expand Down
39 changes: 31 additions & 8 deletions src/main/java/io/codeka/gaia/hcl/HclTreeListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,50 @@ import java.util.*
class HclTreeListener : hclBaseListener() {

var variables: MutableList<Variable> = LinkedList()
var outputs: MutableList<Output> = LinkedList()

private var current: Variable = Variable()
private var currentVariable: Variable = Variable()
private var currentOutput:Output = Output()

override fun enterVariableDirective(ctx: hclParser.VariableDirectiveContext) {
this.current = Variable()
this.current.name = ctx.identifier().text
this.currentVariable = Variable()
this.currentVariable.name = ctx.identifier().text
}

override fun exitVariableDirective(ctx: hclParser.VariableDirectiveContext) {
this.variables.add(this.current)
this.variables.add(this.currentVariable)
}

override fun enterType(ctx: hclParser.TypeContext) {
this.current.type = ctx.TYPE().text
this.currentVariable.type = ctx.TYPE().text
}

override fun enterDescription(ctx: hclParser.DescriptionContext) {
this.current.description = ctx.STRING().text
override fun enterVariableDescription(ctx: hclParser.VariableDescriptionContext) {
this.currentVariable.description = ctx.STRING().text
}

override fun enterR_default(ctx: hclParser.R_defaultContext) {
this.current.default = ctx.defaultValue().text
this.currentVariable.default = ctx.expression().text
}

override fun enterOutputDirective(ctx: hclParser.OutputDirectiveContext) {
this.currentOutput = Output(name = ctx.identifier().text)
}

override fun exitOutputDirective(ctx: hclParser.OutputDirectiveContext) {
this.outputs.add(this.currentOutput)
}

override fun enterOutputValue(ctx: hclParser.OutputValueContext) {
this.currentOutput.value = ctx.expression().text
}

override fun enterOutputDescription(ctx: hclParser.OutputDescriptionContext) {
this.currentOutput.description = ctx.STRING().text
}

override fun enterSensitive(ctx: hclParser.SensitiveContext) {
this.currentOutput.sensitive = ctx.BOOLEAN().text
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ package io.codeka.gaia.hcl

data class Variable(var name: String = "", var type: String = "", var description: String = "", var default: String = "");

data class Output(var name: String = "", var value: String = "", var description: String = "", var sensitive: String = "false");

30 changes: 29 additions & 1 deletion src/test/java/io/codeka/gaia/hcl/HCLParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
class HCLParserTest {

@Test
void parsing_variable_shouldWork() throws IOException {
void parsing_variables_shouldWork() throws IOException {
// given
// loading test file
CharStream charStream = CharStreams.fromStream(new ClassPathResource("hcl/variables.tf").getInputStream());
Expand Down Expand Up @@ -44,4 +44,32 @@ void parsing_variable_shouldWork() throws IOException {
assertThat(hclTreeListener.getVariables()).contains(stringVar, numberVar, boolVar);
}

@Test
void parsing_outputs_shouldWork() throws IOException {
// given
// loading test file
CharStream charStream = CharStreams.fromStream(new ClassPathResource("hcl/outputs.tf").getInputStream());

// configuring antlr lexer
hclLexer lexer = new hclLexer(charStream);

// configuring antlr parser
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
hclParser parser = new hclParser(tokenStream);

// when
// walk the AST
ParseTreeWalker walker = new ParseTreeWalker();
var hclTreeListener = new HclTreeListener();
walker.walk(hclTreeListener, parser.file());

// then
assertThat(hclTreeListener.getOutputs()).hasSize(2);

var output1 = new Output("\"instance_ip_addr\"", "\"${aws_instance.server.private_ip}\"", "\"The private IP address of the main server instance.\"", "false");
var output2 = new Output("\"db_password\"", "aws_db_instance.db[1].password", "\"The password for logging in to the database.\"", "true");

assertThat(hclTreeListener.getOutputs()).contains(output1, output2);
}

}
10 changes: 10 additions & 0 deletions src/test/resources/hcl/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
output "instance_ip_addr" {
value = "${aws_instance.server.private_ip}"
description = "The private IP address of the main server instance."
}

output "db_password" {
value = aws_db_instance.db[1].password
description = "The password for logging in to the database."
sensitive = true
}

0 comments on commit 812fe04

Please sign in to comment.