mirror of
https://github.com/Xeeynamo/sotn-decomp.git
synced 2024-11-23 13:09:44 +00:00
8287841ccd
Ubuntu/Debian and Python recommend using virtual environments for project-specific Python dependencies and as of Ubuntu 24 this is lightly enforced when installing packages via pip. This is due to pip and the system package manager installing files to the same location which may cause either's internal state to no longer reflect what is actually installed. This updates the project to use a Python `virtualenv` for project dependencies and updates internal scripts to support both global and virtualenvs, but favors virtualenvs for new workspaces. All tools that hardcode `/usr/bin/python3` now use `env(1)` to find the first `python3` in the path. For those with a virtualenv configured, this will be the Python managed there. For everyone else, this should be the system Python or whatever other scheme they may have used previously (assuming `python3` already existed in their `PATH`). The `Makefile` has been updated to prepend `.venv/bin` to the `PATH` and use `python3` from there if it exists and has been configured. It also has a new `python-dependencies` target which will configure the venv and install all python dependnecies there. The `Dockerfile` has been updated to create an external `.venv` outside of the project directory. Python's `virtualenv`s are not relocatable and may hardcode paths which are mounted differently in the container and host. To deal with differences in paths between the container (which mounts the host's project directory to `/sotn`) host which may be at an arbitarary directory the `VENV_PATH` environment variable is used to override paths in the `Makefile`. GitHub workflows have been updated to use `.venv`.
33 lines
836 B
Python
33 lines
836 B
Python
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import json
|
|
|
|
|
|
def patch(config_file_name):
|
|
with open(config_file_name, "r") as f:
|
|
patches = json.load(f)
|
|
for patch in patches:
|
|
name = patch["name"]
|
|
with open(name, "r+b") as f:
|
|
for str_offset in patch:
|
|
if not str_offset.startswith("0x"):
|
|
continue
|
|
offset = int(str_offset[2:], base=16)
|
|
value = patch[str_offset]
|
|
f.seek(offset)
|
|
f.write(bytes([value]))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="given a configuration, patches an existing binary"
|
|
)
|
|
parser.add_argument(
|
|
"config",
|
|
help="File path of the patch configuration",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
patch(args.config)
|