gitee.com/mirrors_opencollective/goreleaser@v0.45.0/pipeline/build/checkmain.go (about) 1 package build 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/parser" 7 "go/token" 8 "os" 9 10 "github.com/goreleaser/goreleaser/config" 11 "github.com/goreleaser/goreleaser/context" 12 "github.com/pkg/errors" 13 ) 14 15 func checkMain(ctx *context.Context, build config.Build) error { 16 var main = build.Main 17 if main == "" { 18 main = "." 19 } 20 stat, ferr := os.Stat(main) 21 if os.IsNotExist(ferr) { 22 return errors.Wrapf(ferr, "could not open %s", main) 23 } 24 if stat.IsDir() { 25 packs, err := parser.ParseDir(token.NewFileSet(), main, nil, 0) 26 if err != nil { 27 return errors.Wrapf(err, "failed to parse dir: %s", main) 28 } 29 for _, pack := range packs { 30 for _, file := range pack.Files { 31 if hasMain(file) { 32 return nil 33 } 34 } 35 } 36 return fmt.Errorf("build for %s does not contain a main function", build.Binary) 37 } 38 file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0) 39 if err != nil { 40 return errors.Wrapf(err, "failed to parse file: %s", build.Main) 41 } 42 if hasMain(file) { 43 return nil 44 } 45 return fmt.Errorf("build for %s does not contain a main function", build.Binary) 46 } 47 48 func hasMain(file *ast.File) bool { 49 for _, decl := range file.Decls { 50 fn, isFn := decl.(*ast.FuncDecl) 51 if !isFn { 52 continue 53 } 54 if fn.Name.Name == "main" && fn.Recv == nil { 55 return true 56 } 57 } 58 return false 59 }