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