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:
cargo install cargo-sync-readme
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-readme
lets 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-readme
is simpler and just requires a single marker. To sum up:cargo-readme
is heavier and is likely to require you to break your file into two separate files but contains more customization options whilecargo-sync-readme
only 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!