clap-rs / clap

A full featured, fast Command Line Argument Parser for Rust
docs.rs/clap
Apache License 2.0
14.25k stars 1.04k forks source link

Add JSON Export for App #918

Open mitsuhiko opened 7 years ago

mitsuhiko commented 7 years ago

It would be great to be able to export the app with all subcommands, options and args to JSON (or something similar) so documentation tools can then pick up on it and make documentation pages.

kbknapp commented 7 years ago

Great suggestion, I'd love this. I have it on the back burner to add serde impls, specifically so we could get YAML and JSON. This will probably come out in the 3.x release which I keep hoping is right on the horizon...but then my day job goes and monopolizes my time. Hopefully soonish!

mitsuhiko commented 7 years ago

I was toying around with making a soft version of this that just spits out some json but it's not clear on what basis this could be implemented. I was taking the completion code as a reference (the zsh one spits out most of the info I need) but it uses lots of internal APIs.

I wonder if it would make sense to base the completion code on an abstraction that could become public and then also be used for other exporting.

kbknapp commented 7 years ago

I bet providing Debug impls would get us 90% of the way there. Not full on JSON, but close. src/args/arg_builder/valued.rs would need a manual impl because of the validator[_os], but everything else could probably be derived

kbknapp commented 7 years ago

Also I should also add, providing serde::Serialize for either YAML or JSON (or really any target) isn't a breaking change, and doesn't need to wait for 3.x. The only part that would be "breaking" is using serde for the Deserialize for YAML. Although, even then not technically breaking because the API used would be different than the current App::from_yaml.

kbknapp commented 7 years ago

So actually providing a JSON/YAML serialization doesn't seem to be that hard, and is pretty straight forward. Maybe I can knock it out this week.

I will want the serde{_json._yaml} crates to be optional and behind a feature flag. And I want to keep the minimum version of Rust 1.11 if possibe (so no #[derive(..)] or ?) for the time being.

mitsuhiko commented 7 years ago

You could keep serde internal for now and just provide an export to JSON / YAML function that directly writes to a writer.

pksunkara commented 3 years ago

Blocked by https://github.com/dtolnay/serde-yaml/issues/94

epage commented 3 years ago

Like with #853, #1041 could help with the lifetime blocker

MikailBag commented 3 years ago

AFAIU, serde-yaml lifetime limitations are not really blockers: one can serialize to JSON at first, and then serialize serde_json::Value to YAML.

Also, JSON seems to be subset of YAML, so json-serialized string can be interpreted as yaml.

epage commented 3 years ago

Forgot which issue I was on, in general, exporting isn't blocked on the lifetime issue, only importing and only for yaml.

I'm assuming we'd want to solve these several issues (#853, #1630, this one) together, providing a single serialization/deserialization experience and not have serde for most types and then a special case for deserializing from yaml, which would make the lifetime issue a blocker.

epage commented 2 years ago

How much would https://github.com/clap-rs/clap/issues/2914 help in this case?

The idea would be that help generation is split into the generator and formatter. This would allow user-defined formatters, like man pages. Would that work for this case?