graphql-engine/cli/commands/init.go

165 lines
4.2 KiB
Go
Raw Normal View History

2018-06-24 16:40:48 +03:00
package commands
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/ghodss/yaml"
"github.com/hasura/graphql-engine/cli"
"github.com/manifoldco/promptui"
"github.com/pkg/errors"
"github.com/spf13/cobra"
2019-01-28 16:55:28 +03:00
"github.com/spf13/viper"
2018-06-24 16:40:48 +03:00
)
const (
defaultDirectory = "hasura"
)
2018-06-27 15:04:09 +03:00
// NewInitCmd is the definition for init command
2018-06-24 16:40:48 +03:00
func NewInitCmd(ec *cli.ExecutionContext) *cobra.Command {
opts := &initOptions{
EC: ec,
}
initCmd := &cobra.Command{
Use: "init",
Short: "Initialize directory for Hasura GraphQL Engine migrations",
Long: "Create directories and files required for enabling migrations on Hasura GraphQL Engine",
Example: ` # Create a directory to store migrations
hasura init
2018-06-24 16:40:48 +03:00
# Now, edit <my-directory>/config.yaml to add endpoint and admin secret
2018-06-24 16:47:01 +03:00
# Create a directory with endpoint and admin secret configured:
hasura init --directory <my-project> --endpoint https://my-graphql-engine.com --admin-secret adminsecretkey
# See https://docs.hasura.io/1.0/graphql/manual/migrations/index.html for more details`,
2018-06-24 16:40:48 +03:00
SilenceUsage: true,
PreRun: func(cmd *cobra.Command, args []string) {
2019-01-28 16:55:28 +03:00
ec.Viper = viper.New()
2018-06-27 15:04:09 +03:00
},
2018-06-24 16:40:48 +03:00
RunE: func(cmd *cobra.Command, args []string) error {
return opts.run()
2018-06-24 16:40:48 +03:00
},
}
f := initCmd.Flags()
f.StringVar(&opts.InitDir, "directory", "", "name of directory where files will be created")
f.StringVar(&opts.Endpoint, "endpoint", "", "http(s) endpoint for Hasura GraphQL Engine")
f.StringVar(&opts.AdminSecret, "admin-secret", "", "admin secret for Hasura GraphQL Engine")
f.StringVar(&opts.AdminSecret, "access-key", "", "access key for Hasura GraphQL Engine")
f.MarkDeprecated("access-key", "use --admin-secret instead")
2018-06-24 16:40:48 +03:00
return initCmd
}
type initOptions struct {
EC *cli.ExecutionContext
Endpoint string
AdminSecret string
InitDir string
2018-06-24 16:40:48 +03:00
}
func (o *initOptions) run() error {
var dir string
2018-06-27 15:04:09 +03:00
// prompt for init directory if it's not set already
if o.InitDir == "" {
2018-06-24 16:40:48 +03:00
p := promptui.Prompt{
Label: "Name of project directory ",
Default: defaultDirectory,
}
r, err := p.Run()
if err != nil {
return handlePromptError(err)
}
if strings.TrimSpace(r) != "" {
dir = r
2018-06-24 16:40:48 +03:00
} else {
dir = defaultDirectory
2018-06-24 16:40:48 +03:00
}
} else {
dir = o.InitDir
}
if o.EC.ExecutionDirectory == "" {
o.EC.ExecutionDirectory = dir
} else {
o.EC.ExecutionDirectory = filepath.Join(o.EC.ExecutionDirectory, dir)
2018-06-24 16:40:48 +03:00
}
var infoMsg string
2018-06-27 15:04:09 +03:00
// create the execution directory
if _, err := os.Stat(o.EC.ExecutionDirectory); err == nil {
return errors.Errorf("directory '%s' already exist", o.EC.ExecutionDirectory)
}
err := os.MkdirAll(o.EC.ExecutionDirectory, os.ModePerm)
if err != nil {
return errors.Wrap(err, "error creating setup directories")
}
infoMsg = fmt.Sprintf(`directory created. execute the following commands to continue:
2018-06-24 16:40:48 +03:00
cd %s
hasura console
`, o.EC.ExecutionDirectory)
2018-06-24 16:40:48 +03:00
2018-06-27 15:04:09 +03:00
// create other required files, like config.yaml, migrations directory
err = o.createFiles()
2018-06-24 16:40:48 +03:00
if err != nil {
return err
}
2018-06-27 15:04:09 +03:00
o.EC.Logger.Info(infoMsg)
2018-06-24 16:40:48 +03:00
return nil
}
2018-06-27 15:04:09 +03:00
// createFiles creates files required by the CLI in the ExecutionDirectory
2018-06-24 16:40:48 +03:00
func (o *initOptions) createFiles() error {
2018-06-27 15:04:09 +03:00
// create the directory
2018-06-24 16:40:48 +03:00
err := os.MkdirAll(filepath.Dir(o.EC.ExecutionDirectory), os.ModePerm)
if err != nil {
return errors.Wrap(err, "error creating setup directories")
}
2018-06-27 15:04:09 +03:00
// set config object
config := &cli.ServerConfig{
2018-06-24 16:40:48 +03:00
Endpoint: "http://localhost:8080",
}
2018-06-27 15:04:09 +03:00
if o.Endpoint != "" {
2018-06-24 16:40:48 +03:00
config.Endpoint = o.Endpoint
}
if o.AdminSecret != "" {
config.AdminSecret = o.AdminSecret
2018-06-27 15:04:09 +03:00
}
2018-06-24 16:40:48 +03:00
2018-06-27 15:04:09 +03:00
// write the config file
2018-06-24 16:40:48 +03:00
data, err := yaml.Marshal(config)
if err != nil {
return errors.Wrap(err, "cannot convert to yaml")
}
2018-06-27 15:04:09 +03:00
o.EC.ConfigFile = filepath.Join(o.EC.ExecutionDirectory, "config.yaml")
2018-06-24 16:40:48 +03:00
err = ioutil.WriteFile(o.EC.ConfigFile, data, 0644)
if err != nil {
return errors.Wrap(err, "cannot write config file")
}
2018-06-27 15:04:09 +03:00
// create migrations directory
2018-06-24 16:40:48 +03:00
o.EC.MigrationDir = filepath.Join(o.EC.ExecutionDirectory, "migrations")
err = os.MkdirAll(o.EC.MigrationDir, os.ModePerm)
if err != nil {
return errors.Wrap(err, "cannot write migration directory")
}
return nil
}
func handlePromptError(err error) error {
if err == promptui.ErrInterrupt {
return errors.New("cancelled by user")
}
return errors.Wrap(err, "prompt failed")
}