about summary refs log tree commit diff stats
path: root/pkgs/by-name/fu/fupdate/src
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/fu/fupdate/src')
-rw-r--r--pkgs/by-name/fu/fupdate/src/cli.rs46
-rw-r--r--pkgs/by-name/fu/fupdate/src/main.rs46
2 files changed, 92 insertions, 0 deletions
diff --git a/pkgs/by-name/fu/fupdate/src/cli.rs b/pkgs/by-name/fu/fupdate/src/cli.rs
new file mode 100644
index 00000000..6f970ac4
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/src/cli.rs
@@ -0,0 +1,46 @@
+use std::{env, ffi::OsStr, fs::read_dir};
+
+use clap::Parser;
+use clap_complete::{engine::ArgValueCompleter, CompletionCandidate};
+
+/// This is a Nix flake update manager.
+#[derive(Parser, Debug)]
+#[command(author, version, about)]
+pub struct CliArgs {
+    /// The command to execute.
+    #[arg(add = ArgValueCompleter::new(get_fupdate_commands))]
+    pub command: Vec<String>,
+}
+
+fn get_fupdate_commands(current: &OsStr) -> Vec<CompletionCandidate> {
+    let mut output = vec![];
+    let path = env::var("PATH").unwrap_or_default();
+
+    let Some(current) = current.to_str() else {
+        return output;
+    };
+
+    for directory in path.split(':') {
+        if let Ok(mut read) = read_dir(directory) {
+            for value in read.by_ref().flatten() {
+                let file_name = value.file_name();
+                let name = file_name.to_string_lossy();
+                let Some(stripped) = name.strip_prefix("fupdate-") else {
+                    continue;
+                };
+
+                if stripped.starts_with(current) {
+                    output.push(CompletionCandidate::new(
+                        value
+                            .file_name()
+                            .to_string_lossy()
+                            .strip_prefix("fupdate-")
+                            .expect("Exists"),
+                    ));
+                }
+            }
+        }
+    }
+
+    output
+}
diff --git a/pkgs/by-name/fu/fupdate/src/main.rs b/pkgs/by-name/fu/fupdate/src/main.rs
new file mode 100644
index 00000000..759f65ec
--- /dev/null
+++ b/pkgs/by-name/fu/fupdate/src/main.rs
@@ -0,0 +1,46 @@
+use std::process::Command;
+
+use anyhow::{bail, Context, Result};
+use clap::{CommandFactory, Parser};
+
+pub mod cli;
+
+use crate::cli::CliArgs;
+
+fn main() -> Result<(), anyhow::Error> {
+    clap_complete::CompleteEnv::with_factory(CliArgs::command).complete();
+
+    let args = CliArgs::parse();
+
+    let command = args.command.first().map_or("flake", String::as_str);
+
+    {
+        let args = if args.command.len() > 1 {
+            &args.command[1..]
+        } else {
+            &[]
+        };
+
+        // println!("Running: `fupdate-{command} {}`", args.join(" "));
+
+        let mut child = Command::new(format!("fupdate-{command}"))
+            .args(args)
+            .spawn()
+            .with_context(|| format!("Failed to spawn `fupdate-{command}`"))?;
+
+        if !child
+            .wait()
+            .with_context(|| format!("Failed to wait for `fupdate-{command}` to finish"))?
+            .success()
+        {
+            bail!("Command `fupdate-{command} {}` failed!", args.join(" "));
+        }
+    }
+
+    Ok(())
+}
+
+#[test]
+fn verify_cli() {
+    CliArgs::command().debug_assert();
+}