Several changed and improvements
This commit is contained in:
parent
c9e7ec3621
commit
710dd69efb
28
README.md
28
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
|
[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
|
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
|
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
|
[`hclfmt`](https://github.com/fatih/hclfmt) and `hcl2json` (coming soon) is
|
||||||
these tools.
|
written based on these tools.
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
If you are already familiar with Go's own parser family it's really easy to
|
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
|
dive. It basically resembles the same logic. However there are several differences
|
||||||
and the implemntation is completely different. Right now it contains the
|
and the implementation is completely different. Right now it contains the
|
||||||
following packages:
|
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
|
* `scanner`: scanner is a lexical scanner. It scans a given HCL file and
|
||||||
returns a stream of tokens.
|
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
|
* `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`
|
The whole parser family was created because I wanted a `hclfmt` command, which
|
||||||
command, which like `gofmt` formats a HCL file. I didn't want to use the
|
like `gofmt` would format a HCL file. I didn't want to use the package
|
||||||
package [github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first
|
[github/hashicorp/hcl](https://github.com/hashicorp/hcl) in the first place,
|
||||||
place, because the lexer and parser is generated and it doesn't expose any kind
|
because the lexer and parser is generated and it doesn't expose any kind of
|
||||||
of flexibility.
|
flexibility.
|
||||||
|
|
||||||
Another reason was that I wanted to learn and experience how to implement a
|
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
|
## License
|
||||||
|
|
||||||
|
@ -1,42 +1,41 @@
|
|||||||
// This comes from Terraform, as a test
|
|
||||||
variable "foo" {
|
variable "foo" {
|
||||||
default = "bar"
|
default = "bar"
|
||||||
description = "bar"
|
description = "bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "aws" {
|
provider "aws" {
|
||||||
access_key = "foo"
|
access_key = "foo"
|
||||||
secret_key = "bar"
|
secret_key = "bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "do" {
|
provider "do" {
|
||||||
api_key = "${var.foo}"
|
api_key = "${var.foo}"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group" "firewall" {
|
resource "aws_security_group" "firewall" {
|
||||||
count = 5
|
count = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
resource aws_instance "web" {
|
resource aws_instance "web" {
|
||||||
ami = "${var.foo}"
|
ami = "${var.foo}"
|
||||||
security_groups = [
|
security_groups = [
|
||||||
"foo",
|
"foo",
|
||||||
"${aws_security_group.firewall.foo}"
|
"${aws_security_group.firewall.foo}",
|
||||||
]
|
]
|
||||||
|
network_interface = {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
|
||||||
network_interface {
|
foo = ["faith", arslan]
|
||||||
device_index = 0
|
|
||||||
description = "Main network interface"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_instance" "db" {
|
resource "aws_instance" "db" {
|
||||||
security_groups = "${aws_security_group.firewall.*.id}"
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
VPC = "foo"
|
VPC = "foo"
|
||||||
|
depends_on = ["aws_instance.web"]
|
||||||
depends_on = ["aws_instance.web"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output "web_ip" {
|
output "web_ip" {
|
||||||
value = "${aws_instance.web.private_ip}"
|
value = "${aws_instance.web.private_ip}"
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ const (
|
|||||||
tab = byte('\t')
|
tab = byte('\t')
|
||||||
)
|
)
|
||||||
|
|
||||||
// node
|
// output prints creates a printable HCL output and returns it.
|
||||||
func (p *printer) output(n ast.Node) []byte {
|
func (p *printer) output(n ast.Node) []byte {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ type entry struct {
|
|||||||
var data = []entry{
|
var data = []entry{
|
||||||
{"complexhcl.input", "complexhcl.golden"},
|
{"complexhcl.input", "complexhcl.golden"},
|
||||||
{"list.input", "list.golden"},
|
{"list.input", "list.golden"},
|
||||||
|
{"comment.input", "comment.golden"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFiles(t *testing.T) {
|
func TestFiles(t *testing.T) {
|
||||||
@ -115,12 +116,6 @@ func format(src []byte) ([]byte, error) {
|
|||||||
|
|
||||||
var buf bytes.Buffer
|
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{}
|
cfg := &Config{}
|
||||||
if err := cfg.Fprint(&buf, node); err != nil {
|
if err := cfg.Fprint(&buf, node); err != nil {
|
||||||
return nil, fmt.Errorf("print: %s", err)
|
return nil, fmt.Errorf("print: %s", err)
|
||||||
|
15
printer/testdata/comment.golden
vendored
Normal file
15
printer/testdata/comment.golden
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Foo
|
||||||
|
|
||||||
|
/* Bar */
|
||||||
|
|
||||||
|
/*
|
||||||
|
/*
|
||||||
|
Baz
|
||||||
|
*/
|
||||||
|
|
||||||
|
# Another
|
||||||
|
|
||||||
|
# Multiple
|
||||||
|
# Lines
|
||||||
|
|
||||||
|
foo = "bar"
|
15
printer/testdata/comment.input
vendored
Normal file
15
printer/testdata/comment.input
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Foo
|
||||||
|
|
||||||
|
/* Bar */
|
||||||
|
|
||||||
|
/*
|
||||||
|
/*
|
||||||
|
Baz
|
||||||
|
*/
|
||||||
|
|
||||||
|
# Another
|
||||||
|
|
||||||
|
# Multiple
|
||||||
|
# Lines
|
||||||
|
|
||||||
|
foo = "bar"
|
Loading…
Reference in New Issue
Block a user