3
3
//! This module implements the command-line parsing of the build system which
4
4
//! has various flags to configure how it's run.
5
5
6
- use std::path::PathBuf;
6
+ use std::path::{Path, PathBuf} ;
7
7
8
- use clap::{Parser, ValueEnum};
8
+ use clap::{CommandFactory, Parser, ValueEnum};
9
9
10
10
use crate::builder::{Builder, Kind};
11
11
use crate::config::{target_selection_list, Config, TargetSelectionList};
@@ -54,15 +54,15 @@ pub struct Flags {
54
54
/// Build directory, overrides `build.build-dir` in `config.toml`
55
55
pub build_dir: Option<PathBuf>,
56
56
57
- #[arg(global(true), long, value_name = "BUILD")]
57
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "BUILD")]
58
58
/// build target of the stage0 compiler
59
59
pub build: Option<String>,
60
60
61
- #[arg(global(true), long, value_name = "HOST", value_parser = target_selection_list)]
61
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "HOST", value_parser = target_selection_list)]
62
62
/// host targets to build
63
63
pub host: Option<TargetSelectionList>,
64
64
65
- #[arg(global(true), long, value_name = "TARGET", value_parser = target_selection_list)]
65
+ #[arg(global(true), long, value_hint = clap::ValueHint::Other, value_name = "TARGET", value_parser = target_selection_list)]
66
66
/// target targets to build
67
67
pub target: Option<TargetSelectionList>,
68
68
@@ -73,7 +73,7 @@ pub struct Flags {
73
73
/// include default paths in addition to the provided ones
74
74
pub include_default_paths: bool,
75
75
76
- #[arg(global(true), long)]
76
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long)]
77
77
pub rustc_error_format: Option<String>,
78
78
79
79
#[arg(global(true), long, value_hint = clap::ValueHint::CommandString, value_name = "CMD")]
@@ -82,16 +82,16 @@ pub struct Flags {
82
82
#[arg(global(true), long)]
83
83
/// dry run; don't build anything
84
84
pub dry_run: bool,
85
- #[arg(global(true), long, value_name = "N")]
85
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
86
86
/// stage to build (indicates compiler to use/test, e.g., stage 0 uses the
87
87
/// bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)
88
88
pub stage: Option<u32>,
89
89
90
- #[arg(global(true), long, value_name = "N")]
90
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
91
91
/// stage(s) to keep without recompiling
92
92
/// (pass multiple times to keep e.g., both stages 0 and 1)
93
93
pub keep_stage: Vec<u32>,
94
- #[arg(global(true), long, value_name = "N")]
94
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "N")]
95
95
/// stage(s) of the standard library to keep without recompiling
96
96
/// (pass multiple times to keep e.g., both stages 0 and 1)
97
97
pub keep_stage_std: Vec<u32>,
@@ -103,6 +103,7 @@ pub struct Flags {
103
103
global(true),
104
104
short,
105
105
long,
106
+ value_hint = clap::ValueHint::Other,
106
107
default_value_t = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get),
107
108
value_name = "JOBS"
108
109
)]
@@ -117,7 +118,7 @@ pub struct Flags {
117
118
/// otherwise, use the default configured behaviour
118
119
pub warnings: Warnings,
119
120
120
- #[arg(global(true), long, value_name = "FORMAT")]
121
+ #[arg(global(true), value_hint = clap::ValueHint::Other, long, value_name = "FORMAT")]
121
122
/// rustc error format
122
123
pub error_format: Option<String>,
123
124
#[arg(global(true), long)]
@@ -133,13 +134,13 @@ pub struct Flags {
133
134
#[arg(global(true), long, value_name = "VALUE")]
134
135
pub llvm_skip_rebuild: Option<bool>,
135
136
/// generate PGO profile with rustc build
136
- #[arg(global(true), long, value_name = "PROFILE")]
137
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
137
138
pub rust_profile_generate: Option<String>,
138
139
/// use PGO profile for rustc build
139
- #[arg(global(true), long, value_name = "PROFILE")]
140
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
140
141
pub rust_profile_use: Option<String>,
141
142
/// use PGO profile for LLVM build
142
- #[arg(global(true), long, value_name = "PROFILE")]
143
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
143
144
pub llvm_profile_use: Option<String>,
144
145
// LLVM doesn't support a custom location for generating profile
145
146
// information.
@@ -152,7 +153,7 @@ pub struct Flags {
152
153
#[arg(global(true), long)]
153
154
pub llvm_bolt_profile_generate: bool,
154
155
/// use BOLT profile for LLVM build
155
- #[arg(global(true), long, value_name = "PROFILE")]
156
+ #[arg(global(true), value_hint = clap::ValueHint::FilePath, long, value_name = "PROFILE")]
156
157
pub llvm_bolt_profile_use: Option<String>,
157
158
#[arg(global(true))]
158
159
/// paths for the subcommand
@@ -524,3 +525,23 @@ impl Subcommand {
524
525
}
525
526
}
526
527
}
528
+
529
+ /// Returns the shell completion for a given shell, if the result differs from the current
530
+ /// content of `path`. If `path` does not exist, always returns `Some`.
531
+ pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Option<String> {
532
+ let mut cmd = Flags::command();
533
+ let current = if !path.exists() {
534
+ String::new()
535
+ } else {
536
+ std::fs::read_to_string(path).unwrap_or_else(|_| {
537
+ eprintln!("couldn't read {}", path.display());
538
+ crate::detail_exit(1)
539
+ })
540
+ };
541
+ let mut buf = Vec::new();
542
+ clap_complete::generate(shell, &mut cmd, "x.py", &mut buf);
543
+ if buf == current.as_bytes() {
544
+ return None;
545
+ }
546
+ Some(String::from_utf8(buf).expect("completion script should be UTF-8"))
547
+ }
0 commit comments