mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-17 20:47:50 +02:00
fix: accepting non-main.go files as well
Previous code was handling only main.go as the main build file, but the main function can actually be in any file. Now, if a specific file (*.go) is passed, that file will be checked for the main function. If a folder is passed, the package will be scanned for the main function.
This commit is contained in:
parent
13d2bca06f
commit
9a9b9373a2
@ -45,7 +45,17 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
}
|
||||
|
||||
func checkMain(ctx *context.Context, build config.Build) error {
|
||||
var dir = strings.Replace(build.Main, "main.go", "", -1)
|
||||
if strings.HasSuffix(build.Main, ".go") {
|
||||
file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse file: %s", build.Main)
|
||||
}
|
||||
if !hasMain(file) {
|
||||
return fmt.Errorf("build for %s does not contain a main function", build.Binary)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
var dir = build.Main
|
||||
if dir == "" {
|
||||
dir = "."
|
||||
}
|
||||
@ -55,21 +65,27 @@ func checkMain(ctx *context.Context, build config.Build) error {
|
||||
}
|
||||
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
|
||||
}
|
||||
if hasMain(file) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("build for %s does not contain a main function", build.Binary)
|
||||
}
|
||||
|
||||
func hasMain(file *ast.File) bool {
|
||||
for _, decl := range file.Decls {
|
||||
fn, isFn := decl.(*ast.FuncDecl)
|
||||
if !isFn {
|
||||
continue
|
||||
}
|
||||
if fn.Name.Name == "main" && fn.Recv == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func runPipeOnBuild(ctx *context.Context, build config.Build) error {
|
||||
if err := runHook(build.Env, build.Hooks.Pre); err != nil {
|
||||
return errors.Wrap(err, "pre hook failed")
|
||||
|
@ -277,7 +277,7 @@ func TestRunPipeWithouMainFunc(t *testing.T) {
|
||||
})
|
||||
t.Run("not main.go", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = "foo.go"
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `failed to parse dir: foo.go: open foo.go: no such file or directory`)
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `failed to parse file: foo.go: open foo.go: no such file or directory`)
|
||||
})
|
||||
t.Run("glob", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = "."
|
||||
@ -289,23 +289,62 @@ func TestRunPipeWithouMainFunc(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
|
||||
folder, back := testlib.Mktmp(t)
|
||||
defer back()
|
||||
assert.NoError(t, ioutil.WriteFile(
|
||||
filepath.Join(folder, "foo.go"),
|
||||
[]byte("package main\nfunc main() {println(0)}"),
|
||||
0644,
|
||||
))
|
||||
var config = config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
Binary: "foo",
|
||||
Hooks: config.Hooks{},
|
||||
Goos: []string{
|
||||
runtime.GOOS,
|
||||
},
|
||||
Goarch: []string{
|
||||
runtime.GOARCH,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var ctx = context.New(config)
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = ""
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
})
|
||||
t.Run("foo.go", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = "foo.go"
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
})
|
||||
t.Run("glob", func(t *testing.T) {
|
||||
ctx.Config.Builds[0].Main = "."
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
func exists(file string) bool {
|
||||
_, err := os.Stat(file)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func writeMainWithoutMainFunc(t *testing.T, folder string) {
|
||||
writeFile(t, folder, "package main\nconst a = 2\nfunc notMain() {println(0)}")
|
||||
assert.NoError(t, ioutil.WriteFile(
|
||||
filepath.Join(folder, "main.go"),
|
||||
[]byte("package main\nconst a = 2\nfunc notMain() {println(0)}"),
|
||||
0644,
|
||||
))
|
||||
}
|
||||
|
||||
func writeGoodMain(t *testing.T, folder string) {
|
||||
writeFile(t, folder, "package main\nvar a = 1\nfunc main() {println(0)}")
|
||||
}
|
||||
|
||||
func writeFile(t *testing.T, folder, content string) {
|
||||
assert.NoError(t, ioutil.WriteFile(
|
||||
filepath.Join(folder, "main.go"), []byte(content), 0644),
|
||||
)
|
||||
filepath.Join(folder, "main.go"),
|
||||
[]byte("package main\nvar a = 1\nfunc main() {println(0)}"),
|
||||
0644,
|
||||
))
|
||||
}
|
||||
|
||||
func assertContainsError(t *testing.T, err error, s string) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user