Skip to main content

Crate umbral_cli

Crate umbral_cli 

Source
Expand description

Library surface for user binaries to host umbral’s management subcommands.

umbral-cli ships as two artefacts. The library (this crate) exposes dispatch — the entry point user binaries call to gain the serve / migrate / makemigrations / inspectdb / dumpdata / loaddata subcommands. The binary (umbral) ships as the global scaffolding tool installed via cargo install umbral-cli, and handles startproject / startapp from outside any project.

§Quickstart

In your project’s src/main.rs:

use umbral::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    tracing_subscriber::fmt::init();

    let settings = Settings::from_env()?;
    let pool = umbral::db::connect(&settings.database_url).await?;

    let app = App::builder()
        .settings(settings)
        .database("default", pool)
        .model::<Article>()
        .build_deferred()?;

    umbral_cli::dispatch(app).await
}

Then:

cargo run -- migrate
cargo run -- serve
cargo run -- makemigrations

The subcommands run against the published ambient state (pool, model registry) that the builder set up, so they see every model and plugin the user wired into the builder.

Note build_deferred(), not build(). It wires everything but leaves each plugin’s on_ready hook unfired, so dispatch can fire it once it knows what argv asked for — never for migrate, which exists precisely because the tables those hooks want to seed do not exist yet (gaps3 #41).

Modules§

scaffold
Project + plugin scaffolding.

Constants§

STANDALONE_COMMANDS
The built-in commands that need NO project — no App, database, settings, or compiled models — and can therefore run standalone. Every OTHER command (serve, migrate, makemigrations, seed_data, …) needs the project’s compiled App, so the global umbral binary forwards it to cargo run -- <cmd> instead.

Functions§

builtin_command_names
The framework binary’s own subcommands — serve, migrate, makemigrations, … — read off the derived clap parser rather than hand-listed, so a new subcommand reserves its own name with nothing to remember.
cargo_run_forward_args
Build the cargo argv for forwarding a umbral <cmd> [args...] invocation to the current project’s binary (cargo run -- <cmd> [args...]).
dispatch
Parse argv and run the requested management subcommand against the passed-in App. The user binary’s main.rs calls this after wiring its App — see the module-level docs for the pattern.
dispatch_with_argv
Same as dispatch but argv is passed explicitly instead of read from the process. Lets tests exercise the routing without spawning a subprocess. User code should call dispatch (which reads std::env::args_os() and delegates here).
in_cargo_project
Whether start (or any ancestor) contains a Cargo.toml — i.e. we’re inside a Cargo project cargo run could build. Mirrors how cargo itself finds the manifest by walking up from the working directory, so umbral <cmd> works from a subdirectory just like cargo run does.
try_run_standalone
If argv names a project-independent built-in, run it and return Some(result). Return None otherwise, so the caller (the global umbral binary) forwards the command to the project via cargo run.