feat(source): support cherry-picking commits for git sources
- add source.cherry_pick (and cherry-pick alias) to package spec parsing/serialization - apply listed cherry-picks in order after git checkout - reject cherry_pick on non-git sources with explicit error - include cherry_pick in interactive spec TOML output - add parsing/behavior tests and update Source test fixtures
This commit is contained in:
@@ -425,6 +425,7 @@ pub fn create_interactive() -> Result<PackageSpec> {
|
||||
extract_dir,
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
};
|
||||
|
||||
if show_advanced {
|
||||
@@ -791,6 +792,17 @@ pub fn spec_to_minimal_toml(spec: &PackageSpec) -> anyhow::Result<String> {
|
||||
),
|
||||
);
|
||||
}
|
||||
if !s.cherry_pick.is_empty() {
|
||||
st.insert(
|
||||
"cherry_pick".into(),
|
||||
Value::Array(
|
||||
s.cherry_pick
|
||||
.iter()
|
||||
.map(|rev| Value::String(rev.clone()))
|
||||
.collect(),
|
||||
),
|
||||
);
|
||||
}
|
||||
arr.push(Value::Table(st));
|
||||
}
|
||||
root.insert("source".into(), Value::Array(arr));
|
||||
@@ -1316,6 +1328,7 @@ mod tests {
|
||||
extract_dir: "foo-1.0".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
@@ -1365,6 +1378,7 @@ mod tests {
|
||||
extract_dir: "foo-1.0".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
@@ -1401,6 +1415,7 @@ mod tests {
|
||||
extract_dir: "foo-1.0".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
@@ -1464,6 +1479,7 @@ mod tests {
|
||||
extract_dir: "foo-1.0".into(),
|
||||
patches: vec!["fix.patch".into()],
|
||||
post_extract: vec!["autoreconf -fi".into()],
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
@@ -1525,6 +1541,7 @@ mod tests {
|
||||
extract_dir: "$name-$version".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
@@ -1560,6 +1577,7 @@ mod tests {
|
||||
extract_dir: "foo-1.0".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Autotools,
|
||||
|
||||
@@ -1153,6 +1153,7 @@ type = "custom"
|
||||
);
|
||||
assert!(spec.sources()[0].patches.is_empty());
|
||||
assert!(spec.sources()[0].post_extract.is_empty());
|
||||
assert!(spec.sources()[0].cherry_pick.is_empty());
|
||||
assert_eq!(spec.spec_dir, tmp.path());
|
||||
}
|
||||
|
||||
@@ -1193,6 +1194,40 @@ type = "custom"
|
||||
assert_eq!(spec.sources()[1].extract_dir, "bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_git_source_with_cherry_pick() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let path = tmp.path().join("pkg.toml");
|
||||
|
||||
std::fs::write(
|
||||
&path,
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "1.0"
|
||||
description = "d"
|
||||
homepage = "h"
|
||||
license = "MIT"
|
||||
|
||||
[source]
|
||||
url = "https://example.com/foo.git#main"
|
||||
sha256 = "skip"
|
||||
extract_dir = "foo"
|
||||
cherry_pick = ["deadbeef", "cafebabe"]
|
||||
|
||||
[build]
|
||||
type = "custom"
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let spec = PackageSpec::from_file(&path).unwrap();
|
||||
assert_eq!(
|
||||
spec.sources()[0].cherry_pick,
|
||||
vec!["deadbeef".to_string(), "cafebabe".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_package_dependencies_overrides() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
@@ -2378,6 +2413,7 @@ type = "custom"
|
||||
extract_dir: "e".into(),
|
||||
patches: Vec::new(),
|
||||
post_extract: Vec::new(),
|
||||
cherry_pick: Vec::new(),
|
||||
}],
|
||||
build: Build {
|
||||
build_type: BuildType::Custom,
|
||||
@@ -2503,6 +2539,18 @@ pub struct Source {
|
||||
/// post_extract = ["autoreconf -fi"]
|
||||
#[serde(default)]
|
||||
pub post_extract: Vec<String>,
|
||||
|
||||
/// Optional list of git commit hashes/revs to cherry-pick after checkout.
|
||||
///
|
||||
/// This is only valid for git sources (`*.git` URL or `url#rev` git form).
|
||||
/// Example:
|
||||
/// cherry_pick = ["a1b2c3d4", "deadbeef"]
|
||||
#[serde(
|
||||
default,
|
||||
alias = "cherry-pick",
|
||||
deserialize_with = "deserialize_string_or_array"
|
||||
)]
|
||||
pub cherry_pick: Vec<String>,
|
||||
}
|
||||
|
||||
/// Manual source copied before standard source fetching.
|
||||
|
||||
Reference in New Issue
Block a user