github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/cmd/root.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  
     7  	"github.com/apex/log"
     8  	"github.com/apex/log/handlers/cli"
     9  	"github.com/fatih/color"
    10  	"github.com/spf13/cobra"
    11  )
    12  
    13  func Execute(version string, exit func(int), args []string) {
    14  	// enable colored output on travis
    15  	if os.Getenv("CI") != "" {
    16  		color.NoColor = false
    17  	}
    18  	log.SetHandler(cli.Default)
    19  	newRootCmd(version, exit).Execute(args)
    20  }
    21  
    22  func (cmd *rootCmd) Execute(args []string) {
    23  	cmd.cmd.SetArgs(args)
    24  
    25  	if shouldPrependRelease(cmd.cmd, args) {
    26  		cmd.cmd.SetArgs(append([]string{"release"}, args...))
    27  	}
    28  
    29  	if err := cmd.cmd.Execute(); err != nil {
    30  		code := 1
    31  		msg := "command failed"
    32  		eerr := &exitError{}
    33  		if errors.As(err, &eerr) {
    34  			code = eerr.code
    35  			if eerr.details != "" {
    36  				msg = eerr.details
    37  			}
    38  		}
    39  		log.WithError(err).Error(msg)
    40  		cmd.exit(code)
    41  	}
    42  }
    43  
    44  type rootCmd struct {
    45  	cmd   *cobra.Command
    46  	debug bool
    47  	exit  func(int)
    48  }
    49  
    50  func newRootCmd(version string, exit func(int)) *rootCmd {
    51  	root := &rootCmd{
    52  		exit: exit,
    53  	}
    54  	cmd := &cobra.Command{
    55  		Use:   "goreleaser",
    56  		Short: "Deliver Go binaries as fast and easily as possible",
    57  		Long: `GoReleaser is a release automation tool for Go projects.
    58  Its goal is to simplify the build, release and publish steps while providing
    59  variant customization options for all steps.
    60  
    61  GoReleaser is built for CI tools, you only need to download and execute it
    62  in your build script. Of course, you can also install it locally if you wish.
    63  
    64  You can also customize your entire release process through a
    65  single .goreleaser.yml file.
    66  `,
    67  		Version:       version,
    68  		SilenceUsage:  true,
    69  		SilenceErrors: true,
    70  		Args:          cobra.NoArgs,
    71  		PersistentPreRun: func(cmd *cobra.Command, args []string) {
    72  			if root.debug {
    73  				log.SetLevel(log.DebugLevel)
    74  				log.Debug("debug logs enabled")
    75  			}
    76  		},
    77  	}
    78  
    79  	cmd.PersistentFlags().BoolVar(&root.debug, "debug", false, "Enable debug mode")
    80  	cmd.AddCommand(
    81  		newBuildCmd().cmd,
    82  		newReleaseCmd().cmd,
    83  		newCheckCmd().cmd,
    84  		newInitCmd().cmd,
    85  		newDocsCmd().cmd,
    86  	)
    87  
    88  	root.cmd = cmd
    89  	return root
    90  }
    91  
    92  func shouldPrependRelease(cmd *cobra.Command, args []string) bool {
    93  	// find current cmd, if its not root, it means the user actively
    94  	// set a command, so let it go
    95  	xmd, _, _ := cmd.Find(args)
    96  	if xmd != cmd {
    97  		return false
    98  	}
    99  
   100  	// allow help and the two __complete commands.
   101  	if len(args) > 0 && (args[0] == "help" || args[0] == "completion" ||
   102  		args[0] == cobra.ShellCompRequestCmd || args[0] == cobra.ShellCompNoDescRequestCmd) {
   103  		return false
   104  	}
   105  
   106  	// if we have != 1 args, assume its a release
   107  	if len(args) != 1 {
   108  		return true
   109  	}
   110  
   111  	// given that its 1, check if its one of the valid standalone flags
   112  	// for the root cmd
   113  	for _, s := range []string{"-h", "--help", "-v", "--version"} {
   114  		if s == args[0] {
   115  			// if it is, we should run the root cmd
   116  			return false
   117  		}
   118  	}
   119  
   120  	// otherwise, we should probably prepend release
   121  	return true
   122  }