github.com/segakazzz/buffalo@v0.16.22-0.20210119082501-1f52048d3feb/buffalo/cmd/setup.go (about)

     1  package cmd
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"strings"
     9  
    10  	"github.com/gobuffalo/events"
    11  	"github.com/gobuffalo/meta"
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  var setupOptions = struct {
    17  	verbose       bool
    18  	dropDatabases bool
    19  }{}
    20  
    21  type setupCheck func(meta.App) error
    22  
    23  var setupCmd = &cobra.Command{
    24  	Use:   "setup",
    25  	Short: "Setup a newly created, or recently checked out application.",
    26  	Long: `Setup runs through checklist to make sure dependencies are setup correctly.
    27  
    28  Asset Pipeline (if used):
    29  * Runs "npm install" or "yarn install" to install asset dependencies.
    30  
    31  Database (if used):
    32  * Runs "buffalo db create -a" to create databases.
    33  * Runs "buffalo db migrate" to run database migrations.
    34  * Runs "buffalo task db:seed" to seed the database (if the task exists).
    35  
    36  Tests:
    37  * Runs "buffalo test" to confirm the application's tests are running properly.
    38  `,
    39  	RunE: func(cmd *cobra.Command, args []string) error {
    40  		app := meta.New(".")
    41  		payload := events.Payload{
    42  			"app": app,
    43  		}
    44  		events.EmitPayload(EvtSetupStarted, payload)
    45  		for _, check := range []setupCheck{assetCheck, databaseCheck, testCheck} {
    46  			err := check(app)
    47  			if err != nil {
    48  				events.EmitError(EvtSetupErr, err, payload)
    49  				return err
    50  			}
    51  		}
    52  		events.EmitPayload(EvtSetupFinished, payload)
    53  		return nil
    54  	},
    55  }
    56  
    57  func testCheck(meta.App) error {
    58  	err := run(exec.Command("buffalo", "test"))
    59  	if err != nil {
    60  		return fmt.Errorf("We encountered the following error when trying to run your applications tests:\n%s", err)
    61  	}
    62  	return nil
    63  }
    64  
    65  func databaseCheck(app meta.App) error {
    66  	if !app.WithPop {
    67  		return nil
    68  	}
    69  	for _, check := range []setupCheck{dbCreateCheck, dbMigrateCheck, dbSeedCheck} {
    70  		err := check(app)
    71  		if err != nil {
    72  			return err
    73  		}
    74  	}
    75  	return nil
    76  }
    77  
    78  func dbCreateCheck(meta.App) error {
    79  	if setupOptions.dropDatabases {
    80  		err := run(exec.Command("buffalo", "pop", "drop", "-a"))
    81  		if err != nil {
    82  			return fmt.Errorf("We encountered an error when trying to drop your application's databases. Please check to make sure that your database server is running and that the username and passwords found in the database.yml are properly configured and set up on your database server.\n %s", err)
    83  		}
    84  	}
    85  	err := run(exec.Command("buffalo", "pop", "create", "-a"))
    86  	if err != nil {
    87  		return fmt.Errorf("We encountered an error when trying to create your application's databases. Please check to make sure that your database server is running and that the username and passwords found in the database.yml are properly configured and set up on your database server.\n %s", err)
    88  	}
    89  	return nil
    90  }
    91  
    92  func dbMigrateCheck(meta.App) error {
    93  	err := run(exec.Command("buffalo", "pop", "migrate"))
    94  	if err != nil {
    95  		return fmt.Errorf("We encountered the following error when trying to migrate your database:\n%s", err)
    96  	}
    97  	return nil
    98  }
    99  
   100  func dbSeedCheck(meta.App) error {
   101  	cmd := exec.Command("buffalo", "t", "list")
   102  	out, err := cmd.Output()
   103  	if err != nil {
   104  		// no tasks configured, so return
   105  		return nil
   106  	}
   107  	if bytes.Contains(out, []byte("db:seed")) {
   108  		err := run(exec.Command("buffalo", "task", "db:seed"))
   109  		if err != nil {
   110  			return fmt.Errorf("We encountered the following error when trying to seed your database:\n%s", err)
   111  		}
   112  	}
   113  	return nil
   114  }
   115  
   116  func assetCheck(app meta.App) error {
   117  	if !app.WithWebpack {
   118  		return nil
   119  	}
   120  	if app.WithYarn {
   121  		return yarnCheck(app)
   122  	}
   123  	return npmCheck(app)
   124  }
   125  
   126  func npmCheck(app meta.App) error {
   127  	err := nodeCheck(app)
   128  	if err != nil {
   129  		return err
   130  	}
   131  	err = run(exec.Command("npm", "install", "--no-progress"))
   132  	if err != nil {
   133  		return fmt.Errorf("We encountered the following error when trying to install your asset dependencies using npm:\n%s", err)
   134  	}
   135  	return nil
   136  }
   137  
   138  func yarnCheck(app meta.App) error {
   139  	if err := nodeCheck(app); err != nil {
   140  		return err
   141  	}
   142  	if _, err := exec.LookPath("yarnpkg"); err != nil {
   143  		err := run(exec.Command("npm", "install", "-g", "yarn"))
   144  		if err != nil {
   145  			return fmt.Errorf("This application require yarn, and we could not find it installed on your system. We tried to install it for you, but ran into the following error:\n%s", err)
   146  		}
   147  	}
   148  	if err := run(exec.Command("yarnpkg", "install", "--no-progress")); err != nil {
   149  		return fmt.Errorf("We encountered the following error when trying to install your asset dependencies using yarn:\n%s", err)
   150  	}
   151  	return nil
   152  }
   153  
   154  func nodeCheck(meta.App) error {
   155  	if _, err := exec.LookPath("node"); err != nil {
   156  		return fmt.Errorf("this application requires node, and we could not find it installed on your system please install node and try again")
   157  	}
   158  	if _, err := exec.LookPath("npm"); err != nil {
   159  		return fmt.Errorf("this application requires npm, and we could not find it installed on your system please install npm and try again")
   160  	}
   161  	return nil
   162  }
   163  
   164  func run(cmd *exec.Cmd) error {
   165  	logrus.Infof("--> %s", strings.Join(cmd.Args, " "))
   166  	cmd.Stdin = os.Stdin
   167  	cmd.Stderr = os.Stderr
   168  	cmd.Stdout = os.Stdout
   169  	return cmd.Run()
   170  }
   171  
   172  func init() {
   173  	setupCmd.Flags().BoolVarP(&setupOptions.verbose, "verbose", "v", false, "run with verbose output")
   174  	setupCmd.Flags().BoolVarP(&setupOptions.dropDatabases, "drop", "d", false, "drop existing databases")
   175  
   176  	decorate("setup", setupCmd)
   177  	RootCmd.AddCommand(setupCmd)
   178  }