-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
refactor(cli): normalize the application of default option values #7220
Conversation
✅ [V2]
To edit notification comments on pull requests, go to your Netlify site settings. |
⚡️ Lighthouse report for the changes in this PR:
Lighthouse ran on https://deploy-preview-7220--docusaurus-2.netlify.app/ |
Size Change: 0 B Total Size: 803 kB ℹ️ View Unchanged
|
@@ -74,7 +74,9 @@ async function writePluginTranslationFiles({ | |||
|
|||
export async function writeTranslations( | |||
siteDir: string, | |||
options: WriteTranslationsOptions & ConfigOptions & {locale?: string}, | |||
options: Partial< |
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.
not fan of this kind of change 🤷♂️ I'd rather do the opposite and ensure all commands are never partial => handle edge cases and apply defaults at the edge of the system
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 problem is that writeTranslations
should not be seen as fully internal. It's exported from the main interface and users may import @docusaurus/core
and use it as a programmatic API. Therefore, I'd keep maximum compatibility with the CLI interface.
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.
Related: #4841 We should always assume the existence of those users that don't interact through the CLI. Even if it's technically not documented usage, I don't see why it makes the architecture any different if we apply defaults within docusuarus.mjs
or writeTranslations.ts
—as long as we only apply it once. NOT doing it in docusuarus.mjs
means (a) more permissive programmatic API and (b) a CLI registry that's easier to maintain in the long term because it's not intertwined with the implementation, but only a very thin wrapper around each exported function.
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, that seems reasonable
What I don't like is to have long methods receiving partial options, where there's always a risk to end up using the partial option on which default was not properly applied
Can we split the methods in 2, something like this?
function doWriteTranslations(siteDir: string, options: Options) {
// actual code
}
export function writeTranslations(siteDir: string, options: Partial<Options>) {
return doWriteTranslations(siteDir, applyDefaults(options))
}
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.
Yes, makes sense.
siteDir, | ||
{ | ||
dir = 'build', | ||
port = 3000, |
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.
where are these default values being applied now?
isn't it convenient that the default value and the doc message mentioning it are co-located?
Why not doing the opposite instead: always apply all default values in this file, ensuring we don't have to handle partial options anywhere else in the system?
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.
These have always been applied internally, before and after. These default values actually only serve the purpose of being confusing & overly defensive.
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.
as far as I understand this is the only place where 3000
is defined.
Otherwise it's the default of the underlying lib, which as you can see, can change over time (vercel/serve#680)
I'd rather keep applying these defaults explicitly so that we don't depend on underlying deps changes.
Also we can use the default options in commander help messages
.option('-p, --port <port>', `use specified port (default: ${DefaultServeOptions.port})`)
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... you're sure? 😄
const basePort = portOption ? parseInt(portOption, 10) : DEFAULT_PORT; |
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.
ah 😅 didn't search in utils
270aef3
to
af15be2
Compare
Actually... many of the default values are applied again in the underlying utility functions, which is a good thing, because these utility functions are re-used in multiple places where the concerns about the option values are different. The functions in |
Motivation
Right now, our CLI code is a bit messy, because default values are applied at different stages. Sometimes we apply default values directly in the command
action
; sometimes we pretend an argument of a function is optional while in practice it always exists... I decided to decouple the CLI implementation from the actual command interface, i.e. the CLI only passes the arguments down, without caring what's inside it. This should make the code much cleaner.A big pain point of commander, though, is that its typings are quite loose. I can't find a great way to work around it at the moment.
Have you read the Contributing Guidelines on pull requests?
Yes
Test Plan
All commands work the same as before.