Files
clice/scripts/plugin-def.py
2026-01-26 01:01:39 +08:00

99 lines
2.5 KiB
Python

import hashlib
import re
from pathlib import Path
import sys
clice_apis = []
# all of the files in `include/`, other than `include/Server/Plugin.h`
for path in Path("include/").glob("**/*.h"):
if path.name == "Plugin.h":
continue
clice_apis.append(path)
clice_apis = [
# the dependencies of the clice.
Path("config/llvm-manifest.json"),
# the clice C/C++ sources.
*sorted(clice_apis),
]
def fatal(message: str):
print(f"error: {message}", file=sys.stderr)
sys.exit(1)
def sha256sum(paths: list[Path]) -> str:
digest = hashlib.sha256()
for path in paths:
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def clice_api_content():
content = []
content.append("#if 0")
for path in clice_apis:
with path.open("r") as file:
content.append(f"// begin of {path}")
content.append(file.read())
content.append(f"// end of {path}")
content.append("#endif")
return "\n".join(content)
def plugin_def_hash():
hash_val = sha256sum(clice_apis)
return f"sha256:{hash_val}"
def update():
hash_val = plugin_def_hash()
with open("include/Server/Plugin.h", "r") as file:
content = file.read()
content = re.sub(
r"#define CLICE_PLUGIN_DEF_HASH .*",
f'#define CLICE_PLUGIN_DEF_HASH "{hash_val}"',
content,
)
with open("include/Server/Plugin.h", "w") as file:
file.write(content)
def check():
hash_val = plugin_def_hash()
with open("include/Server/Plugin.h", "r") as file:
content = file.read()
match = re.search(r'#define CLICE_PLUGIN_DEF_HASH "(.*)"', content)
if match is None:
fatal("plugin def hash not found in include/Server/Plugin.h")
if match.group(1) != hash_val:
fatal(
f"plugin def hash mismatch in include/Server/Plugin.h, expected: {hash_val}, actual: {match.group(1)}"
)
print(f"plugin def hash is up to date: {hash_val}")
def main():
if len(sys.argv) > 1:
if sys.argv[1] == "update":
update()
check()
elif sys.argv[1] == "check":
check()
elif sys.argv[1] == "content":
print(clice_api_content())
else:
fatal(
f"invalid command: {sys.argv[1]}, expected: update, check",
)
else:
fatal("no command provided, expected: update, check")
if __name__ == "__main__":
main()