packer: Clean up some of the JSON syntax stuff

This commit is contained in:
Mitchell Hashimoto 2013-07-01 14:46:32 -07:00
parent fdb0131ec5
commit cceb9c04b0
2 changed files with 145 additions and 146 deletions

View File

@ -1,6 +1,8 @@
## 0.1.4 (unreleased)
IMPROVEMENTS:
* core: Template syntax errors now show line and character number. [GH-56]
## 0.1.3 (July 1, 2013)

View File

@ -57,29 +57,6 @@ type rawProvisionerConfig struct {
rawConfig interface{}
}
// displaySyntaxError returns a location for the json syntax error
// Adapted from:
// https://groups.google.com/forum/#!topic/golang-nuts/fizimmXtVfc
func displaySyntaxError(js []byte, syntaxError error) (err error) {
syntax, ok := syntaxError.(*json.SyntaxError)
if !ok {
err = syntaxError
return
}
newline := []byte{'\x0a'}
space := []byte{' '}
start, end := bytes.LastIndex(js[:syntax.Offset], newline)+1, len(js)
if idx := bytes.Index(js[start:], newline); idx >= 0 {
end = start + idx
}
line, pos := bytes.Count(js[:start], newline)+1, int(syntax.Offset) - start - 1
err = fmt.Errorf("\nError in line %d: %s \n%s\n%s^", line, syntaxError, js[start:end], bytes.Repeat(space, pos))
return
}
// ParseTemplate takes a byte slice and parses a Template from it, returning
// the template and possibly errors while loading the template. The error
// could potentially be a MultiError, representing multiple errors. Knowing
@ -89,7 +66,27 @@ func ParseTemplate(data []byte) (t *Template, err error) {
var rawTpl rawTemplate
err = json.Unmarshal(data, &rawTpl)
if err != nil {
err = displaySyntaxError(data, err)
syntaxErr, ok := err.(*json.SyntaxError)
if !ok {
return
}
// We have a syntax error. Extract out the line number and friends.
// https://groups.google.com/forum/#!topic/golang-nuts/fizimmXtVfc
newline := []byte{'\x0a'}
start := bytes.LastIndex(data[:syntaxErr.Offset], newline)+1
end := len(data)
if idx := bytes.Index(data[start:], newline); idx >= 0 {
end = start + idx
}
line := bytes.Count(data[:start], newline)+1
pos := int(syntaxErr.Offset) - start - 1
err = fmt.Errorf("Error in line %d, char %d: %s\n%s",
line, pos, syntaxErr, data[start:end])
return
}