Add an option to handle enums with ugly casing (#270)
There are a bunch of places in genqlient where we just kind of hope you don't have ridiculous casing conflicts in your schema. Apparently with enum values there are actual schemas that have this problem! Now we have an option to disable. I ended up putting it all under `casing` instead of in `bindings` so we can clearly document the list of algorithms we support, and so we can have an `all_enums` value if you're working with a schema with a lot of this; in the future we may want to add similar behavior for types/fields, add more possible algorithms (e.g. to make things unexported), etc. I added tests for the new feature, although the way the tests are set up it wasn't convenient to do so for a schema where this is actually required. I also added a check for case conflicts that points you to this option. (I don't want to do it automatically for reasons described in the issue; mainly it just seemed a bit too magical.) Fixes #265.
This commit is contained in:
@@ -31,6 +31,7 @@ type Config struct {
|
||||
ClientGetter string `yaml:"client_getter"`
|
||||
Bindings map[string]*TypeBinding `yaml:"bindings"`
|
||||
PackageBindings []*PackageBinding `yaml:"package_bindings"`
|
||||
Casing Casing `yaml:"casing"`
|
||||
Optional string `yaml:"optional"`
|
||||
OptionalGenericType string `yaml:"optional_generic_type"`
|
||||
StructReferences bool `yaml:"use_struct_references"`
|
||||
@@ -68,6 +69,59 @@ type PackageBinding struct {
|
||||
Package string `yaml:"package"`
|
||||
}
|
||||
|
||||
// CasingAlgorithm represents a way that genqlient can handle casing, and is
|
||||
// documented further in the [genqlient.yaml docs].
|
||||
//
|
||||
// [genqlient.yaml docs]: https://github.com/Khan/genqlient/blob/main/docs/genqlient.yaml
|
||||
type CasingAlgorithm string
|
||||
|
||||
const (
|
||||
CasingDefault CasingAlgorithm = "default"
|
||||
CasingRaw CasingAlgorithm = "raw"
|
||||
)
|
||||
|
||||
func (algo CasingAlgorithm) validate() error {
|
||||
switch algo {
|
||||
case CasingDefault, CasingRaw:
|
||||
return nil
|
||||
default:
|
||||
return errorf(nil, "unknown casing algorithm: %s", algo)
|
||||
}
|
||||
}
|
||||
|
||||
// Casing wraps the casing-related options, and is documented further in
|
||||
// the [genqlient.yaml docs].
|
||||
//
|
||||
// [genqlient.yaml docs]: https://github.com/Khan/genqlient/blob/main/docs/genqlient.yaml
|
||||
type Casing struct {
|
||||
AllEnums CasingAlgorithm `yaml:"all_enums"`
|
||||
Enums map[string]CasingAlgorithm `yaml:"enums"`
|
||||
}
|
||||
|
||||
func (casing *Casing) validate() error {
|
||||
if casing.AllEnums != "" {
|
||||
if err := casing.AllEnums.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, algo := range casing.Enums {
|
||||
if err := algo.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (casing *Casing) forEnum(graphQLTypeName string) CasingAlgorithm {
|
||||
if specificConfig, ok := casing.Enums[graphQLTypeName]; ok {
|
||||
return specificConfig
|
||||
}
|
||||
if casing.AllEnums != "" {
|
||||
return casing.AllEnums
|
||||
}
|
||||
return CasingDefault
|
||||
}
|
||||
|
||||
// pathJoin is like filepath.Join but 1) it only takes two argsuments,
|
||||
// and b) if the second argument is an absolute path the first argument
|
||||
// is ignored (similar to how python's os.path.join() works).
|
||||
@@ -172,6 +226,10 @@ func (c *Config) ValidateAndFillDefaults(baseDir string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Casing.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user