allow multiple queries-files
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# These are the defaults, and are just included to be explicit.
|
# These are the defaults, and are just included to be explicit.
|
||||||
package: example
|
package: example
|
||||||
schema: schema.graphql
|
schema: schema.graphql
|
||||||
queries: queries.graphql
|
queries:
|
||||||
|
- queries.graphql
|
||||||
generated: generated.go
|
generated: generated.go
|
||||||
use_context: true
|
use_context: true
|
||||||
|
|||||||
+6
-5
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
var defaultConfig = &Config{
|
var defaultConfig = &Config{
|
||||||
Schema: "schema.graphql",
|
Schema: "schema.graphql",
|
||||||
Queries: "queries.graphql",
|
Queries: []string{"queries.graphql"},
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ContextType: "context.Context",
|
ContextType: "context.Context",
|
||||||
}
|
}
|
||||||
@@ -26,9 +26,8 @@ type Config struct {
|
|||||||
// TODO: Allow fetching a schema via introspection (will need to figure out
|
// TODO: Allow fetching a schema via introspection (will need to figure out
|
||||||
// how to convert that to SDL).
|
// how to convert that to SDL).
|
||||||
Schema string `yaml:"schema"`
|
Schema string `yaml:"schema"`
|
||||||
// The filename with the queries; defaults to queries.graphql
|
// Filenames or globs with the queries; defaults to queries.graphql.
|
||||||
// TODO: allow multiple files?
|
Queries []string `yaml:"queries"`
|
||||||
Queries string `yaml:"queries"`
|
|
||||||
// The filename to which to write the generated code; defaults to
|
// The filename to which to write the generated code; defaults to
|
||||||
// generated.go
|
// generated.go
|
||||||
Generated string `yaml:"generated"`
|
Generated string `yaml:"generated"`
|
||||||
@@ -50,7 +49,9 @@ func (c *Config) ValidateAndFillDefaults(configFilename string) error {
|
|||||||
// Make paths relative to config dir
|
// Make paths relative to config dir
|
||||||
configDir := filepath.Dir(configFilename)
|
configDir := filepath.Dir(configFilename)
|
||||||
c.Schema = filepath.Join(configDir, c.Schema)
|
c.Schema = filepath.Join(configDir, c.Schema)
|
||||||
c.Queries = filepath.Join(configDir, c.Queries)
|
for i := range c.Queries {
|
||||||
|
c.Queries[i] = filepath.Join(configDir, c.Queries[i])
|
||||||
|
}
|
||||||
c.Generated = filepath.Join(configDir, c.Generated)
|
c.Generated = filepath.Join(configDir, c.Generated)
|
||||||
|
|
||||||
if c.Package == "" {
|
if c.Package == "" {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func TestGenerate(t *testing.T) {
|
|||||||
|
|
||||||
goCode, err := Generate(&Config{
|
goCode, err := Generate(&Config{
|
||||||
Schema: filepath.Join("testdata", "schema.graphql"),
|
Schema: filepath.Join("testdata", "schema.graphql"),
|
||||||
Queries: filepath.Join("testdata", graphqlFilename),
|
Queries: []string{filepath.Join("testdata", graphqlFilename)},
|
||||||
Package: "test",
|
Package: "test",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+40
-13
@@ -3,6 +3,7 @@ package generate
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/vektah/gqlparser/v2"
|
"github.com/vektah/gqlparser/v2"
|
||||||
"github.com/vektah/gqlparser/v2/ast"
|
"github.com/vektah/gqlparser/v2/ast"
|
||||||
@@ -26,24 +27,50 @@ func getSchema(filename string) (*ast.Schema, error) {
|
|||||||
return schema, nil
|
return schema, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAndValidateQueries(filename string, schema *ast.Schema) (*ast.QueryDocument, error) {
|
func getAndValidateQueries(filenames []string, schema *ast.Schema) (*ast.QueryDocument, error) {
|
||||||
text, err := ioutil.ReadFile(filename)
|
// We merge all the queries into a single query-document, since operations
|
||||||
if err != nil {
|
// in one might reference fragments in another.
|
||||||
return nil, fmt.Errorf("unreadable query-spec file %v: %v", filename, err)
|
//
|
||||||
|
// TODO(benkraft): It might be better to merge just within a filename, so
|
||||||
|
// that fragment-names don't need to be unique across files.
|
||||||
|
mergedQueryDoc := new(ast.QueryDocument)
|
||||||
|
|
||||||
|
for _, filename := range filenames {
|
||||||
|
switch filepath.Ext(filename) {
|
||||||
|
case ".graphql":
|
||||||
|
// Cf. gqlparser.LoadQuery
|
||||||
|
text, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unreadable query-spec file %v: %v", filename, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
queryDoc, err := getQueriesFromString(string(text), filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedQueryDoc.Operations = append(mergedQueryDoc.Operations, queryDoc.Operations...)
|
||||||
|
mergedQueryDoc.Fragments = append(mergedQueryDoc.Fragments, queryDoc.Fragments...)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown file type: %v", filename)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following is more or less gqlparser.LoadQuery, but we can provide a
|
graphqlErrors := validator.Validate(schema, mergedQueryDoc)
|
||||||
// name so we might as well (and we break out the two errors).
|
|
||||||
document, graphqlError := parser.ParseQuery(
|
|
||||||
&ast.Source{Name: filename, Input: string(text)})
|
|
||||||
if graphqlError != nil { // ParseQuery returns type *graphql.Error, yuck
|
|
||||||
return nil, fmt.Errorf("invalid query-spec file %v: %v", filename, graphqlError)
|
|
||||||
}
|
|
||||||
|
|
||||||
graphqlErrors := validator.Validate(schema, document)
|
|
||||||
if graphqlErrors != nil {
|
if graphqlErrors != nil {
|
||||||
return nil, fmt.Errorf("query-spec does not match schema: %v", graphqlErrors)
|
return nil, fmt.Errorf("query-spec does not match schema: %v", graphqlErrors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mergedQueryDoc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getQueriesFromString(text string, filename string) (*ast.QueryDocument, error) {
|
||||||
|
document, graphqlError := parser.ParseQuery(
|
||||||
|
&ast.Source{Name: filename, Input: text})
|
||||||
|
if graphqlError != nil { // ParseQuery returns type *graphql.Error, yuck
|
||||||
|
return nil, fmt.Errorf("invalid query-spec file %v: %v", filename, graphqlError)
|
||||||
|
}
|
||||||
|
|
||||||
return document, nil
|
return document, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user