Have you ever struggled with welcoming people on your project pages, be them on GitHub or docs.rs? One major problem we’re facing when developping crates is that we need to maintain several places where documentation is important:
lib.rs / main.rs files, that get
rendered as front page on docs.rs.
This is important because we want people to have nice onboardings
when hitting the official documentations of our crates.README.md, that gets
automatically rendered as HTML when you end up on the project’s GitHub page. This page should
provide as many as possible hints and information about what the
project is and how to use it.However, sometimes, I just don’t want to bother writing twice the same thing and honestly, I don’t really know whether the README file is a good place to write an onboarding section, since that should also be included in your Rust documentation on docs.rs.
So… I’ve been thinking of a way to fix that, without really investing too much time in it. But lately, I came to the realization that I often have this pattern:
lib.rs
or main.rs. For instance, I’m pretty proud of the onboarding documentation of
warmy. It’s exhaustive, easy for newcomers, it has plenty of
links and explanations and it renders pretty nice on docs.rs.Here, (2.) is a manual and annoying task: I open my editor, make a block selection of the documentation, store it in a buffer, apply a smart macro on it to remove the Rust annotation and then paste the result in the README after having purged it from the previous documentation… That’s tedious and not very interesting.
cargo sync-readme
to the
rescue!#So, yesterday, I decided to start working on a small tool that would automate all this for me. The idea is the following:
cargo sync-readme synchronizes your README (the
file specified by the readme key in your
Cargo.toml, or just README.md by
default) with the entrypoint of your library or binary crate (by
default, lib.rs or main.rs, or what is
defined at the path key in your manifest).<!-- cargo-sync-readme --> marker must
lie on a single line where you want the documentation to be
inserted in your README.<!-- cargo-sync-readme start> and
<!-- cargo-sync-readme end -->.This is really all you have to do.
cargo sync-readme will take care of the rest for you.
There’re two hypothesis that the command requires to be true,
though:
//! annotation to write your
documentation. This is currently how
cargo sync-readme works. It doesn’t have to be solely
using this annotation on longer term, but currently, this is the
only annotation supported. More can be added if needed.Basically, insert the marker once, and run
cargo sync-readme. Every time you change your Rust
documentation, just call cargo sync-readme once again
to synchronize the documentation in your README file.
Currently, cargo sync-readme doesn’t work with
workspace crates. You will have to go into each of the workspace’s
members to run cargo sync-readme if you want to
synchronize their respective READMEs.
cargo sync-readme is already available on crates.io
for you to use. You can install it as a development tool with the
following command:
Disclaimer: after having published
cargo-sync-readme, I was told that there is already another cargo plugin, cargo-readme, that already does that. Indeed, that crate does more or less the same job. However, the way it does it is very different. First, it uses a template file whilecargo-sync-readmelets you use your README file without having to depend on a template. Also, cargo-readme has special semantics in its template (like {{crate_name}}, etc.) whilecargo-sync-readmeis simpler and just requires a single marker. To sum up:cargo-readmeis heavier and is likely to require you to break your file into two separate files but contains more customization options whilecargo-sync-readmeonly requires a single line in your README and will synchronize from within that same file.
Feel free to comment, open issues, drink beers, share that awesome bear driving a sausage podracer and most of all… keep the vibes!