Unify completion list between x test tidy and x run generate-completions
This commit is contained in:
parent
0c4fa2690d
commit
46ce66ff5c
3 changed files with 36 additions and 32 deletions
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap_complete::{Generator, shells};
|
||||
|
||||
use crate::core::build_steps::dist::distdir;
|
||||
use crate::core::build_steps::test;
|
||||
use crate::core::build_steps::tool::{self, SourceType, Tool};
|
||||
|
|
@ -285,36 +287,35 @@ impl Step for GenerateWindowsSys {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return tuples of (shell, file containing completions).
|
||||
pub fn get_completion_paths(builder: &Builder<'_>) -> Vec<(&'static dyn Generator, PathBuf)> {
|
||||
vec![
|
||||
(&shells::Bash as &'static dyn Generator, builder.src.join("src/etc/completions/x.py.sh")),
|
||||
(&shells::Zsh, builder.src.join("src/etc/completions/x.py.zsh")),
|
||||
(&shells::Fish, builder.src.join("src/etc/completions/x.py.fish")),
|
||||
(&shells::PowerShell, builder.src.join("src/etc/completions/x.py.ps1")),
|
||||
(&shells::Bash, builder.src.join("src/etc/completions/x.sh")),
|
||||
(&shells::Zsh, builder.src.join("src/etc/completions/x.zsh")),
|
||||
(&shells::Fish, builder.src.join("src/etc/completions/x.fish")),
|
||||
(&shells::PowerShell, builder.src.join("src/etc/completions/x.ps1")),
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct GenerateCompletions;
|
||||
|
||||
macro_rules! generate_completions {
|
||||
( $( ( $shell:ident, $filename:expr ) ),* ) => {
|
||||
$(
|
||||
if let Some(comp) = get_completion($shell, &$filename) {
|
||||
std::fs::write(&$filename, comp).expect(&format!("writing {} completion", stringify!($shell)));
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl Step for GenerateCompletions {
|
||||
type Output = ();
|
||||
|
||||
/// Uses `clap_complete` to generate shell completions.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
use clap_complete::shells::{Bash, Fish, PowerShell, Zsh};
|
||||
|
||||
generate_completions!(
|
||||
(Bash, builder.src.join("src/etc/completions/x.py.sh")),
|
||||
(Zsh, builder.src.join("src/etc/completions/x.py.zsh")),
|
||||
(Fish, builder.src.join("src/etc/completions/x.py.fish")),
|
||||
(PowerShell, builder.src.join("src/etc/completions/x.py.ps1")),
|
||||
(Bash, builder.src.join("src/etc/completions/x.sh")),
|
||||
(Zsh, builder.src.join("src/etc/completions/x.zsh")),
|
||||
(Fish, builder.src.join("src/etc/completions/x.fish")),
|
||||
(PowerShell, builder.src.join("src/etc/completions/x.ps1"))
|
||||
);
|
||||
for (shell, path) in get_completion_paths(builder) {
|
||||
if let Some(comp) = get_completion(shell, &path) {
|
||||
std::fs::write(&path, comp).unwrap_or_else(|e| {
|
||||
panic!("writing completion into {} failed: {e:?}", path.display())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@ use std::ffi::{OsStr, OsString};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs, iter};
|
||||
|
||||
use clap_complete::shells;
|
||||
|
||||
use crate::core::build_steps::compile::{Std, run_cargo};
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
|
||||
use crate::core::build_steps::llvm::get_llvm_version;
|
||||
use crate::core::build_steps::run::get_completion_paths;
|
||||
use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
|
||||
use crate::core::build_steps::tool::{self, COMPILETEST_ALLOW_FEATURES, SourceType, Tool};
|
||||
use crate::core::build_steps::toolstate::ToolState;
|
||||
|
|
@ -1153,14 +1152,12 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to
|
|||
cmd.delay_failure().run(builder);
|
||||
|
||||
builder.info("x.py completions check");
|
||||
let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"]
|
||||
.map(|filename| builder.src.join("src/etc/completions").join(filename));
|
||||
let completion_paths = get_completion_paths(builder);
|
||||
if builder.config.cmd.bless() {
|
||||
builder.ensure(crate::core::build_steps::run::GenerateCompletions);
|
||||
} else if get_completion(shells::Bash, &bash).is_some()
|
||||
|| get_completion(shells::Fish, &fish).is_some()
|
||||
|| get_completion(shells::PowerShell, &powershell).is_some()
|
||||
|| crate::flags::get_completion(shells::Zsh, &zsh).is_some()
|
||||
} else if completion_paths
|
||||
.into_iter()
|
||||
.any(|(shell, path)| get_completion(shell, &path).is_some())
|
||||
{
|
||||
eprintln!(
|
||||
"x.py completions were changed; run `x.py run generate-completions` to update them"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use clap::{CommandFactory, Parser, ValueEnum};
|
||||
use clap_complete::Generator;
|
||||
#[cfg(feature = "tracing")]
|
||||
use tracing::instrument;
|
||||
|
||||
|
|
@ -644,7 +645,7 @@ impl Subcommand {
|
|||
|
||||
/// Returns the shell completion for a given shell, if the result differs from the current
|
||||
/// content of `path`. If `path` does not exist, always returns `Some`.
|
||||
pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Option<String> {
|
||||
pub fn get_completion(shell: &dyn Generator, path: &Path) -> Option<String> {
|
||||
let mut cmd = Flags::command();
|
||||
let current = if !path.exists() {
|
||||
String::new()
|
||||
|
|
@ -662,7 +663,12 @@ pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Opt
|
|||
.expect("file name should be UTF-8")
|
||||
.rsplit_once('.')
|
||||
.expect("file name should have an extension");
|
||||
clap_complete::generate(shell, &mut cmd, bin_name, &mut buf);
|
||||
|
||||
// We sort of replicate `clap_complete::generate` here, because we want to call it with
|
||||
// `&dyn Generator`, but that function requires `G: Generator` instead.
|
||||
cmd.set_bin_name(bin_name);
|
||||
cmd.build();
|
||||
shell.generate(&cmd, &mut buf);
|
||||
if buf == current.as_bytes() {
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue