This change adds a few more compiler tests and rearranges some bits and pieces that came up while doing so. For example, we now issue warnings for incorrect casing and/or extensions of the Mufile (and test these conditions). As part of doing that, it became clear the layering between the mu/compiler and mu/workspace packages wasn't quite right, so some logic got moved around; additionally, the separation of concerns between mu/workspace and mu/schema wasn't quite right, so this has been fixed also (workspace just understands Mufile related things while schema understands how to unmarshal the specific supported extensions).
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
// Copyright 2016 Marapongo, Inc. All rights reserved.
|
|
|
|
package compiler
|
|
|
|
import (
|
|
"github.com/golang/glog"
|
|
|
|
"github.com/marapongo/mu/pkg/diag"
|
|
"github.com/marapongo/mu/pkg/errors"
|
|
"github.com/marapongo/mu/pkg/schema"
|
|
)
|
|
|
|
type Parser interface {
|
|
// Diag fetches the diagnostics sink used by this parser.
|
|
Diag() diag.Sink
|
|
|
|
// Parse detects and parses input from the given path. If an error occurs, the return value will be nil. It is
|
|
// expected that errors are conveyed using the diag.Sink interface.
|
|
Parse(doc *diag.Document) *schema.Stack
|
|
}
|
|
|
|
func NewParser(c Compiler) Parser {
|
|
return &parser{c}
|
|
}
|
|
|
|
type parser struct {
|
|
c Compiler
|
|
}
|
|
|
|
func (p *parser) Diag() diag.Sink {
|
|
return p.c.Diag()
|
|
}
|
|
|
|
func (p *parser) Parse(doc *diag.Document) *schema.Stack {
|
|
glog.Infof("Parsing Mufile: %v (len(body)=%v)", doc.File, len(doc.Body))
|
|
if glog.V(2) {
|
|
defer func() {
|
|
glog.V(2).Infof("Parsing Mufile '%v' completed w/ %v warnings and %v errors",
|
|
doc.File, p.Diag().Warnings(), p.Diag().Errors())
|
|
}()
|
|
}
|
|
|
|
// We support many file formats. Detect the file extension and deserialize the contents.
|
|
// TODO: we need to expand templates as part of the parsing process
|
|
var stack schema.Stack
|
|
marshaler, has := schema.Marshalers[doc.Ext()]
|
|
if !has {
|
|
glog.Fatalf("No marshaler registered for this Mufile extension: %v", doc.Ext())
|
|
return nil
|
|
}
|
|
|
|
if err := marshaler.Unmarshal(doc.Body, &stack); err != nil {
|
|
p.Diag().Errorf(errors.IllegalMufileSyntax.WithDocument(doc), err)
|
|
// TODO: it would be great if we issued an error per issue found in the file with line/col numbers.
|
|
return nil
|
|
}
|
|
return &stack
|
|
}
|