about summary refs log tree commit diff stats
path: root/pkgs/by-name/fu/fupdate/src/cli.rs
blob: 6f970ac476268d65f71bc48b7b9ab93f537551de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
}