From 7957415c33b66f7e7b15c7901da9374dd117ad92 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 29 Aug 2022 15:45:20 +0200 Subject: [PATCH 1/3] Move old flags down --- CHANGELOG.md | 11 ++++++ src/dfx/src/main.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53bbcbee5b..97ae0092a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ ## DFX +### feat: Backwards compatibility for flags + +The location of some flags has moved. For example: + +``` +Old: dfx canister --network local id mydapp +New: dfx canister id --network local mydapp +``` + +To reduce disruption, this PR rewrites some common command line patterns from the old format to the new, and issuses a warning. + ### feat: print the dashboard URL on startup When running `dfx start` or `dfx replica`, the path to the dashboard page is now printed. diff --git a/src/dfx/src/main.rs b/src/dfx/src/main.rs index 112f77cc5c..a2717e0d63 100644 --- a/src/dfx/src/main.rs +++ b/src/dfx/src/main.rs @@ -188,6 +188,8 @@ fn init_env(env_opts: EnvOpts) -> DfxResult { } fn main() { + handle_legacy_flags(); + let cli_opts = CliOpts::parse(); let command = cli_opts.command; let mut error_diagnosis: Diagnosis = NULL_DIAGNOSIS; @@ -209,3 +211,92 @@ fn main() { std::process::exit(255); } } + +/// Some flags have moved. In a few common cases we detect this, warn the user and reorder the flags. +fn handle_legacy_flags() { + let arg_strings: Vec = std::env::args().collect(); + let args: Vec<&str> = arg_strings.iter().map(|s| s.as_str()).collect(); + eprintln!("Args: {args:?}"); + + /// Macro for rewriting arguments. + /// + /// nargs == the number of arguments to consider for rewriting. + /// old == a pattern for the start of the provided arguments + /// new == the replacement arguments + /// condition == any additional condition, above pattern matching, to apply. + /// + /// Example: + /// ``` + /// rewrite!(4, ["wallet", "--network", network, "balance"], ["wallet", "balance", "--network", network]) + /// ``` + macro_rules! rewrite { + ($nargs:expr, $old:pat, $new:expr) => { + rewrite!($nargs, $old, $new, $true); + }; + ($nargs:expr, $old:pat, $new:expr, $condition:expr) => { + let arg_slice_start = 1; + let arg_slice_end = arg_slice_start + $nargs; + if args.len() >= arg_slice_end { + if let $old = &args[arg_slice_start..arg_slice_end] { + if $condition { + let mut exe = std::process::Command::new(std::env::current_exe().unwrap()); + exe.args($new).args(&args[arg_slice_end..]); + eprintln!("dfx flags have moved. Please see dfx --help for details. Rewritten {:?} to: {:?}", args, exe.get_args()); + std::process::exit(exe.status().unwrap().code().unwrap_or_default()); + } + } + } + }; + } + + // The top level no longer supports --identity or --network so push these down to the subcommand. + // Example: + // Old: dfx --identity default canister id foo + // New: dfx canister --identity default id foo + rewrite!( + 3, + [flag, value, command], + [command, flag, value], + !command.starts_with("--") && ["--identity", "--network"].contains(flag) + ); + rewrite!( + 5, + [flag1, value1, flag2, value2, command], + [command, flag1, value1, flag2, value2], + !command.starts_with("--") + && ["--identity", "--network"].contains(flag1) + && ["--identity", "--network"].contains(flag2) + ); + + // Push some flags down one further: + // Example: + // Old: dfx canister --network local id mydapp + // New: dfx canister id --network local mydapp + let commands = ["wallet", "canister", "identity"]; + let flags = ["--identity", "--network", "--canister", "--wallet"]; + rewrite!( + 4, + [command, flag1, value1, subcommand], + [command, subcommand, flag1, value1], + commands.contains(command) && !subcommand.starts_with("--") && flags.contains(flag1) + ); + rewrite!( + 6, + [command, flag1, value1, flag2, value2, subcommand], + [command, subcommand, flag1, value1, flag2, value2], + commands.contains(command) + && !subcommand.starts_with("--") + && flags.contains(flag1) + && flags.contains(flag2) + ); + rewrite!( + 8, + [command, flag1, value1, flag2, value2, flag3, value3, subcommand], + [command, subcommand, flag1, value1, flag2, value2, flag3, value3], + commands.contains(command) + && !subcommand.starts_with("--") + && flags.contains(flag1) + && flags.contains(flag2) + && flags.contains(flag3) + ); +} From c78e2dedf0601629d28adab786f96e80eaaa755e Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 29 Aug 2022 16:18:34 +0200 Subject: [PATCH 2/3] squelch --- src/dfx/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dfx/src/main.rs b/src/dfx/src/main.rs index a2717e0d63..682a79eec2 100644 --- a/src/dfx/src/main.rs +++ b/src/dfx/src/main.rs @@ -216,7 +216,6 @@ fn main() { fn handle_legacy_flags() { let arg_strings: Vec = std::env::args().collect(); let args: Vec<&str> = arg_strings.iter().map(|s| s.as_str()).collect(); - eprintln!("Args: {args:?}"); /// Macro for rewriting arguments. /// From f868b74ae195939f444f939e52ef39ef99a7a5aa Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 29 Aug 2022 16:23:50 +0200 Subject: [PATCH 3/3] ++ --- src/dfx/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfx/src/main.rs b/src/dfx/src/main.rs index 682a79eec2..e512edb8ad 100644 --- a/src/dfx/src/main.rs +++ b/src/dfx/src/main.rs @@ -230,7 +230,7 @@ fn handle_legacy_flags() { /// ``` macro_rules! rewrite { ($nargs:expr, $old:pat, $new:expr) => { - rewrite!($nargs, $old, $new, $true); + rewrite!($nargs, $old, $new, true); }; ($nargs:expr, $old:pat, $new:expr, $condition:expr) => { let arg_slice_start = 1;