Skip to content

Commit

Permalink
Allow to override the version of git-cinnabar for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
glandium committed Aug 31, 2024
1 parent 9ea2d6d commit a379253
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 27 deletions.
10 changes: 3 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ libc = "0.2"
once_cell = "1.13"
percent-encoding = "2"
rand = "0.8"
semver = "1.0"
sha-1 = "0.10"
tee = "0.1"
tempfile = "3"
Expand Down Expand Up @@ -104,10 +105,6 @@ version = "1"
default-features = false
features = ["std"]

[dependencies.semver]
version = "1.0"
optional = true

[dependencies.shared_child]
version = "1.0"
optional = true
Expand Down Expand Up @@ -146,7 +143,6 @@ version = "0.1"
optional = true

[dev-dependencies]
semver = "1.0"
tempfile = "3"

[profile.release]
Expand All @@ -161,9 +157,9 @@ default = ["version-check"]
# libcurl.so compatibility (Linux only).
curl-compat = ["rustflags"]
# Check and report when a new version is available.
version-check = ["semver", "shared_child"]
version-check = ["shared_child"]
# Download and apply new versions.
self-update = ["semver", "shared_child", "dep:tar", "dep:xz2", "dep:zip", "windows-sys/Win32_System_Threading"]
self-update = ["shared_child", "dep:tar", "dep:xz2", "dep:zip", "windows-sys/Win32_System_Threading"]

# Development features

Expand Down
32 changes: 30 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3698,8 +3698,8 @@ impl FromStr for AbbrevSize {
#[derive(Parser)]
#[command(
name = "git-cinnabar",
version=*SHORT_VERSION,
long_version=*FULL_VERSION,
version=SHORT_VERSION.as_ref(),
long_version=FULL_VERSION.as_ref(),
arg_required_else_help = true,
dont_collapse_args_in_usage = true,
subcommand_required = true,
Expand Down Expand Up @@ -5165,6 +5165,30 @@ pub fn get_config(name: &str) -> Option<OsString> {
get_config_remote(name, None)
}

pub trait ConfigType: ToOwned {
fn from_os_string(value: OsString) -> Option<Self::Owned>;
}

impl ConfigType for str {
fn from_os_string(value: OsString) -> Option<Self::Owned> {
value.into_string().ok()
}
}

impl ConfigType for bool {
fn from_os_string(value: OsString) -> Option<Self::Owned> {
match value.as_bytes() {
b"1" | b"true" => Some(true),
b"" | b"0" | b"false" => Some(false),
_ => None,
}
}
}

pub fn get_typed_config<T: ConfigType + ?Sized>(name: &str) -> Option<T::Owned> {
get_config(name).and_then(T::from_os_string)
}

pub fn get_config_remote(name: &str, remote: Option<&str>) -> Option<OsString> {
const PREFIX: &str = "GIT_CINNABAR_";
let mut env_key = String::with_capacity(name.len() + PREFIX.len());
Expand Down Expand Up @@ -5281,6 +5305,7 @@ bitflags! {
const GIT_COMMIT = 0x2;
const TAG = 0x4;
const BRANCH = 0x8;
const TEST = 0x100;
}
}
pub struct AllExperiments {
Expand Down Expand Up @@ -5309,6 +5334,9 @@ static EXPERIMENTS: Lazy<AllExperiments> = Lazy::new(|| {
b"branch" => {
flags |= Experiments::BRANCH;
}
b"test" => {
flags |= Experiments::TEST;
}
s if s.starts_with(b"similarity") => {
if let Some(value) = s[b"similarity".len()..].strip_prefix(b"=") {
match u8::from_bytes(value) {
Expand Down
108 changes: 90 additions & 18 deletions src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,43 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::borrow::{Borrow, Cow};
use std::str::FromStr;

use once_cell::sync::Lazy;
use semver::Version;

use crate::git::CommitId;
use crate::{experiment, get_typed_config, ConfigType, Experiments};

macro_rules! join {
($s:expr) => {
Cow::Borrowed($s)
};
($($s:expr),+) => {
Cow::Owned(itertools::join(&[$($s),+], ""))
}
}

macro_rules! full_version {
($short_version:expr, $build_commit:expr, $modified:expr, $macro:ident) => {
if $build_commit.is_empty() {
$macro!($short_version)
} else {
$macro!(
$short_version,
"-",
$build_commit,
if $modified { "-modified" } else { "" }
)
}
};
}

mod static_ {
use clap::crate_version;
use concat_const::concat;
// Work around https://github.com/rust-lang/rust-analyzer/issues/8828 with `as cat`.
use concat_const::concat as cat;
use git_version::git_version;

#[cfg(any(feature = "version-check", feature = "self-update"))]
Expand All @@ -17,7 +49,7 @@ mod static_ {
args = ["--always", "--match=nothing/", "--abbrev=40", "--dirty=m"],
fallback = "",
);
const MODIFIED: bool = matches!(GIT_VERSION.as_bytes().last(), Some(b'm'));
pub const MODIFIED: bool = matches!(GIT_VERSION.as_bytes().last(), Some(b'm'));
pub const BUILD_COMMIT: &str = unsafe {
// Subslicing is not supported in const yet.
std::str::from_utf8_unchecked(std::slice::from_raw_parts(
Expand All @@ -29,25 +61,67 @@ mod static_ {
#[cfg(any(feature = "version-check", feature = "self-update"))]
pub const BUILD_BRANCH: BuildBranch = BuildBranch::from_version(SHORT_VERSION);

#[allow(clippy::const_is_empty)]
pub const FULL_VERSION: &str = if BUILD_COMMIT.is_empty() {
SHORT_VERSION
// #[allow(clippy::const_is_empty)]
pub const FULL_VERSION: &str = full_version!(SHORT_VERSION, BUILD_COMMIT, MODIFIED, cat);
}

fn value<'a, T: 'a + ConfigType + ?Sized, F: FnOnce(&T) -> bool>(
config: &str,
static_value: &'a T,
filter: F,
) -> Cow<'a, T> {
if let Some(value) = experiment(Experiments::TEST)
.then(|| get_typed_config::<T>(config))
.flatten()
.filter(|x| filter(x.borrow()))
{
Cow::Owned(value)
} else {
concat!(
SHORT_VERSION,
"-",
BUILD_COMMIT,
if MODIFIED { "-modified" } else { "" }
)
Cow::Borrowed(static_value)
}
}

macro_rules! value {
($config:expr, $static_value:expr) => {
value!($config, $static_value, |_| true)
};
($config:expr, $static_value:expr, $filter:expr) => {
Lazy::new(|| value($config, $static_value, $filter))
};
}

pub static SHORT_VERSION: Lazy<&'static str> = Lazy::new(|| static_::SHORT_VERSION);
#[cfg(any(feature = "version-check", feature = "self-update"))]
pub static BUILD_COMMIT: Lazy<&'static str> = Lazy::new(|| static_::BUILD_COMMIT);
type Value<T> = Lazy<Cow<'static, T>>;

fn is_overridden<T: ConfigType + ?Sized>(value: &Value<T>) -> bool {
matches!(**value, Cow::Owned(_))
}

pub static SHORT_VERSION: Value<str> =
value!("version", static_::SHORT_VERSION, |v| Version::parse(v)
.is_ok());
pub static BUILD_COMMIT: Value<str> = value!("commit", static_::BUILD_COMMIT, |c| c.is_empty()
|| CommitId::from_str(c).is_ok());
static MODIFIED: Value<bool> = value!("modified", &static_::MODIFIED);
#[cfg(any(feature = "version-check", feature = "self-update"))]
pub static BUILD_BRANCH: Lazy<BuildBranch> = Lazy::new(|| static_::BUILD_BRANCH);
pub static FULL_VERSION: Lazy<&'static str> = Lazy::new(|| static_::FULL_VERSION);
pub static BUILD_BRANCH: Lazy<BuildBranch> = Lazy::new(|| {
if is_overridden(&SHORT_VERSION) {
BuildBranch::from_version(&SHORT_VERSION)
} else {
static_::BUILD_BRANCH
}
});
pub static FULL_VERSION: Value<str> = Lazy::new(|| {
if is_overridden(&SHORT_VERSION) || is_overridden(&BUILD_COMMIT) || is_overridden(&MODIFIED) {
full_version!(
SHORT_VERSION.as_ref(),
BUILD_COMMIT.as_ref(),
*MODIFIED.as_ref(),
join
)
} else {
Cow::Borrowed(static_::FULL_VERSION)
}
});

#[cfg(any(feature = "version-check", feature = "self-update"))]
#[derive(PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -91,8 +165,6 @@ impl BuildBranch {
#[cfg(any(feature = "version-check", feature = "self-update"))]
#[test]
fn test_build_branch() {
use semver::Version;

// The following tests outline the expected lifecycle.
let from_version = |v| {
assert!(Version::parse(v).is_ok());
Expand Down

0 comments on commit a379253

Please sign in to comment.