-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Derive documentation can be improved #3189
Comments
My reply on reddit to dnaka91 which hasn't been responded to
|
FWIW, for me as a Love the new derive macro, btw. It's fantastic. |
I considered including the derive reference directly in the doc comments but there is a lot shared between We do link to the derive reference from the top-level docs but linking directly from the traits themselves would be a big help. We've been versioning the links to external documentation, relying on Still debating on whether to keep the derive reference in the repo or to move it do an empty module. The tutorials being separate is helped a lot by our ability to test them and link to the example code easily. So far the derive reference only has 1 tested code sample. |
This is to help with clap-rs#3189
I actually completely missed the link to derive reference and it gave me headache for hours and then it was all there along front of README.md but for some reason I missed it - it probably has to have a heading in README.md under "Derive" section and then some text around it to give a reference as the plain link is easily ignored - or at least for me it was. I only got to the refernce documentation when reading the source and associated doc comments somewhere thick deep. I've created #3269 in order to document what is expected to be supported with flattened in the future. I've also done crate-ci/clap-cargo#28 to document downstream clap-cargo limitations with the associated required flatten with no alternative to use/inject methods either with individual arguments or as a collective. |
https://internals.rust-lang.org/t/rustdoc-include-an-external-markdown-file-as-a-separate-page/15994/5 seems relevant for this discussion. |
I had the same experience. I had skipped over the table of contents and quickly saw a "Derive API" link which very much looked like it would link to a reference page. When it took me to the tutorial page, I thought "oh I guess this is their idea of documentation". Perhaps these links should instead look like "Derive API (tutorial)" or "Derive API (reference, tutorial)". |
Since I randomly found this issue while googling something else, I'll chip in: my main pain point with a Markdown file on Github vs Docs.rs is the lack of navigation - I need to scroll manually, or scroll back to the top and click on a header, there's no floating ToC. To give an example: reading through Arg magic attributes, I came across |
@jaskij thats a really good point about the value of a floating ToC. Unfortunately, custom documentation on docs.rs can't participate in the ToC (e.g. clap, structopt). So let me re-summarize the benefits of the different documentation platforms mdbook
github markdown source rendering
github wiki
docs.rs
|
Actually, GH wiki supports a sidebar - you need a file called As for mdbook - couldn't you just have the book as a subdirectory in the main repo, and build and publish from there? No need for a separate repository that way. |
With Github, I'm referring to the markdown rendering of source. I've added Github Wiki to the comparison. As for "places for project content", I'm not referring to repos but places the user has to browse to as that was one of the complaints of using mdbook. |
A quick comment unrelated to the location of the documentation: It took me a while to notice the part that says 'any arg method can also be used as an attribute', because I was looking for how to set a delimiter, and my instinct was to search for 'delimiter', 'comma', 'list', etc. on the documentation, assuming that like the magic attributes they would be listed out. I'm not sure it's worth copying that information, but on the other hand the current setup makes it feel like you need to just read pages of unrelated options to discover it. |
Yes, I've not wanted to maintain a duplicate of the builder API in the derive documentation. I'm trying to think how to further improve the situation. Maybe we should put the raw attribute description for each type of attribute first since its short, it won't obscure things too badly for the developer more familiar with clap's derive that is wanting more details on a specific magic attribute. If that sounds good or if you have any other thoughts, let us know! |
As someone who is somewhat familiar with the API, I find myself checking the examples in the repo and then just going off of my knowledge. This is mostly useful for the basics I forgot - like which trait to use. With the option to just call methods in the attribute, for stuff I don't know off-hand, I often go the other way around - check the methods on the trait, and either check the derive docs for an equivalent or just use the method. While they are slightly more readable, I'm not entirely sure separate attributes are worth the maintenance effort. For attributes which are just trait methods with clearer syntax, maybe keep it link-only? |
Yes, my plan is to just keep linking to docs.rs for people to look up the builder methods to see what they can use as attributes, not even enumerating the builder methods. The challenge at hand, which has been an ongoing one judging by the number of duplicate questions of #3538, is how to help users understand this. My proposal was a tweak to make the raw attribute section for each type of attribute come before the magic attribute one. Any other ideas to help users understand the relationship of the APIs would be appreciated. |
I think putting raw first might help. Looking at the page, If I jump to 'Command Attributes' and skim my eyes down it, I see 'Magic Attributes', then text, then 'Arg Attributes' is the next thing that catches my eye, skipping over 'Raw Attributes'. I think it's a mix of how the header nesting is deep enough that they aren't much bigger than surrounding text, the large amount of block text and occasional bolded text in the magic attributes, and that the magic attributes section is very long while the raw attributes section is short. All together, I missed it the first time because my eyes treated it as part of the above section, moving it first would help because as the shorter section, it will be clear where it starts and ends. (I'll admit part of the problem is skimming over reading the documentation properly, but I also feel that should be expected of a reference - it's like a dictionary or index, users expect to jump to the part relevant to them) |
Based on feedback in clap-rs#3189
@CraftSpider docs are updated. Hopefully this works out better for the next person! |
As a new user, I am also finding the documentation scattered and confusing. I've spent like 3-4 hours now trying to understand the basics of clap and evaluating whether it's a good choice for what I'm building. I'm including in this time that I spent looking into alternatives on https://libs.rs because the clap documentation was so confusing and hard to follow. I feel like it shouldn't take nearly this much effort and time for new users to get started and decide if clap is a good fit for their project. I'll walk through some of my thought process trying to figure out how to start to hopefully illustrate the issues. So, being a Rust library, the first place I expect documentation to be is https://docs.rs/clap. Right away, it's confusing: "This allows using the Derive API which provides access to the Builder API as attributes on a struct" You're using one API to access another API? What does that mean?? I'm already confused. Which API should I use and why? Alright, I'll click the links to the documentation for each API. Start reading each page... I'm still confused, which API should I use and why? I'll try going back to docs.rs, hopefully it's clearer than these overwhelming tutorials on GitHub. Scroll down... aspirations section looks good. Ah, finally an explanation of the differences between the APIs. Okay, it seems the derive API is probably a good fit for my purposes, but I'm not sure yet, so I want to learn a bit more about each API first. Okay, I'll go back to the tutorials on GitHub. Wait, what even are these APIs? I don't see any code, just command output. Keep scrolling hoping to find code to get a better understanding... nope, still no code. Oh, there are "Example" links... but I thought I was already reading the examples? Alright, I'll click the link anyway. Cool, finally found some code. Wait, what is going on in this code? #[clap(author, version, about, long_about = None)] Where do the author, verison, and about information come from?? What is a #[clap(name = "MyApp")]
#[clap(author = "Kevin K. <[email protected]>")]
#[clap(version = "1.0")]
#[clap(about = "Does awesome things", long_about = None)] I'm still confused about the very first example without those inline values. Dang, I have a lot of browser tabs open at this point, what was I reading again? Keep reading the tutorial, finally, I find this sentence: "You can use #[clap(author, version, about)] attribute defaults to fill these fields in from your Cargo.toml file." Great! But why wasn't that explained in an inline comment in the source code of the very first example? Keep reading... "Any Command builder function can be used as an attribute." I thought I was reading the Derive documentation, why is this talking about builder functions now? Also, where are those builder functions documented? Should I be using the builder API after all? "Command" looks like the name of a struct, I'll try looking it up on docs.rs... okay, but I'm still lost what the relationship is between what's documented in docs.rs and what I'm reading in this tutorial. Here are some suggestions to improve this:
|
I wonder if a (gentle) guide should not be written and pointed to at the top of lib.rs as a "start here". It probably should start with the Builder API, then move to the Derive API. As a sidenote, I been wanting to write such a guide for a while, sort of a Rust version of this Python one. Other things always got in the way of course, but my main excuse was waitin for clap v3. |
From fumbling around the documentation and piecing together scattered information, this is my understanding of the APIs. Please correct me if I'm wrong:
|
Thank you @Be-ing for working through that and taking the time to reflect on your experience and share it! This will be a big help in finding ways to improve the docs. I especially agree that not providing a more direct guidance on when to use which API is not ideal. Some of the structure issues and non-inline code blocks is coming from a bad experience where the examples compiled but did not work. Our current form of documentation is tested to make sure that the specified arguments will produce the expected output. I talk more about the different documentation approaches earlier however, I think I thought of a way around some of the problems we had and will take a crack within the next week or so to try to address it. In supporting users in clap, one of the hardest things has been trying to get across how to use the builder documentation to use the derive API. I still feel like trying to reproduce all of the builder documentation as derive documentation would be a big task that would be hard to keep in sync, so it falls on finding ways to communicate that the derive API is a wrapper around the builder API and how to look things up in the builder documentation to use it in the derive API. |
@tshepang another related resource is https://rust-cli.github.io/book/index.html |
I agree that having nearly duplicate documentation wouldn't be maintainable. Perhaps it could help to have derive macro examples inline in the rustdoc documentation for the builder API? |
A couple of things happened when preparing to release 3.0 - We needed derive documentation - I had liked how serde handled theres - I had bad experiences finding things in structopt's documentation - The examples were broken and we needed tests - The examples seemed to follow a pattern of having tutorial content and cookbook content - We had been getting bug reports from people looking at master and thinking they were looking at what is currently released - We had gotten feedback to keep down the number of places that documentation was located From this, we went with a mix of docs.rs and github - We kept the number of content locations at 2 rather than 3 by not having an external site like serde - We rewrote the examples into explicit tutorials and cookbooks to align with the 4 styles of documentation - We could test our examples by running `console` code blocks with trycmd - Documentation was versioned and the README pointed to the last release This had downsides - The tutorials didn't have the code inlined - Users still had a hard time finding and navigating between the different forms of documentation - In practice, we were less likely to cross-link between the different types of documentation Moving to docs.rs would offer a lot of benefits, even if it is only designed for Rust-reference documentation and isn't good for Rust derive reference documentation, tutorials, cookbooks, etc. The big problem was keeping the examples tested to keep maintenance costs down. Maybe its just me but its easy to overlook - You can pull documentation from a file using `#[doc = "path"]` - Repeated doc attributes get concatenated rather than first or last writer winning Remember these when specifically thinking about Rust documentation made me realize that we could get everything into docs.rs. When doing this - Tutorial code got brought in as was one of the aims - We needed to split the lib documentation and the README to have all of the linking work. This allowed us to specialize them according to their rule (user vs contributor) - We needed to avoid users getting caught up in making a decision between Derive and Builder APIs so we put the focus on the derive API with links to the FAQ to help users decide when to use one or the other. - Improved cross-referencing between different parts of the documentation - Limited inline comments were added to example code - Introductory example code intentionally does not have teaching comments in it as its meant to give a flavor or sense of things and not meant to teach on its own. This is a first attempt. There will be a lot of room for further improvement. Current know downsides: - Content source is more split up for the tutorials This hopefully addresses clap-rs#3189
A couple of things happened when preparing to release 3.0 - We needed derive documentation - I had liked how serde handled theres - I had bad experiences finding things in structopt's documentation - The examples were broken and we needed tests - The examples seemed to follow a pattern of having tutorial content and cookbook content - We had been getting bug reports from people looking at master and thinking they were looking at what is currently released - We had gotten feedback to keep down the number of places that documentation was located From this, we went with a mix of docs.rs and github - We kept the number of content locations at 2 rather than 3 by not having an external site like serde - We rewrote the examples into explicit tutorials and cookbooks to align with the 4 styles of documentation - We could test our examples by running `console` code blocks with trycmd - Documentation was versioned and the README pointed to the last release This had downsides - The tutorials didn't have the code inlined - Users still had a hard time finding and navigating between the different forms of documentation - In practice, we were less likely to cross-link between the different types of documentation Moving to docs.rs would offer a lot of benefits, even if it is only designed for Rust-reference documentation and isn't good for Rust derive reference documentation, tutorials, cookbooks, etc. The big problem was keeping the examples tested to keep maintenance costs down. Maybe its just me but its easy to overlook - You can pull documentation from a file using `#[doc = "path"]` - Repeated doc attributes get concatenated rather than first or last writer winning Remember these when specifically thinking about Rust documentation made me realize that we could get everything into docs.rs. When doing this - Tutorial code got brought in as was one of the aims - We needed to split the lib documentation and the README to have all of the linking work. This allowed us to specialize them according to their rule (user vs contributor) - We needed to avoid users getting caught up in making a decision between Derive and Builder APIs so we put the focus on the derive API with links to the FAQ to help users decide when to use one or the other. - Improved cross-referencing between different parts of the documentation - Limited inline comments were added to example code - Introductory example code intentionally does not have teaching comments in it as its meant to give a flavor or sense of things and not meant to teach on its own. This is a first attempt. There will be a lot of room for further improvement. Current know downsides: - Content source is more split up for the tutorials This hopefully addresses clap-rs#3189
The new version of the documentation is now out: https://docs.rs/clap/latest/clap/ Please use this issue for concerns with this approach resolving the concerns in this issue. If things seem settled on the general approach, I will then close this issue. Please open new issues for new concerns or specific concerns that can be iterated on with the new approach. |
That's much better, thanks! |
I think this issue can be closed now. |
As a follow up, raw attributes continue to be a point of confusion so I've created #4090 to further discuss their documentation |
Please complete the following tasks
Rust Version
rustc 1.55.0 (c8dfcfe04 2021-09-06)
Clap Version
v3.0.0-rc.0
Description
From mitsuhiko
From dnaka91
I wanted to make sure we captured this feedback and raised visibility of it so we can hear from more voices to help in working out what we shoud do improve this
The text was updated successfully, but these errors were encountered: