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.
Lint is failing with some inscrutable panic (on a commit with no code
changes). Let's try bumping the version in case they fixed it.
Additionally, the new version's github action uses Go 1.19, which means
it pulls in gofmt updates to match the new [doc-comment formatting rules][1].
So I added Go 1.19 to our list of versions to test (fixes#216)
and updated some of our doc-comments to format better in the
new world (mostly using the new link syntax).
[1]: https://go.dev/doc/comment
Test plan: make lint
## Summary:
We typically name our types `OperationFieldTypeFieldType`, but if a
type's name matches the preceding field-name, we omit the type-name.
In #71 I changed the behavior such that we no longer do that in the case
where the type's name matches some suffix of the name-so-far that's
longer than just the leaf field-name.
This was semi-intentional; I assumed it didn't matter and would be more
predictable this way. But it turns out that was a feature, both in the
sense that almost any change to the type-name-generator is breaking, and
in the sense that it made the names uglier. Plus, now that we have
better conflict-detection (#94), the possibility that some tricksy
type-names could cause problems is no longer as much of an issue, so we
can be a little less careful here. (Although I think this is no less
safe than before; the field-names are the important part.) So in this
commit I revert the change.
Specifically, this comes up a lot at Khan where we do
```
mutation ForcePhantom {
forcePhantom { # type: ForcePhantom
error { ... } # type: ForcePhantomError
}
}
```
Before #71, and again after this change, we'll generate
`ForcePhantomForcePhantomError` for `error`; before we'd generate
`ForcePhantomForcePhantomErrorForcePhantomError`.
Issue: https://github.com/Khan/genqlient/issues/109
## Test plan:
make tesc
Author: benjaminjkraft
Reviewers: csilvers, aberkan, dnerdy, jvoll, mahtabsabet, MiguelCastillo, StevenACoffman
Required Reviewers:
Approved By: csilvers
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/110
🖍 _This is an audit!_ 🖍
Auditors: StevenACoffman
Author: benjaminjkraft
Required Reviewers:
Approved By:
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/100
## Summary:
In this commit I add two related features to genqlient:
conflict-detection to avoid generating two distinct types with the same
name, and an option to specify the type-name genqlient should use for
some type.
The conflict-detection was pretty simple once I realized I had already
written all the code to do it in #70. There was a bunch of wiring,
since we now need to keep track of the GraphQL type/selection-set that
each type corresponds to, but it was pretty straightforward. This
allows us to:
- detect and reject if you have really sneaky type-names (there are some
examples documented in `names.go`)
- more clearly crash if genqlient accidentally generates two conflicting
types, and
- avoid stack-overflow when handing recursive (input) types (although
sadly the poor support for options on input types (#14) makes them
difficult to use in many cases; you really need to be able to set
`pointer: true`)
And with that all set up, the type-naming was also easy! (It doesn't
have to get into the core of the type-generator, just plug in where we
choose names. The desire for conflict detection was the main reason I
hadn't set it up already.) Note that the existing limitation of #70 that
the fields have to be in exactly the same order remains (and is now
documented as #93); it's not deeply hard to fix but it's surprisingly
much work.
Issue: https://github.com/Khan/genqlient/issues/60
Issue: https://github.com/Khan/genqlient/issues/12
## Test plan:
make check
Author: benjaminjkraft
Reviewers: StevenACoffman, jvoll, benjaminjkraft, aberkan, csilvers, dnerdy, mahtabsabet, MiguelCastillo
Required Reviewers:
Approved By: StevenACoffman, 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/94
## Summary:
In this commit I reorganize much of our documentation into a new `docs`
directory, where there will hopefully be more room to grow and to
organize things in a user-friendly way. There's almost no net-new
documentation, although of course it's a great time to review it anyway.
In particular:
- I moved the documentation for the `genqlient.yaml` config file into an
example file instead of GoDoc (which now just points to the example
file); I think this will be a lot clearer for casual users.
- I moved the documentation for the `@genqlient` directive out of GoDoc
and into a GraphQL schema file (since while it's a comment it's all
real syntax), likewise, and made the `GenqlientDirective` type private
(since there's now nothing useful to do with it).
- I moved `DESIGN.md` and the logo into `docs/` (just to keep the
toplevel a bit cleaner), and separated the Contributing section of the
README into `docs/CONTRIBUTING.md` (which github will automatically
link on various issue and PR pages).
This leaves it so that:
- README.md is the only documentation at the toplevel (and will become
just the high-level introduction as I add more user docs to `docs/`)
- GoDoc is only documentation for if you want to call genqlient
programmatically (which is fairly limited as the API surface is quite
small: it's now just Main, Generate, and Config, plus a constructor, a
single method, and a bunch of fields on the latter)
In future commits, I'll add some more new documentation to the `docs`
directory.
Issue: https://github.com/Khan/genqlient/issues/26
## Test plan:
make check (and read the docs)
Author: benjaminjkraft
Reviewers: jvoll, benjaminjkraft, aberkan, dnerdy, MiguelCastillo, mahtabsabet
Required Reviewers:
Approved By: jvoll
Checks: ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint
Pull Request URL: https://github.com/Khan/genqlient/pull/84
## Summary:
When adding support for interfaces, I did not do the type-names as I
intended: they came out to be `MyFieldMyType`, not
`MyInterfaceMyFieldMyType`, which is inconsistent, but not strictly
wrong. But once supporting fragments, this is also now incorrect.
(Exactly why is described in the comments inline.) In this commit, in
any case, I fix it.
To do that, I finally did the last of the refactors I've been hoping to
do but unable to successfully implement, which is to make the type-name
and type-name-prefix management clearer. In the past it was kind of
spread out, and each caller would have to pass the right name into
`convertDefinition`, which go quite unwieldy. Now, the case that really
wanted that -- the operation toplevel -- just does it own thing; and the
main name-generation code is factored out into a separate file with
tests, and with a long comment that goes into all the details of the
algorithm that the design-doc didn't cover. (I even had some fun using
a linked list to implement the prefix-stack!)
This allowed me to fix the above bug fairly easily -- actually the fix
was pretty much automatic once I understood how to organize things.
There is one change which is that if your query name is unexported, we
no longer do the same with the input-type names; it's unclear to me if
anyone will actually care about this behavior (Khan always makes the
queries exported) but if they did it was very inconsistent (only at the
query toplevel, and only for input-objects, not enums), so we can
reimplement it properly if that comes up. As a bonus fix, we now better
handle the case where your type-names are lowercase, which is legal if
nonstandard GraphQL.
Issue: https://github.com/Khan/genqlient/issues/8
## Test plan:
make tesc
Author: benjaminjkraft
Reviewers: dnerdy, benjaminjkraft, aberkan, MiguelCastillo
Required Reviewers:
Approved by: dnerdy
Checks: ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Test (1.13), ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Test (1.13), ✅ Lint
Pull request URL: https://github.com/Khan/genqlient/pull/71