|
1 | 1 | #![warn(rust_2018_idioms)] // while we're getting used to 2018
|
2 | 2 | #![allow(clippy::all)]
|
3 | 3 |
|
| 4 | +use cargo::util::config::{ConfigError, ConfigErrorKind, Value}; |
4 | 5 | use cargo::util::toml::StringOrVec;
|
5 | 6 | use cargo::util::CliError;
|
6 | 7 | use cargo::util::{self, closest_msg, command_prelude, CargoResult, CliResult, Config};
|
@@ -52,18 +53,32 @@ fn builtin_aliases_execs(cmd: &str) -> Option<&(&str, &str, &str)> {
|
52 | 53 | BUILTIN_ALIASES.iter().find(|alias| alias.0 == cmd)
|
53 | 54 | }
|
54 | 55 |
|
| 56 | +/// Resolve the aliased command from the [`Config`] with a given command string. |
| 57 | +/// |
| 58 | +/// The search fallback chain is: |
| 59 | +/// |
| 60 | +/// 1. Get the aliased command as a string. |
| 61 | +/// 2. If the aliased command is not a string, get it as an array. |
| 62 | +/// 3. If cannot find any, finds one insides [`BUILTIN_ALIASES`]. |
| 63 | +/// 4. If still no command is found, return `None`. |
55 | 64 | fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
|
56 |
| - let alias_name = format!("alias.{}", command); |
57 |
| - let user_alias = match config.get_string(&alias_name) { |
58 |
| - Ok(Some(record)) => Some( |
| 65 | + let alias_name = format!("alias.{command}"); |
| 66 | + let user_alias = match config.get::<Value<String>>(&alias_name) { |
| 67 | + Ok(record) => Some( |
59 | 68 | record
|
60 | 69 | .val
|
61 | 70 | .split_whitespace()
|
62 | 71 | .map(|s| s.to_string())
|
63 | 72 | .collect(),
|
64 | 73 | ),
|
65 |
| - Ok(None) => None, |
66 |
| - Err(_) => config.get::<Option<Vec<String>>>(&alias_name)?, |
| 74 | + Err(e) => match e.downcast_ref::<ConfigError>().map(|e| e.kind()) { |
| 75 | + // Just report we cannot find anything. |
| 76 | + Some(ConfigErrorKind::MissingKey) => None, |
| 77 | + // Alias might be set as an toml array, fallback and try it. |
| 78 | + Some(ConfigErrorKind::UnexpectedValue) => config.get::<Option<_>>(&alias_name)?, |
| 79 | + // A unrecoverable error, e.g. TOML parsing error. Relay it to the user. |
| 80 | + Some(ConfigErrorKind::Custom) | None => return Err(e), |
| 81 | + }, |
67 | 82 | };
|
68 | 83 |
|
69 | 84 | let result = user_alias.or_else(|| {
|
|
0 commit comments