From 26e07090225209d72ed38fd64d4a205e75428b22 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 1 Aug 2020 15:29:28 -0400 Subject: [PATCH 1/5] Add some tests around parsing toolchain descriptions --- src/dist/dist.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/dist/dist.rs b/src/dist/dist.rs index f1fc3f84a6..2751f7f9a3 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -31,7 +31,7 @@ static TOOLCHAIN_CHANNELS: &[&str] = &[ r"\d{1}\.\d{1,3}\.\d{1,2}", ]; -#[derive(Debug)] +#[derive(Debug, PartialEq)] struct ParsedToolchainDesc { channel: String, date: Option, @@ -940,3 +940,71 @@ fn utc_from_manifest_date(date_str: &str) -> Option> { .ok() .map(|date| Utc.from_utc_date(&date)) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parsed_toolchain_desc_parse() { + let success_cases = vec![ + ("nightly", ("nightly", None, None)), + ("beta", ("beta", None, None)), + ("stable", ("stable", None, None)), + ("0.0.0", ("0.0.0", None, None)), + ("0.0.0-", ("0.0.0", None, None)), // possibly a bug? + ("0.0.0--", ("0.0.0", None, Some("-"))), // possibly a bug? + ("9.999.99", ("9.999.99", None, None)), + ("0.0.0-anything", ("0.0.0", None, Some("anything"))), + // possibly unexpected behavior, if someone typos a date? + ( + "0.0.0-00000-000-000", + ("0.0.0", None, Some("00000-000-000")), + ), + ("0.0.0-0000-00-00", ("0.0.0", Some("0000-00-00"), None)), + ("0.0.0-0000-00-00-", ("0.0.0", Some("0000-00-00"), None)), // possibly a bug? + ( + "0.0.0-0000-00-00-any-other-thing", + ("0.0.0", Some("0000-00-00"), Some("any-other-thing")), + ), + ]; + + for (input, (channel, date, target)) in success_cases { + let parsed = input.parse::(); + assert!( + parsed.is_ok(), + "expected parsing of `{}` to succeed: {:?}", + input, + parsed + ); + + let expected = ParsedToolchainDesc { + channel: channel.into(), + date: date.map(String::from), + target: target.map(String::from), + }; + assert_eq!(parsed.unwrap(), expected, "input: `{}`", input); + } + + let failure_cases = vec!["anything", "00.0000.000", "3", "3.4", "", "--"]; + + for input in failure_cases { + let parsed = input.parse::(); + assert!( + parsed.is_err(), + "expected parsing of `{}` to fail: {:?}", + input, + parsed + ); + + let error_message = format!("invalid toolchain name: '{}'", input); + + assert_eq!( + parsed.unwrap_err().to_string(), + error_message, + "input: `{}`", + input + ); + } + } +} From af867d53a3fc591bf400d933549c8eab94dfae9e Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 1 Aug 2020 18:28:41 -0400 Subject: [PATCH 2/5] In toolchain parsing, require characters after a hyphen for a successful target match --- src/dist/dist.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 2751f7f9a3..86e47eb04b 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -146,7 +146,7 @@ impl FromStr for ParsedToolchainDesc { fn from_str(desc: &str) -> Result { lazy_static! { static ref TOOLCHAIN_CHANNEL_PATTERN: String = format!( - r"^({})(?:-(\d{{4}}-\d{{2}}-\d{{2}}))?(?:-(.*))?$", + r"^({})(?:-(\d{{4}}-\d{{2}}-\d{{2}}))?(?:-(.+))?$", TOOLCHAIN_CHANNELS.join("|") ); // Note this regex gives you a guaranteed match of the channel (1) @@ -952,17 +952,17 @@ mod tests { ("beta", ("beta", None, None)), ("stable", ("stable", None, None)), ("0.0.0", ("0.0.0", None, None)), - ("0.0.0-", ("0.0.0", None, None)), // possibly a bug? ("0.0.0--", ("0.0.0", None, Some("-"))), // possibly a bug? ("9.999.99", ("9.999.99", None, None)), ("0.0.0-anything", ("0.0.0", None, Some("anything"))), + ("0.0.0-0000-00-00", ("0.0.0", Some("0000-00-00"), None)), // possibly unexpected behavior, if someone typos a date? ( "0.0.0-00000-000-000", ("0.0.0", None, Some("00000-000-000")), ), - ("0.0.0-0000-00-00", ("0.0.0", Some("0000-00-00"), None)), - ("0.0.0-0000-00-00-", ("0.0.0", Some("0000-00-00"), None)), // possibly a bug? + // possibly unexpected behavior, if someone forgets to add target after the hyphen? + ("0.0.0-0000-00-00-", ("0.0.0", None, Some("0000-00-00-"))), ( "0.0.0-0000-00-00-any-other-thing", ("0.0.0", Some("0000-00-00"), Some("any-other-thing")), @@ -986,7 +986,7 @@ mod tests { assert_eq!(parsed.unwrap(), expected, "input: `{}`", input); } - let failure_cases = vec!["anything", "00.0000.000", "3", "3.4", "", "--"]; + let failure_cases = vec!["anything", "00.0000.000", "3", "3.4", "", "--", "0.0.0-"]; for input in failure_cases { let parsed = input.parse::(); From 71f09c551f85d14ade730151e92db0aef4161795 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Mon, 3 Aug 2020 20:49:57 -0400 Subject: [PATCH 3/5] Add some tests around parsing partial target triples --- src/dist/dist.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 86e47eb04b..1a1766b01f 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -51,7 +51,7 @@ pub struct PartialToolchainDesc { pub target: PartialTargetTriple, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct PartialTargetTriple { pub arch: Option, pub os: Option, @@ -1007,4 +1007,67 @@ mod tests { ); } } + + #[test] + fn test_partial_target_triple_new() { + let success_cases = vec![ + ("", (None, None, None)), + ("i386", (Some("i386"), None, None)), + ("pc-windows", (None, Some("pc-windows"), None)), + ("gnu", (None, None, Some("gnu"))), + ("i386-gnu", (Some("i386"), None, Some("gnu"))), + ("pc-windows-gnu", (None, Some("pc-windows"), Some("gnu"))), + ("i386-pc-windows", (Some("i386"), Some("pc-windows"), None)), + ( + "i386-pc-windows-gnu", + (Some("i386"), Some("pc-windows"), Some("gnu")), + ), + ]; + + for (input, (arch, os, env)) in success_cases { + let partial_target_triple = PartialTargetTriple::new(input); + assert!( + partial_target_triple.is_some(), + "expected `{}` to create some partial target triple; got None", + input + ); + + let expected = PartialTargetTriple { + arch: arch.map(String::from), + os: os.map(String::from), + env: env.map(String::from), + }; + + assert_eq!( + partial_target_triple.unwrap(), + expected, + "input: `{}`", + input + ); + } + + let failure_cases = vec![ + "anything", + "any-other-thing", + "-", + "--", + "i386-", + "i386-pc-", + "i386-pc-windows-", + "-pc-windows", + "i386-pc-windows-anything", + "0000-00-00-", + "00000-000-000", + ]; + + for input in failure_cases { + let partial_target_triple = PartialTargetTriple::new(input); + assert!( + partial_target_triple.is_none(), + "expected `{}` to be `None`, was: `{:?}`", + input, + partial_target_triple + ); + } + } } From 00f48fed8c18f63494920ca964b9bb99694a7419 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Sat, 1 Aug 2020 18:22:01 -0400 Subject: [PATCH 4/5] Parse version numbers optionally without the patch version specified Fixes #794. --- src/dist/dist.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 1a1766b01f..1b71e58f45 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -27,8 +27,8 @@ static TOOLCHAIN_CHANNELS: &[&str] = &[ "nightly", "beta", "stable", - // Allow from 1.0.0 through to 9.999.99 - r"\d{1}\.\d{1,3}\.\d{1,2}", + // Allow from 1.0.0 through to 9.999.99 with optional patch version + r"\d{1}\.\d{1,3}(?:\.\d{1,2})?", ]; #[derive(Debug, PartialEq)] @@ -951,6 +951,7 @@ mod tests { ("nightly", ("nightly", None, None)), ("beta", ("beta", None, None)), ("stable", ("stable", None, None)), + ("0.0", ("0.0", None, None)), ("0.0.0", ("0.0.0", None, None)), ("0.0.0--", ("0.0.0", None, Some("-"))), // possibly a bug? ("9.999.99", ("9.999.99", None, None)), @@ -986,7 +987,7 @@ mod tests { assert_eq!(parsed.unwrap(), expected, "input: `{}`", input); } - let failure_cases = vec!["anything", "00.0000.000", "3", "3.4", "", "--", "0.0.0-"]; + let failure_cases = vec!["anything", "00.0000.000", "3", "", "--", "0.0.0-"]; for input in failure_cases { let parsed = input.parse::(); From 7efa731a0356861258ed3527216206f6313940a5 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Wed, 11 Nov 2020 21:02:53 -0500 Subject: [PATCH 5/5] Document that major.minor is now an acceptable channel name --- doc/src/concepts/toolchains.md | 10 +++++----- src/cli/help.rs | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/src/concepts/toolchains.md b/doc/src/concepts/toolchains.md index 7f15d38668..7523ee6070 100644 --- a/doc/src/concepts/toolchains.md +++ b/doc/src/concepts/toolchains.md @@ -15,15 +15,15 @@ Standard release channel toolchain names have the following form: ``` [-][-] - = stable|beta|nightly| + = stable|beta|nightly|| = YYYY-MM-DD = ``` -'channel' is either a named release channel or an explicit version number, -such as `1.42.0`. Channel names can be optionally appended with an archive -date, as in `nightly-2014-12-18`, in which case the toolchain is downloaded -from the archive for that date. +'channel' is a named release channel, a major and minor version number such as +`1.42`, or a fully specified version number, such as `1.42.0`. Channel names +can be optionally appended with an archive date, as in `nightly-2014-12-18`, in +which case the toolchain is downloaded from the archive for that date. Finally, the host may be specified as a target triple. This is most useful for installing a 32-bit compiler on a 64-bit platform, or for installing the diff --git a/src/cli/help.rs b/src/cli/help.rs index cfa2036d4e..ce97f15fee 100644 --- a/src/cli/help.rs +++ b/src/cli/help.rs @@ -55,14 +55,15 @@ pub static TOOLCHAIN_HELP: &str = r"DISCUSSION: [-][-] - = stable|beta|nightly| + = stable|beta|nightly|| = YYYY-MM-DD = - 'channel' is either a named release channel or an explicit version - number, such as '1.42.0'. Channel names can be optionally appended - with an archive date, as in 'nightly-2017-05-09', in which case - the toolchain is downloaded from the archive for that date. + 'channel' is a named release channel, a major and minor version + number such as `1.42`, or a fully specified version number, such + as `1.42.0`. Channel names can be optionally appended with an + archive date, as in `nightly-2014-12-18`, in which case the + toolchain is downloaded from the archive for that date. The host may be specified as a target triple. This is most useful for installing a 32-bit compiler on a 64-bit platform, or for