81 lines
2.6 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|