Skip to content
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

Document a binary? #238

Open
e-matteson opened this issue Sep 24, 2018 · 21 comments
Open

Document a binary? #238

e-matteson opened this issue Sep 24, 2018 · 21 comments
Labels
E-medium Effort: This requires a fair amount of work mentor This has instructions for getting started P-medium Medium priority S-needs-design Status: There's a problem here, but no obvious solution; or the solution raises other questions

Comments

@e-matteson
Copy link

e-matteson commented Sep 24, 2018

edit(@jyn514): Mentoring instructions for this issue are here: #238 (comment)

My crate has a macro that defines structs, and I want the docs to include an example of one of those generated structs. My solution was to write a binary, src/bin/example.rs, that invokes the macro.

This works great when I run cargo doc. I see example listed in the crates sidebar, and it contains docs for the generated struct. However, it doesn't show up in docs.rs.

I tried adding this to Cargo.toml, but it didn't help:

[[bin]]
name = "example"
doc = true

Is there some magical argument I can pass using [package.metadata.docs.rs] that will make it document the binary? Any other suggestions?

@e-matteson
Copy link
Author

I worked around this issue the same way the bitflags crate does: adding an example_generated.rs module that is only compiled when an example_generated feature is used, and telling docs.rs to use that feature:

[package.metadata.docs.rs]
features = [ "example_generated" ]

I'll leave this issue open for now even though my specific problem is solved, since it would still be useful to document whether docs.rs can handle binaries. But feel free to close it if that's more appropriate.

@pickfire
Copy link
Contributor

@jyn514 Do we need to get an RFC for this to allow documentation for binary?

@jyn514
Copy link
Member

jyn514 commented Apr 25, 2020

@pickfire no, this does not need an RFC. To get this implemented, we need to

  • Stop passing --lib to cargo
  • Stop filtering out binary targets
  • Decide what to do if there are multiple binaries. I think if one has default-run = true we should build that and otherwise fall back to building the library.
  • Decide what to do if there is both a binary and a library. I think in that case we should only build the library.

Possibly we could also make the behavior configurable, although I'd rather avoid that in a first draft of the feature.

@jyn514
Copy link
Member

jyn514 commented Apr 25, 2020

I'm happy to mentor or take PRs for this but I won't have time to work on it myself in the near future.

@jyn514 jyn514 added mentor This has instructions for getting started E-medium Effort: This requires a fair amount of work wishlist labels Apr 25, 2020
@pickfire
Copy link
Contributor

pickfire commented May 20, 2020

Now I am wondering what to document in a binary. I think it is possible to put what needs to be documented in lib.rs. I kinda forgot my reason to work on this.

But looking at the source section in docs.rs, I think it would be good if it shows the binary and examples probably? But IIRC cargo does not publish examples and binaries together.

@Nemo157
Copy link
Member

Nemo157 commented May 20, 2020

Unless you are filtering them out explicitly Cargo will include the example and binaries into the packaged crate.

One issue with this is that the default binary and the library have the same target name, so you get a warning and lose the output from one if you build both:

The bin target `foo` in package `foo v0.1.0 (/tmp/tmp.zK3J7HRdS3/foo)` has the same output filename as the lib target `foo` in package `foo v0.1.0 (/tmp/tmp.zK3J7HRdS3/foo)`.
Colliding filename is: /tmp/tmp.zK3J7HRdS3/foo/target/doc/foo/index.html

I also think this could also need some work on the rustdoc side to make it first class:

  1. It should be possible to generate documentation for actual examples, not having to put an example in as a binary. (Actually, it appears that putting doc = true on an example works, there's just no cargo doc flag to say to document an example).
  2. The sidebar should distinguish between different crate types, right now all libraries and binaries are lumped together under a "Crates" heading, this could be divided into "Library crates" and "Binary crates" (and "Example crates" if that's supported).

(TBH I see much more usefulness out of being able to have documented examples than binaries, but they're very similar in implementation).

@pickfire
Copy link
Contributor

@Nemo157 Ah, I didn't mean to document examples or binaries straight away, of course it might still be useful to document pub items in binary to show others like the command line arguments the application accepts.

What I meant is the examples seemed to be missing from https://docs.rs/crate/clap/2.33.1/source/

@Nemo157
Copy link
Member

Nemo157 commented May 20, 2020

That’s because clap explicitly excludes its examples from being published:

exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]

@pickfire
Copy link
Contributor

Oh, sorry. I didn't notice that.

@Kixiron Kixiron mentioned this issue Jun 3, 2020
@jyn514 jyn514 added P-medium Medium priority and removed wishlist labels Jun 27, 2020
@jyn514 jyn514 added the S-needs-design Status: There's a problem here, but no obvious solution; or the solution raises other questions label Aug 2, 2020
@volks73
Copy link

volks73 commented Nov 9, 2020

Greetings! I just wanted to provide some additional context and a use-case for documenting binaries on doc.rs.

I have created the cargo-wix Cargo subcommand. Generally, Cargo subcommands are hosted on crates.io and installed using cargo install. Their relatively close coupling to the Cargo and crates.io ecosystem would suggest the documentation should be included with docs.rs as part of that ecosystem. However, I recognize there is a lot of discussion around binary distribution and a healthy desire to avoid Cargo/crates.io replacing system package managers for binary distribution.

Furthermore, the cargo install command is advertised as a mechanism to quickly experiment and test binaries and should not be used as a replacement for system level package managers and system distribution mechanisms. Given that the cargo install command is for experimentation, early stage development, and bleeding edge distribution of features, there should be no expectation of any binary documentation (it simply hasn't been written yet or it is out-of-date to the latest implementation developments in a project). From this lack of expectation, then docs.rs should not concern itself with binary documentation. Binary documentation should be provided by the system distribution and help system. However, Cargo subcommands appear to be a very specific, niche exception because of their association with the Rust ecosystem.

The discussion appeared to be focused on documenting examples, but there was this comment by @pickfire:

Now I am wondering what to document in a binary.

Just to give an example on documenting a binary versus a library, separate from package examples, I have structured the cargo-wix project as a binary (cargo-wix) that uses the library (wix) and provides both to developers that want to use the subcommand (binary) or interact with the WiX Toolset from another Rust project (library). With this organization, I have module-level documentation for the binary located in the src\main.rs source file that walks through usage examples of the subcommand and provides additional documentation for various CLI options and flags. Basically, manpage-like documentation since Windows does not have such a system, which I acknowledge makes my use-case even more specific and niche. This documentation is not appropriate, or applicable, to the usage of the library. There is a separate module-level documentation for the library in the src\lib.rs source file, with examples and information about using the library.

Currently, only the library documentation is available on docs.rs. I have added a link to the binary documentation within the documentation, but it results in a "Crate not found" error through docs.rs. I believe this is because the link is automatically generated by rustdoc and since the binary documentation is not generated through docs.rs, the link is broken. Ideally, I would like both documentation available on docs.rs with the binary documentation being the default/primary as I believe this is the more useful and the current majority use-case of the project. The current workaround has been to host the documentation with GitHub pages and have the index.html file be for the binary module-level documentation. Please observe in the GitHub-hosted documentation, both the cargo_wix and wix crate are listed and the links between the binary and library module-level documentation work. However, I would like to move away from GitHub Pages and use docs.rs, as this is the convention and best practices. It would also greatly simplify updating and releasing for me.

It is possible I am missing some configuration directive that would eliminate needing to use the GitHub Pages workaround and accomplish my ideal documentation state with no change to the excellent docs.rs codebase. A non-exhaustive review of issues on binary documentation yielded this issue, but I did not see any existing configuration directives that would be appropriate. Below is a snippet of the Cargo.toml file:

[[bin]]
name = "cargo-wix"

[lib]
name = "wix"

Any information and/or direction would be greatly appreciated.

@jyn514
Copy link
Member

jyn514 commented Nov 9, 2020

@volks73 you're not missing anything, this isn't implemented. It's waiting on the design issues mentioned in #238 (comment).

@pickfire
Copy link
Contributor

I was thinking of adding the binary to the top-level project left section. Right now there is a big Crates section only but I wonder if we want to document binaries and examples would be put it to the left as well?

image

Like Binaries and Examples? I wonder if name crashes are possible, like bin/wix/index.html or examples/hello/index.html?

@jyn514
Copy link
Member

jyn514 commented Nov 10, 2020

@pickfire that's a rustdoc section, you'd need to make rustdoc aware of the difference between binaries and libraries somehow. I think that's a good change, but it doesn't belong in docs.rs.

@pickfire
Copy link
Contributor

But if it works in rustdoc why it shouldn't be in docs.rs?

@jyn514
Copy link
Member

jyn514 commented Nov 10, 2020

@pickfire it doesn't work in rustdoc, that's my point. I think it should be added to rustdoc instead of special cased by docs.rs.

@pickfire
Copy link
Contributor

pickfire commented Nov 10, 2020

Ah, sorry. I was saying that if it works in the future. I was wondering why you say it shouldn't be in docs.rs even if it works in rustdoc. Time confusion.

@Nemo157
Copy link
Member

Nemo157 commented Nov 10, 2020

@pickfire if you have binaries and examples with doc = true and that don't have a conflicting name then they do appear under that list. You can see an example in the docs that @volks73 linked (this is a great example of why it would be nice for docs.rs to support this feature ❤️).

image

I mentioned above that this gets a little confusing, and I think it would be a good rustdoc feature to be able to partition these based on the type of crate:

image

So I think the required steps to get this working (and these can all be done independently) are:

  1. Support building docs for binaries on the docs.rs side. We could:
    • start doing this implicitly (where the binary name does not overlap the library name)
    • doing it for binaries that have an explicit doc = true in Cargo.toml
    • some other explicit opt-in (package.metadata.docs.rs?)
  2. Support building docs for examples in docs.rs. Same options as building docs for binaries in how to decide when to build them (though options other than doc = true would require a cargo feature to be able to build, cargo doc --examples doesn't currently work Feature/Enhancement: cargo doc --examples to render example documentation cargo#4508). One downside of this is that examples get dev-dependencies as well (which may cause additional build failures for crates if we implicitly start doing this).
  3. Fix Multiple crates with the same name lead to conflicting target/doc/crate directories rust#56169 so we can support cases where the binary name overlaps the library.
  4. Create a rustdoc feature for the partitioned headers (and probably needs cargo support)
  5. Allow configuring the default target displayed (and maybe heuristically detect it) so that e.g. @volks73 could set package.metadata.docs.rs.default-doc-target = "cargo-wix" to have https://docs.rs/cargo-wix go to the binary docs instead of the library docs (unfortunate naming overlap here between "target" (--target) and "target" ([lib]/[[bin]]/[[example]]).

@pickfire
Copy link
Contributor

pickfire commented Nov 10, 2020

@pickfire if you have binaries and examples with doc = true and that don't have a conflicting name then they do appear under that list. You can see an example in the docs that @volks73 linked (this is a great example of why it would be nice for docs.rs to support this feature heart).

The link looks good but the thing I was thinking before this was not to manually write out the docs, I was thinking of something like clap to auto-generate the docs to be displayed since clap have a bunch of metadata, especially with the release of clap 3 which it can now #[derive(Clap)]. I personally think manually write the docs for these command line option could easily go out of sync (in terms of order or examples or description) when the options increased.

@Nemo157
Copy link
Member

Nemo157 commented Nov 10, 2020

That's not really under the control of docs.rs, it seems likely to me that users could use a proc-macro to auto-generate their docs.

e.g. for examples I tried out using this little snippet to embed the example source into the doc-page and it worked relatively well.

#![feature(external_doc)]
//! ``rust
#![doc(include = "main.rs")]
//! ``

By just getting the docs published on docs.rs then users can start experimenting with solutions like this (and maybe end up with new features for rustdoc, that don't need changes to docs.rs).

@volks73
Copy link

volks73 commented Nov 10, 2020

5. Allow configuring the default target displayed (and maybe heuristically detect it) so that e.g. @volks73 could set `package.metadata.docs.rs.default-doc-target = "cargo-wix"` to have `https://docs.rs/cargo-wix` go to the binary docs instead of the library docs (unfortunate naming overlap here between "target" (`--target`) and "target" (`[lib]`/`[[bin]]`/`[[example]]`).

Instead of default-doc-target, would default-doc-crate or default-crate avoid some overloading of the "target" word? At least currently, the binary and library documentation are listed as "Crates" and the usage of "crate" would provide a simple association and identifier to the configuration directives purpose. Not 100% set on this, I have run in to the "target" overloaded wording problem, too.

This combined with 1 from @Nemo157's list would go a long way for me, but I am bias to my edge case. Fortunately for my use case I am able to have different Cargo target names for binary and library crates. I definitely see the value and problem with the naming conflicts between binary and library crates in a project. I think I actually used cargo-wix and wix to get around this problem; otherwise, I would have gone with just cargo-wix. Other Cargo-related crates generally follow the cargo-<NAME> convention, even for libraries. For example, cargo-metadata for the cargo metadata subcommand.

@jyn514
Copy link
Member

jyn514 commented Sep 30, 2022

start doing this implicitly (where the binary name does not overlap the library name)

I think this would be fairly easy to do when there's only 1 binary and no library, and wouldn't require major changes to the UI or build logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-medium Effort: This requires a fair amount of work mentor This has instructions for getting started P-medium Medium priority S-needs-design Status: There's a problem here, but no obvious solution; or the solution raises other questions
Projects
None yet
Development

No branches or pull requests

5 participants