Skip to content

Commit

Permalink
moss/cli: Add --generate-completions for zsh, fish, bash
Browse files Browse the repository at this point in the history
Signed-off-by: Ikey Doherty <ikey@serpentos.com>
  • Loading branch information
ikeycode committed Nov 6, 2024
1 parent d5e5a72 commit c9eece2
Showing 1 changed file with 33 additions and 6 deletions.
39 changes: 33 additions & 6 deletions moss/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
//
// SPDX-License-Identifier: MPL-2.0

use std::{env, path::PathBuf};
use std::{env, fs, io, path::Path, path::PathBuf};

use clap::{Arg, ArgAction, Command};
use clap_complete::{
generate_to,
shells::{Bash, Fish, Zsh},
};
use clap_mangen::Man;
use moss::{installation, runtime, Installation};
use thiserror::Error;
Expand Down Expand Up @@ -68,6 +72,14 @@ fn command() -> Command {
.value_name("DIR")
.hide(true),
)
.arg(
Arg::new("generate-completions")
.long("generate-completions")
.help("Generate shell completions")
.action(ArgAction::Set)
.value_name("DIR")
.hide(true),
)
.arg_required_else_help(true)
.subcommand(extract::command())
.subcommand(index::command())
Expand All @@ -84,7 +96,7 @@ fn command() -> Command {
}

/// Generate manpages for all commands recursively
fn generate_manpages(cmd: &Command, dir: &std::path::Path, prefix: Option<&str>) -> std::io::Result<()> {
fn generate_manpages(cmd: &Command, dir: &Path, prefix: Option<&str>) -> io::Result<()> {
let name = cmd.get_name();
let man = Man::new(cmd.to_owned());
let mut buffer: Vec<u8> = Default::default();
Expand All @@ -96,7 +108,7 @@ fn generate_manpages(cmd: &Command, dir: &std::path::Path, prefix: Option<&str>)
format!("{}.1", name)
};

std::fs::write(dir.join(filename), buffer)?;
fs::write(dir.join(filename), buffer)?;

for subcmd in cmd.get_subcommands() {
let new_prefix = if let Some(p) = prefix {
Expand All @@ -109,18 +121,33 @@ fn generate_manpages(cmd: &Command, dir: &std::path::Path, prefix: Option<&str>)
Ok(())
}

/// Generate shell completions
fn generate_completions(cmd: &mut Command, dir: &Path) -> io::Result<()> {
generate_to(Bash, cmd, "moss", dir)?;
generate_to(Fish, cmd, "moss", dir)?;
generate_to(Zsh, cmd, "moss", dir)?;
Ok(())
}

/// Process all CLI arguments
pub fn process() -> Result<(), Error> {
let args = replace_aliases(env::args());
let matches = command().get_matches_from(args);

if let Some(dir) = matches.get_one::<String>("generate-manpages") {
let dir = std::path::Path::new(dir);
std::fs::create_dir_all(dir)?;
let dir = Path::new(dir);
fs::create_dir_all(dir)?;
generate_manpages(&command(), dir, None)?;
return Ok(());
}

if let Some(dir) = matches.get_one::<String>("generate-completions") {
let dir = Path::new(dir);
fs::create_dir_all(dir)?;
generate_completions(&mut command(), dir)?;
return Ok(());
}

// Print the version, but not if the user is using the version subcommand
if matches.get_flag("verbose") {
if let Some(command) = matches.subcommand_name() {
Expand Down Expand Up @@ -234,5 +261,5 @@ pub enum Error {
Installation(#[from] installation::Error),

#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
Io(#[from] io::Error),
}

0 comments on commit c9eece2

Please sign in to comment.