Skip to content

Commit 46ce66f

Browse files
committed
Unify completion list between x test tidy and x run generate-completions
1 parent 0c4fa26 commit 46ce66f

File tree

3 files changed

+36
-32
lines changed

3 files changed

+36
-32
lines changed

src/bootstrap/src/core/build_steps/run.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
66
use std::path::PathBuf;
77

8+
use clap_complete::{Generator, shells};
9+
810
use crate::core::build_steps::dist::distdir;
911
use crate::core::build_steps::test;
1012
use crate::core::build_steps::tool::{self, SourceType, Tool};
@@ -285,36 +287,35 @@ impl Step for GenerateWindowsSys {
285287
}
286288
}
287289

290+
/// Return tuples of (shell, file containing completions).
291+
pub fn get_completion_paths(builder: &Builder<'_>) -> Vec<(&'static dyn Generator, PathBuf)> {
292+
vec![
293+
(&shells::Bash as &'static dyn Generator, builder.src.join("src/etc/completions/x.py.sh")),
294+
(&shells::Zsh, builder.src.join("src/etc/completions/x.py.zsh")),
295+
(&shells::Fish, builder.src.join("src/etc/completions/x.py.fish")),
296+
(&shells::PowerShell, builder.src.join("src/etc/completions/x.py.ps1")),
297+
(&shells::Bash, builder.src.join("src/etc/completions/x.sh")),
298+
(&shells::Zsh, builder.src.join("src/etc/completions/x.zsh")),
299+
(&shells::Fish, builder.src.join("src/etc/completions/x.fish")),
300+
(&shells::PowerShell, builder.src.join("src/etc/completions/x.ps1")),
301+
]
302+
}
303+
288304
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
289305
pub struct GenerateCompletions;
290306

291-
macro_rules! generate_completions {
292-
( $( ( $shell:ident, $filename:expr ) ),* ) => {
293-
$(
294-
if let Some(comp) = get_completion($shell, &$filename) {
295-
std::fs::write(&$filename, comp).expect(&format!("writing {} completion", stringify!($shell)));
296-
}
297-
)*
298-
};
299-
}
300-
301307
impl Step for GenerateCompletions {
302308
type Output = ();
303309

304310
/// Uses `clap_complete` to generate shell completions.
305311
fn run(self, builder: &Builder<'_>) {
306-
use clap_complete::shells::{Bash, Fish, PowerShell, Zsh};
307-
308-
generate_completions!(
309-
(Bash, builder.src.join("src/etc/completions/x.py.sh")),
310-
(Zsh, builder.src.join("src/etc/completions/x.py.zsh")),
311-
(Fish, builder.src.join("src/etc/completions/x.py.fish")),
312-
(PowerShell, builder.src.join("src/etc/completions/x.py.ps1")),
313-
(Bash, builder.src.join("src/etc/completions/x.sh")),
314-
(Zsh, builder.src.join("src/etc/completions/x.zsh")),
315-
(Fish, builder.src.join("src/etc/completions/x.fish")),
316-
(PowerShell, builder.src.join("src/etc/completions/x.ps1"))
317-
);
312+
for (shell, path) in get_completion_paths(builder) {
313+
if let Some(comp) = get_completion(shell, &path) {
314+
std::fs::write(&path, comp).unwrap_or_else(|e| {
315+
panic!("writing completion into {} failed: {e:?}", path.display())
316+
});
317+
}
318+
}
318319
}
319320

320321
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ use std::ffi::{OsStr, OsString};
88
use std::path::{Path, PathBuf};
99
use std::{env, fs, iter};
1010

11-
use clap_complete::shells;
12-
1311
use crate::core::build_steps::compile::{Std, run_cargo};
1412
use crate::core::build_steps::doc::DocumentationFormat;
1513
use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
1614
use crate::core::build_steps::llvm::get_llvm_version;
15+
use crate::core::build_steps::run::get_completion_paths;
1716
use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget;
1817
use crate::core::build_steps::tool::{self, COMPILETEST_ALLOW_FEATURES, SourceType, Tool};
1918
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
11531152
cmd.delay_failure().run(builder);
11541153

11551154
builder.info("x.py completions check");
1156-
let [bash, zsh, fish, powershell] = ["x.py.sh", "x.py.zsh", "x.py.fish", "x.py.ps1"]
1157-
.map(|filename| builder.src.join("src/etc/completions").join(filename));
1155+
let completion_paths = get_completion_paths(builder);
11581156
if builder.config.cmd.bless() {
11591157
builder.ensure(crate::core::build_steps::run::GenerateCompletions);
1160-
} else if get_completion(shells::Bash, &bash).is_some()
1161-
|| get_completion(shells::Fish, &fish).is_some()
1162-
|| get_completion(shells::PowerShell, &powershell).is_some()
1163-
|| crate::flags::get_completion(shells::Zsh, &zsh).is_some()
1158+
} else if completion_paths
1159+
.into_iter()
1160+
.any(|(shell, path)| get_completion(shell, &path).is_some())
11641161
{
11651162
eprintln!(
11661163
"x.py completions were changed; run `x.py run generate-completions` to update them"

src/bootstrap/src/core/config/flags.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use std::path::{Path, PathBuf};
77

88
use clap::{CommandFactory, Parser, ValueEnum};
9+
use clap_complete::Generator;
910
#[cfg(feature = "tracing")]
1011
use tracing::instrument;
1112

@@ -644,7 +645,7 @@ impl Subcommand {
644645

645646
/// Returns the shell completion for a given shell, if the result differs from the current
646647
/// content of `path`. If `path` does not exist, always returns `Some`.
647-
pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Option<String> {
648+
pub fn get_completion(shell: &dyn Generator, path: &Path) -> Option<String> {
648649
let mut cmd = Flags::command();
649650
let current = if !path.exists() {
650651
String::new()
@@ -662,7 +663,12 @@ pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Opt
662663
.expect("file name should be UTF-8")
663664
.rsplit_once('.')
664665
.expect("file name should have an extension");
665-
clap_complete::generate(shell, &mut cmd, bin_name, &mut buf);
666+
667+
// We sort of replicate `clap_complete::generate` here, because we want to call it with
668+
// `&dyn Generator`, but that function requires `G: Generator` instead.
669+
cmd.set_bin_name(bin_name);
670+
cmd.build();
671+
shell.generate(&cmd, &mut buf);
666672
if buf == current.as_bytes() {
667673
return None;
668674
}

0 commit comments

Comments
 (0)