@@ -153,7 +153,8 @@ func (c *Context) activeglobal() *avo.Global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) AddError(err error) {
|
func (c *Context) AddError(err error) {
|
||||||
c.errs = append(c.errs, err)
|
e := exterr(err)
|
||||||
|
c.errs = append(c.errs, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) AddErrorMessage(msg string) {
|
func (c *Context) AddErrorMessage(msg string) {
|
||||||
|
|||||||
30
build/error.go
Normal file
30
build/error.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mmcloughlin/avo/internal/stack"
|
||||||
|
"github.com/mmcloughlin/avo/src"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error represents an error during building, optionally tagged with the position at which it happened.
|
||||||
|
type Error struct {
|
||||||
|
Position src.Position
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// exterr constructs an Error with position derived from the first frame in the
|
||||||
|
// call stack outside this package.
|
||||||
|
func exterr(err error) Error {
|
||||||
|
e := Error{Err: err}
|
||||||
|
if f := stack.ExternalCaller(); f != nil {
|
||||||
|
e.Position = src.FramePosition(*f).Relwd()
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
msg := e.Err.Error()
|
||||||
|
if e.Position.IsValid() {
|
||||||
|
return e.Position.String() + ": " + msg
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
34
src/src.go
34
src/src.go
@@ -1,6 +1,11 @@
|
|||||||
package src
|
package src
|
||||||
|
|
||||||
import "strconv"
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
// Position represents a position in a source file.
|
// Position represents a position in a source file.
|
||||||
type Position struct {
|
type Position struct {
|
||||||
@@ -8,6 +13,13 @@ type Position struct {
|
|||||||
Line int // 1-up
|
Line int // 1-up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FramePosition(f runtime.Frame) Position {
|
||||||
|
return Position{
|
||||||
|
Filename: f.File,
|
||||||
|
Line: f.Line,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IsValid reports whether the position is valid: Line must be positive, but
|
// IsValid reports whether the position is valid: Line must be positive, but
|
||||||
// Filename may be empty.
|
// Filename may be empty.
|
||||||
func (p Position) IsValid() bool {
|
func (p Position) IsValid() bool {
|
||||||
@@ -26,3 +38,23 @@ func (p Position) String() string {
|
|||||||
s += strconv.Itoa(p.Line)
|
s += strconv.Itoa(p.Line)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rel returns Position relative to basepath. If the given filename cannot be
|
||||||
|
// expressed relative to basepath the position will be returned unchanged.
|
||||||
|
func (p Position) Rel(basepath string) Position {
|
||||||
|
q := p
|
||||||
|
if rel, err := filepath.Rel(basepath, q.Filename); err == nil {
|
||||||
|
q.Filename = rel
|
||||||
|
}
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relwd returns Position relative to the current working directory. Returns p
|
||||||
|
// unchanged if the working directory cannot be determined, or the filename
|
||||||
|
// cannot be expressed relative to the working directory.
|
||||||
|
func (p Position) Relwd() Position {
|
||||||
|
if wd, err := os.Getwd(); err == nil {
|
||||||
|
return p.Rel(wd)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user