git.sr.ht/~sircmpwn/gqlgen@v0.0.0-20200522192042-c84d29a1c940/cmd/init.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "fmt" 6 "html/template" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "strings" 11 12 "git.sr.ht/~sircmpwn/gqlgen/api" 13 "git.sr.ht/~sircmpwn/gqlgen/codegen/config" 14 "git.sr.ht/~sircmpwn/gqlgen/internal/code" 15 "git.sr.ht/~sircmpwn/gqlgen/plugin/servergen" 16 "github.com/urfave/cli/v2" 17 ) 18 19 var configTemplate = template.Must(template.New("name").Parse( 20 `# Where are all the schema files located? globs are supported eg src/**/*.graphqls 21 schema: 22 - graph/*.graphqls 23 24 # Where should the generated server code go? 25 exec: 26 filename: graph/generated/generated.go 27 package: generated 28 29 # Uncomment to enable federation 30 # federation: 31 # filename: graph/generated/federation.go 32 # package: generated 33 34 # Where should any generated models go? 35 model: 36 filename: graph/model/models_gen.go 37 package: model 38 39 # Where should the resolver implementations go? 40 resolver: 41 layout: follow-schema 42 dir: graph 43 package: graph 44 45 # Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models 46 # struct_tag: json 47 48 # Optional: turn on to use []Thing instead of []*Thing 49 # omit_slice_element_pointers: false 50 51 # Optional: set to speed up generation time by not performing a final validation pass. 52 # skip_validation: true 53 54 # gqlgen will search for any type names in the schema in these go packages 55 # if they match it will use them, otherwise it will generate them. 56 autobind: 57 - "{{.}}/graph/model" 58 59 # This section declares type mapping between the GraphQL and go type systems 60 # 61 # The first line in each type will be used as defaults for resolver arguments and 62 # modelgen, the others will be allowed when binding to fields. Configure them to 63 # your liking 64 models: 65 ID: 66 model: 67 - git.sr.ht/~sircmpwn/gqlgen/graphql.ID 68 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int 69 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int64 70 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int32 71 Int: 72 model: 73 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int 74 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int64 75 - git.sr.ht/~sircmpwn/gqlgen/graphql.Int32 76 `)) 77 78 var schemaDefault = `# GraphQL schema example 79 # 80 # https://gqlgen.com/getting-started/ 81 82 type Todo { 83 id: ID! 84 text: String! 85 done: Boolean! 86 user: User! 87 } 88 89 type User { 90 id: ID! 91 name: String! 92 } 93 94 type Query { 95 todos: [Todo!]! 96 } 97 98 input NewTodo { 99 text: String! 100 userId: String! 101 } 102 103 type Mutation { 104 createTodo(input: NewTodo!): Todo! 105 } 106 ` 107 108 var initCmd = &cli.Command{ 109 Name: "init", 110 Usage: "create a new gqlgen project", 111 Flags: []cli.Flag{ 112 &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, 113 &cli.StringFlag{Name: "config, c", Usage: "the config filename"}, 114 &cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server.go"}, 115 &cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "graph/schema.graphqls"}, 116 }, 117 Action: func(ctx *cli.Context) error { 118 configFilename := ctx.String("config") 119 serverFilename := ctx.String("server") 120 121 pkgName := code.ImportPathForDir(".") 122 if pkgName == "" { 123 return fmt.Errorf("unable to determine import path for current directory, you probably need to run go mod init first") 124 } 125 126 if err := initSchema(ctx.String("schema")); err != nil { 127 return err 128 } 129 if !configExists(configFilename) { 130 if err := initConfig(configFilename, pkgName); err != nil { 131 return err 132 } 133 } 134 135 GenerateGraphServer(serverFilename) 136 return nil 137 }, 138 } 139 140 func GenerateGraphServer(serverFilename string) { 141 cfg, err := config.LoadConfigFromDefaultLocations() 142 if err != nil { 143 fmt.Fprintln(os.Stderr, err.Error()) 144 } 145 146 if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { 147 fmt.Fprintln(os.Stderr, err.Error()) 148 } 149 150 fmt.Fprintf(os.Stdout, "Exec \"go run ./%s\" to start GraphQL server\n", serverFilename) 151 } 152 153 func configExists(configFilename string) bool { 154 var cfg *config.Config 155 156 if configFilename != "" { 157 cfg, _ = config.LoadConfig(configFilename) 158 } else { 159 cfg, _ = config.LoadConfigFromDefaultLocations() 160 } 161 return cfg != nil 162 } 163 164 func initConfig(configFilename string, pkgName string) error { 165 if configFilename == "" { 166 configFilename = "gqlgen.yml" 167 } 168 169 if err := os.MkdirAll(filepath.Dir(configFilename), 0755); err != nil { 170 return fmt.Errorf("unable to create config dir: " + err.Error()) 171 } 172 173 var buf bytes.Buffer 174 if err := configTemplate.Execute(&buf, pkgName); err != nil { 175 panic(err) 176 } 177 178 if err := ioutil.WriteFile(configFilename, buf.Bytes(), 0644); err != nil { 179 return fmt.Errorf("unable to write cfg file: " + err.Error()) 180 } 181 182 return nil 183 } 184 185 func initSchema(schemaFilename string) error { 186 _, err := os.Stat(schemaFilename) 187 if !os.IsNotExist(err) { 188 return nil 189 } 190 191 if err := os.MkdirAll(filepath.Dir(schemaFilename), 0755); err != nil { 192 return fmt.Errorf("unable to create schema dir: " + err.Error()) 193 } 194 195 if err = ioutil.WriteFile(schemaFilename, []byte(strings.TrimSpace(schemaDefault)), 0644); err != nil { 196 return fmt.Errorf("unable to write schema file: " + err.Error()) 197 } 198 return nil 199 }