diff --git a/build.rs b/build.rs index aa54539..fc7d954 100644 --- a/build.rs +++ b/build.rs @@ -33,24 +33,41 @@ /// - `target/debug/build/ouch-195b34a8adca6ec3/out/completions` /// /// The _"195b34a8adca6ec3"_ part is a hash that might change between runs. -use std::{env, fs::create_dir_all, path::Path}; +use std::{env, fs, path::Path}; -use clap::{ArgEnum, IntoApp}; +use clap::IntoApp; use clap_complete::{generate_to, Shell}; +const TARGET_SHELLS: &[Shell] = &[Shell::Bash, Shell::Zsh, Shell::Fish]; + include!("src/opts.rs"); fn main() { println!("cargo:rerun-if-env-changed=GEN_COMPLETIONS"); + println!("cargo:rerun-if-env-changed=OUCH_COMPLETIONS_FOLDER"); - if let Some(completions_output_directory) = detect_completions_output_directory() { - create_dir_all(&completions_output_directory).expect("Could not create shell completions output folder."); - let app = &mut Opts::command(); + let completions_output_directory = match detect_completions_output_directory() { + Some(inner) => inner, + _ => return, + }; - for shell in Shell::value_variants() { - generate_to(*shell, app, "ouch", &completions_output_directory) - .unwrap_or_else(|err| panic!("Failed to generate shell completions for {}: {}.", shell, err)); - } + fs::create_dir_all(&completions_output_directory).expect("Could not create shell completions output folder."); + + let app = &mut Opts::command(); + + for shell in TARGET_SHELLS { + let target_directory = if env::var_os("OUCH_COMPLETIONS_FOLDER").is_some() { + let shell_name = shell.to_string(); + + let shell_dir = completions_output_directory.join(&shell_name); + fs::create_dir(&shell_dir).expect("Failed to create directory for shell completions"); + + shell_dir + } else { + completions_output_directory.clone() + }; + generate_to(*shell, app, "ouch", &target_directory) + .unwrap_or_else(|err| panic!("Failed to generate shell completions for {}: {}.", shell, err)); } } @@ -63,6 +80,10 @@ fn detect_completions_output_directory() -> Option { return Some(dir.into()); }; + get_deprecated_completions_directory() +} + +fn get_deprecated_completions_directory() -> Option { // If set, directory goes inside of cargo's `target/` let gen_completions = env::var_os("GEN_COMPLETIONS").map(|var| &var == "1").unwrap_or(false); if gen_completions { diff --git a/src/opts.rs b/src/opts.rs index e33fbdc..b42b225 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -10,6 +10,9 @@ use clap::{Parser, ValueHint}; /// Repository: https://github.com/ouch-org/ouch #[derive(Parser, Debug)] #[clap(about, version)] +// Ignore bare urls in the documentation of this file because the doc comments +// are also being used by Clap's --help generation +#[allow(rustdoc::bare_urls)] pub struct Opts { /// Skip [Y/n] questions positively. #[clap(short, long, conflicts_with = "no", global = true)] @@ -48,6 +51,7 @@ pub struct Opts { // Clap commands: // - `help` #[derive(Parser, PartialEq, Eq, Debug)] +#[allow(rustdoc::bare_urls)] pub enum Subcommand { /// Compress one or more files into one output file. #[clap(alias = "c")] diff --git a/src/utils/fs.rs b/src/utils/fs.rs index ec321bd..96f5523 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -126,8 +126,8 @@ pub fn try_infer_extension(path: &Path) -> Option { } /// Returns true if a path is a symlink. -/// This is the same as the nightly https://doc.rust-lang.org/std/path/struct.Path.html#method.is_symlink -// Useful to detect broken symlinks when compressing. (So we can safely ignore them) +/// This is the same as the nightly +/// Useful to detect broken symlinks when compressing. (So we can safely ignore them) pub fn is_symlink(path: &Path) -> bool { fs::symlink_metadata(path) .map(|m| m.file_type().is_symlink())