Skip to content

impulse-sw/smart-patcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

smart-patcher

Patcher based on rules. Written for Deployer.

Features:

  • script support (Python, Lua, Rhai) - to find, replace, or decode/encode
  • regexes

Build

Install the Deployer and run:

deployer build

Or build by cargo:

cargo install --path .

Usage

See the patch examples in examples folder. You can run tests with them by Deployer.

The usage is easy:

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:

[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:

  1. Set of rules to select files to patch
  2. Set of rules to find file section to patch
  3. Replace or inplace content
  4. (Optionally) Decoder and encoder for any non-text files

Typical patch file looks like this:

{
  "patches": [
    {
      "files": [...],
      "decoder": ...,
      "encoder": ...,
      "patch_find_graph": [...],
      "replace": ...,
      "inplace": ...
    },..
  ]
}

1. Select rules

There are two types of select rules: just and re:

[
  {
    "just": "test_v5.docx"
  },
  {
    "re": ".*\\.docx"
  }
]

For match just rule, file path has to end with just value (e.g., tests/test_v5.docx). For re rule, file path has to match with Rust regular expression (read regex crate documentation).

2. File section rules

There are several rule types to cut text sections step by step:

  1. contains - if file isn't contain the text described by contains value's regular expression, the patch is not applied to it
  2. not_contains - nearly the same
  3. before and after - cuts the patchable area before and after specified regular expression matches
  4. find_by_{lua,python,rhai} - cuts the section by Lua/Python/Rhai script

This is how a step by step set looks like:

{
  "patch_find_graph": [
    {
      "contains": "file must contain this text to apply the patch"
    },
    {
      "before": "we select all before this text..."
    },
    {
      "after": "...but after this."
    },
    {
      "find_by_python": "some_script_afterall.py"
    }
  ]
}

Script examples can be found at tests folder.

3. replace and inplace content

{
  "replace": {
    "from_to": [
      "some text to be replaced",
      "some resulting text"
    ]
  },
  "inplace": "some text at cursor"
}

inplace value will be inserted at begin or end of selected text area. If the last file section rule was before, cursor will be at the end of section; otherwise it will be at the begin of section, if you're not using the scripts. Any script can specify cursot_at_end = True|False as third return value of the find function (e.g. see tests/test_v4.py and examples/patch4.json).

replace value will perform the replacement only and only if selected text area isn't empty. Simple from_to form just replace all matches of a first text with a second text. But you can specify by_{lua,python,rhai} form:

{
  "replace":   {
    "by_rhai": "some_script.rhai"
  }
}

For example, see tests/test_v8.py.

4. decoder and encoder content

See the tests/test_v5.py example (and tests/test_v5.docx file). This is simple example how you can transform your Microsoft Word document - and any other type of files - to text and vice versa to patch the content you need.

{
  "decoder": {
    "python": "tests/test_v5.py"
  },
  "encoder": {
    "python": "tests/test_v5.py"
  },
}

You can also specify lua and rhai values instead of python.