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](https://img.shields.io/badge/rust-1.85%2B-blue?style=flat-square&logo=rust)](https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html)
[![License](https://img.shields.io/crates/l/bare-script.svg?style=flat-square)](LICENSE-MIT)
[![ crates.io](https://img.shields.io/crates/d/bare-script.svg?style=flat-square)](https://crates.io/crates/bare-script)
[![codecov](https://codecov.io/gh/bare-rs/bare-script/branch/main/graph/badge.svg)](https://codecov.io/gh/bare-rs/bare-script)
[![CI](https://github.com/bare-rs/bare-script/actions/workflows/ci.yml/badge.svg)](https://github.com/bare-rs/bare-script/actions/workflows/ci.yml)
[![Documentation](https://img.shields.io/docsrs/bare-script?style=flat-square)](https://docs.rs/bare-script)
[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-blue?style=flat-square)](https://github.com/bare-rs/bare-script)

**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


```rust
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


```rust
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


```rust
use bare_script::sync::Pipeline;

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

### Type-safe Arguments


```rust
use bare_script::Args;

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

### Shell Helpers


```rust
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


```rust
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


- [x] Core command execution framework
- [x] Type-safe argument parsing
- [x] Pipeline and redirection support
- [x] Cross-platform compatibility layer
- [x] Environment variable management
- [x] Output streaming (via Pipeline)
- [x] Background process management
- [x] 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:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT License ([LICENSE-MIT]LICENSE-MIT)

## Contributing


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

### Testing


This project includes multiple test suites:

```bash
# 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](https://rust-fuzz.github.io/book/cargo-fuzz.html):

```bash
# 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]https://crates.io/crates/bare-types - Zero-cost foundation for type-safe domain modeling
- [bare-config]https://crates.io/crates/bare-config - Type-safe configuration authority