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"
|
"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 {
|
type Config struct {
|
||||||
// The filename with the GraphQL schema (in SDL format); defaults to
|
// The filename with the GraphQL schema (in SDL format); defaults to
|
||||||
// schema.graphql
|
// schema.graphql
|
||||||
@@ -100,8 +104,9 @@ type Config struct {
|
|||||||
// them at your own risk!
|
// them at your own risk!
|
||||||
AllowBrokenFeatures bool `yaml:"allow_broken_features"`
|
AllowBrokenFeatures bool `yaml:"allow_broken_features"`
|
||||||
|
|
||||||
// Set automatically to the filename of the config file itself.
|
// The directory of the config-file (relative to which all the other paths
|
||||||
configFilename string
|
// are resolved). Set by ValidateAndFillDefaults.
|
||||||
|
baseDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// A TypeBinding represents a Go type to which genqlient will bind a particular
|
// 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"`
|
ExpectExactFields string `yaml:"expect_exact_fields"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// baseDir returns the directory of the config-file (relative to which
|
// ValidateAndFillDefaults ensures that the configuration is valid, and fills
|
||||||
// all the other paths are resolved).
|
// in any options that were unspecified.
|
||||||
func (c *Config) baseDir() string {
|
//
|
||||||
return filepath.Dir(c.configFilename)
|
// 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 {
|
||||||
func (c *Config) ValidateAndFillDefaults(configFilename string) error {
|
c.baseDir = baseDir
|
||||||
c.configFilename = configFilename
|
|
||||||
// Make paths relative to config dir
|
// 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 {
|
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 != "" {
|
if c.ExportOperations != "" {
|
||||||
c.ExportOperations = filepath.Join(c.baseDir(), c.ExportOperations)
|
c.ExportOperations = filepath.Join(baseDir, c.ExportOperations)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.ContextType == "" {
|
if c.ContextType == "" {
|
||||||
@@ -173,6 +177,8 @@ func (c *Config) ValidateAndFillDefaults(configFilename string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadAndValidateConfig reads the configuration from the given file, validates
|
||||||
|
// it, and returns it.
|
||||||
func ReadAndValidateConfig(filename string) (*Config, error) {
|
func ReadAndValidateConfig(filename string) (*Config, error) {
|
||||||
text, err := ioutil.ReadFile(filename)
|
text, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -185,7 +191,7 @@ func ReadAndValidateConfig(filename string) (*Config, error) {
|
|||||||
return nil, errorf(nil, "invalid config file %v: %v", filename, err)
|
return nil, errorf(nil, "invalid config file %v: %v", filename, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = config.ValidateAndFillDefaults(filename)
|
err = config.ValidateAndFillDefaults(filepath.Dir(filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errorf(nil, "invalid config file %v: %v", filename, err)
|
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
|
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
|
// See Config for more on creating a configuration. The return value is a map
|
||||||
// wish to manage the config-reading (ReadAndValidateConfig) and file-writing
|
// from filename to the generated file-content (e.g. Go source). Callers who
|
||||||
// on their own. (Those are wired in by Main.)
|
// don't want to manage reading and writing the files should call Main.
|
||||||
func Generate(config *Config) (map[string][]byte, error) {
|
func Generate(config *Config) (map[string][]byte, error) {
|
||||||
// Step 1: Read in the schema and operations from the files defined by the
|
// 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
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
document, err := getAndValidateQueries(config.baseDir(), config.Operations, schema)
|
document, err := getAndValidateQueries(config.baseDir, config.Operations, schema)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -145,43 +145,43 @@ func defaultConfig(t *testing.T) *Config {
|
|||||||
// configurations. It uses snapshots, just like TestGenerate.
|
// configurations. It uses snapshots, just like TestGenerate.
|
||||||
func TestGenerateWithConfig(t *testing.T) {
|
func TestGenerateWithConfig(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
fakeConfigFilename string
|
baseDir string // relative to dataDir
|
||||||
config *Config // omits Schema and Operations, set below.
|
config *Config // omits Schema and Operations, set below.
|
||||||
}{
|
}{
|
||||||
{"DefaultConfig", "genqlient.yaml", defaultConfig(t)},
|
{"DefaultConfig", "", defaultConfig(t)},
|
||||||
{"Subpackage", "genqlient.yaml", &Config{
|
{"Subpackage", "", &Config{
|
||||||
Generated: "mypkg/myfile.go",
|
Generated: "mypkg/myfile.go",
|
||||||
}},
|
}},
|
||||||
{"SubpackageConfig", "mypkg/genqlient.yaml", &Config{
|
{"SubpackageConfig", "mypkg", &Config{
|
||||||
Generated: "myfile.go", // (relative to genqlient.yaml)
|
Generated: "myfile.go", // (relative to genqlient.yaml)
|
||||||
}},
|
}},
|
||||||
{"PackageName", "genqlient.yaml", &Config{
|
{"PackageName", "", &Config{
|
||||||
Generated: "myfile.go",
|
Generated: "myfile.go",
|
||||||
Package: "mypkg",
|
Package: "mypkg",
|
||||||
}},
|
}},
|
||||||
{"ExportOperations", "genqlient.yaml", &Config{
|
{"ExportOperations", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ExportOperations: "operations.json",
|
ExportOperations: "operations.json",
|
||||||
}},
|
}},
|
||||||
{"CustomContext", "genqlient.yaml", &Config{
|
{"CustomContext", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
||||||
}},
|
}},
|
||||||
{"NoContext", "genqlient.yaml", &Config{
|
{"NoContext", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ContextType: "-",
|
ContextType: "-",
|
||||||
}},
|
}},
|
||||||
{"ClientGetter", "genqlient.yaml", &Config{
|
{"ClientGetter", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromContext",
|
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromContext",
|
||||||
}},
|
}},
|
||||||
{"ClientGetterCustomContext", "genqlient.yaml", &Config{
|
{"ClientGetterCustomContext", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromMyContext",
|
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromMyContext",
|
||||||
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
ContextType: "github.com/Khan/genqlient/internal/testutil.MyContext",
|
||||||
}},
|
}},
|
||||||
{"ClientGetterNoContext", "genqlient.yaml", &Config{
|
{"ClientGetterNoContext", "", &Config{
|
||||||
Generated: "generated.go",
|
Generated: "generated.go",
|
||||||
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromNowhere",
|
ClientGetter: "github.com/Khan/genqlient/internal/testutil.GetClientFromNowhere",
|
||||||
ContextType: "-",
|
ContextType: "-",
|
||||||
@@ -192,9 +192,9 @@ func TestGenerateWithConfig(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
config := test.config
|
config := test.config
|
||||||
|
baseDir := filepath.Join(dataDir, test.baseDir)
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
err := config.ValidateAndFillDefaults(
|
err := config.ValidateAndFillDefaults(baseDir)
|
||||||
filepath.Join(dataDir, test.fakeConfigFilename))
|
|
||||||
config.Schema = filepath.Join(dataDir, "schema.graphql")
|
config.Schema = filepath.Join(dataDir, "schema.graphql")
|
||||||
config.Operations = []string{filepath.Join(dataDir, sourceFilename)}
|
config.Operations = []string{filepath.Join(dataDir, sourceFilename)}
|
||||||
if err != nil {
|
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
|
package generate
|
||||||
|
|
||||||
import (
|
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() {
|
func Main() {
|
||||||
exitIfError := func(err error) {
|
exitIfError := func(err error) {
|
||||||
if err != nil {
|
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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
Reference in New Issue
Block a user