github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/cmd/root.go (about)

     1  package cmd
     2  
     3  import (
     4  	_ "embed"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/JarrahG/buffalocli/internal/cmd/build"
    10  	"github.com/JarrahG/buffalocli/internal/cmd/destroy"
    11  	"github.com/JarrahG/buffalocli/internal/cmd/dev"
    12  	"github.com/JarrahG/buffalocli/internal/cmd/fix"
    13  	"github.com/JarrahG/buffalocli/internal/cmd/generate"
    14  	"github.com/JarrahG/buffalocli/internal/cmd/info"
    15  	"github.com/JarrahG/buffalocli/internal/cmd/new"
    16  	cmdplugins "github.com/JarrahG/buffalocli/internal/cmd/plugins"
    17  	"github.com/JarrahG/buffalocli/internal/cmd/routes"
    18  	"github.com/JarrahG/buffalocli/internal/cmd/setup"
    19  	"github.com/JarrahG/buffalocli/internal/cmd/task"
    20  	"github.com/JarrahG/buffalocli/internal/cmd/test"
    21  	"github.com/JarrahG/buffalocli/internal/cmd/version"
    22  	"github.com/JarrahG/buffalocli/internal/plugins"
    23  	"github.com/sirupsen/logrus"
    24  	"github.com/spf13/cobra"
    25  )
    26  
    27  const (
    28  	dbNotFound  = `unknown command "db"`
    29  	popNotFound = `unknown command "pop"`
    30  )
    31  
    32  var (
    33  	anywhereCommands = []string{"completion", "help", "info", "new", "version"}
    34  
    35  	//go:embed popinstructions.txt
    36  	popInstallInstructions string
    37  )
    38  
    39  // Execute adds all child commands to the root command sets flags appropriately.
    40  // This is called by main.main(). It only needs to happen once to the rootCmd.
    41  func Execute() {
    42  	rootCmd := cmd()
    43  	err := rootCmd.Execute()
    44  	if err == nil {
    45  		return
    46  	}
    47  
    48  	if strings.Contains(err.Error(), dbNotFound) || strings.Contains(err.Error(), popNotFound) {
    49  		logrus.Errorf(popInstallInstructions)
    50  		os.Exit(-1)
    51  	}
    52  	logrus.Errorf("Error: %s", err)
    53  	if strings.Contains(err.Error(), dbNotFound) || strings.Contains(err.Error(), popNotFound) {
    54  		fmt.Println(popInstallInstructions)
    55  		os.Exit(-1)
    56  	}
    57  	os.Exit(-1)
    58  }
    59  
    60  // preRunCheck confirms that the command being called can be
    61  // invoked within the current folder. Some commands like generators
    62  // require to be called from the root of the project.
    63  func preRunCheck(cmd *cobra.Command, args []string) error {
    64  	if err := plugins.Load(); err != nil {
    65  		return err
    66  	}
    67  
    68  	cmdName := cmd.Name()
    69  	if cmd.Parent() != cmd.Root() {
    70  		// e.g. `completion` for `buffalo completion bash` instead of `bash`
    71  		cmdName = cmd.Parent().Name()
    72  	}
    73  
    74  	for _, freeCmd := range anywhereCommands {
    75  		if freeCmd == cmdName {
    76  			return nil
    77  		}
    78  	}
    79  
    80  	// check if command is being run from inside a buffalo project
    81  	_, err := os.Stat(".buffalo.dev.yml")
    82  	if err != nil {
    83  		return fmt.Errorf("you need to be inside your buffalo project path to run this command")
    84  	}
    85  
    86  	return nil
    87  }
    88  
    89  func cmd() *cobra.Command {
    90  	rootCmd := &cobra.Command{
    91  		Use:               "buffalo",
    92  		Short:             "Build Buffalo applications with ease",
    93  		PersistentPreRunE: preRunCheck,
    94  		TraverseChildren:  true,
    95  		SilenceErrors:     true,
    96  	}
    97  
    98  	newCmd := new.Cmd()
    99  	setupCmd := setup.Cmd()
   100  	generateCmd := generate.Cmd()
   101  	destroyCmd := destroy.Cmd()
   102  	versionCmd := version.Cmd()
   103  	testCmd := test.Cmd()
   104  	devCmd := dev.Cmd()
   105  	taskCmd := task.Cmd()
   106  	routesCmd := routes.Cmd()
   107  
   108  	decorate("new", newCmd)
   109  	decorate("info", rootCmd)
   110  	decorate("fix", rootCmd)
   111  	decorate("update", rootCmd)
   112  	decorate("setup", setupCmd)
   113  	decorate("generate", generateCmd)
   114  	decorate("destroy", destroyCmd)
   115  	decorate("version", versionCmd)
   116  	decorate("test", testCmd)
   117  	decorate("dev", devCmd)
   118  	decorate("task", taskCmd)
   119  	decorate("routes", routesCmd)
   120  
   121  	rootCmd.AddCommand(newCmd)
   122  	rootCmd.AddCommand(build.Cmd())
   123  	rootCmd.AddCommand(cmdplugins.PluginsCmd)
   124  	rootCmd.AddCommand(info.Cmd())
   125  	rootCmd.AddCommand(setupCmd)
   126  	rootCmd.AddCommand(generateCmd)
   127  	rootCmd.AddCommand(fix.Cmd())
   128  	rootCmd.AddCommand(destroyCmd)
   129  	rootCmd.AddCommand(versionCmd)
   130  	rootCmd.AddCommand(testCmd)
   131  	rootCmd.AddCommand(devCmd)
   132  	rootCmd.AddCommand(taskCmd)
   133  	rootCmd.AddCommand(routesCmd)
   134  
   135  	decorate("root", rootCmd)
   136  
   137  	return rootCmd
   138  }