Skip to main content

Crate cicero

Crate cicero 

Source
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 template

You 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. githubcrates-iodocs-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 Error type, 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.