Skip to content

Commit

Permalink
Merge pull request #21 from rightscale/better_script_errors
Browse files Browse the repository at this point in the history
Print all JavaScript compilation errors in the fpt script command
  • Loading branch information
douglaswth authored May 6, 2020
2 parents 82a73e3 + 591735f commit 7321031
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: go
go:
- 1.13.x
- 1.14.x
matrix:
include:
- os: linux
Expand Down
4 changes: 4 additions & 0 deletions cmd/fpt/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v1.1.0 / 2020-05-05
-------------------
* Print all JavaScript compilation errors in the `fpt script` command (#18)

v1.0.9 / 2020-03-12
-------------------
* Bump timeout for http client to 5 minutes
Expand Down
48 changes: 44 additions & 4 deletions cmd/fpt/script.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import (

"github.com/pkg/errors"
"github.com/robertkrimen/otto"
"github.com/robertkrimen/otto/ast"
"github.com/robertkrimen/otto/parser"

// This import loads the otto runtime with underscore library enabled.
_ "github.com/robertkrimen/otto/underscore"
)
Expand All @@ -26,6 +29,7 @@ var (
type script struct {
name string
code string
line int
result string
params []string
}
Expand All @@ -35,6 +39,24 @@ type param struct {
value interface{}
}

type scriptErrorList struct {
errs parser.ErrorList
file string
line int
}

func (s *scriptErrorList) Error() string {
r := regexp.MustCompile(`^(` + regexp.QuoteMeta(s.file) + `: Line )(\d+):`)
errs := make([]string, len(s.errs))
for i, err := range s.errs {
e := err.Error()
matches := r.FindStringSubmatch(e)
line, _ := strconv.Atoi(matches[2])
errs[i] = r.Copy().ReplaceAllString(e, fmt.Sprintf("%v%v:", matches[1], s.line-1+line))
}
return strings.Join(errs, "\n")
}

func runScript(ctx context.Context, file, outfile, result, name string, options []string) error {
rd, err := os.Open(file)
if err != nil {
Expand All @@ -56,7 +78,10 @@ func runScript(ctx context.Context, file, outfile, result, name string, options
return err
}

var data interface{}
var (
data interface{}
line int
)
if strings.Contains(src, "rs_pt_ver") {
scripts := getScripts(src)
// for i, s := range scripts {
Expand All @@ -68,6 +93,7 @@ func runScript(ctx context.Context, file, outfile, result, name string, options
} else if len(scripts) == 1 {
name = scripts[0].name
src = scripts[0].code
line = scripts[0].line
result = scripts[0].result
} else if len(scripts) > 0 {
names := []string{}
Expand All @@ -76,6 +102,7 @@ func runScript(ctx context.Context, file, outfile, result, name string, options
names = append(names, s.name)
if s.name == name {
src = s.code
line = s.line
result = s.result
found = true
break
Expand All @@ -89,7 +116,16 @@ func runScript(ctx context.Context, file, outfile, result, name string, options
}
fmt.Printf("Running script %q from %s and writing %s to %s\n", name, file, result, outfile)

data, err = execScript(src, params, result)
code, err := parser.ParseFile(nil, file, src, 0)
if err != nil {
switch e := err.(type) {
case parser.ErrorList:
err = &scriptErrorList{errs: e, file: file, line: line}
}
return err
}

data, err = execScript(code, params, result)

if err != nil {
return err
Expand All @@ -105,7 +141,7 @@ func runScript(ctx context.Context, file, outfile, result, name string, options
return nil
}

func execScript(code string, params []*param, result string) (out interface{}, err error) {
func execScript(code *ast.Program, params []*param, result string) (out interface{}, err error) {
defer func() {
if caught := recover(); caught != nil {
if caught == errHalt {
Expand Down Expand Up @@ -309,11 +345,12 @@ func getScripts(src string) []*script {
scriptEndRe := regexp.MustCompile(`^\s*end\s*$`)
codeStartRe := regexp.MustCompile(`^\s*code ('.*|".*|<<-?[A-Z_]+\s*)$`)
var codeEndRe *regexp.Regexp
var codeLine int

scriptLines := []string{}
codeLines := []string{}
name := ""
for _, line := range lines {
for i, line := range lines {
if inCode {
//fmt.Println("DBG HERE_CODE", line)
if matches := codeEndRe.FindStringSubmatch(line); len(matches) > 0 {
Expand Down Expand Up @@ -344,12 +381,14 @@ func getScripts(src string) []*script {
scripts = append(scripts, &script{
name: name,
code: unquote(strings.Join(codeLines, "\n")),
line: codeLine,
result: unquote(result),
params: params,
})
} else if matches := codeStartRe.FindStringSubmatch(line); len(matches) > 0 {
//fmt.Println("DBG HERE_CODE START")
inCode = true
codeLine = i + 1
if strings.HasPrefix(matches[1], "'") {
codeEndRe = regexp.MustCompile(`^(.*?[^\\]')`)
codeLines = append(codeLines, matches[1])
Expand All @@ -359,6 +398,7 @@ func getScripts(src string) []*script {
} else {
end := strings.TrimPrefix(strings.TrimPrefix(matches[1], "<<"), "-")
codeEndRe = regexp.MustCompile(`^\s*` + end)
codeLine++
}
} else {
scriptLines = append(scriptLines, line)
Expand Down
37 changes: 34 additions & 3 deletions cmd/fpt/script_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,34 @@ import (
"os"
"reflect"
"testing"

"github.com/robertkrimen/otto/parser"
)

func TestScriptErrorListError(t *testing.T) {
var (
file = "test.pt"
code = `var a = {
b-c: 1
};
`
exp = `test.pt: Line 11:4 Unexpected token -
test.pt: Line 11:8 Unexpected number
test.pt: Line 12:1 Unexpected token }
test.pt: Line 13:1 Unexpected end of input
test.pt: Line 13:1 Unexpected end of input`
)

_, err := parser.ParseFile(nil, file, code, 0)
err = &scriptErrorList{errs: err.(parser.ErrorList), file: file, line: 10}

got := err.Error()

if got != exp {
t.Errorf("scriptErrorList.Error(): expected:\n%q\n:got:\n%q", exp, got)
}
}

func TestGetScripts(t *testing.T) {
tests := []struct {
name string
Expand All @@ -18,12 +44,14 @@ func TestGetScripts(t *testing.T) {
{
name: "do_filter",
code: "var filtered_datacenters = [];\nvar matchers = []\nvar end = [\"a\"]\n\nconsole.log(datacenters.length)\nfiltered_datacenters = [\"foo\"]",
line: 42,
params: []string{"datacenters", "testing_one"},
result: "filtered_datacenters",
},
{
name: "otra",
code: "console.log(otra)\nRESVAR=otra[0]",
line: 56,
params: []string{"otra"},
result: "RESVAR",
},
Expand All @@ -40,16 +68,19 @@ func TestGetScripts(t *testing.T) {
for j, expS := range tt.exp {
gotS := got[j]
if gotS.name != expS.name {
t.Errorf("GetScripts(%s)[%d]: expected name %s got %s", tt.name, j, expS.name, gotS.name)
t.Errorf("GetScripts(%s)[%d]: expected name: %s got: %s", tt.name, j, expS.name, gotS.name)
}
if gotS.result != expS.result {
t.Errorf("GetScripts(%s)[%d]: expected result %s got %s", tt.name, j, expS.result, gotS.result)
t.Errorf("GetScripts(%s)[%d]: expected result: %s got %s", tt.name, j, expS.result, gotS.result)
}
if gotS.code != expS.code {
t.Errorf("GetScripts(%s)[%d]: code differs. expected:\n%q\ngot:\n%q", tt.name, j, expS.code, gotS.code)
}
if gotS.line != expS.line {
t.Errorf("GetScripts(%s)[%d]: line differs. expected:\n%v\ngot:\n%v", tt.name, j, expS.line, gotS.line)
}
if !reflect.DeepEqual(gotS.params, expS.params) {
t.Errorf("GetScripts(%s)[%d]: expected params:%v got :%v", tt.name, j, expS.params, gotS.params)
t.Errorf("GetScripts(%s)[%d]: expected params: %v got: %v", tt.name, j, expS.params, gotS.params)
}

}
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ require (
github.com/alecthomas/kingpin v2.2.6+incompatible
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/douglaswth/rsrdp v0.0.0-20151016234338-276cfcdf9e52
github.com/douglaswth/rsrdp v0.0.0-20151016234338-276cfcdf9e52 // indirect
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/jessevdk/go-flags v1.4.0 // indirect
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1
github.com/onsi/ginkgo v1.8.0
github.com/onsi/gomega v1.5.0
github.com/pkg/errors v0.8.1
github.com/rlmcpherson/s3gof3r v0.5.0 // indirect
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
github.com/spf13/afero v1.2.0 // indirect
github.com/spf13/viper v1.3.1
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
Expand Down Expand Up @@ -120,6 +122,8 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rlmcpherson/s3gof3r v0.5.0 h1:1izOJpTiohSibfOHuNyEA/yQnAirh05enzEdmhez43k=
github.com/rlmcpherson/s3gof3r v0.5.0/go.mod h1:s7vv7SMDPInkitQMuZzH615G7yWHdrU2r/Go7Bo71Rs=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4=
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
Expand Down

0 comments on commit 7321031

Please sign in to comment.