Expand description
§Cicero
Cicero helps you implement a CLI for the CI needs of your Rust project.
You implement this CLI in Rust to benefit from its flexibility and familiarity, while Cicero provides a framework that simplifies common patterns and solves the hard parts that you really shouldn’t write a custom solution for.
§Usage
Below is a working example for building a distribution archive. The modules would be put into separate files.
mod main_rs {
use clap::Parser;
use crate::distribution;
#[derive(Parser)]
enum Cli {
Distribution(distribution::DistributionCli),
}
cicero::workspace!(); //collect information about your workspace crates
fn main() -> cicero::Result<()> {
cicero::init::tracing().init(); //set up logging
match Cli::parse() { //can add multiple subcommands/workflows
Cli::Distribution(cli) => cli.run(),
}
}
}
mod distribution {
use std::path::Path;
use cicero::distribution::{bundle::zip::ZipBundler, Distribution, build::{ExecutableBuilder, target}};
use cicero::path::repo_path;
use crate::main_rs::workspace;
#[derive(clap::Args)]
pub struct DistributionCli;
impl DistributionCli {
pub fn run(self) -> cicero::Result<()> {
let distribution = Distribution::new("myproject")?;
distribution
.add_file_from_path(
"README.md", //include into distribution as "README.md"
repo_path!("README.md") //load from path relative to repository root (compile-safe!)
)?
.add_executable(
"myproject_ci", //include as "myproject_ci", or "myproject_ci.exe" when targeting Windows
ExecutableBuilder::new(
workspace::package::example_distribution //crate name from your workspace, as collected by `cicero::workspace!()` above
)
.target(
// `target` module provides compile-time access to targets supported by the Rust compiler.
// Can also parse from the CLI via `Target::from_str()`.
target::x86_64_unknown_linux_gnu
)
)?;
distribution
.dir("doc")? //include the following under a subdirectory "doc/"
.add_all(|dir| build_doc(dir))?;
let path = distribution.bundle(ZipBundler)?;
eprintln!("Placed distribution into {path:?}.");
Ok(())
}
}
use cicero::commands::{Cli, Crate};
use cicero::command_exit_ok::CommandExitOk;
pub static MDBOOK: Cli = Crate::new("mdbook").into_cli(); //defines installation instructions for a CLI tool
pub fn build_doc(out_dir: &Path) -> cicero::Result<()> {
MDBOOK.command() //triggers installation and provides std::process:Command object
.arg("build")
.arg("--dest-dir").arg(out_dir) //write files into distribution directory
.current_dir(repo_path!("doc/"))
.status_exit_ok()?; //runs command like `.status()`, but returns error when status code != 0
Ok(())
}
}
In a codebase with Cicero set up, you would run this example with cargo ci distribution.
It will then build a ZIP archive that contains these files:
myproject
├── README.md
├── myproject_ci (executable)
└── doc
└── ...§Getting Started
Cicero uses a file structure akin to the cargo-xtask pattern. To set it up, you can use the following commands:
cargo install cicero_cli
cicero init #run in your repository
cargo ci hello #runs the 'hello' workflow added by the default templateYou can find usage examples in the Cicero repository: https://codeberg.org/trem/cicero/src/branch/main/examples
§Changelog
The changelog is available here: https://codeberg.org/trem/cicero/src/branch/main/CHANGELOG.md
Modules§
- cache
- Cache intermediate files, so you only have to generate them once.
- command_
exit_ ok - Simplify error handling when a command returns a nonzero exit code.
- commands
- Manage and auto-install CLI tools you need in your CI code.
- distribution
- Bundle a release archive for shipping to users.
- error
- Additional error handling tooling, re-exported from
anyhow. github crates-io docs-rs - init
- Initialization helpers to use in your
main.rs. - path
- Access paths in your repository safely.
- task
- Implementations of common CI tasks.
Macros§
- workspace
- Collect workspace metadata and provide it in a module called
workspace, where this macro is used.
Structs§
- Error
- The
Errortype, a wrapper around a dynamic error type.
Type Aliases§
- Result
Result<T, Error>
Attribute Macros§
- cli
- Easily allow a function to be used as a CLI subcommand.