Clean up godoc (#82)
## Summary: Before open-sourcing, we want to make sure that (a) GoDoc looks reasonable, and (b) everything in the API is something we want to commit to. In this commit, I do some miscellaneous cleanup on both fronts; this does involve a few breaking changes to the programmatic API (better now than once it has users). In future commits, I'll likely move the documentation for `genqlient.yaml` and `@genqlient` to clearer places, and make `GenqlientDirective` private, such that GoDoc is really only for programmatic users. Fixes #25. Issue: https://github.com/Khan/genqlient/issues/25 ## Test plan: make check Author: benjaminjkraft Reviewers: dnerdy, benjaminjkraft, jvoll, aberkan, MiguelCastillo, mahtabsabet Required Reviewers: Approved By: dnerdy, jvoll Checks: ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint Pull Request URL: https://github.com/Khan/genqlient/pull/82
This commit is contained in:
+21
-15
@@ -10,6 +10,10 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config represents genqlient's configuration, generally read from
|
||||
// genqlient.yaml.
|
||||
//
|
||||
// Callers must call ValidateAndFillDefaults before using the config.
|
||||
type Config struct {
|
||||
// The filename with the GraphQL schema (in SDL format); defaults to
|
||||
// schema.graphql
|
||||
@@ -100,8 +104,9 @@ type Config struct {
|
||||
// them at your own risk!
|
||||
AllowBrokenFeatures bool `yaml:"allow_broken_features"`
|
||||
|
||||
// Set automatically to the filename of the config file itself.
|
||||
configFilename string
|
||||
// The directory of the config-file (relative to which all the other paths
|
||||
// are resolved). Set by ValidateAndFillDefaults.
|
||||
baseDir string
|
||||
}
|
||||
|
||||
// A TypeBinding represents a Go type to which genqlient will bind a particular
|
||||
@@ -134,22 +139,21 @@ type TypeBinding struct {
|
||||
ExpectExactFields string `yaml:"expect_exact_fields"`
|
||||
}
|
||||
|
||||
// baseDir returns the directory of the config-file (relative to which
|
||||
// all the other paths are resolved).
|
||||
func (c *Config) baseDir() string {
|
||||
return filepath.Dir(c.configFilename)
|
||||
}
|
||||
|
||||
func (c *Config) ValidateAndFillDefaults(configFilename string) error {
|
||||
c.configFilename = configFilename
|
||||
// ValidateAndFillDefaults ensures that the configuration is valid, and fills
|
||||
// in any options that were unspecified.
|
||||
//
|
||||
// The argument is the directory relative to which paths will be interpreted,
|
||||
// typically the directory of the config file.
|
||||
func (c *Config) ValidateAndFillDefaults(baseDir string) error {
|
||||
c.baseDir = baseDir
|
||||
// Make paths relative to config dir
|
||||
c.Schema = filepath.Join(c.baseDir(), c.Schema)
|
||||
c.Schema = filepath.Join(baseDir, c.Schema)
|
||||
for i := range c.Operations {
|
||||
c.Operations[i] = filepath.Join(c.baseDir(), c.Operations[i])
|
||||
c.Operations[i] = filepath.Join(baseDir, c.Operations[i])
|
||||
}
|
||||
c.Generated = filepath.Join(c.baseDir(), c.Generated)
|
||||
c.Generated = filepath.Join(baseDir, c.Generated)
|
||||
if c.ExportOperations != "" {
|
||||
c.ExportOperations = filepath.Join(c.baseDir(), c.ExportOperations)
|
||||
c.ExportOperations = filepath.Join(baseDir, c.ExportOperations)
|
||||
}
|
||||
|
||||
if c.ContextType == "" {
|
||||
@@ -173,6 +177,8 @@ func (c *Config) ValidateAndFillDefaults(configFilename string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadAndValidateConfig reads the configuration from the given file, validates
|
||||
// it, and returns it.
|
||||
func ReadAndValidateConfig(filename string) (*Config, error) {
|
||||
text, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
@@ -185,7 +191,7 @@ func ReadAndValidateConfig(filename string) (*Config, error) {
|
||||
return nil, errorf(nil, "invalid config file %v: %v", filename, err)
|
||||
}
|
||||
|
||||
err = config.ValidateAndFillDefaults(filename)
|
||||
err = config.ValidateAndFillDefaults(filepath.Dir(filename))
|
||||
if err != nil {
|
||||
return nil, errorf(nil, "invalid config file %v: %v", filename, err)
|
||||
}
|
||||
|
||||
@@ -329,11 +329,12 @@ func (g *generator) addOperation(op *ast.OperationDefinition) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate returns a map from absolute-path filename to generated content.
|
||||
// Generate is the main programmatic entrypoint to genqlient, and generates and
|
||||
// returns Go source code based on the given configuration.
|
||||
//
|
||||
// This is the main entrypoint to the code-generation process for callers who
|
||||
// wish to manage the config-reading (ReadAndValidateConfig) and file-writing
|
||||
// on their own. (Those are wired in by Main.)
|
||||
// See Config for more on creating a configuration. The return value is a map
|
||||
// from filename to the generated file-content (e.g. Go source). Callers who
|
||||
// don't want to manage reading and writing the files should call Main.
|
||||
func Generate(config *Config) (map[string][]byte, error) {
|
||||
// Step 1: Read in the schema and operations from the files defined by the
|
||||
// config (and validate the operations against the schema). This is all
|
||||
@@ -343,7 +344,7 @@ func Generate(config *Config) (map[string][]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
document, err := getAndValidateQueries(config.baseDir(), config.Operations, schema)
|
||||
document, err := getAndValidateQueries(config.baseDir, config.Operations, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+15
-15
@@ -145,43 +145,43 @@ func defaultConfig(t *testing.T) *Config {
|
||||
// configurations. It uses snapshots, just like TestGenerate.
|
||||
func TestGenerateWithConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fakeConfigFilename string
|
||||
config *Config // omits Schema and Operations, set below.
|
||||
name string
|
||||
baseDir string // relative to dataDir
|
||||
config *Config // omits Schema and Operations, set below.
|
||||
}{
|
||||
{"DefaultConfig", "genqlient.yaml", defaultConfig(t)},
|
||||
{"Subpackage", "genqlient.yaml", &Config{
|
||||
{"DefaultConfig", "", defaultConfig(t)},
|
||||
{"Subpackage", "", &Config{
|
||||
Generated: "mypkg/myfile.go",
|
||||
}},
|
||||
{"SubpackageConfig", "mypkg/genqlient.yaml", &Config{
|
||||
{"SubpackageConfig", "mypkg", &Config{
|
||||
Generated: "myfile.go", // (relative to genqlient.yaml)
|
||||
}},
|
||||
{"PackageName", "genqlient.yaml", &Config{
|
||||
{"PackageName", "", &Config{
|
||||
Generated: "myfile.go",
|
||||
Package: "mypkg",
|
||||
}},
|
||||
{"ExportOperations", "genqlient.yaml", &Config{
|
||||
{"ExportOperations", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ExportOperations: "operations.json",
|
||||
}},
|
||||
{"CustomContext", "genqlient.yaml", &Config{
|
||||
{"CustomContext", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
||||
}},
|
||||
{"NoContext", "genqlient.yaml", &Config{
|
||||
{"NoContext", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ContextType: "-",
|
||||
}},
|
||||
{"ClientGetter", "genqlient.yaml", &Config{
|
||||
{"ClientGetter", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromContext",
|
||||
}},
|
||||
{"ClientGetterCustomContext", "genqlient.yaml", &Config{
|
||||
{"ClientGetterCustomContext", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromMyContext",
|
||||
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
||||
}},
|
||||
{"ClientGetterNoContext", "genqlient.yaml", &Config{
|
||||
{"ClientGetterNoContext", "", &Config{
|
||||
Generated: "generated.go",
|
||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromNowhere",
|
||||
ContextType: "-",
|
||||
@@ -192,9 +192,9 @@ func TestGenerateWithConfig(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
config := test.config
|
||||
baseDir := filepath.Join(dataDir, test.baseDir)
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := config.ValidateAndFillDefaults(
|
||||
filepath.Join(dataDir, test.fakeConfigFilename))
|
||||
err := config.ValidateAndFillDefaults(baseDir)
|
||||
config.Schema = filepath.Join(dataDir, "schema.graphql")
|
||||
config.Operations = []string{filepath.Join(dataDir, sourceFilename)}
|
||||
if err != nil {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Package generate provides programmatic access to genqlient's functionality,
|
||||
// and documentation of its configuration options. For general usage
|
||||
// documentation, see github.com/Khan/genqlient.
|
||||
package generate
|
||||
|
||||
import (
|
||||
@@ -50,6 +53,9 @@ See https://github.com/Khan/genqlient for full documentation.
|
||||
`)
|
||||
}
|
||||
|
||||
// Main is the command-line entrypoint to genqlient; it's equivalent to calling
|
||||
// `go run github.com/Khan/genqlient`. For lower-level control over
|
||||
// genqlient's operation, see Generate.
|
||||
func Main() {
|
||||
exitIfError := func(err error) {
|
||||
if err != nil {
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
// package main is at the root to allow "go run github.com/Khan/genqlient"
|
||||
// genqlient is a GraphQL client generator for Go.
|
||||
//
|
||||
// To run genqlient:
|
||||
// go run github.com/Khan/genqlient
|
||||
// For programmatic access, see the "generate" package, below. For
|
||||
// user documentation, see github.com/Khan/genqlient.
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
Reference in New Issue
Block a user