Skip to main content

Crate cargo_reedme

Crate cargo_reedme 

Source
Expand description

crates.io docs.rs license msrv github

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.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 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 --check

On 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 World is the single input that the program receives, essentially the program is almost entirely a pure function

Structs§

GeneratedReadme
Data about individual README files
Output
Output of the program, with all computed README paths

Functions§

resolve