Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Library Usage

cargo-generate is also a Rust library. Any crate can depend on it and drive template generation from code, using the same path as the cargo generate CLI.

A full worked example lives in this repository at examples/how-to-use-cargo-gen-as-library/. The snippets below are pulled straight from that file with mdbook’s {{#include}}, so they cannot drift out of sync.

Depend on cargo-generate

Add the crate to your Cargo.toml:

[dependencies]
cargo-generate = "*"

Cargo features

FeatureDefaultDescription
gitFetching templates from git repositories, and initializing a repository in the generated project. Pulls in gix and reqwest.

If your tool only ever generates from local templates, turning git off drops the whole gix/reqwest/rustls tree:

[dependencies]
cargo-generate = { version = "*", default-features = false }

Your code does not change. GenerateArgs, TemplatePath and Vcs keep every field, so whatever compiled with default features still compiles. What changes is at runtime: asking for a git template — as the example on this page does — or for a git repository in the generated project returns an error naming the feature rather than doing the work. Local-path templates, hooks, rendering and workspace membership are unaffected.

Imports

Three types cover the common cases:

#![allow(unused)]
fn main() {
use cargo_generate::{generate, GenerateArgs, TemplatePath, Vcs};
}
  • GenerateArgs mirrors the top-level CLI arguments.
  • TemplatePath describes where the template comes from: a git url, a local path, a favorite, etc.
  • Vcs controls which version control system (if any) is initialized in the generated project.

1. Build a GenerateArgs

Populate only the fields you care about; everything else falls back to GenerateArgs::default() / TemplatePath::default():

#![allow(unused)]
fn main() {
    let wasm_pack_args = GenerateArgs {
        name: Some("my-project".to_string()),
        vcs: Some(Vcs::Git),
        template_path: TemplatePath {
            git: Some("https://github.com/rustwasm/wasm-pack-template.git".to_string()),
            ..TemplatePath::default()
        },
        ..GenerateArgs::default()
    };
}

The example above is equivalent to running:

cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project

2. Call generate

generate runs the same flow as the CLI: clone the template, expand placeholders, run hooks, and (if a VCS is requested) initialize the new repository. On success it returns the PathBuf of the generated project:

#![allow(unused)]
fn main() {
    let _path = generate(wasm_pack_args).expect("something went wrong!");
}

Generating without git

If your tool carries its own blueprint, there is nothing to clone — and no reason to carry a git implementation. examples/scaffold-from-blueprint/ is that shape in full, with default-features = false on its dependency line.

The blueprint is compiled into the binary, so the tool keeps working wherever it is installed:

#![allow(unused)]
fn main() {
/// The blueprint, as bytes in the binary. Nothing is read from the
/// source tree at runtime, so the tool keeps working after
/// `cargo install`.
static BLUEPRINT: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/blueprint");
}

cargo-generate reads templates from a directory, so the bytes are unpacked to a temporary one first. It has to outlive the call — dropping it takes the blueprint with it:

#![allow(unused)]
fn main() {
    // cargo-generate reads templates from a directory, so hand it one.
    // `tmp` has to outlive the call — dropping it deletes the blueprint.
    let tmp = TempDir::new()?;
    BLUEPRINT.extract(tmp.path())?;
}

From there it is an ordinary local-path generation:

#![allow(unused)]
fn main() {
    let args = GenerateArgs {
        name: Some("my-service".to_string()),
        // Without the `git` feature this is already the default, but
        // saying it is what makes the example independent of that.
        vcs: Some(Vcs::None),
        template_path: TemplatePath {
            path: Some(tmp.path().display().to_string()),
            ..TemplatePath::default()
        },
        ..GenerateArgs::default()
    };
}

vcs: Some(Vcs::None) is redundant without the git feature — that is already the default there — but stating it keeps the example working the same way whichever features are on.

Running the example

From a checkout of this repository:

cd examples/how-to-use-cargo-gen-as-library
cargo run

This creates a my-project/ directory in the current folder, the same result you would get from running cargo generate on the command line.