hclprinter: initial printer package

This commit is contained in:
Fatih Arslan 2015-10-03 03:30:57 +03:00
parent 9c29a82788
commit e5a8a1fa62
2 changed files with 155 additions and 0 deletions

92
hclprinter/hclprinter.go Normal file
View File

@ -0,0 +1,92 @@
package hclprinter
import (
"bytes"
"fmt"
"io"
"text/tabwriter"
"github.com/hashicorp/hcl/hcl"
)
type printer struct {
cfg Config
obj *hcl.Object
}
func (p *printer) output() []byte {
var buf bytes.Buffer
fmt.Println("STARTING OUTPUT")
return buf.Bytes()
}
// A Mode value is a set of flags (or 0). They control printing.
type Mode uint
const (
RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored
TabIndent // use tabs for indentation independent of UseSpaces
UseSpaces // use spaces instead of tabs for alignment
)
// A Config node controls the output of Fprint.
type Config struct {
Mode Mode // default: 0
Tabwidth int // default: 8
Indent int // default: 0 (all code is indented at least by this much)
}
func (c *Config) fprint(output io.Writer, obj *hcl.Object) error {
p := &printer{
cfg: *c,
obj: obj,
}
// TODO(arslan): implement this
// redirect output through a trimmer to eliminate trailing whitespace
// (Input to a tabwriter must be untrimmed since trailing tabs provide
// formatting information. The tabwriter could provide trimming
// functionality but no tabwriter is used when RawFormat is set.)
// output = &trimmer{output: output}
// redirect output through a tabwriter if necessary
if c.Mode&RawFormat == 0 {
minwidth := c.Tabwidth
padchar := byte('\t')
if c.Mode&UseSpaces != 0 {
padchar = ' '
}
twmode := tabwriter.DiscardEmptyColumns
if c.Mode&TabIndent != 0 {
minwidth = 0
twmode |= tabwriter.TabIndent
}
output = tabwriter.NewWriter(output, minwidth, c.Tabwidth, 1, padchar, twmode)
}
// write printer result via tabwriter/trimmer to output
if _, err := output.Write(p.output()); err != nil {
return err
}
// flush tabwriter, if any
var err error
if tw, _ := output.(*tabwriter.Writer); tw != nil {
err = tw.Flush()
}
return err
}
func (c *Config) Fprint(output io.Writer, obj *hcl.Object) error {
return c.fprint(output, obj)
}
// Fprint "pretty-prints" an HCL object to output
// It calls Config.Fprint with default settings.
func Fprint(output io.Writer, obj *hcl.Object) error {
return (&Config{Tabwidth: 8}).Fprint(output, obj)
}

View File

@ -0,0 +1,63 @@
package hclprinter
import (
"os"
"testing"
"github.com/hashicorp/hcl/hcl"
)
var complexHcl = `// This comes from Terraform, as a test
variable "foo" {
default = "bar"
description = "bar"
}
provider "aws" {
access_key = "foo"
secret_key = "bar"
}
provider "do" {
api_key = "${var.foo}"
}
resource "aws_security_group" "firewall" {
count = 5
}
resource aws_instance "web" {
ami = "${var.foo}"
security_groups = [
"foo",
"${aws_security_group.firewall.foo}"
]
network_interface {
device_index = 0
description = "Main network interface"
}
}
resource "aws_instance" "db" {
security_groups = "${aws_security_group.firewall.*.id}"
VPC = "foo"
depends_on = ["aws_instance.web"]
}
output "web_ip" {
value = "${aws_instance.web.private_ip}"
}
`
func TestPrint(t *testing.T) {
obj, err := hcl.Parse(complexHcl)
if err != nil {
t.Fatal(err)
}
if err := Fprint(os.Stdout, obj); err != nil {
t.Error(err)
}
}