diff --git a/generate/config.go b/generate/config.go new file mode 100644 index 0000000..1ebf520 --- /dev/null +++ b/generate/config.go @@ -0,0 +1,76 @@ +package generate + +import ( + "fmt" + "io/ioutil" + "path/filepath" + + "gopkg.in/yaml.v2" +) + +var defaultConfig = &Config{ + Schema: "schema.graphql", + Queries: "queries.graphql", + Generated: "generated.go", +} + +type Config struct { + // The package name for the output code; defaults to the directory name of + // Generated + Package string `yaml:"package"` + // The filename with the GraphQL schema (in SDL format); defaults to + // schema.graphql + // TODO: allow other formats + // TODO: allow URLs + Schema string `yaml:"schema"` + // The filename with the queries; defaults to queries.graphql + Queries string `yaml:"queries"` + // The filename to which to write the generated code; defaults to + // generated.go + Generated string `yaml:"generated"` +} + +func (c *Config) ValidateAndFillDefaults() error { + if c.Schema == "" { + c.Schema = defaultConfig.Schema + } + if c.Queries == "" { + c.Queries = defaultConfig.Queries + } + if c.Generated == "" { + c.Generated = defaultConfig.Generated + } + + if c.Package == "" { + abs, err := filepath.Abs(c.Generated) + if err != nil { + return fmt.Errorf("unable to guess package-name: %v", err) + } + + base := filepath.Base(abs) + // TODO: remove/replace bad chars, make sure there's something left? + c.Package = base + } + + return nil +} + +func ReadAndValidateConfig(filename string) (*Config, error) { + text, err := ioutil.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("unreadable config file %v: %v", filename, err) + } + + var config Config + err = yaml.Unmarshal(text, config) + if err != nil { + return nil, fmt.Errorf("invalid config file %v: %v", filename, err) + } + + err = config.ValidateAndFillDefaults() + if err != nil { + return nil, fmt.Errorf("invalid config file %v: %v", filename, err) + } + + return &config, nil +} diff --git a/generate/generate.go b/generate/generate.go index 9595589..b11512e 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -90,7 +90,6 @@ func fromASTOperation(op *ast.OperationDefinition, schema *ast.Schema) operation } func Generate(schema *ast.Schema, document *ast.QueryDocument) ([]byte, error) { - // TODO: this should probably get factored out operations := make([]operation, len(document.Operations)) for i, op := range document.Operations { operations[i] = fromASTOperation(op, schema) diff --git a/generate/main.go b/generate/main.go index f69b9c7..d73110e 100644 --- a/generate/main.go +++ b/generate/main.go @@ -2,30 +2,27 @@ package generate import ( "fmt" - "io" "os" ) -func outputWriter(filename string) (io.Writer, error) { - if filename == "-" { - return os.Stdout, nil - } - - f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return nil, fmt.Errorf("could not open generated file %v: %v", - filename, err) - } - return f, nil -} - -func ParseGenerateAndWrite(specFilename, schemaFilename string, out io.Writer) error { - schema, err := getSchema(schemaFilename) +func parseGenerateAndWrite(configFilename string) error { + config, err := ReadAndValidateConfig(configFilename) if err != nil { return err } - document, err := getAndValidateQueries(specFilename, schema) + out, err := os.OpenFile(config.Generated, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return fmt.Errorf("could not open generated file %v: %v", + config.Generated, err) + } + + schema, err := getSchema(config.Schema) + if err != nil { + return err + } + + document, err := getAndValidateQueries(config.Queries, schema) if err != nil { return err } @@ -48,16 +45,10 @@ func Main() { } }() - if len(os.Args) != 4 { - err = fmt.Errorf("usage: %s queries.graphql schema.graphql generated.go", - os.Args[0]) + if len(os.Args) != 2 { + err = fmt.Errorf("usage: %s genql.yaml", os.Args[0]) return } - out, err := outputWriter(os.Args[3]) - if err != nil { - return - } - - err = ParseGenerateAndWrite(os.Args[1], os.Args[2], out) + err = parseGenerateAndWrite(os.Args[1]) } diff --git a/go.mod b/go.mod index 35533c5..d35f243 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,5 @@ require ( github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f // indirect github.com/vektah/gqlparser v1.2.0 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect + gopkg.in/yaml.v2 v2.2.2 ) diff --git a/graphql/client.go b/graphql/client.go index eacf1e2..8fc76fb 100644 --- a/graphql/client.go +++ b/graphql/client.go @@ -30,6 +30,7 @@ type payload struct { } func (client *Client) MakeRequest(ctx context.Context, query string, retval interface{}, variables map[string]interface{}) error { + // TODO: streaming reads and writes body, err := json.Marshal(payload{ Query: query, Variables: variables,