112 lines
2.3 KiB
Go
112 lines
2.3 KiB
Go
package builder
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/marte-dev/marte-dev-tools/internal/parser"
|
|
)
|
|
|
|
type Builder struct {
|
|
Files []string
|
|
}
|
|
|
|
func NewBuilder(files []string) *Builder {
|
|
return &Builder{Files: files}
|
|
}
|
|
|
|
func (b *Builder) Build(outputDir string) error {
|
|
packages := make(map[string]*parser.Configuration)
|
|
|
|
for _, file := range b.Files {
|
|
content, err := ioutil.ReadFile(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
p := parser.NewParser(string(content))
|
|
config, err := p.Parse()
|
|
if err != nil {
|
|
return fmt.Errorf("error parsing %s: %v", file, err)
|
|
}
|
|
|
|
pkgURI := ""
|
|
if config.Package != nil {
|
|
pkgURI = config.Package.URI
|
|
}
|
|
|
|
if existing, ok := packages[pkgURI]; ok {
|
|
existing.Definitions = append(existing.Definitions, config.Definitions...)
|
|
} else {
|
|
packages[pkgURI] = config
|
|
}
|
|
}
|
|
|
|
for pkg, config := range packages {
|
|
if pkg == "" {
|
|
continue // Or handle global package
|
|
}
|
|
|
|
outputPath := filepath.Join(outputDir, pkg+".marte")
|
|
err := b.writeConfig(outputPath, config)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *Builder) writeConfig(path string, config *parser.Configuration) error {
|
|
f, err := os.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
for _, def := range config.Definitions {
|
|
b.writeDefinition(f, def, 0)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *Builder) writeDefinition(f *os.File, def parser.Definition, indent int) {
|
|
indentStr := strings.Repeat(" ", indent)
|
|
switch d := def.(type) {
|
|
case *parser.Field:
|
|
fmt.Fprintf(f, "%s%s = %s\n", indentStr, d.Name, b.formatValue(d.Value))
|
|
case *parser.ObjectNode:
|
|
fmt.Fprintf(f, "%s%s = {\n", indentStr, d.Name)
|
|
for _, subDef := range d.Subnode.Definitions {
|
|
b.writeDefinition(f, subDef, indent+1)
|
|
}
|
|
fmt.Fprintf(f, "%s}\n", indentStr)
|
|
}
|
|
}
|
|
|
|
func (b *Builder) formatValue(val parser.Value) string {
|
|
switch v := val.(type) {
|
|
case *parser.StringValue:
|
|
return fmt.Sprintf("\"%s\"", v.Value)
|
|
case *parser.IntValue:
|
|
return v.Raw
|
|
case *parser.FloatValue:
|
|
return v.Raw
|
|
case *parser.BoolValue:
|
|
return fmt.Sprintf("%v", v.Value)
|
|
case *parser.ReferenceValue:
|
|
return v.Value
|
|
case *parser.ArrayValue:
|
|
elements := []string{}
|
|
for _, e := range v.Elements {
|
|
elements = append(elements, b.formatValue(e))
|
|
}
|
|
return fmt.Sprintf("{%s}", strings.Join(elements, " "))
|
|
default:
|
|
return ""
|
|
}
|
|
}
|