Files
sausage/host/src/main.rs
T

81 lines
2.6 KiB
Rust

//! The `sausage` binary: subcommands only, each delegates to its module.
use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser)]
#[command(version, about)]
struct Cli {
/// Shared host-user compile cache (otherwise SAUSAGE_CACHE or the XDG cache folder).
#[arg(long, global = true)]
cache: Option<PathBuf>,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
/// Start a world: the harness, its services and a console.
Run {
world: PathBuf,
#[arg(long)]
userland: Option<PathBuf>,
},
/// Run a shell in a world. With `-c`, run one command and exit with its status.
Sh {
world: PathBuf,
#[arg(short = 'c')]
command: Option<String>,
#[arg(long)]
userland: Option<PathBuf>,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
if let Some(cache) = cli.cache {
sausage::process::configure_cache(cache)?;
}
match cli.command {
Command::Run { world, userland } => {
let bundle =
userland.or_else(|| std::env::var_os("SAUSAGE_USERLAND").map(PathBuf::from));
sausage::harness::run_with_userland(&world, bundle.as_deref()).await
}
Command::Sh {
world,
command,
userland,
} => {
use sausage::exec::{Command, Exec, Options, Stream};
let bundle =
userland.or_else(|| std::env::var_os("SAUSAGE_USERLAND").map(PathBuf::from));
let world = sausage::world::World::open_with_userland(&world, bundle.as_deref())?;
let runtime = sausage::process::Runtime::new(world)?;
let script =
command.ok_or_else(|| anyhow::anyhow!("interactive shell is not implemented"))?;
let status = runtime
.exec(
Command::Shell(script),
Options {
cwd: "/".into(),
..Default::default()
},
&mut |stream, bytes| {
use std::io::Write;
match stream {
Stream::Stdout => {
let _ = std::io::stdout().write_all(bytes);
}
Stream::Stderr => {
let _ = std::io::stderr().write_all(bytes);
}
}
},
)
.await?;
std::process::exit(status);
}
}
}