Implement better CLI API (closes #7).

This commit is contained in:
R-VdP 2023-02-15 12:51:44 +01:00
parent 972d27b977
commit 0d1067ac72
No known key found for this signature in database
2 changed files with 81 additions and 19 deletions

View file

@ -14,16 +14,11 @@ struct NixBuildOutput {
outputs: HashMap<String, String>, outputs: HashMap<String, String>,
} }
pub fn generate(flake_uri: &str) -> Result<()> { pub fn generate(flake_uri: &str) -> Result<StorePath> {
// FIXME: we should not hard-code the system here let store_path = build(flake_uri)?;
let flake_attr = format!("{FLAKE_ATTR}.x86_64-linux");
log::info!("Building new system-manager generation...");
log::info!("Running nix build...");
let store_path = run_nix_build(flake_uri, &flake_attr).and_then(get_store_path)?;
let profile_dir = Path::new(PROFILE_DIR); let profile_dir = Path::new(PROFILE_DIR);
let profile_name = Path::new(PROFILE_NAME); let profile_name = Path::new(PROFILE_NAME);
log::info!("Creating new generation from {}", store_path); log::info!("Creating new generation from {}", store_path);
install_nix_profile(&store_path, profile_dir, profile_name).map(print_out_and_err)?; install_nix_profile(&store_path, profile_dir, profile_name).map(print_out_and_err)?;
@ -31,7 +26,16 @@ pub fn generate(flake_uri: &str) -> Result<()> {
create_gcroot(GCROOT_PATH, &profile_dir.join(profile_name))?; create_gcroot(GCROOT_PATH, &profile_dir.join(profile_name))?;
log::info!("Done"); log::info!("Done");
Ok(()) Ok(store_path)
}
pub fn build(flake_uri: &str) -> Result<StorePath> {
// FIXME: we should not hard-code the system here
let flake_attr = format!("{FLAKE_ATTR}.x86_64-linux");
log::info!("Building new system-manager generation...");
log::info!("Running nix build...");
run_nix_build(flake_uri, &flake_attr).and_then(get_store_path)
} }
fn install_nix_profile( fn install_nix_profile(

View file

@ -1,6 +1,6 @@
use std::process::ExitCode; use std::process::ExitCode;
use anyhow::{anyhow, Result}; use anyhow::Result;
use clap::Parser; use clap::Parser;
use system_manager::StorePath; use system_manager::StorePath;
@ -12,17 +12,39 @@ struct Args {
action: Action, action: Action,
} }
#[derive(clap::Args, Debug)]
struct BuildArgs {
#[arg(long)]
flake_uri: String,
}
#[derive(clap::Args, Debug)]
struct ActivationArgs {
#[arg(long, action)]
ephemeral: bool,
}
#[derive(clap::Subcommand, Debug)] #[derive(clap::Subcommand, Debug)]
enum Action { enum Action {
Activate { Activate {
#[arg(long)] #[arg(long)]
store_path: StorePath, store_path: StorePath,
#[arg(long, action)] #[command(flatten)]
ephemeral: bool, activation_args: ActivationArgs,
},
Build {
#[command(flatten)]
build_args: BuildArgs,
}, },
Generate { Generate {
#[arg(long)] #[command(flatten)]
flake_uri: String, build_args: BuildArgs,
},
Switch {
#[command(flatten)]
build_args: BuildArgs,
#[command(flatten)]
activation_args: ActivationArgs,
}, },
} }
@ -35,19 +57,55 @@ fn main() -> ExitCode {
} }
fn go(action: Action) -> Result<()> { fn go(action: Action) -> Result<()> {
check_root()?;
match action { match action {
Action::Activate { Action::Activate {
store_path, store_path,
ephemeral, activation_args: ActivationArgs { ephemeral },
} => system_manager::activate::activate(store_path, ephemeral), } => {
Action::Generate { flake_uri } => system_manager::generate::generate(&flake_uri), check_root()?;
activate(store_path, ephemeral)
} }
Action::Build {
build_args: BuildArgs { flake_uri },
} => build(flake_uri),
Action::Generate {
build_args: BuildArgs { flake_uri },
} => {
check_root()?;
generate(flake_uri).map(|_| ())
}
Action::Switch {
build_args: BuildArgs { flake_uri },
activation_args: ActivationArgs { ephemeral },
} => {
check_root()?;
let store_path = generate(flake_uri)?;
activate(store_path, ephemeral)
}
}
}
fn build(flake_uri: String) -> Result<()> {
let store_path = do_build(flake_uri)?;
log::info!("{store_path}");
Ok(())
}
fn do_build(flake_uri: String) -> Result<StorePath> {
system_manager::generate::build(&flake_uri)
}
fn generate(flake_uri: String) -> Result<StorePath> {
system_manager::generate::generate(&flake_uri)
}
fn activate(store_path: StorePath, ephemeral: bool) -> Result<()> {
system_manager::activate::activate(store_path, ephemeral)
} }
fn check_root() -> Result<()> { fn check_root() -> Result<()> {
if !nix::unistd::Uid::is_root(nix::unistd::getuid()) { if !nix::unistd::Uid::is_root(nix::unistd::getuid()) {
return Err(anyhow!("We need root permissions.")); anyhow::bail!("We need root permissions.")
} }
Ok(()) Ok(())
} }