1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-03 13:11:48 +02:00

refactor: using ast parser instead

Using the ast parser, so we don't need to glob and goreleaser will work
reliably even if the files aren't gofmt'd.
This commit is contained in:
Carlos Alexandro Becker 2017-11-19 15:26:21 -02:00 committed by Carlos Alexandro Becker
parent eb48a028bd
commit 48ddd4c0eb
3 changed files with 46 additions and 41 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ dist/
vendor
coverage.txt
goreleaser
debug.test

View File

@ -4,7 +4,9 @@ package build
import (
"fmt"
"io/ioutil"
"go/ast"
"go/parser"
"go/token"
"os"
"os/exec"
"path/filepath"
@ -16,7 +18,6 @@ import (
"github.com/goreleaser/goreleaser/internal/buildtarget"
"github.com/goreleaser/goreleaser/internal/ext"
"github.com/goreleaser/goreleaser/internal/name"
zglob "github.com/mattn/go-zglob"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
@ -44,25 +45,26 @@ func (Pipe) Run(ctx *context.Context) error {
}
func checkMain(ctx *context.Context, build config.Build) error {
var glob = build.Main
if !strings.HasSuffix(glob, "main.go") {
// TODO: in real live , glob will never be empty. Maybe this is worth
// guarding here anyway
glob = glob + "/" + "*.go"
var dir = strings.Replace(build.Main, "main.go", "", -1)
if dir == "" {
dir = "."
}
log.Debugf("glob is %s", glob)
files, err := zglob.Glob(glob)
packs, err := parser.ParseDir(token.NewFileSet(), dir, nil, 0)
if err != nil {
return errors.Wrap(err, "failed to find go files")
return errors.Wrapf(err, "failed dir: %s", dir)
}
log.WithField("files", files).Debug("go files")
for _, file := range files {
bts, err := ioutil.ReadFile(file)
if err != nil {
return errors.Wrapf(err, "failed to read file: %s", file)
}
if strings.Contains(string(bts), "func main() {") {
return nil
for _, pack := range packs {
for _, file := range pack.Files {
for _, decl := range file.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok {
continue
}
log.Info(fn.Name.Name)
if fn.Name.Name == "main" && fn.Recv == nil {
return nil
}
}
}
}
return fmt.Errorf("build for %s does not contain a main function", build.Binary)

View File

@ -234,35 +234,33 @@ func TestRunInvalidLdflags(t *testing.T) {
}
func TestRunPipeFailingHooks(t *testing.T) {
prepare := func() *context.Context {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Dist: folder,
Builds: []config.Build{
{
Main: ".",
Binary: "hooks",
Hooks: config.Hooks{},
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Dist: folder,
Builds: []config.Build{
{
Binary: "hooks",
Hooks: config.Hooks{},
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
},
}
return context.New(config)
},
}
t.Run("pre-hook", func(t *testing.T) {
var ctx = prepare()
var ctx = context.New(config)
ctx.Config.Builds[0].Hooks.Pre = "exit 1"
ctx.Config.Builds[0].Hooks.Post = "echo post"
assert.EqualError(t, Pipe{}.Run(ctx), `pre hook failed: `)
})
t.Run("post-hook", func(t *testing.T) {
var ctx = prepare()
var ctx = context.New(config)
ctx.Config.Builds[0].Hooks.Pre = "echo pre"
ctx.Config.Builds[0].Hooks.Post = "exit 1"
assert.EqualError(t, Pipe{}.Run(ctx), `post hook failed: `)
})
@ -288,6 +286,10 @@ func TestRunPipeWithouMainFunc(t *testing.T) {
},
}
var ctx = context.New(config)
t.Run("empty", func(t *testing.T) {
ctx.Config.Builds[0].Main = ""
assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`)
})
t.Run("glob", func(t *testing.T) {
ctx.Config.Builds[0].Main = "."
assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`)
@ -304,11 +306,11 @@ func exists(file string) bool {
}
func writeMainWithoutMainFunc(t *testing.T, folder string) {
writeFile(t, folder, "package main\nfunc notMain() {println(0)}")
writeFile(t, folder, "package main\nconst a = 2\nfunc notMain() {println(0)}")
}
func writeGoodMain(t *testing.T, folder string) {
writeFile(t, folder, "package main\nfunc main() {println(0)}")
writeFile(t, folder, "package main\nvar a = 1\nfunc main() {println(0)}")
}
func writeFile(t *testing.T, folder, content string) {