Files
genqlient/generate/config.go
T

103 lines
2.9 KiB
Go

package generate
import (
"fmt"
"go/token"
"io/ioutil"
"path/filepath"
"strings"
"gopkg.in/yaml.v2"
)
var defaultConfig = &Config{
Schema: "schema.graphql",
Queries: "queries.graphql",
Generated: "generated.go",
ContextType: "context.Context",
}
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 fetching a schema via introspection (will need to figure out
// how to convert that to SDL).
Schema string `yaml:"schema"`
// The filename with the queries; defaults to queries.graphql
// TODO: allow multiple files?
Queries string `yaml:"queries"`
// The filename to which to write the generated code; defaults to
// generated.go
Generated string `yaml:"generated"`
// Set to the fully-qualified name of a type which generated helpers should
// accept and use as the context.Context for HTTP requests. Defaults to
// context.Context; set to the empty string to omit context entirely.
ContextType string `yaml:"context_type"`
// If set, a snippet of Go code to get a *graphql.Client from the context
// (which will be named ctx). For example, this might do
// ctx.Value(myKey).(*graphql.Client). If omitted, client must be
// passed to each method explicitly.
// TODO: what if you want to do an import in this snippet, e.g. for a
// getter function, global var, or a context-key-type?
// TODO: what if you want to return err?
ClientGetter string `yaml:"client_getter"`
}
func (c *Config) ValidateAndFillDefaults(configFilename string) error {
// Make paths relative to config dir
configDir := filepath.Dir(configFilename)
c.Schema = filepath.Join(configDir, c.Schema)
c.Queries = filepath.Join(configDir, c.Queries)
c.Generated = filepath.Join(configDir, c.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(filepath.Dir(abs))
if !token.IsIdentifier(base) {
return fmt.Errorf("unable to guess package-name: %v is not a valid identifier", base)
}
c.Package = base
}
return nil
}
func (c *Config) ContextPackage() string {
if c.ContextType == "" {
return ""
}
i := strings.LastIndex(c.ContextType, ".")
return c.ContextType[:i]
}
func ReadAndValidateConfig(filename string) (*Config, error) {
config := *defaultConfig
if filename != "" {
text, err := ioutil.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("unreadable config file %v: %v", filename, err)
}
err = yaml.Unmarshal(text, &config)
if err != nil {
return nil, fmt.Errorf("invalid config file %v: %v", filename, err)
}
}
err := config.ValidateAndFillDefaults(filename)
if err != nil {
return nil, fmt.Errorf("invalid config file %v: %v", filename, err)
}
return &config, nil
}