Expand description
Generate README.md from documentation comments in lib.rs or main.rs
§Example
The following documentation in lib.rs:
//! This prints all prime numbers, using [`println!`]:
//!
//! ```
//! # fn main() {
//! for i in 2.. {
//! if is_prime(i) {
//! println!("{i}");
//! }
//! }
//! # }
//! ```Generates the following README.md when running cargo +nightly reedme:
This prints all prime numbers, using [`println!`](https://doc.rust-lang.org/stable/std/macro.println.html):
```rust
for i in 2.. {
if is_prime(i) {
println!("{i}");
}
}
```§Installation
cargo install cargo-reedme§Features
- Generate
README.mdfrom documentation comments inlib.rs - Intra-doc link resolution
- Code blocks transformation
- Macro expansion
- Check mode
- Workspace support
- Cargo features
- Informational note
- Config
- Incremented headings
- Use programmatically from scripts
§Generate README.md from documentation comments in lib.rs
Running cargo +nightly reedme will take your doc comments and generate a README from them. This src/lib.rs:
//! Hello, world!Generates the following README.md:
<!-- cargo-reedme: start -->
Hello, world!
<!-- cargo-reedme: end -->If the README.md file already exists, it must have a <!-- cargo-reedme --> somewhere inside of it. If the README.md contains the following:
# my_crate
<!-- cargo-reedme -->Running cargo +nightly reedme will replace that <!-- cargo-reedme --> with documentation from lib.rs:
# my_crate
<!-- cargo-reedme: start -->
Hello, world!
<!-- cargo-reedme: end -->Further invocations of cargo +nightly reedme update the inserted region
§Intra-doc link resolution
Intra-doc links will be transformed into absolute URLs:
//! This data structure is [`serde_json::Value`](Value).
struct Value;The above generate the following README.md:
This data structure is [`serde_json::Value`](https://docs.rs/serde_json/1.0.149/serde_json/enum.Value.html).§Code blocks transformation
Code blocks will have rust language added, and hidden lines (lines starting with #) will be removed:
//! An example program:
//!
//! ```
//! # fn main() {
//! // "hello world" in Rust
//! println!("Hello, world!");
//! # }
//! ```The above generates the following README.md:
An example program:
```rust
// "hello world" in Rust
println!("Hello, world!");
```§Macro expansion
Macros in doc comments get properly expanded:
//! ```toml
//! [dependencies]
#![doc = concat!("derive_aliases = '", env!("CARGO_PKG_VERSION"), "'")]
//! ```The above generates the following README.md:
```toml
[dependencies]
derive_aliases = '0.4'
```Notice that the concat! and inner env! macro was expanded appropriately.
§Check mode
Run cargo reedme as part of your CI pipeline!
The --check flag is used to make sure PRs keep the README.md up to date with lib.rs doc comments.
An example workflow that runs cargo reedme --check on every commit and PR:
# .github/workflows/cargo-reedme.yaml
name: cargo-reedme
on:
pull_request:
push:
branches:
- main
jobs:
cargo-reedme:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions-rust-lang/setup-rust-toolchain@v1
- run: cargo install --locked cargo-reedme@0.6.1
- run: cargo +nightly reedme --checkOn failure, the program exits with a non-zero exit code and prints a colorful diff between the expected and actual README.md files
§Workspace support
Generate README.mds for all crates in your workspace with a single command!
Supports --workspace, --exclude, and --package
§Cargo features
Supports --all-features, --features, and --no-default-features
§Informational note
When cargo +nightly reedme generates your README.md file, it will insert a comment that explains how this section was generated:
# my_crate
<!-- cargo-reedme: start -->
<!-- cargo-reedme: info-start
Do not edit this region by hand
===============================
This region was generated from Rust documentation comments by `cargo-reedme` using this command:
cargo reedme
for more info: https://github.com/nik-rev/cargo-reedme
cargo-reedme: info-end -->
Your documentation
<!-- cargo-reedme: end -->This note can be customized via the note field in metadata table in Cargo.toml
§Config
You can configure the behavior of cargo reedme via the crate-level [package.metadata] table in Cargo.toml:
# project/crates/foo_bar/Cargo.toml
[package.metadata.cargo-reedme]
# ... your settings go here ...…or the workspace-level [workspace.metadata] table
# project/Cargo.toml
[workspace.metadata.cargo-reedme]
# ... your settings go here ...And if none of the above are defined, cargo reedme will use fields of the same names as defined in metadata.docs.rs (see docs.rs metadata section)
§Default config
The default config is this:
#! This is the default configuration for `cargo-reedme`
#!
#! These fields can be overridden in:
#!
#! - `[package.metadata.cargo-reedme]` in package `Cargo.toml`
#! - `[workspace.metadata.cargo-reedme]` in virtual manifest, workspace `Cargo.toml`
# The base URL for every generated URL in the README
#
# https://docs.rs/serde_json/1.0.149/serde_json/enum.Value.html
# ^^^^^^^^^^^^^^^
base-url = "https://docs.rs"
# The note that appears at the beginning of the generated section.
#
# When running with `--check`, the note can differ. 2 README files are considered the same
# regardless of the difference between their "note" section.
#
# Available values for interpolation:
#
# - `args`: Command-line arguments received
# - `toolchain`: Value of RUST_TOOLCHAIN environment variable
note = """
Do not edit this region by hand
===============================
This region was generated from Rust documentation comments by `cargo-reedme` using this command:
cargo +{toolchain} reedme {args}
for more info: https://github.com/nik-rev/cargo-reedme
"""
# Which target to generate the README for
#
# Possible values:
#
# - "lib": README will be generated for the library target (lib.rs)
# - "bin": README will be generated for the binary target (main.rs)
# - "bin:<name>": README will be generated for the binary target with the given name
# - "heuristic": README will be generated for the library target (lib.rs), and if it doesn't exist or
# its documentation is empty, the README will be generated for the first binary target (main.rs)
target = "heuristic"
# If `true`, increases level of all headings by 1 when inserting into a README
# that already has a level 1 heading before the inserted region
increment-headings = true
# If the "latest" version should be used when generating links, or the exact version
#
# - `true`: in the URL, "latest" will always be set as the version
#
# Example generated URL: https://docs.rs/serde_json/latest/serde_json/enum.Value.html
#
# - `false`: in the URL, the crate's current version will be set
#
# Note that because docs.rs can take a while to build your crate's version - it means shortly after
# releases, the links in your crate's documentation will be broken - until docs.rs finishes building your crate
#
# Example generated URL: https://docs.rs/serde_json/1.0.149/serde_json/enum.Value.html
use-latest-version = true
# Features to pass to Cargo
#
# If not specified, defaults to the value of `metadata.docs.rs.rustdoc-args` in `Cargo.toml`
#
# features = []
# Whether to pass `--all-features` to Cargo
#
# If not specified, defaults to the value of `metadata.docs.rs.rustdoc-args` in `Cargo.toml`
#
# all-features = false
# Whether to pass `--no-default-features` to Cargo
#
# If not specified, defaults to `metadata.docs.rs.no-default-features`
#
# no-default-features = false
# Additional `RUSTFLAGS` to set
#
# If not specified, defaults to the value of `metadata.docs.rs.rustdoc-args` in `Cargo.toml`
#
# rustc-args = []
# Additional `RUSTDOCFLAGS` to set
#
# If not specified, defaults to the value of `metadata.docs.rs.rustdoc-args` in `Cargo.toml`
#
# rustdoc-args = []Fun fact: This README itself is generated by cargo +nightly reedme. The above TOML is added from the default_config.toml file like this:
#![doc = include_str!("default_config.toml")]§Incremented headings
It’s good practice to only have a single level 1 heading. rustdoc will decrement all of your settings in the output HTML files, so your level 1 headings become level 2 headings and so on.
cargo reedme does the same. If your README file already has a level 1 heading, every heading will be incremented:
//! # Usage
//!
//! ...
//!
//! # Examples
//!
//! ...The following README.md file:
# docstr
<!-- cargo-reedme -->Will be updated to this, when running cargo +nightly reedme:
# docstr
## Usage
...
## Examples
...§Use programmatically from scripts
The --json flag can be used to have cargo +nightly reedme do all computation but not write any files, so you can
do with that data as you please.
You can also use cargo reedme as a crate. 95% of the cargo reedme’s logic lives in a single, pure function cargo_reedme::resolve
which does no IO. It has the following signature:
pub fn resolve(world: &World) -> Result<Output>You can take a look at main.rs to see how this function is called
§Credits
This project was inspired by:
Re-exports§
pub use world::World;
Modules§
- config
- Handles configuration in the
Cargo.toml[workspace.metadata]and[package.metadata]sections - insert_
into_ readme - Handles logic for inserting generated README files into existing README files
- world
- The
Worldis the single input that the program receives, essentially the program is almost entirely a pure function
Structs§
- Generated
Readme - Data about individual README files
- Output
- Output of the program, with all computed README paths