feat: add completions subcommand
This commit is contained in:
@@ -14,7 +14,7 @@ build = "build.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.6.6", features = ["derive"] }
|
clap = { version = "4.6.6", features = ["derive"] }
|
||||||
# clap_complete = "4.5.35"
|
clap_complete = "4.6.9"
|
||||||
anyhow = "1.0.104"
|
anyhow = "1.0.104"
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use super::{Django, DockerCompose, Link, Postgres};
|
use super::{Django, DockerCompose, Link, Postgres};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
use clap_complete::Shell;
|
||||||
|
|
||||||
/// A program for interacting with various dockerized applications.
|
/// A program for interacting with various dockerized applications.
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@@ -34,4 +35,10 @@ pub enum Commands {
|
|||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Link,
|
command: Link,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Print a shell completion script on stdout
|
||||||
|
Completions {
|
||||||
|
/// Shell to generate the script for
|
||||||
|
shell: Shell,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,5 +50,6 @@ fn main() -> Result<()> {
|
|||||||
null,
|
null,
|
||||||
} => scripts::link::check(&paths, porcelain, null),
|
} => scripts::link::check(&paths, porcelain, null),
|
||||||
},
|
},
|
||||||
|
cli::Commands::Completions { shell } => scripts::completions::completions(shell),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
46
src/scripts/completions.rs
Normal file
46
src/scripts/completions.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use clap::CommandFactory;
|
||||||
|
use clap_complete::{Shell, generate};
|
||||||
|
|
||||||
|
use crate::cli::Ahab;
|
||||||
|
|
||||||
|
pub fn completions(shell: Shell) -> Result<()> {
|
||||||
|
let script = script(shell);
|
||||||
|
|
||||||
|
let mut stdout = io::stdout().lock();
|
||||||
|
match stdout.write_all(&script).and_then(|()| stdout.flush()) {
|
||||||
|
Err(e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(()),
|
||||||
|
result => result.context("writing the completion script"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn script(shell: Shell) -> Vec<u8> {
|
||||||
|
let mut cmd = Ahab::command();
|
||||||
|
let name = cmd.get_name().to_string();
|
||||||
|
|
||||||
|
let mut script = Vec::new();
|
||||||
|
generate(shell, &mut cmd, name, &mut script);
|
||||||
|
script
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{Shell, script};
|
||||||
|
use clap::ValueEnum;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn every_shell_gets_a_script_covering_the_subcommands() {
|
||||||
|
for shell in Shell::value_variants() {
|
||||||
|
let out = String::from_utf8(script(*shell)).expect("script is utf8");
|
||||||
|
|
||||||
|
for subcommand in ["compose", "django", "postgres", "link", "completions"] {
|
||||||
|
assert!(
|
||||||
|
out.contains(subcommand),
|
||||||
|
"{shell:?} script never mentions {subcommand}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod completions;
|
||||||
pub mod django;
|
pub mod django;
|
||||||
pub mod docker;
|
pub mod docker;
|
||||||
pub mod docker_compose;
|
pub mod docker_compose;
|
||||||
|
|||||||
Reference in New Issue
Block a user