Skip to content

Commit a383ddc

Browse files
authored
Rollup merge of rust-lang#128878 - Kobzol:refactor-flags, r=onur-ozkan
Slightly refactor `Flags` in bootstrap The next step for rust-lang#126819 is to track commands executed inside `Config::parse`. This is quite challenging, because (tracked) command execution needs to access some state that is stored inside `Config`, which creates a sort of a chicken-and-egg problem. I would like to first untangle `Config::parse` a little bit, which is what this PR starts with. Tracking issue: rust-lang#126819 r? `@onur-ozkan`
2 parents 712dbe9 + 5431a93 commit a383ddc

File tree

8 files changed

+48
-29
lines changed

8 files changed

+48
-29
lines changed

src/bootstrap/src/bin/main.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ use std::str::FromStr;
1111
use std::{env, process};
1212

1313
use bootstrap::{
14-
find_recent_config_change_ids, human_readable_changes, t, Build, Config, Subcommand,
14+
find_recent_config_change_ids, human_readable_changes, t, Build, Config, Flags, Subcommand,
1515
CONFIG_CHANGE_HISTORY,
1616
};
1717

1818
fn main() {
1919
let args = env::args().skip(1).collect::<Vec<_>>();
20-
let config = Config::parse(&args);
20+
21+
if Flags::try_parse_verbose_help(&args) {
22+
return;
23+
}
24+
25+
let flags = Flags::parse(&args);
26+
let config = Config::parse(flags);
2127

2228
let mut build_lock;
2329
let _build_lock_guard;

src/bootstrap/src/core/builder/tests.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use std::thread;
33
use super::*;
44
use crate::core::build_steps::doc::DocumentationFormat;
55
use crate::core::config::Config;
6+
use crate::Flags;
67

78
fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
89
configure_with_args(&[cmd.to_owned()], host, target)
910
}
1011

1112
fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config {
12-
let mut config = Config::parse(cmd);
13+
let mut config = Config::parse(Flags::parse(cmd));
1314
// don't save toolstates
1415
config.save_toolstates = None;
1516
config.dry_run = DryRun::SelfCheck;
@@ -23,7 +24,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config
2324
let submodule_build = Build::new(Config {
2425
// don't include LLVM, so CI doesn't require ninja/cmake to be installed
2526
rust_codegen_backends: vec![],
26-
..Config::parse(&["check".to_owned()])
27+
..Config::parse(Flags::parse(&["check".to_owned()]))
2728
});
2829
submodule_build.require_submodule("src/doc/book", None);
2930
config.submodules = Some(false);

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ impl Config {
11911191
}
11921192
}
11931193

1194-
pub fn parse(args: &[String]) -> Config {
1194+
pub fn parse(flags: Flags) -> Config {
11951195
#[cfg(test)]
11961196
fn get_toml(_: &Path) -> TomlConfig {
11971197
TomlConfig::default()
@@ -1221,11 +1221,10 @@ impl Config {
12211221
exit!(2);
12221222
})
12231223
}
1224-
Self::parse_inner(args, get_toml)
1224+
Self::parse_inner(flags, get_toml)
12251225
}
12261226

1227-
pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
1228-
let mut flags = Flags::parse(args);
1227+
pub(crate) fn parse_inner(mut flags: Flags, get_toml: impl Fn(&Path) -> TomlConfig) -> Config {
12291228
let mut config = Config::default_opts();
12301229

12311230
// Set flags.

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

+17-7
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ pub struct Flags {
183183
}
184184

185185
impl Flags {
186-
pub fn parse(args: &[String]) -> Self {
187-
let first = String::from("x.py");
188-
let it = std::iter::once(&first).chain(args.iter());
186+
/// Check if `<cmd> -h -v` was passed.
187+
/// If yes, print the available paths and return `true`.
188+
pub fn try_parse_verbose_help(args: &[String]) -> bool {
189189
// We need to check for `<cmd> -h -v`, in which case we list the paths
190190
#[derive(Parser)]
191191
#[command(disable_help_flag(true))]
@@ -198,24 +198,34 @@ impl Flags {
198198
cmd: Kind,
199199
}
200200
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
201-
HelpVerboseOnly::try_parse_from(it.clone())
201+
HelpVerboseOnly::try_parse_from(normalize_args(args))
202202
{
203203
println!("NOTE: updating submodules before printing available paths");
204-
let config = Config::parse(&[String::from("build")]);
204+
let config = Config::parse(Self::parse(&[String::from("build")]));
205205
let build = Build::new(config);
206206
let paths = Builder::get_help(&build, subcommand);
207207
if let Some(s) = paths {
208208
println!("{s}");
209209
} else {
210210
panic!("No paths available for subcommand `{}`", subcommand.as_str());
211211
}
212-
crate::exit!(0);
212+
true
213+
} else {
214+
false
213215
}
216+
}
214217

215-
Flags::parse_from(it)
218+
pub fn parse(args: &[String]) -> Self {
219+
Flags::parse_from(normalize_args(args))
216220
}
217221
}
218222

223+
fn normalize_args(args: &[String]) -> Vec<String> {
224+
let first = String::from("x.py");
225+
let it = std::iter::once(first).chain(args.iter().cloned());
226+
it.collect()
227+
}
228+
219229
#[derive(Debug, Clone, Default, clap::Subcommand)]
220230
pub enum Subcommand {
221231
#[command(aliases = ["b"], long_about = "\n

src/bootstrap/src/core/config/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[allow(clippy::module_inception)]
22
mod config;
3-
pub(crate) mod flags;
3+
pub mod flags;
44
#[cfg(test)]
55
mod tests;
66

src/bootstrap/src/core/config/tests.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ use crate::core::build_steps::clippy::get_clippy_rules_in_order;
1212
use crate::core::config::{LldMode, Target, TargetSelection, TomlConfig};
1313

1414
fn parse(config: &str) -> Config {
15-
Config::parse_inner(&["check".to_string(), "--config=/does/not/exist".to_string()], |&_| {
16-
toml::from_str(&config).unwrap()
17-
})
15+
Config::parse_inner(
16+
Flags::parse(&["check".to_string(), "--config=/does/not/exist".to_string()]),
17+
|&_| toml::from_str(&config).unwrap(),
18+
)
1819
}
1920

2021
#[test]
@@ -108,7 +109,7 @@ fn clap_verify() {
108109
#[test]
109110
fn override_toml() {
110111
let config = Config::parse_inner(
111-
&[
112+
Flags::parse(&[
112113
"check".to_owned(),
113114
"--config=/does/not/exist".to_owned(),
114115
"--set=change-id=1".to_owned(),
@@ -121,7 +122,7 @@ fn override_toml() {
121122
"--set=target.x86_64-unknown-linux-gnu.rpath=false".to_owned(),
122123
"--set=target.aarch64-unknown-linux-gnu.sanitizers=false".to_owned(),
123124
"--set=target.aarch64-apple-darwin.runner=apple".to_owned(),
124-
],
125+
]),
125126
|&_| {
126127
toml::from_str(
127128
r#"
@@ -201,12 +202,12 @@ runner = "x86_64-runner"
201202
#[should_panic]
202203
fn override_toml_duplicate() {
203204
Config::parse_inner(
204-
&[
205+
Flags::parse(&[
205206
"check".to_owned(),
206207
"--config=/does/not/exist".to_string(),
207208
"--set=change-id=1".to_owned(),
208209
"--set=change-id=2".to_owned(),
209-
],
210+
]),
210211
|&_| toml::from_str("change-id = 0").unwrap(),
211212
);
212213
}
@@ -226,7 +227,7 @@ fn profile_user_dist() {
226227
.and_then(|table: toml::Value| TomlConfig::deserialize(table))
227228
.unwrap()
228229
}
229-
Config::parse_inner(&["check".to_owned()], get_toml);
230+
Config::parse_inner(Flags::parse(&["check".to_owned()]), get_toml);
230231
}
231232

232233
#[test]
@@ -301,7 +302,7 @@ fn order_of_clippy_rules() {
301302
"-Aclippy::foo1".to_string(),
302303
"-Aclippy::foo2".to_string(),
303304
];
304-
let config = Config::parse(&args);
305+
let config = Config::parse(Flags::parse(&args));
305306

306307
let actual = match &config.cmd {
307308
crate::Subcommand::Clippy { allow, deny, warn, forbid, .. } => {

src/bootstrap/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod core;
4343
mod utils;
4444

4545
pub use core::builder::PathSet;
46-
pub use core::config::flags::Subcommand;
46+
pub use core::config::flags::{Flags, Subcommand};
4747
pub use core::config::Config;
4848

4949
pub use utils::change_tracker::{

src/bootstrap/src/utils/helpers/tests.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::PathBuf;
55
use crate::utils::helpers::{
66
check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, symlink_dir,
77
};
8-
use crate::Config;
8+
use crate::{Config, Flags};
99

1010
#[test]
1111
fn test_make() {
@@ -58,7 +58,8 @@ fn test_check_cfg_arg() {
5858

5959
#[test]
6060
fn test_program_out_of_date() {
61-
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
61+
let config =
62+
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
6263
let tempfile = config.tempdir().join(".tmp-stamp-file");
6364
File::create(&tempfile).unwrap().write_all(b"dummy value").unwrap();
6465
assert!(tempfile.exists());
@@ -73,7 +74,8 @@ fn test_program_out_of_date() {
7374

7475
#[test]
7576
fn test_symlink_dir() {
76-
let config = Config::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]);
77+
let config =
78+
Config::parse(Flags::parse(&["check".to_owned(), "--config=/does/not/exist".to_owned()]));
7779
let tempdir = config.tempdir().join(".tmp-dir");
7880
let link_path = config.tempdir().join(".tmp-link");
7981

0 commit comments

Comments
 (0)