From 5918e3592bc4088eae49154017a7debcd76ada22 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Sun, 25 Oct 2015 01:23:50 +0300 Subject: [PATCH] printer: initial implementation. I'm still experimenting though --- printer/nodes.go | 83 +++++++++++++++++++++++++++++++++++++++++ printer/printer.go | 15 ++------ printer/printer_test.go | 9 ++++- 3 files changed, 95 insertions(+), 12 deletions(-) diff --git a/printer/nodes.go b/printer/nodes.go index b0c0dd8..9be9f4e 100644 --- a/printer/nodes.go +++ b/printer/nodes.go @@ -1 +1,84 @@ package printer + +import ( + "bytes" + "fmt" + + "github.com/fatih/hcl/ast" +) + +func (p *printer) printNode(n ast.Node) []byte { + var buf bytes.Buffer + + switch t := n.(type) { + case *ast.ObjectList: + fmt.Println("printing objectList", t) + for _, item := range t.Items { + buf.Write(p.printObjectItem(item)) + } + case *ast.ObjectKey: + fmt.Println("printing objectKey", t) + case *ast.ObjectItem: + fmt.Println("printing objectItem", t) + buf.Write(p.printObjectItem(t)) + case *ast.LiteralType: + buf.Write(p.printLiteral(t)) + case *ast.ListType: + buf.Write(p.printList(t)) + case *ast.ObjectType: + fmt.Println("printing ObjectType", t) + default: + fmt.Printf(" unknown type: %T\n", n) + } + + return buf.Bytes() +} + +func (p *printer) printObjectItem(o *ast.ObjectItem) []byte { + var buf bytes.Buffer + + for i, k := range o.Keys { + buf.WriteString(k.Token.Text) + if i != len(o.Keys)-1 || len(o.Keys) == 1 { + buf.WriteString(" ") + } + + // reach end of key + if i == len(o.Keys)-1 { + buf.WriteString("=") + buf.WriteString(" ") + } + } + + buf.Write(p.printNode(o.Val)) + return buf.Bytes() +} + +func (p *printer) printLiteral(l *ast.LiteralType) []byte { + return []byte(l.Token.Text) +} + +func (p *printer) printList(l *ast.ListType) []byte { + var buf bytes.Buffer + buf.WriteString("[") + + for i, item := range l.List { + if item.Pos().Line != l.Lbrack.Line { + // not same line + buf.WriteString("\n") + } + + buf.Write(p.printNode(item)) + + if i != len(l.List)-1 { + buf.WriteString(",") + buf.WriteString(" ") + } else if item.Pos().Line != l.Lbrack.Line { + buf.WriteString(",") + buf.WriteString("\n") + } + } + + buf.WriteString("]") + return buf.Bytes() +} diff --git a/printer/printer.go b/printer/printer.go index 1c46343..4121569 100644 --- a/printer/printer.go +++ b/printer/printer.go @@ -1,7 +1,6 @@ package printer import ( - "bytes" "fmt" "io" "text/tabwriter" @@ -10,20 +9,14 @@ import ( ) type printer struct { + out []byte // raw printer result cfg Config node ast.Node } func (p *printer) output() []byte { - var buf bytes.Buffer fmt.Println("STARTING OUTPUT") - - ast.Walk(p.node, func(n ast.Node) bool { - fmt.Printf("n = %+v\n", n) - return true - }) - - return buf.Bytes() + return p.printNode(p.node) } // A Mode value is a set of flags (or 0). They control printing. @@ -38,7 +31,7 @@ const ( // A Config node controls the output of Fprint. type Config struct { Mode Mode // default: 0 - Tabwidth int // default: 8 + Tabwidth int // default: 4 Indent int // default: 0 (all code is indented at least by this much) } @@ -94,5 +87,5 @@ func (c *Config) Fprint(output io.Writer, node ast.Node) error { // Fprint "pretty-prints" an HCL node to output // It calls Config.Fprint with default settings. func Fprint(output io.Writer, node ast.Node) error { - return (&Config{Tabwidth: 8}).Fprint(output, node) + return (&Config{Tabwidth: 4}).Fprint(output, node) } diff --git a/printer/printer_test.go b/printer/printer_test.go index 98b409b..493733b 100644 --- a/printer/printer_test.go +++ b/printer/printer_test.go @@ -7,6 +7,12 @@ import ( "github.com/fatih/hcl/parser" ) +var listHCL = `foo = ["fatih", "arslan"]` +var listHCL2 = `foo = [ + "fatih", + "arslan", +]` + var complexHcl = `// This comes from Terraform, as a test variable "foo" { default = "bar" @@ -52,7 +58,8 @@ output "web_ip" { ` func TestPrint(t *testing.T) { - node, err := parser.Parse([]byte(complexHcl)) + // node, err := parser.Parse([]byte(complexHcl)) + node, err := parser.Parse([]byte(listHCL2)) if err != nil { t.Fatal(err) }