bare-script 0.1.1

The type-safe scripting authority for Rust. A framework for building robust shell commands and automation with 'Parse, don't validate' philosophy.
Documentation

bare-script

Rust Version License  crates.io codecov CI Documentation unsafe forbidden

The type-safe scripting authority for Rust.

A framework for building robust shell commands and automation with "Parse, don't validate" philosophy.

Overview

bare-script provides a type-safe approach to building shell commands and automation scripts in Rust:

  • Type-safe commands - Strongly typed command arguments and options
  • Validation at boundaries - Parse and validate input once, then trust throughout execution
  • Cross-platform - Works consistently across Linux, macOS, and Windows
  • Composable - Build complex pipelines from simple commands
  • Zero runtime overhead - After validation, command execution is cost-free

Philosophy

Parse, Don't Validate

Traditional shell scripting relies on loose string manipulation and runtime checks. bare-script enforces:

  1. Parse - Convert command-line input into strongly typed values
  2. Validate - Ensure values meet constraints at command invocation
  3. Trust - Use validated values without re-checking during execution

This eliminates common shell scripting pitfalls and ensures type safety.

Quick Start

use bare_script::sync::CommandBuilder;

fn main() -> Result<(), bare_script::ScriptError> {
    let output = CommandBuilder::new("ls")
        .arg("-l")
        .arg("-h")
        .capture_output()
        .execute()?;

    println!("{}", output);
    eprintln!("{}", output.stderr_str());
    Ok(())
}

Async Quick Start

use bare_script::proc::CommandBuilder;

#[tokio::main]
async fn main() -> Result<(), bare_script::ScriptError> {
    let output = CommandBuilder::new("ls")
        .arg("-l")
        .arg("-h")
        .capture_output()
        .execute()
        .await?;

    println!("{}", output);
    eprintln!("{}", output.stderr_str());
    Ok(())
}

Features

  • Type-safe command building - Compile-time guarantee of valid command structure
  • Type-safe arguments - Args builder for validated CLI arguments
  • Cross-platform execution - Consistent behavior across operating systems
  • Pipeline support - Chain commands with pipes (sync & async)
  • Output capture - Capture stdout, stderr, and exit codes
  • Environment control - Set and manage environment variables
  • Working directory management - Execute commands in specific directories
  • Timeout support - Execute commands with timeouts
  • Shell integration helpers - which, command_exists, eval

Examples

Pipeline

use bare_script::sync::Pipeline;

let output = Pipeline::new("echo")
    .arg("hello world")
    .pipe("grep")
    .arg("hello")
    .capture_output()
    .execute()?;

Type-safe Arguments

use bare_script::Args;

let args = Args::new()
    .flag("-v", "--verbose")
    .option("-o", "--output")
    .value("file.txt")
    .positional()
    .validate()?;

Shell Helpers

use bare_script::shell;

// Find executable in PATH
if let Some(path) = which("ls")? {
    println!("Found: {}", path);
}

// Execute shell command
let output = eval("echo $HOME")?;

Timeout

use std::time::Duration;
use bare_script::sync::CommandBuilder;

let result = CommandBuilder::new("sleep")
    .arg("10")
    .execute_with_timeout(Duration::from_secs(1));

assert!(result.is_err());

Roadmap

  • Core command execution framework
  • Type-safe argument parsing
  • Pipeline and redirection support
  • Cross-platform compatibility layer
  • Environment variable management
  • Output streaming (via Pipeline)
  • Background process management
  • Shell integration helpers

MSRV (Minimum Supported Rust Version)

This crate requires Rust 1.85.0 or later. This is due to:

  • Edition 2024 features and syntax
  • Strict linting configuration (#![forbid(unsafe_code)])
  • Advanced type-state pattern usage

We aim to support the two latest stable Rust releases.

License

Licensed under either of:

Contributing

Contributions are welcome! Please open an issue or submit a PR.

Testing

This project includes multiple test suites:

# Run all tests

cargo test


# Run with coverage

cargo llvm-cov --all-features


# Run benchmarks

cargo bench


# Run fuzz tests (requires nightly)

cargo +nightly fuzz run fuzz_args

Fuzzing

For fuzz testing, we use cargo-fuzz:

# Install cargo-fuzz

cargo +nightly install cargo-fuzz


# Run fuzz tests

cargo +nightly fuzz run fuzz_args

Note: Fuzzing requires nightly Rust.

Related Crates

  • bare-types - Zero-cost foundation for type-safe domain modeling
  • bare-config - Type-safe configuration authority