Skip to content

Commit

Permalink
Merge branch 'unstable' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
markcda committed Jan 6, 2025
2 parents a61e2e3 + 7ab845f commit ff47430
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 25 deletions.
13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
[package]
name = "smart-patcher"
version = "0.1.1"
version = "0.1.3"
edition = "2024"

[dependencies]
anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] }
mlua = { version = "0.10", features = ["anyhow", "lua54", "vendored"] }
pyo3 = { version = "0.23", features = ["auto-initialize"] }
mlua = { optional = true, version = "0.10", features = ["anyhow", "lua54", "vendored"] }
pyo3 = { optional = true, version = "0.23", features = ["auto-initialize"] }
regex = "1.11"
rhai = "1.20"
rhai = { optional = true, version = "1.20" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
walkdir = "2.5"

[features]
default = ["tests", "generate-patches"]
tests = []
generate-patches = []
generate-patches = ["python", "lua", "rhai"]
python = ["dep:pyo3"]
lua = ["dep:mlua"]
rhai = ["dep:rhai"]
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ smart-patcher apply {patch-file.json} {folder-to-patch}

If you use any scripts, make sure that the path to the script files is relative to the patch file.

Also you can use `smart-patcher` as library and even specify needed features:

```toml
[dependencies]
smart-patcher = { git = "https://github.com/impulse-sw/smart-patcher", tag = "0.1.3", default-features = false, features = ["python", "lua", "rhai"] }
```

## Patches

To write a patch you must define:
Expand Down
33 changes: 29 additions & 4 deletions deploy-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,32 @@
],
"commands": [
{
"bash_c": "cargo clippy",
"bash_c": "cargo clippy --no-default-features",
"ignore_fails": false,
"show_success_output": true,
"show_bash_c": true,
"only_when_fresh": null
}
]
}
}
},
{
"title": "Lint v2",
"desc": "Got from `Cargo Clippy`.",
"info": "[email protected]",
"tags": [
"cargo",
"clippy"
],
"action": {
"PreBuild": {
"supported_langs": [
"Rust"
],
"commands": [
{
"bash_c": "cargo clippy --no-default-features --features=python,lua,rhai",
"ignore_fails": false,
"show_success_output": true,
"show_bash_c": true,
Expand All @@ -68,7 +93,7 @@
],
"commands": [
{
"bash_c": "cargo build --release --no-default-features",
"bash_c": "cargo build --release --no-default-features --features=python,lua,rhai",
"ignore_fails": false,
"show_success_output": false,
"show_bash_c": true,
Expand All @@ -94,7 +119,7 @@
],
"commands": [
{
"bash_c": "cargo test --no-default-features",
"bash_c": "cargo test --no-default-features --features=python,lua,rhai",
"ignore_fails": false,
"show_success_output": true,
"show_bash_c": true,
Expand Down Expand Up @@ -245,4 +270,4 @@
"smart-patcher"
]
]
}
}
11 changes: 11 additions & 0 deletions examples/patch9.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"patches": [
{
"files": [],
"patch_find_graph": [],
"replace": {
"by_python": "../tests/test_v9.py"
}
}
]
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
pub mod patch;
pub mod regex;

#[cfg(feature = "python")]
pub mod python_exec;
#[cfg(feature = "lua")]
pub mod lua_exec;
#[cfg(feature = "rhai")]
pub mod rhai_exec;
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ pub(crate) mod cmd;
pub(crate) mod patch;
pub(crate) mod regex;

#[cfg(feature = "python")]
pub(crate) mod python_exec;
#[cfg(feature = "lua")]
pub(crate) mod lua_exec;
#[cfg(feature = "rhai")]
pub(crate) mod rhai_exec;

use clap::Parser;
Expand Down
66 changes: 50 additions & 16 deletions src/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ use walkdir::WalkDir;

use crate::regex::RegexIR;

#[cfg(feature = "lua")]
use crate::lua_exec;
#[cfg(feature = "python")]
use crate::python_exec;
#[cfg(feature = "rhai")]
use crate::rhai_exec;

#[derive(Deserialize, Serialize, PartialEq, Default, Clone, Debug)]
Expand Down Expand Up @@ -36,16 +39,22 @@ pub enum FindRule {
NotContains(RegexIR),
Before(RegexIR),
After(RegexIR),
#[cfg(feature = "python")]
FindByPython(PathBuf),
#[cfg(feature = "lua")]
FindByLua(PathBuf),
#[cfg(feature = "rhai")]
FindByRhai(PathBuf),
}

#[derive(Deserialize, Serialize, PartialEq, Clone, Debug)]
#[serde(rename_all="snake_case")]
pub enum DecodeBy {
#[cfg(feature = "python")]
Python(PathBuf),
#[cfg(feature = "lua")]
Lua(PathBuf),
#[cfg(feature = "rhai")]
Rhai(PathBuf),
}

Expand All @@ -55,8 +64,11 @@ pub type EncodeBy = DecodeBy;
#[serde(rename_all="snake_case")]
pub enum Replacer {
FromTo(String, String),
#[cfg(feature = "python")]
ByPython(PathBuf),
#[cfg(feature = "lua")]
ByLua(PathBuf),
#[cfg(feature = "rhai")]
ByRhai(PathBuf),
}

Expand Down Expand Up @@ -114,52 +126,62 @@ impl PatchFile {
})
}

fn read(path: &Path, patch_dir: &Path, decoder: &Option<DecodeBy>) -> anyhow::Result<String> {
fn read(path: &Path, _patch_dir: &Path, decoder: &Option<DecodeBy>) -> anyhow::Result<String> {
match decoder {
None => {
let mut content = String::new();
File::open(path)?.read_to_string(&mut content)?;
Ok(content)
},
#[cfg(feature = "python")]
Some(DecodeBy::Python(script)) => {
let mut content = vec![];
File::open(path)?.read_to_end(&mut content)?;
Ok(python_exec::decode_by(patch_dir, script, &content)?)
Ok(python_exec::decode_by(_patch_dir, script, &content)?)
},
#[cfg(feature = "lua")]
Some(DecodeBy::Lua(script)) => {
let mut content = vec![];
File::open(path)?.read_to_end(&mut content)?;
Ok(lua_exec::decode_by(patch_dir, script, &content)?)
Ok(lua_exec::decode_by(_patch_dir, script, &content)?)
},
#[cfg(feature = "rhai")]
Some(DecodeBy::Rhai(script)) => {
let mut content = vec![];
File::open(path)?.read_to_end(&mut content)?;
Ok(rhai_exec::decode_by(patch_dir, script, &content)?)
Ok(rhai_exec::decode_by(_patch_dir, script, &content)?)
},
#[cfg(not(any(feature = "python", feature = "lua", feature = "rhai")))]
Some(_) => anyhow::bail!("Any decoder variants are unsupported. Build `smart-patcher` with `python`, `lua` or `rhai` feature."),
}
}

fn write(path: &Path, patch_dir: &Path, encoder: &Option<EncodeBy>, content: &str) -> anyhow::Result<()> {
fn write(path: &Path, _patch_dir: &Path, encoder: &Option<EncodeBy>, content: &str) -> anyhow::Result<()> {
match encoder {
None => {
fs::write(path, content)?;
Ok(())
},
#[cfg(feature = "python")]
Some(EncodeBy::Python(script)) => {
let content = python_exec::encode_by(patch_dir, script, content)?;
let content = python_exec::encode_by(_patch_dir, script, content)?;
fs::write(path, content)?;
Ok(())
},
#[cfg(feature = "lua")]
Some(EncodeBy::Lua(script)) => {
let content = lua_exec::encode_by(patch_dir, script, content)?;
let content = lua_exec::encode_by(_patch_dir, script, content)?;
fs::write(path, content)?;
Ok(())
},
#[cfg(feature = "rhai")]
Some(EncodeBy::Rhai(script)) => {
let content = rhai_exec::encode_by(patch_dir, script, content)?;
let content = rhai_exec::encode_by(_patch_dir, script, content)?;
fs::write(path, content)?;
Ok(())
},
#[cfg(not(any(feature = "python", feature = "lua", feature = "rhai")))]
Some(_) => anyhow::bail!("Any encoder variants are unsupported. Build `smart-patcher` with `python`, `lua` or `rhai` feature."),
}
}

Expand All @@ -172,9 +194,12 @@ impl PatchFile {
if !middle.is_empty() && let Some(replacer) = &patch.replace {
match replacer {
Replacer::FromTo(from, to) => { middle = middle.replace(from, to); },
#[cfg(feature = "python")]
Replacer::ByPython(path) => { middle = python_exec::replace_by(patch_dir, path, &middle)?; },
Replacer::ByLua(path) => { middle = lua_exec::replace_by(patch_dir, path, &middle)?; }
Replacer::ByRhai(path) => { middle = rhai_exec::replace_by(patch_dir, path, &middle)?; }
#[cfg(feature = "lua")]
Replacer::ByLua(path) => { middle = lua_exec::replace_by(patch_dir, path, &middle)?; },
#[cfg(feature = "rhai")]
Replacer::ByRhai(path) => { middle = rhai_exec::replace_by(patch_dir, path, &middle)?; },
}
}
if let Some(inplace) = &patch.inplace {
Expand All @@ -194,7 +219,7 @@ impl PatchFile {
Ok(None)
}

fn find_section(content: &str, patch_dir: &Path, rules: &[FindRule]) -> anyhow::Result<Option<(std::ops::Range<usize>, CursorType)>> {
fn find_section(content: &str, _patch_dir: &Path, rules: &[FindRule]) -> anyhow::Result<Option<(std::ops::Range<usize>, CursorType)>> {
let mut current_pos = 0;
let mut start_pos = None;
let mut end_pos = None;
Expand All @@ -218,33 +243,36 @@ impl PatchFile {
current_pos += mat.end();
} else { return Ok(None); }
},
#[cfg(feature = "python")]
FindRule::FindByPython(path) => {
let (new_start, new_end, cursor_at_end) = python_exec::find_by(patch_dir, path, content, start_pos, end_pos)?;
let (new_start, new_end, cursor_at_end) = python_exec::find_by(_patch_dir, path, content, start_pos, end_pos)?;

if start_pos.is_none() && new_start != 0 { start_pos = Some(new_start); }
if end_pos.is_none() && new_end != content.len() { end_pos = Some(new_end); }

if cursor_at_end { cursor = CursorType::End; }
else { cursor = CursorType::Start; }
},
#[cfg(feature = "lua")]
FindRule::FindByLua(path) => {
let (new_start, new_end, cursor_at_end) = lua_exec::find_by(patch_dir, path, content, start_pos, end_pos)?;
let (new_start, new_end, cursor_at_end) = lua_exec::find_by(_patch_dir, path, content, start_pos, end_pos)?;

if start_pos.is_none() && new_start != 0 { start_pos = Some(new_start); }
if end_pos.is_none() && new_end != content.len() { end_pos = Some(new_end); }

if cursor_at_end { cursor = CursorType::End; }
else { cursor = CursorType::Start; }
}
},
#[cfg(feature = "rhai")]
FindRule::FindByRhai(path) => {
let (new_start, new_end, cursor_at_end) = rhai_exec::find_by(patch_dir, path, content, start_pos, end_pos)?;
let (new_start, new_end, cursor_at_end) = rhai_exec::find_by(_patch_dir, path, content, start_pos, end_pos)?;

if start_pos.is_none() && new_start != 0 { start_pos = Some(new_start); }
if end_pos.is_none() && new_end != content.len() { end_pos = Some(new_end); }

if cursor_at_end { cursor = CursorType::End; }
else { cursor = CursorType::Start; }
}
},
}
}

Expand Down Expand Up @@ -331,6 +359,7 @@ mod tests {
}

#[test]
#[cfg(feature = "python")]
fn find_v4() -> anyhow::Result<()> {
let patch = Patch {
files: vec![],
Expand All @@ -355,6 +384,7 @@ mod tests {
}

#[test]
#[cfg(feature = "python")]
fn find_v5() -> anyhow::Result<()> {
let patch = Patch {
files: vec![FilePath::Just(PathBuf::from("test_v5.docx"))],
Expand All @@ -374,6 +404,7 @@ mod tests {
}

#[test]
#[cfg(feature = "lua")]
fn find_v6() -> anyhow::Result<()> {
let patch = Patch {
files: vec![],
Expand All @@ -398,6 +429,7 @@ mod tests {
}

#[test]
#[cfg(feature = "rhai")]
fn find_v7() -> anyhow::Result<()> {
let patch = Patch {
files: vec![],
Expand All @@ -422,6 +454,7 @@ mod tests {
}

#[test]
#[cfg(feature = "python")]
fn find_v8() -> anyhow::Result<()> {
let patch = Patch {
files: vec![],
Expand All @@ -442,6 +475,7 @@ mod tests {
}

#[test]
#[cfg(feature = "python")]
fn find_v9() -> anyhow::Result<()> {
let patch = Patch {
files: vec![],
Expand Down

0 comments on commit ff47430

Please sign in to comment.