printer: initial implementation. I'm still experimenting though
This commit is contained in:
parent
71105156e2
commit
5918e3592b
@ -1 +1,84 @@
|
|||||||
package printer
|
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()
|
||||||
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
@ -10,20 +9,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type printer struct {
|
type printer struct {
|
||||||
|
out []byte // raw printer result
|
||||||
cfg Config
|
cfg Config
|
||||||
node ast.Node
|
node ast.Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *printer) output() []byte {
|
func (p *printer) output() []byte {
|
||||||
var buf bytes.Buffer
|
|
||||||
fmt.Println("STARTING OUTPUT")
|
fmt.Println("STARTING OUTPUT")
|
||||||
|
return p.printNode(p.node)
|
||||||
ast.Walk(p.node, func(n ast.Node) bool {
|
|
||||||
fmt.Printf("n = %+v\n", n)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Mode value is a set of flags (or 0). They control printing.
|
// 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.
|
// A Config node controls the output of Fprint.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Mode Mode // default: 0
|
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)
|
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
|
// Fprint "pretty-prints" an HCL node to output
|
||||||
// It calls Config.Fprint with default settings.
|
// It calls Config.Fprint with default settings.
|
||||||
func Fprint(output io.Writer, node ast.Node) error {
|
func Fprint(output io.Writer, node ast.Node) error {
|
||||||
return (&Config{Tabwidth: 8}).Fprint(output, node)
|
return (&Config{Tabwidth: 4}).Fprint(output, node)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,12 @@ import (
|
|||||||
"github.com/fatih/hcl/parser"
|
"github.com/fatih/hcl/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var listHCL = `foo = ["fatih", "arslan"]`
|
||||||
|
var listHCL2 = `foo = [
|
||||||
|
"fatih",
|
||||||
|
"arslan",
|
||||||
|
]`
|
||||||
|
|
||||||
var complexHcl = `// This comes from Terraform, as a test
|
var complexHcl = `// This comes from Terraform, as a test
|
||||||
variable "foo" {
|
variable "foo" {
|
||||||
default = "bar"
|
default = "bar"
|
||||||
@ -52,7 +58,8 @@ output "web_ip" {
|
|||||||
`
|
`
|
||||||
|
|
||||||
func TestPrint(t *testing.T) {
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user