-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for a config file to the generate-persisted-query-manifest
CLI
#295
Conversation
🦋 Changeset detectedLatest commit: 1e8a07d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
|
||
globInclude?: string[]; | ||
globExclude?: string[]; | ||
export interface PersistedQueryManifestConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tweaked the names of these options. Let me know if you like these or prefer something different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(heading out for a bit, feel free to make progress/merge/etc)
files.add(f); | ||
} | ||
], | ||
output: "persisted-query-manifest.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would lean towards stdout as the default (I'm not sure there are great defaults, most likely people want things under src
, and it's a lot easier for folks to just change stdout to a file without even using a config file than to figure out what the program's shorthand for writing to stdout is?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I went this way is because our initial list of instructions included this command:
rover pq publish <GRAPH_REF> --manifest ./operations/pqs/pqm.json
This assumes a written file to read from. I'm fine changing it to stdout as the default if the plan is to document this command using stdout by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to merge as-is for now and we can revisit this topic 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel like printing to stdout is a better default.
If I have a CLI program that prints to stdout, I 100% of the time immediately know that if I'd rather it go to a file I can just use >
.
If I have a CLI program that prints to a file, I have to figure out which convention it uses for stdout (-
? STDOUT
? something special?) in order to change it.
Plus it'll help remind us to take care to print any errors to stderr :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I respectfully disagree and I came to this decision for a couple reasons.
- Our work-in-progress documentation discusses in detail creating persisted query manifest files, which also shows examples of the
rover
command that uses a file to generate that list in GraphOS. I felt there would be a huge disconnect if we defaulted to stdout when our documentation encourages files. - Files are trackable in
git
, and I expect many teams will want to see diffs in code reviews to understand what changes are made to query bodies. Writing to stdout is much more invisible and hard to understand what might be changing.
That being said, I see no reason why we couldn't add a CLI option that allows you to print the result to stdout/stderr in case people like that workflow better. I just wouldn't make this the default behavior.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to agree to disagree (and leave it your way) here. But it does seem like something that would be helpful to be able to override on a per-execution basis rather than just in the config file, and with stdout as an easily achievable goal (which is I think what you're saying here).
(For example, if you have some sort of super custom transform that requires you to post-process the manifest file every time, it does seem like writing to stdout and using a pipe would be attractive.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, sorry I should have mentioned that when I said "CLI option", I meant you'd do something like:
npx generate-persisted-query-manifest --stdout
(option name TBD)
This would override the output
in your config file. I don't see this being an option you change in the config file itself.
Do you have recommendations on the option name? Not sure if there is a common convention in commands for this kind of thing or not.
const { Command } = require("commander"); | ||
const { cosmiconfig } = require("cosmiconfig"); | ||
const { generatePersistedQueryManifest, defaults } = require("./dist/index.js"); | ||
const { TypeScriptLoader } = require("cosmiconfig-typescript-loader"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't say I get the point of letting you load TS files if there's no obvious way to teach the TS file what the type it's supposed to return is? Or are you able to import PersistedQueryManifestConfig within the file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep! You're able to import the type in the config file, which gives you autocompletion and inline docs for each option.
It looks like this (also in the PR description):
// persisted-query-manifest.config.ts
import { PersistedQueryManifestConfig } from '@apollo/generate-persisted-query-manifest';
const config: PersistedQueryManifestConfig = {
documents: 'path/to/documents/**/*.{ts,tsx}'
};
export default config;
generate-persisted-query-manifeest
CLIgenerate-persisted-query-manifest
CLI
const supportedExtensions = ["json", "yml", "yaml", "js", "ts", "cjs"]; | ||
|
||
const searchPlaces = supportedExtensions.flatMap((extension) => [ | ||
`.${moduleName}.config.${extension}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure that having the dot-prefix and the not-dot-prefix versions are both that valuable. It's twice as much to document and twice as many places to look for a thing? I thought this was just us using cosmiconfig defaults but if we're defining our own conventions then maybe we should just make a choice, especially since you can just pass -c
if you want something different than our choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefixing with the dot would make it a hidden file and some may prefer that. I don't think its a bad thing to support both, especially because cosmiconfig does this out of the box. I'm sure we could find a way to make documentation succinct. I'm just not driven by "too much to document" as being the reason to limit the options here.
The reason I have searchPlaces
to begin with and I don't just use cosmiconfig('persisted-query-manifest')
is because the manifest file is written to persisted-query-manifest.json
, which is included in list of files that cosmiconfig will look by default. To differentiate, I figured I'd enforce .config
in the filename.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK with an agree to disagree here too. I do think that letting people specify their own config filename means we can have a more opinionated default, but if your opinion is to have a vaguer opinion then I guess it's opinionated to be less opinionated :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can have a more opinionated default
I'm not necessarily against this. In fact, I'd say the search places I have here now are actually a bit more opinionated than the cosmiconfig defaults (I enforce .config.<ext>
. cosmiconfig will search for rc
files as well, etc).
In fact I could probably simplify how we look for this by saying:
Create a config file named
persisted-query-manifest.config.<extension>
where<extension>
is one ofjson
,yml
,yaml
,js
,ts
, orcjs
. You may also prefix the file with a dot (.
) if you prefer hidden files.
What would you like to see as a more opinionated default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think that's a better way to document it than a long list. I guess my opinion would be to drop the final sentence and people who want hidden files are welcome to pass --config
. But it's bikeshed-painting at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but the reason I left it is because client teams are typically used to config files that support .
in the name (jest, prettier, eslint, etc).
Agreed though, just bikeshedding at this point 😆
/** | ||
* Paths to your GraphQL documents: queries, mutations, subscriptions, and fragments. | ||
*/ | ||
documents?: string | string[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit surprising that this doesn't have "patterns" in its name when the others do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GraphQL Codegen, one of the most popular tools of its kind, uses documents
for this exact thing. While its not necessarily a community convention, I figured using a name that another popular tool uses would make this feel a bit more familiar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just endeavor to be fully codegen-compatible (since many folks might use both tools) and let you specify your ignores here too with !
like codegen does? Looks like they use globby
under the hood. (Or maybe we just should use @graphql-tools/code-file-loader
which is one layer of wrapping up from the graphql-tag-pluck package we're using now?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered that as well and would be happy to reduce the number of options here if we like this better. I opted to maintain them separate, but only because you had created them separate initially 😆.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess my main reaction was that it's weird to have "patterns" in one name and not the other; a nice way to resolve that is just "do the same exact thing as graphql-code-generator", and it looks like that might be relatively straightforward by switching to globby
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep for sure. Naming is hard and I couldn't think of anything better since documentsIgnore
sounded weird and was on the fence of whether ignoredDocuments
would make sense to people.
I'm all for simplifying to match graphql code generator 100% though so I'll make this change.
globExclude?: string[]; | ||
export interface PersistedQueryManifestConfig { | ||
/** | ||
* Paths to your GraphQL documents: queries, mutations, subscriptions, and fragments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be helpful to define how the patterns work (even just by referring to "it's anything processed by the glob
npm package")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure! I can provide an update here.
files.add(f); | ||
} | ||
], | ||
output: "persisted-query-manifest.json", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel like printing to stdout is a better default.
If I have a CLI program that prints to stdout, I 100% of the time immediately know that if I'd rather it go to a file I can just use >
.
If I have a CLI program that prints to a file, I have to figure out which convention it uses for stdout (-
? STDOUT
? something special?) in order to change it.
Plus it'll help remind us to take care to print any errors to stderr :)
The CLI can now take a config file that will be used for the operation extraction. The CLI uses
cosmiconfig
and will, by default, search for a config file in these locations:.persisted-query-manifest.config.json
persisted-query-manifest.config.json
.persisted-query-manifest.config.yml
persisted-query-manifest.config.yml
.persisted-query-manifest.config.yaml
persisted-query-manifest.config.yaml
.persisted-query-manifest.config.js
persisted-query-manifest.config.js
.persisted-query-manifest.config.ts
persisted-query-manifest.config.ts
.persisted-query-manifest.config.cjs
persisted-query-manifest.config.cjs
persisted-query-manifest
key inpackage.json
You can also provide the location of the config file with the
--config
option to the CLI:The config file can be configured with the following options:
documents
(string | string[]
) - The glob patterns where the CLI tool should search for GraphQL operations.src/**/*.{graphql,js,jsx,ts,tsx}
.documentIgnorePatterns
(string | string[]
) - Glob patterns where the tool should exclude searching for GraphQL operations.["**/*.d.ts", "**/*.spec.{js,jsx,ts,tsx}", "**/*.story.{js,jsx,ts,tsx}", "**/*.test.{js,jsx,ts,tsx}"]
output
(string
) - Path where the manifest should be written.persisted-query-manifest.json
When the config file is a TypeScript file, you can import the
PersistedQueryManifestConfig
type to get autocompletion and type checking on the config object.