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:
parent
eb48a028bd
commit
48ddd4c0eb
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ dist/
|
||||
vendor
|
||||
coverage.txt
|
||||
goreleaser
|
||||
debug.test
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user