init.go

  1package cmd
  2
  3import (
  4	"bytes"
  5	"fmt"
  6	"io/ioutil"
  7	"os"
  8	"strings"
  9
 10	"github.com/99designs/gqlgen/codegen"
 11	"github.com/pkg/errors"
 12	"github.com/urfave/cli"
 13	"gopkg.in/yaml.v2"
 14)
 15
 16var configComment = `
 17# .gqlgen.yml example
 18#
 19# Refer to https://gqlgen.com/config/
 20# for detailed .gqlgen.yml documentation.
 21`
 22
 23var schemaDefault = `
 24# GraphQL schema example
 25#
 26# https://gqlgen.com/getting-started/
 27
 28type Todo {
 29  id: ID!
 30  text: String!
 31  done: Boolean!
 32  user: User!
 33}
 34
 35type User {
 36  id: ID!
 37  name: String!
 38}
 39
 40type Query {
 41  todos: [Todo!]!
 42}
 43
 44input NewTodo {
 45  text: String!
 46  userId: String!
 47}
 48
 49type Mutation {
 50  createTodo(input: NewTodo!): Todo!
 51}
 52`
 53
 54var initCmd = cli.Command{
 55	Name:  "init",
 56	Usage: "create a new gqlgen project",
 57	Flags: []cli.Flag{
 58		cli.BoolFlag{Name: "verbose, v", Usage: "show logs"},
 59		cli.StringFlag{Name: "config, c", Usage: "the config filename"},
 60		cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server/server.go"},
 61		cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "schema.graphql"},
 62	},
 63	Action: func(ctx *cli.Context) {
 64		initSchema(ctx.String("schema"))
 65		config := initConfig(ctx)
 66
 67		GenerateGraphServer(config, ctx.String("server"))
 68	},
 69}
 70
 71func GenerateGraphServer(config *codegen.Config, serverFilename string) {
 72	for _, filename := range config.SchemaFilename {
 73		schemaRaw, err := ioutil.ReadFile(filename)
 74		if err != nil {
 75			fmt.Fprintln(os.Stderr, "unable to open schema: "+err.Error())
 76			os.Exit(1)
 77		}
 78		config.SchemaStr[filename] = string(schemaRaw)
 79	}
 80
 81	if err := config.Check(); err != nil {
 82		fmt.Fprintln(os.Stderr, "invalid config format: "+err.Error())
 83		os.Exit(1)
 84	}
 85
 86	if err := codegen.Generate(*config); err != nil {
 87		fmt.Fprintln(os.Stderr, err.Error())
 88		os.Exit(1)
 89	}
 90
 91	if err := codegen.GenerateServer(*config, serverFilename); err != nil {
 92		fmt.Fprintln(os.Stderr, err.Error())
 93		os.Exit(1)
 94	}
 95
 96	fmt.Fprintf(os.Stdout, "Exec \"go run ./%s\" to start GraphQL server\n", serverFilename)
 97}
 98
 99func initConfig(ctx *cli.Context) *codegen.Config {
100	var config *codegen.Config
101	var err error
102	configFilename := ctx.String("config")
103	if configFilename != "" {
104		config, err = codegen.LoadConfig(configFilename)
105	} else {
106		config, err = codegen.LoadConfigFromDefaultLocations()
107	}
108
109	if config != nil {
110		fmt.Fprintf(os.Stderr, "init failed: a configuration file already exists at %s\n", config.FilePath)
111		os.Exit(1)
112	}
113
114	if !os.IsNotExist(errors.Cause(err)) {
115		fmt.Fprintln(os.Stderr, err.Error())
116		os.Exit(1)
117	}
118
119	if configFilename == "" {
120		configFilename = "gqlgen.yml"
121	}
122	config = codegen.DefaultConfig()
123
124	config.Resolver = codegen.PackageConfig{
125		Filename: "resolver.go",
126		Type:     "Resolver",
127	}
128
129	var buf bytes.Buffer
130	buf.WriteString(strings.TrimSpace(configComment))
131	buf.WriteString("\n\n")
132	{
133		var b []byte
134		b, err = yaml.Marshal(config)
135		if err != nil {
136			fmt.Fprintln(os.Stderr, "unable to marshal yaml: "+err.Error())
137			os.Exit(1)
138		}
139		buf.Write(b)
140	}
141
142	err = ioutil.WriteFile(configFilename, buf.Bytes(), 0644)
143	if err != nil {
144		fmt.Fprintln(os.Stderr, "unable to write config file: "+err.Error())
145		os.Exit(1)
146	}
147
148	return config
149}
150
151func initSchema(schemaFilename string) {
152	_, err := os.Stat(schemaFilename)
153	if !os.IsNotExist(err) {
154		return
155	}
156
157	err = ioutil.WriteFile(schemaFilename, []byte(strings.TrimSpace(schemaDefault)), 0644)
158	if err != nil {
159		fmt.Fprintln(os.Stderr, "unable to write schema file: "+err.Error())
160		os.Exit(1)
161	}
162}