From 5c4ccc02fbc18ffdef3b2bfa7ea96acc51ab2b99 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 7 Sep 2023 00:02:40 +0900 Subject: [PATCH] Reject inclusive range without end expression --- src/version.rs | 28 ++++++++++++++++++++-------- tests/test.rs | 8 ++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/version.rs b/src/version.rs index 6593febf..53554894 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,6 +1,6 @@ use std::{fmt, str::FromStr}; -use anyhow::{Context as _, Error, Result}; +use anyhow::{bail, Context as _, Error, Result}; #[derive(Copy, Clone)] pub(crate) struct Version { @@ -57,9 +57,9 @@ impl fmt::Display for VersionRange { if let MaybeVersion::Version(start) = self.start_inclusive { write!(f, "{start}")?; } - write!(f, "..=")?; + write!(f, "..")?; if let MaybeVersion::Version(end) = self.end_inclusive { - write!(f, "{end}")?; + write!(f, "={end}")?; } Ok(()) } @@ -71,12 +71,24 @@ impl FromStr for VersionRange { fn from_str(s: &str) -> Result { let (start, end) = if let Some((start, end)) = s.split_once("..") { let end = match end.strip_prefix('=') { - Some(end) => end, + Some(end) => { + if end.is_empty() { + // Reject inclusive range without end expression (`..=` and `..=`). (same behavior as Rust's inclusive range) + bail!( + "inclusive range `{s}` must have end expression; consider using `{}` or `{s}`", + s.replace("..=", "..") + ) + } + end + } None => { - warn!( - "using `..` for inclusive range is deprecated; consider using `{}`", - s.replace("..", "..=") - ); + // `..` and `..` are okay, so only warn `..`. + if !end.is_empty() { + warn!( + "using `..` for inclusive range is deprecated; consider using `{}`", + s.replace("..", "..=") + ); + } end } }; diff --git a/tests/test.rs b/tests/test.rs index 77674845..f9cac600 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1446,6 +1446,14 @@ fn version_range_failure() { .assert_failure("real") .stderr_contains("major version must be 1"); + // inclusive range without end expression + cargo_hack(["check", "--version-range", "..="]).assert_failure("real").stderr_contains( + "inclusive range `..=` must have end expression; consider using `..` or `..=`", + ); + cargo_hack(["check", "--version-range", "1.45..="]).assert_failure("real").stderr_contains( + "inclusive range `1.45..=` must have end expression; consider using `1.45..` or `1.45..=`", + ); + // patch version cargo_hack(["check", "--version-range", "1.45.2.."]) .assert_failure("real") // warn