eh: clean up dispatch logic

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I63671355750a3c839f71d9155b8c918d6a6a6964
This commit is contained in:
raf 2025-11-13 00:54:48 +03:00
commit 790ea414c3
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
4 changed files with 51 additions and 39 deletions

View file

@ -62,17 +62,20 @@ impl NixCommand {
self self
} }
#[must_use] pub const fn impure(mut self, yes: bool) -> Self { #[must_use]
pub const fn impure(mut self, yes: bool) -> Self {
self.impure = yes; self.impure = yes;
self self
} }
#[must_use] pub const fn interactive(mut self, yes: bool) -> Self { #[must_use]
pub const fn interactive(mut self, yes: bool) -> Self {
self.interactive = yes; self.interactive = yes;
self self
} }
#[must_use] pub const fn print_build_logs(mut self, yes: bool) -> Self { #[must_use]
pub const fn print_build_logs(mut self, yes: bool) -> Self {
self.print_build_logs = yes; self.print_build_logs = yes;
self self
} }

View file

@ -33,7 +33,8 @@ pub enum EhError {
pub type Result<T> = std::result::Result<T, EhError>; pub type Result<T> = std::result::Result<T, EhError>;
impl EhError { impl EhError {
#[must_use] pub const fn exit_code(&self) -> i32 { #[must_use]
pub const fn exit_code(&self) -> i32 {
match self { match self {
Self::ProcessExit { code } => *code, Self::ProcessExit { code } => *code,
Self::NixCommandFailed(_) => 1, Self::NixCommandFailed(_) => 1,

View file

@ -30,6 +30,36 @@ fn main() {
} }
} }
// Design partially taken from Stash
fn dispatch_multicall(app_name: &str, args: std::env::Args) -> Option<Result<i32>> {
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
let fixer = util::DefaultNixFileFixer;
let classifier = util::DefaultNixErrorClassifier;
match app_name {
"nr" => Some(run::handle_nix_run(
&rest,
&hash_extractor,
&fixer,
&classifier,
)),
"ns" => Some(shell::handle_nix_shell(
&rest,
&hash_extractor,
&fixer,
&classifier,
)),
"nb" => Some(build::handle_nix_build(
&rest,
&hash_extractor,
&fixer,
&classifier,
)),
_ => None,
}
}
fn run_app() -> Result<i32> { fn run_app() -> Result<i32> {
let mut args = env::args(); let mut args = env::args();
let bin = args.next().unwrap_or_else(|| "eh".to_string()); let bin = args.next().unwrap_or_else(|| "eh".to_string());
@ -39,31 +69,8 @@ fn run_app() -> Result<i32> {
.unwrap_or("eh"); .unwrap_or("eh");
// If invoked as nr/ns/nb, dispatch directly and exit // If invoked as nr/ns/nb, dispatch directly and exit
match app_name { if let Some(result) = dispatch_multicall(app_name, args) {
"nr" => { return result;
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
let fixer = util::DefaultNixFileFixer;
let classifier = util::DefaultNixErrorClassifier;
return run::handle_nix_run(&rest, &hash_extractor, &fixer, &classifier);
}
"ns" => {
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
let fixer = util::DefaultNixFileFixer;
let classifier = util::DefaultNixErrorClassifier;
return shell::handle_nix_shell(&rest, &hash_extractor, &fixer, &classifier);
}
"nb" => {
let rest: Vec<String> = args.collect();
let hash_extractor = util::RegexHashExtractor;
let fixer = util::DefaultNixFileFixer;
let classifier = util::DefaultNixErrorClassifier;
return build::handle_nix_build(&rest, &hash_extractor, &fixer, &classifier);
}
_ => {}
} }
let cli = Cli::parse(); let cli = Cli::parse();

View file

@ -23,9 +23,10 @@ impl HashExtractor for RegexHashExtractor {
for pattern in &patterns { for pattern in &patterns {
if let Ok(re) = Regex::new(pattern) if let Ok(re) = Regex::new(pattern)
&& let Some(captures) = re.captures(stderr) && let Some(captures) = re.captures(stderr)
&& let Some(hash) = captures.get(1) { && let Some(hash) = captures.get(1)
return Some(hash.as_str().to_string()); {
} return Some(hash.as_str().to_string());
}
} }
None None
} }
@ -62,9 +63,10 @@ impl NixFileFixer for DefaultNixFileFixer {
if path.is_dir() { if path.is_dir() {
stack.push(path); stack.push(path);
} else if let Some(ext) = path.extension() } else if let Some(ext) = path.extension()
&& ext.eq_ignore_ascii_case("nix") { && ext.eq_ignore_ascii_case("nix")
files.push(path); {
} files.push(path);
}
} }
} }
if files.is_empty() { if files.is_empty() {
@ -99,10 +101,9 @@ impl NixFileFixer for DefaultNixFileFixer {
} }
} }
if replaced { if replaced {
fs::write(file_path, new_content) fs::write(file_path, new_content).map_err(|_| EhError::HashFixFailed {
.map_err(|_| EhError::HashFixFailed { path: file_path.to_string_lossy().to_string(),
path: file_path.to_string_lossy().to_string() })?;
})?;
Ok(true) Ok(true)
} else { } else {
Ok(false) Ok(false)