-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1 parent
94bda5a
commit e27873f
Showing
8 changed files
with
341 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# The directory of the main repo | ||
WORK_DIR=$1 | ||
|
||
PATCH_TOOL_DIR=$WORK_DIR/tools/patch_tool | ||
|
||
# The package which needs to be patched | ||
# It always be the package which triggers the test | ||
PATCH_PACKAGE=$2 | ||
|
||
# The URL of the patch points to | ||
PATCH_TARGET_URL=$3 | ||
|
||
# The commit hash of the patch | ||
PATCH_COMMIT_HASH=$4 | ||
|
||
# To run the main repo actions | ||
mkdir .github/workflows/actions | ||
mv $WORK_DIR/.github/workflows/actions/* .github/workflows/actions | ||
|
||
# To do the patch for current commit | ||
cd $PATCH_TOOL_DIR | ||
cargo run -- ../../ $PATCH_PACKAGE $PATCH_TARGET_URL $PATCH_COMMIT_HASH |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/target |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[dependencies] | ||
anyhow = "1.0" | ||
toml = "0.8" | ||
|
||
[dependencies.serde] | ||
features = ["derive"] | ||
version = "1.0" | ||
|
||
[package] | ||
edition = "2021" | ||
name = "patch_tool" | ||
version = "0.1.0" | ||
|
||
[workspace] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
mod patch; | ||
#[macro_use] | ||
extern crate anyhow; | ||
fn main() { | ||
let args: Vec<String> = std::env::args().collect(); | ||
if args.len() < 5 { | ||
println!("Usage: cargo run <cargo_path> <patch_name> <patch_repo_name> <commit>"); | ||
return; | ||
} | ||
let cargo_path = &args[1]; | ||
let patch_name = &args[2]; | ||
// 默认服务端是 github,后续可能需要根据默认参数来传递 | ||
let patch_repo_name = &args[3]; | ||
let commit = &args[4]; | ||
patch::do_patch(cargo_path, patch_name, patch_repo_name, commit).unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use std::fs; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
use toml::Table; | ||
|
||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
pub struct PatchPackage { | ||
name: String, | ||
git: String, | ||
rev: Option<String>, | ||
} | ||
|
||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
pub struct CargoPackage { | ||
name: String, | ||
source: Option<String>, | ||
} | ||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
pub struct CargoLock { | ||
package: Vec<CargoPackage>, | ||
} | ||
|
||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | ||
pub struct GitPatch { | ||
git: String, | ||
commit: String, | ||
} | ||
|
||
fn get_patch_table(cargo_path: &String) -> anyhow::Result<Vec<CargoPackage>> { | ||
let cargo_lock: CargoLock = | ||
toml::from_str(&fs::read_to_string(format!("{}/Cargo.lock", cargo_path)).unwrap()).unwrap(); | ||
let patch_table = cargo_lock | ||
.package | ||
.into_iter() | ||
.filter(|x| match x.source { | ||
Some(ref source) => source.starts_with("git+https://github.com"), | ||
None => false, | ||
}) | ||
.collect(); | ||
Ok(patch_table) | ||
} | ||
|
||
pub fn do_patch( | ||
cargo_path: &String, | ||
patch_name: &String, | ||
patch_repo_name: &String, | ||
commit: &String, | ||
) -> anyhow::Result<()> { | ||
// 提取 patch_repo_name 的 repository 名称,并在前面加一个 / | ||
// 防止指向同一个仓库,导致报错`points to the same source, but patches must point to different sources` | ||
let names = patch_repo_name.split('/').collect::<Vec<&str>>(); | ||
if names.len() != 2 { | ||
return Err(anyhow!("This is not a valid patch repo name")); | ||
} | ||
let patch_git = format!("https://github.com/{}//{}.git", names[0], names[1]); | ||
// Check if the patch name is available | ||
let patch_table = get_patch_table(cargo_path)?; | ||
let patch = patch_table | ||
.iter() | ||
.find(|x| x.name == *patch_name) | ||
.ok_or(anyhow!("Can't find matched patch name"))?; | ||
|
||
// Get the patch info from the specific package | ||
let urls: Vec<&str> = patch.source.as_ref().unwrap().split("#").collect(); | ||
if urls.len() < 2 { | ||
return Err(anyhow!("This is not a valid patch source")); | ||
} | ||
let git_url_end = urls[0].find('?').unwrap_or(urls[0].len()); | ||
let git_url = &urls[0][4..git_url_end]; | ||
|
||
let mut cargo_toml: Table = | ||
toml::from_str(&fs::read_to_string(format!("{}/Cargo.toml", cargo_path))?)?; | ||
if !cargo_toml.contains_key("patch") { | ||
cargo_toml.insert(String::from("patch"), toml::Value::Table(Table::new())); | ||
} | ||
let patch_table = cargo_toml.get_mut("patch").unwrap().as_table_mut().unwrap(); | ||
|
||
if !patch_table.contains_key(git_url) { | ||
patch_table.insert(git_url.to_string(), toml::Value::Table(Table::new())); | ||
} | ||
let crates_io_table = patch_table | ||
.get_mut(git_url) | ||
.unwrap() | ||
.as_table_mut() | ||
.unwrap(); | ||
|
||
let mut git_table = toml::value::Table::new(); | ||
git_table.insert("git".to_string(), toml::Value::String(patch_git.clone())); | ||
git_table.insert("rev".to_string(), toml::Value::String(commit.clone())); | ||
|
||
crates_io_table.insert(patch_name.to_string(), toml::Value::Table(git_table)); | ||
fs::write( | ||
format!("{}/Cargo.toml", cargo_path), | ||
toml::to_string(&cargo_toml).unwrap(), | ||
) | ||
.unwrap(); | ||
Ok(()) | ||
} |