Skip to content

Commit 117a9c2

Browse files
AndreasBackxmeta-codesync[bot]
authored andcommitted
Migrate hermetic_infra/ from Clap 3 to Clap 4
Summary: This is a Claude Code generated diff stack to migrate all existing users of Clap 3 to Clap 4. It follows CLI Foundation ["Clap 4 Migration"](https://www.internalfb.com/wiki/CLI_Foundation/Guidelines_&_How_To/Frameworks_&_Main_Libraries/Rust/Clap_4_Migration/) wiki and "clap4-migration" Claude skill based on it and the Clap changelogs. [Clap 2 and 3 have been deprecated for over 3 years.](https://fb.workplace.com/groups/clifoundation/posts/753507606006249/) They will be deleted soon and this should make it much easier for everyone to move over. Sandcastle should be green indicating that the CLI builds succesfully and any tests related should be good too. Considering there are over a hundred CLIs using Clap 2 and 3, this as good of a signal we are able of getting. If you need more signal, we highly recommend you to look into [Scrut](https://www.internalfb.com/intern/staticdocs/scrut/docs/), an end-to-end CLI testing toolkit. Though this is outside of the scope for this massive diff stack. If you want additional assurances that you can roll back. You might want to have a look at [`cli.deployer`](https://www.internalfb.com/wiki/Cli.deployer/) **Please make sure to review the diff in case of any issues. There might be some slight changes to the CLI due to the large amount of changes that have been seen in Clap over the last years. If you want to make further changes, please make a new diff rebased on this one and they can land them together.** --- reverie-util: parse(try_from_str)→value_parser, number_of_values→num_args, from_iter_safe→try_parse_from. 9 examples: from_args→parse. Also sanitization-clear, bareclient, iris-subscriber, dependency_service, chip, observability_service BUCK deps. Reviewed By: dtolnay Differential Revision: D92826701 fbshipit-source-id: 644a0915ad8f7933b92fb32e6456a928a96957fb
1 parent 1eb1b86 commit 117a9c2

File tree

15 files changed

+54
-72
lines changed

15 files changed

+54
-72
lines changed

detcore-model/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ anyhow = "1.0.98"
1212
bitvec = { version = "1.0", features = ["atomic", "serde"] }
1313
bytesize = "2.0"
1414
chrono = { version = "0.4.41", features = ["clock", "serde", "std"], default-features = false }
15-
clap = { version = "3.2.25", features = ["derive", "env", "regex", "unicode", "wrap_help"] }
15+
clap = { version = "4.5.42", features = ["derive", "env", "string", "unicode", "wrap_help"] }
1616
libc = "0.2.139"
1717
nix = { version = "0.30.1", features = ["dir", "event", "hostname", "inotify", "ioctl", "mman", "mount", "net", "poll", "ptrace", "reboot", "resource", "sched", "signal", "term", "time", "user", "zerocopy"] }
1818
reverie-syscalls = { version = "0.1.0", git = "https://github.com/facebookexperimental/reverie.git", branch = "main" }

detcore-model/src/config.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ use crate::schedule::SigWrapper;
2828
#[derive(Debug, Serialize, Deserialize, Clone, Parser)]
2929
pub struct Config {
3030
/// Disable virtual/logical time. Note that virtual time is required for virtual metadata.
31-
#[clap(long = "no-virtualize-time", parse(from_flag = std::ops::Not::not))]
31+
#[clap(long = "no-virtualize-time", action = clap::ArgAction::SetFalse)]
3232
pub virtualize_time: bool,
3333

3434
/// Disable virtual cpuid
35-
#[clap(long = "no-virtualize-cpuid", parse(from_flag = std::ops::Not::not))]
35+
#[clap(long = "no-virtualize-cpuid", action = clap::ArgAction::SetFalse)]
3636
pub virtualize_cpuid: bool,
3737

3838
/// Epoch of the logical time.
@@ -77,7 +77,7 @@ pub struct Config {
7777

7878
/// Disable substitution of virtual (deterministic) file metadata, in lieu
7979
/// of the real metadata returned by `fstat`, implies `virtualize_time`.
80-
#[clap(long = "no-virtualize-metadata", parse(from_flag = std::ops::Not::not))]
80+
#[clap(long = "no-virtualize-metadata", action = clap::ArgAction::SetFalse)]
8181
pub virtualize_metadata: bool,
8282

8383
/// Sequentialize thread execution deterministically.
@@ -114,15 +114,15 @@ pub struct Config {
114114

115115
/// JSON file to read recorded preemptions from. When `--chaos` mode is activated, these
116116
/// recorded preemption points take the place of randomized scheduling decisions.
117-
#[clap(long, value_name = "filepath", conflicts_with = "replay-schedule-from")]
117+
#[clap(long, value_name = "filepath", conflicts_with = "replay_schedule_from")]
118118
pub replay_preemptions_from: Option<PathBuf>,
119119

120120
/// File to read recorded schedule trace from. This execution will replay the schedule verbatim
121121
/// from the file.
122122
#[clap(
123123
long,
124124
value_name = "filepath",
125-
conflicts_with = "replay-preemptions-from"
125+
conflicts_with = "replay_preemptions_from"
126126
)]
127127
pub replay_schedule_from: Option<PathBuf>,
128128

@@ -142,13 +142,13 @@ pub struct Config {
142142
#[clap(long,
143143
short = 's',
144144
value_name = "index[,path]",
145-
parse(try_from_str = parse_index_with_path))]
145+
value_parser = parse_index_with_path)]
146146
pub stacktrace_event: Vec<(u64, Option<PathBuf>)>,
147147

148148
/// Internal feature used to signal the guest with SIGINT at every `--stacktrace-event`, this is
149149
/// in-lieu of using hermit's internal stacktrace printing facility, to instead have an external
150150
/// debugger handle it. Accepts either signal names or numbers.
151-
#[clap(long, value_name = "signame", parse(try_from_str))]
151+
#[clap(long, value_name = "signame")]
152152
pub stacktrace_signal: Option<SigWrapper>,
153153

154154
/// [DEPRECATED] Print a stacktrace each time the program is preempted. Only makes sense in `--chaos` mode
@@ -209,7 +209,7 @@ pub struct Config {
209209
#[clap(long,
210210
value_name = "uint64|'disabled'",
211211
default_value = "200000000",
212-
parse(try_from_str = parse_preemption_timeout))]
212+
value_parser = parse_preemption_timeout)]
213213
pub preemption_timeout: MaybePreemptionTimeout,
214214

215215
/// Shut down immediately upon SIGINT, rather than letting the guest handle it.
@@ -293,13 +293,13 @@ pub struct Config {
293293
/// Configure memory available for the container. Takes a number of bytes, or shorthand (e.g.
294294
/// "1GB"). Right now this doesn't enforce an upper bound, but does affect the amount of memory
295295
/// reported to the guest.
296-
#[clap(long, default_value = "1GB", parse(try_from_str = try_parse_memory), value_name = "bytesize")]
296+
#[clap(long, default_value = "1GB", value_parser = try_parse_memory, value_name = "bytesize")]
297297
pub memory: u64,
298298

299299
/// Configure extra interrupt points based on thread id and rcb counter. Detcore will raise a precise
300300
/// timer for this RCB whenever it detects that current current thread timeslice intercects any of the
301301
/// interrupt points specified
302-
#[clap(long, value_name = "tid:rcbs", parse(try_from_str = try_parse_numbers_with_colon))]
302+
#[clap(long, value_name = "tid:rcbs", value_parser = try_parse_numbers_with_colon)]
303303
pub interrupt_at: Vec<(DetTid, u64)>,
304304
}
305305

@@ -744,7 +744,7 @@ impl Config {
744744
OsString::from("CMD"), // Silly/unused.
745745
OsString::from(format!("--epoch={}", DEFAULT_EPOCH_STR)),
746746
];
747-
Config::from_iter(args.iter())
747+
Config::parse_from(args.iter())
748748
}
749749

750750
/// Returns effective "rng-seed" parameter taking in account "seed"
@@ -771,6 +771,6 @@ impl Config {
771771
impl Default for Config {
772772
fn default() -> Self {
773773
let v: Vec<String> = vec![];
774-
Config::from_iter(v.iter())
774+
Config::parse_from(v.iter())
775775
}
776776
}

detcore/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ anyhow = "1.0.98"
2828
async-trait = "0.1.86"
2929
bitflags = { version = "2.9", features = ["serde"], default-features = false }
3030
chrono = { version = "0.4.41", features = ["clock", "serde", "std"], default-features = false }
31-
clap = { version = "3.2.25", features = ["derive", "env", "regex", "unicode", "wrap_help"] }
31+
clap = { version = "4.5.42", features = ["derive", "env", "string", "unicode", "wrap_help"] }
3232
detcore-model = { version = "0.0.0", path = "../detcore-model" }
3333
digest = { version = "0.0.0", path = "../common/digest" }
3434
futures = { version = "0.3.31", features = ["async-await", "compat"] }

detcore/src/logdiff.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl LogDiffOpts {
107107
}
108108

109109
/// Indicates which DETLOG entries to be used for log-diff comparison
110-
#[derive(Debug, PartialEq, Eq)]
110+
#[derive(Debug, Clone, PartialEq, Eq)]
111111
pub enum DetLogFilter {
112112
///the start of syscall will be used for logdiff
113113
Syscall,
@@ -138,7 +138,7 @@ impl FromStr for DetLogFilter {
138138
impl Default for LogDiffOpts {
139139
fn default() -> Self {
140140
let v: Vec<String> = vec![];
141-
LogDiffOpts::from_iter(v.iter())
141+
LogDiffOpts::parse_from(v.iter())
142142
}
143143
}
144144

hermit-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
1010
[dependencies]
1111
anyhow = "1.0.98"
1212
bincode = "1.3.3"
13-
clap = { version = "3.2.25", features = ["derive", "env", "regex", "unicode", "wrap_help"] }
13+
clap = { version = "4.5.42", features = ["derive", "env", "string", "unicode", "wrap_help"] }
1414
colored = "2.1.0"
1515
detcore = { version = "0.0.0", path = "../detcore" }
1616
diff = "0.1.13"

hermit-cli/src/bin/hermit/analyze/rundata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ impl RunData {
353353
for arg in &aopts.run_args {
354354
run_cmd.push(arg.to_string());
355355
}
356-
RunOpts::from_iter(run_cmd.iter())
356+
RunOpts::parse_from(run_cmd.iter())
357357
}
358358

359359
/// Extract the (initial) RunOpts for target/run1 that are implied by all of hermit analyze's arguments.

hermit-cli/src/bin/hermit/analyze/types.rs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,7 @@ pub struct AnalyzeOpts {
5959
pub target_exit_code: ExitStatusConstraint,
6060

6161
/// What level of logging to enable for the guest runs.
62-
#[clap(
63-
short,
64-
long,
65-
value_name = "LEVEL",
66-
env = "HERMIT_LOG",
67-
possible_values = &["off", "error", "warn", "info", "debug", "trace"]
68-
)]
62+
#[clap(short, long, value_name = "LEVEL", env = "HERMIT_LOG")]
6963
pub guest_log: Option<LevelFilter>,
7064

7165
/// Insist on perfect determinism before proceeding with the analysis.
@@ -85,9 +79,9 @@ pub struct AnalyzeOpts {
8579
/// the subsequent binary search.
8680
#[clap(
8781
long,
88-
conflicts_with = "run2-seed",
89-
conflicts_with = "run2-preemptions",
90-
conflicts_with = "run2-schedule"
82+
conflicts_with = "run2_seed",
83+
conflicts_with = "run2_preemptions",
84+
conflicts_with = "run2_schedule"
9185
)]
9286
pub minimize: bool,
9387

@@ -101,26 +95,26 @@ pub struct AnalyzeOpts {
10195
/// It is an error if this execution does not meet the indicated target criteria.
10296
#[clap(
10397
long,
104-
conflicts_with = "run1-preemptions",
105-
conflicts_with = "run1-schedule",
98+
conflicts_with = "run1_preemptions",
99+
conflicts_with = "run1_schedule",
106100
value_name = "NUM"
107101
)]
108102
pub run1_seed: Option<u64>,
109103

110104
/// Load target execution from hermit run --record-preemptions-to.
111105
#[clap(
112106
long,
113-
conflicts_with = "run1-seed",
114-
conflicts_with = "run1-schedule",
107+
conflicts_with = "run1_seed",
108+
conflicts_with = "run1_schedule",
115109
value_name = "PATH"
116110
)]
117111
pub run1_preemptions: Option<PathBuf>,
118112

119113
/// Load target execution from hermit run --record-schedule-to.
120114
#[clap(
121115
long,
122-
conflicts_with = "run1-seed",
123-
conflicts_with = "run1-preemptions",
116+
conflicts_with = "run1_seed",
117+
conflicts_with = "run1_preemptions",
124118
value_name = "PATH"
125119
)]
126120
pub run1_schedule: Option<PathBuf>,
@@ -129,26 +123,26 @@ pub struct AnalyzeOpts {
129123
/// does NOT meet the target criteria.
130124
#[clap(
131125
long,
132-
conflicts_with = "run2-preemptions",
133-
conflicts_with = "run2-schedule",
126+
conflicts_with = "run2_preemptions",
127+
conflicts_with = "run2_schedule",
134128
value_name = "NUM"
135129
)]
136130
pub run2_seed: Option<u64>,
137131

138132
/// Load baseline execution from hermit run --record-preemptions-to.
139133
#[clap(
140134
long,
141-
conflicts_with = "run2-seed",
142-
conflicts_with = "run2-schedule",
135+
conflicts_with = "run2_seed",
136+
conflicts_with = "run2_schedule",
143137
value_name = "PATH"
144138
)]
145139
pub run2_preemptions: Option<PathBuf>,
146140

147141
/// Load baseline execution from hermit run --record-schedule-to.
148142
#[clap(
149143
long,
150-
conflicts_with = "run2-seed",
151-
conflicts_with = "run2-preemptions",
144+
conflicts_with = "run2_seed",
145+
conflicts_with = "run2_preemptions",
152146
value_name = "PATH"
153147
)]
154148
pub run2_schedule: Option<PathBuf>,

hermit-cli/src/bin/hermit/global_opts.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,11 @@ use super::tracing::init_stderr_tracing;
3737
#[derive(Debug, Parser, Clone)]
3838
pub struct GlobalOpts {
3939
/// The verbosity level of log output.
40-
#[clap(
41-
short,
42-
long,
43-
value_name = "LEVEL",
44-
env = "HERMIT_LOG",
45-
possible_values = &["off", "error", "warn", "info", "debug", "trace"]
46-
)]
40+
#[clap(short, long, value_name = "LEVEL", env = "HERMIT_LOG")]
4741
pub log: Option<LevelFilter>,
4842

4943
/// Log to a file instead of the terminal.
50-
#[clap(long, value_name = "FILE", env = "HERMIT_LOG_FILE", parse(from_os_str))]
44+
#[clap(long, value_name = "FILE", env = "HERMIT_LOG_FILE")]
5145
pub log_file: Option<PathBuf>,
5246
}
5347

hermit-cli/src/bin/hermit/main.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ mod tracing;
2727
mod verify;
2828
mod version;
2929

30-
use clap::AppSettings;
3130
use clap::Parser;
3231
use colored::*;
3332
use hermit::Error;
@@ -45,7 +44,6 @@ use self::version::Version;
4544
#[clap(
4645
name = "hermit",
4746
version = Version::get(),
48-
global_settings(&[AppSettings::ColoredHelp]),
4947
)]
5048
struct Args {
5149
#[clap(flatten)]
@@ -58,15 +56,15 @@ struct Args {
5856
#[derive(Debug, Parser)]
5957
enum Subcommand {
6058
/// Run a program sandboxed and fully deterministically (unless external networking is allowed).
61-
#[clap(name = "run", setting = AppSettings::TrailingVarArg)]
59+
#[clap(name = "run", trailing_var_arg = true)]
6260
Run(Box<RunOpts>),
6361

6462
/// Record the execution of a program (EXPERIMENTAL).
65-
#[clap(name = "record", setting = AppSettings::TrailingVarArg)]
63+
#[clap(name = "record", trailing_var_arg = true)]
6664
Record(RecordOpts),
6765

6866
/// Replay the execution of a program.
69-
#[clap(name = "replay", setting = AppSettings::TrailingVarArg)]
67+
#[clap(name = "replay", trailing_var_arg = true)]
7068
Replay(ReplayOpts),
7169

7270
/// Take the difference of two (run/record) logs written to files.
@@ -93,7 +91,7 @@ fn main() {
9391
let Args {
9492
global,
9593
mut command,
96-
} = Args::from_args();
94+
} = Args::parse();
9795

9896
command
9997
.main(&global)

hermit-cli/src/bin/hermit/record_start.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,7 @@ pub struct StartOpts {
5151
/// recording was successful with gdbserver enabled.
5252
///
5353
/// The recording is deleted if the replay was successful.
54-
#[clap(
55-
long = "verify-with-gdbex",
56-
value_delimiter = ';',
57-
use_delimiter = true
58-
)]
54+
#[clap(long = "verify-with-gdbex", value_delimiter = ';')]
5955
gdbex: Vec<String>,
6056
}
6157
impl StartOpts {

0 commit comments

Comments
 (0)