Skip to content

refactor: use ordana for cli args parsing and generate docs#19436

Draft
sapphi-red wants to merge 3 commits intovitejs:mainfrom
sapphi-red:refactor/ordana
Draft

refactor: use ordana for cli args parsing and generate docs#19436
sapphi-red wants to merge 3 commits intovitejs:mainfrom
sapphi-red:refactor/ordana

Conversation

@sapphi-red
Copy link
Member

@sapphi-red sapphi-red commented Feb 16, 2025

Description

The cli document can now be generated from the CLI options.
To achieve that, I made a cli argument parser library named ordana that uses util.parseArgs internally.

package size

Since util.parseArgs is not supported by Node 18.0.0, I had to install a polyfill for it. That makes the package size bigger than before. But once we drop support for Node 18.0-18.3, that won't be needed and the package size will be slightly smaller.

package size

before

npm notice package size: 675.6 kB
npm notice unpacked size: 2.8 MB

after

npm notice package size: 681.4 kB
npm notice unpacked size: 2.9 MB

when the polyfill is removed

npm notice package size: 674.2 kB
npm notice unpacked size: 2.8 MB

parse behavior differences

ordana parses the arguments differently from cac in some cases, but I guess that's fine. (I can tweak the behavior if needed)
For example,

  • vite -c ./vite.config-url-base.js build
    • ordana: vite dev at build as root dir with vite.config-url-base.js config
    • cac: vite build at default root dir with vite.config-url-base.js config
  • vite --help build
    • ordana: help for vite
    • cac: help for vite build
  • vite build --unknown --help
    • ordana: throws an error that --unknown is unknown
    • cac: help for vite build

help message diff

before
image
image

after
image
image

@sapphi-red sapphi-red added the p1-chore Doesn't change code behavior (priority) label Feb 16, 2025
@sapphi-red
Copy link
Member Author

Ah, I forgot that I have to implement case conversion.

@bluwy
Copy link
Member

bluwy commented Feb 16, 2025

Might also need to double check --debug support, which can accept boolean or string. I think most arg parsers don't handle this dual-type well.

About the docs generation, just curious, but couldn't we parse the current CLI output (invoked via child process) and try to format that as markdown instead? I'm a bit worried that we're relying on an external package for an opinionated markdown output.

@sapphi-red
Copy link
Member Author

Might also need to double check --debug support, which can accept boolean or string. I think most arg parsers don't handle this dual-type well.

Actually --debug is handled outside the cli.ts. --host accepts boolean or string and handled in cli.ts. I wrote these tests to ensure that it works.
https://github.com/sapphi-red/ordana/blob/5573c6e04a35c0622e2b12bd4338616404e5ec30/packages/ordana/src/parse.test.ts#L135-L185

About the docs generation, just curious, but couldn't we parse the current CLI output (invoked via child process) and try to format that as markdown instead?

I guess it's possible, but I'm not sure if it's easy to do. The Options table has columns separated by char count and probably needs some heuristics.

I'm a bit worried that we're relying on an external package for an opinionated markdown output.

Instead of returning a markdown output, I can also make the package return the needed information and move some function in https://github.com/sapphi-red/ordana/blob/main/packages/gen-docs/src/docs.ts to this repo if that's preferred.
I guess postprocessing it in https://github.com/vitejs/vite/pull/19436/files#diff-204c199ec0bc30d40a452ea8f05ce18e055b28a226bef55e63d9b0ebbc20474d would work as well.

@bluwy
Copy link
Member

bluwy commented Feb 16, 2025

Actually --debug is handled outside the cli.ts. --host accepts boolean or string and handled in cli.ts. I wrote these tests to ensure that it works.
sapphi-red/ordana@5573c6e/packages/ordana/src/parse.test.ts#L135-L185

Ah forgot about that. Thanks for testing it for --host though, I didn't realize you've handled that internally.

Different topic but reading the code that handles string|boolean, it seems quite a lot that I wonder if using mri directly could be easier and faster perf-wise 😅 It doesn't support string|boolean well but the workaround wasn't too hard (lukeed/mri#25).

I guess it's possible, but I'm not sure if it's easy to do. The Options table has columns separated by char count and probably needs some heuristics.

Figuring out the common double-space index shouldn't be too hard I think, but yeah it'll take a bit of code to work.

Instead of returning a markdown output, I can also make the package return the needed information and move some function in sapphi-red/ordana@main/packages/gen-docs/src/docs.ts to this repo if that's preferred.
I guess postprocessing it in #19436 (files) would work as well.

I was thinking it could return a structured output instead, e.g. a metadata object that contains an array of option settings, array of commands supported, etc. The we could use that to construct markdown, which shouldn't be too hard. But I think we can still try your method if you'd like though, for me I don't think we have to change it for now.

@sapphi-red
Copy link
Member Author

Different topic but reading the code that handles string|boolean, it seems quite a lot that I wonder if using mri directly could be easier and faster perf-wise 😅 It doesn't support string|boolean well but the workaround wasn't too hard (lukeed/mri#25).

Yeah, I don't have strong opinion of using util.parseArgs, so I'm fine with swapping the underlying parser lib. I just started with it and went it to the end. I think one point to use util.parseArgs is that it has a better error message.

I was thinking it could return a structured output instead, e.g. a metadata object that contains an array of option settings, array of commands supported, etc.

I was thinking that this would be needed anyways so I'll do that later 👍


I found putting flags before the subcommands (e.g. vite -c ./vite.config-url-base.js build) is used a lot, so I'm going to add support for these case as well.

@sapphi-red
Copy link
Member Author

I found putting flags before the subcommands (e.g. vite -c ./vite.config-url-base.js build) is used a lot, so I'm going to add support for these case as well.

I tried supporting this case, but realized it's hard to do without greedy matching (example case, cac's implementation) 🫠.
While I think non-shared arguments shouldn't come before the subcommand — in which case greedy matching wouldn't be necessary — I don't think it's worth introducing a breaking change just for this.
I’ll probably just stick with cac and write a docs generation script based on its help output 😅.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p1-chore Doesn't change code behavior (priority)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants