mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
6d0d75fbe3
Especially for godoc
192 lines
5.0 KiB
Go
192 lines
5.0 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/ghodss/yaml"
|
|
"github.com/hasura/graphql-engine/cli"
|
|
"github.com/hasura/graphql-engine/cli/util"
|
|
"github.com/manifoldco/promptui"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
const (
|
|
defaultDirectory = "hasura"
|
|
MANIFESTS_DIR = "install-scripts"
|
|
)
|
|
|
|
// NewInitCmd is the definition for init command
|
|
func NewInitCmd(ec *cli.ExecutionContext) *cobra.Command {
|
|
opts := &initOptions{
|
|
EC: ec,
|
|
}
|
|
initCmd := &cobra.Command{
|
|
Use: "init",
|
|
Short: "Initialize directory for Hasura GraphQL Engine",
|
|
Long: "Create directories and files required for Hasura GraphQL Engine",
|
|
Example: ` # Create a directory with installation manifests:
|
|
hasura init --directory <my-directory>
|
|
|
|
# Create a directory with an endpoint configured:
|
|
hasura --directory <my-directory> --endpoint <graphql-engine-endpoint>
|
|
|
|
# See https://docs.hasura.io/0.15/graphql/manual/getting-started for more details`,
|
|
SilenceUsage: true,
|
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
return ec.Prepare()
|
|
},
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return opts.run()
|
|
},
|
|
}
|
|
|
|
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.AccessKey, "access-key", "", "access key for Hasura GraphQL Engine")
|
|
return initCmd
|
|
}
|
|
|
|
type initOptions struct {
|
|
EC *cli.ExecutionContext
|
|
|
|
Endpoint string
|
|
AccessKey string
|
|
InitDir string
|
|
}
|
|
|
|
func (o *initOptions) run() error {
|
|
if o.EC.ExecutionDirectory == "" {
|
|
o.EC.ExecutionDirectory = o.InitDir
|
|
}
|
|
|
|
// prompt for init directory if it's not set already
|
|
if len(o.InitDir) == 0 {
|
|
p := promptui.Prompt{
|
|
Label: "Name of project directory ",
|
|
Default: defaultDirectory,
|
|
}
|
|
r, err := p.Run()
|
|
if err != nil {
|
|
return handlePromptError(err)
|
|
}
|
|
if strings.TrimSpace(r) != "" {
|
|
o.EC.ExecutionDirectory = r
|
|
} else {
|
|
o.EC.ExecutionDirectory = defaultDirectory
|
|
}
|
|
}
|
|
|
|
var infoMsg string
|
|
// If endpoint is not provided, download installation manifests
|
|
if len(o.Endpoint) == 0 {
|
|
o.EC.Spin("Downloading install manifests... ")
|
|
defer o.EC.Spinner.Stop()
|
|
|
|
src, err := o.EC.InstallManifestsRepo.Download()
|
|
if err != nil {
|
|
return errors.Wrap(err, "getting manifests failed")
|
|
}
|
|
defer os.RemoveAll(src)
|
|
o.EC.Spinner.Stop()
|
|
o.EC.Logger.Info("Manifests downloaded")
|
|
|
|
dst := filepath.Join(o.EC.ExecutionDirectory, MANIFESTS_DIR)
|
|
|
|
if _, err := os.Stat(dst); err == nil {
|
|
return errors.Errorf("directory '%s' already exist", dst)
|
|
}
|
|
|
|
o.EC.Spin("Creating manifests in current directory... ")
|
|
defer o.EC.Spinner.Stop()
|
|
err = os.MkdirAll(filepath.Dir(dst), os.ModePerm)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error creating setup directories")
|
|
}
|
|
|
|
// copy manifests to manifests directory (dst)
|
|
err = util.CopyDir(src, dst)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error copying files")
|
|
}
|
|
o.EC.Spinner.Stop()
|
|
infoMsg = fmt.Sprintf("manifests created at [%s]", dst)
|
|
|
|
} else {
|
|
|
|
// if endpoint is set, just 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:
|
|
|
|
cd %s
|
|
%s console
|
|
`, o.EC.ExecutionDirectory, o.EC.CMDName)
|
|
}
|
|
|
|
// create other required files, like config.yaml, migrations directory
|
|
err := o.createFiles()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
o.EC.Logger.Info(infoMsg)
|
|
return nil
|
|
}
|
|
|
|
// createFiles creates files required by the CLI in the ExecutionDirectory
|
|
func (o *initOptions) createFiles() error {
|
|
// create the directory
|
|
err := os.MkdirAll(filepath.Dir(o.EC.ExecutionDirectory), os.ModePerm)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error creating setup directories")
|
|
}
|
|
// set config object
|
|
config := &cli.HasuraGraphQLConfig{
|
|
Endpoint: "http://localhost:8080",
|
|
}
|
|
if o.Endpoint != "" {
|
|
config.Endpoint = o.Endpoint
|
|
}
|
|
if o.AccessKey != "" {
|
|
config.AccessKey = o.AccessKey
|
|
}
|
|
|
|
// write the config file
|
|
data, err := yaml.Marshal(config)
|
|
if err != nil {
|
|
return errors.Wrap(err, "cannot convert to yaml")
|
|
}
|
|
o.EC.ConfigFile = filepath.Join(o.EC.ExecutionDirectory, "config.yaml")
|
|
err = ioutil.WriteFile(o.EC.ConfigFile, data, 0644)
|
|
if err != nil {
|
|
return errors.Wrap(err, "cannot write config file")
|
|
}
|
|
|
|
// create migrations directory
|
|
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")
|
|
}
|