From 710dd69efb797f7ee2228f00199bc5a2cd72fb73 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Mon, 26 Oct 2015 01:34:41 +0300 Subject: [PATCH] Several changed and improvements --- README.md | 28 +++++++++++----------- parser/test-fixtures/complex.hcl | 41 ++++++++++++++++---------------- printer/nodes.go | 2 +- printer/printer_test.go | 7 +----- printer/testdata/comment.golden | 15 ++++++++++++ printer/testdata/comment.input | 15 ++++++++++++ 6 files changed, 66 insertions(+), 42 deletions(-) create mode 100644 printer/testdata/comment.golden create mode 100644 printer/testdata/comment.input diff --git a/README.md b/README.md index 42fe2fe..2ababa5 100644 --- a/README.md +++ b/README.md @@ -4,33 +4,33 @@ HCL is a lexer and parser family written in Go for [HCL](https://github.com/hashicorp/hcl) (Hashicorp Configuration Language). It has several components, similar to Go's own parser family. It provides a set of packages to write tools and customize files written in HCL. For example both -[`hclfmt`](https://github.com/fatih/hclfmt) and `hcl2json` is written based on -these tools. +[`hclfmt`](https://github.com/fatih/hclfmt) and `hcl2json` (coming soon) is +written based on these tools. ## API If you are already familiar with Go's own parser family it's really easy to -dive. It basically resembles the same logic. Howser there several differences -and the implemntation is completely different. Right now it contains the +dive. It basically resembles the same logic. However there are several differences +and the implementation is completely different. Right now it contains the following packages: -* `token`: defines constants reresenting the lexical tokens for a scanned HCL file. +* `token`: defines constants representing the lexical tokens for a scanned HCL file. * `scanner`: scanner is a lexical scanner. It scans a given HCL file and returns a stream of tokens. -* `ast`: declares the types used to repesent the syntax tree for parsed HCL files. +* `ast`: declares the types used to represent the syntax tree for parsed HCL files. * `parser`: parses a given HCL file and creates a AST representation -* `printer`: prints any given ast node and formats +* `printer`: prints any given AST node and formats -## Why did you create it? +## Why -The whole parser familiy was created because I wanted a proper `hclfmt` -command, which like `gofmt` formats a HCL file. I didn't want to use the -package [github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first -place, because the lexer and parser is generated and it doesn't expose any kind -of flexibility. +The whole parser family was created because I wanted a `hclfmt` command, which +like `gofmt` would format a HCL file. I didn't want to use the package +[github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first place, +because the lexer and parser is generated and it doesn't expose any kind of +flexibility. Another reason was that I wanted to learn and experience how to implement a -proper lexer and parser in Go. It was really fun and I think it was worht it. +proper lexer and parser in Go. It was really fun and I think it was worth it. ## License diff --git a/parser/test-fixtures/complex.hcl b/parser/test-fixtures/complex.hcl index cccb5b0..b3bf70d 100644 --- a/parser/test-fixtures/complex.hcl +++ b/parser/test-fixtures/complex.hcl @@ -1,42 +1,41 @@ -// This comes from Terraform, as a test variable "foo" { - default = "bar" - description = "bar" + default = "bar" + description = "bar" } provider "aws" { - access_key = "foo" - secret_key = "bar" + access_key = "foo" + secret_key = "bar" } provider "do" { - api_key = "${var.foo}" + api_key = "${var.foo}" } resource "aws_security_group" "firewall" { - count = 5 + count = 5 } resource aws_instance "web" { - ami = "${var.foo}" - security_groups = [ - "foo", - "${aws_security_group.firewall.foo}" - ] + ami = "${var.foo}" + security_groups = [ + "foo", + "${aws_security_group.firewall.foo}", + ] + network_interface = { + device_index = 0 + description = "Main network interface" + } - network_interface { - device_index = 0 - description = "Main network interface" - } + foo = ["faith", arslan] } resource "aws_instance" "db" { - security_groups = "${aws_security_group.firewall.*.id}" - VPC = "foo" - - depends_on = ["aws_instance.web"] + security_groups = "${aws_security_group.firewall.*.id}" + VPC = "foo" + depends_on = ["aws_instance.web"] } output "web_ip" { - value = "${aws_instance.web.private_ip}" + value = "${aws_instance.web.private_ip}" } diff --git a/printer/nodes.go b/printer/nodes.go index ecbdba5..7aebc59 100644 --- a/printer/nodes.go +++ b/printer/nodes.go @@ -13,7 +13,7 @@ const ( tab = byte('\t') ) -// node +// output prints creates a printable HCL output and returns it. func (p *printer) output(n ast.Node) []byte { var buf bytes.Buffer diff --git a/printer/printer_test.go b/printer/printer_test.go index 1901121..185965f 100644 --- a/printer/printer_test.go +++ b/printer/printer_test.go @@ -26,6 +26,7 @@ type entry struct { var data = []entry{ {"complexhcl.input", "complexhcl.golden"}, {"list.input", "list.golden"}, + {"comment.input", "comment.golden"}, } func TestFiles(t *testing.T) { @@ -115,12 +116,6 @@ func format(src []byte) ([]byte, error) { var buf bytes.Buffer - // test with Spaces - // cfg := &Config{SpacesWidth: 4} - // if err := cfg.Fprint(&buf, node); err != nil { - // return nil, fmt.Errorf("print: %s", err) - // } - cfg := &Config{} if err := cfg.Fprint(&buf, node); err != nil { return nil, fmt.Errorf("print: %s", err) diff --git a/printer/testdata/comment.golden b/printer/testdata/comment.golden new file mode 100644 index 0000000..e32be87 --- /dev/null +++ b/printer/testdata/comment.golden @@ -0,0 +1,15 @@ +// Foo + +/* Bar */ + +/* +/* +Baz +*/ + +# Another + +# Multiple +# Lines + +foo = "bar" diff --git a/printer/testdata/comment.input b/printer/testdata/comment.input new file mode 100644 index 0000000..e32be87 --- /dev/null +++ b/printer/testdata/comment.input @@ -0,0 +1,15 @@ +// Foo + +/* Bar */ + +/* +/* +Baz +*/ + +# Another + +# Multiple +# Lines + +foo = "bar"