mirror of
https://github.com/LostArtefacts/TR2X.git
synced 2025-02-17 04:27:52 +00:00
libtrx: update; migrate tools
This commit is contained in:
parent
418e2b8803
commit
6442709c73
15
.github/workflows/lint.yml
vendored
15
.github/workflows/lint.yml
vendored
@ -15,21 +15,6 @@ jobs:
|
||||
submodules: 'true'
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check JSON files validity
|
||||
shell: python
|
||||
run: |
|
||||
import json
|
||||
from pathlib import Path
|
||||
errors = False
|
||||
for path in Path('.').rglob('**/*.json'):
|
||||
try:
|
||||
json.loads(path.read_text())
|
||||
except json.JSONDecodeError as ex:
|
||||
print(f'Malformed JSON in {path}: {ex}')
|
||||
errors = True
|
||||
if errors:
|
||||
exit(1)
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "util.h"
|
||||
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "inject_util.h"
|
||||
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void InjectImpl(bool enable, void (*from)(void), void (*to)(void))
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include "inject_exec.h"
|
||||
#include "lib/winmm.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <libtrx/filesystem.h>
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -5,9 +5,10 @@
|
||||
#include "global/vars.h"
|
||||
#include "lib/winmm.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <libtrx/filesystem.h>
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b1d1e82e5ce3fd47d746b78209733a11d7ef8996
|
||||
Subproject commit 7a11c77fbdf10c2f959258d57cc8d11a6cd915dc
|
@ -1,28 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
|
||||
from shared.docker import BaseGameEntrypoint
|
||||
from libtrx.cli.game_docker_entrypoint import run_script
|
||||
|
||||
|
||||
class WindowsEntrypoint(BaseGameEntrypoint):
|
||||
BUILD_ROOT = Path("/app/build/win/")
|
||||
COMPILE_ARGS = [
|
||||
run_script(
|
||||
ship_dir=Path("/app/data/ship/"),
|
||||
build_root=Path("/app/build/win/"),
|
||||
compile_args=[
|
||||
"--cross",
|
||||
"/app/tools/docker/game-win/meson_linux_mingw32.txt",
|
||||
]
|
||||
RELEASE_ZIP_SUFFIX = "Windows"
|
||||
RELEASE_ZIP_FILES = [
|
||||
(BUILD_ROOT / "TR2X.exe", "TR2X.exe"),
|
||||
(BUILD_ROOT / "TR2X.dll", "TR2X.dll"),
|
||||
]
|
||||
|
||||
def post_compile(self) -> None:
|
||||
if self.target == "release":
|
||||
for path in self.BUILD_ROOT.glob("*.exe"):
|
||||
self.compress_exe(path)
|
||||
for path in self.BUILD_ROOT.glob("*.dll"):
|
||||
self.compress_exe(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
WindowsEntrypoint().run()
|
||||
],
|
||||
release_zip_filename="TR2X-{version}-Windows.zip",
|
||||
release_zip_files=[
|
||||
(Path("/app/build/win/TR2X.exe"), "TR2X.exe"),
|
||||
(Path("/app/build/win/TR2X.dll"), "TR2X.dll"),
|
||||
],
|
||||
compressable_exes=[
|
||||
Path("/app/build/win/TR2X.exe"),
|
||||
Path("/app/build/win/TR2X.dll"),
|
||||
],
|
||||
)
|
||||
|
@ -5,12 +5,12 @@ from dataclasses import dataclass
|
||||
from enum import StrEnum
|
||||
from pathlib import Path
|
||||
|
||||
from shared.common import PROGRESS_FILE, SRC_DIR
|
||||
from shared.ida_progress import Symbol, parse_progress_file
|
||||
from tr2x.ida_progress import Symbol, parse_progress_file
|
||||
from tr2x.paths import TR2X_PROGRESS_FILE, TR2X_SRC_DIR
|
||||
|
||||
FUNCS_H_FILE = SRC_DIR / "global/funcs.h"
|
||||
VARS_H_FILE = SRC_DIR / "global/vars.h"
|
||||
TYPES_H_FILE = SRC_DIR / "global/types.h"
|
||||
FUNCS_H_FILE = TR2X_SRC_DIR / "global/funcs.h"
|
||||
VARS_H_FILE = TR2X_SRC_DIR / "global/vars.h"
|
||||
TYPES_H_FILE = TR2X_SRC_DIR / "global/types.h"
|
||||
|
||||
|
||||
COMMON_HEADER = [
|
||||
@ -160,7 +160,7 @@ def make_types_h(types: list[str]) -> None:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
progress_file = parse_progress_file(PROGRESS_FILE)
|
||||
progress_file = parse_progress_file(TR2X_PROGRESS_FILE)
|
||||
|
||||
make_funcs_h(progress_file.functions)
|
||||
make_vars_h(progress_file.variables)
|
||||
|
@ -1,100 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# regenerate the .ICO file from .PSD.
|
||||
import argparse
|
||||
import tempfile
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from subprocess import check_call
|
||||
|
||||
|
||||
@dataclass
|
||||
class IconSpec:
|
||||
size: int
|
||||
type: str
|
||||
|
||||
|
||||
SPECS = [
|
||||
IconSpec(size=32, type="bmp"),
|
||||
IconSpec(size=16, type="bmp"),
|
||||
IconSpec(size=256, type="png"),
|
||||
IconSpec(size=128, type="png"),
|
||||
IconSpec(size=64, type="png"),
|
||||
IconSpec(size=48, type="png"),
|
||||
IconSpec(size=32, type="png"),
|
||||
IconSpec(size=16, type="png"),
|
||||
]
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("path", type=Path)
|
||||
parser.add_argument("-o", "--output", type=Path, required=True)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def resize_transformer(path: Path, spec: IconSpec) -> None:
|
||||
check_call(
|
||||
[
|
||||
"convert",
|
||||
f"{path}[0]",
|
||||
"-filter",
|
||||
"lanczos",
|
||||
"-resize",
|
||||
f"{spec.size}x{spec.size}",
|
||||
f'PNG:{path}',
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def quantize_transformer(path: Path, spec: IconSpec) -> None:
|
||||
quantized_path = path.with_stem(f"{path.stem}-quantized")
|
||||
check_call(["pngquant", path, "--output", quantized_path])
|
||||
path.write_bytes(quantized_path.read_bytes())
|
||||
quantized_path.unlink()
|
||||
|
||||
|
||||
def optimize_transformer(path: Path, spec: IconSpec) -> None:
|
||||
check_call(["zopflipng", "-y", path, path])
|
||||
|
||||
|
||||
def convert_transformer(path: Path, spec: IconSpec) -> None:
|
||||
if spec.type != "png":
|
||||
check_call(["convert", path, f'{spec.type.upper()}:{path}'])
|
||||
|
||||
|
||||
TRANSFORMERS = [
|
||||
resize_transformer,
|
||||
quantize_transformer,
|
||||
optimize_transformer,
|
||||
convert_transformer,
|
||||
]
|
||||
|
||||
|
||||
def generate_icon(source_path: Path, target_path: Path) -> None:
|
||||
aux_paths = []
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
tmp_path = Path(tmpdir)
|
||||
for spec in SPECS:
|
||||
aux_path = tmp_path / f"{spec.size}-{spec.type}.tmp"
|
||||
aux_path.write_bytes(source_path.read_bytes())
|
||||
for transform in TRANSFORMERS:
|
||||
transform(aux_path, spec)
|
||||
|
||||
aux_paths.append(aux_path)
|
||||
|
||||
# NOTE: image order is important for certain software.
|
||||
check_call(["identify", *aux_paths])
|
||||
check_call(["convert", *aux_paths, target_path])
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
|
||||
if args.output.exists():
|
||||
args.output.unlink()
|
||||
generate_icon(args.path, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -2,7 +2,7 @@
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from shared.versioning import generate_version
|
||||
from libtrx.versioning import generate_version
|
||||
|
||||
TEMPLATE = """
|
||||
const char *g_TR2XVersion = "TR2X {version}";
|
||||
|
@ -2,8 +2,8 @@
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from shared.common import DATA_DIR
|
||||
from shared.versioning import generate_version
|
||||
from libtrx.versioning import generate_version
|
||||
from tr2x.paths import TR2X_DATA_DIR
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
@ -17,7 +17,7 @@ def write_rc_template(
|
||||
) -> None:
|
||||
template = input_path.read_text()
|
||||
template = template.replace("{version}", version)
|
||||
template = template.replace("{icon_path}", str(DATA_DIR / "icon.ico"))
|
||||
template = template.replace("{icon_path}", str(TR2X_DATA_DIR / "icon.ico"))
|
||||
output_path.write_text(template)
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ def main() -> None:
|
||||
|
||||
for output_path in args.output:
|
||||
write_rc_template(
|
||||
input_path=DATA_DIR / output_path.name,
|
||||
input_path=TR2X_DATA_DIR / output_path.name,
|
||||
output_path=output_path,
|
||||
version=version,
|
||||
)
|
||||
|
@ -1,25 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from subprocess import run
|
||||
from libtrx.versioning import generate_version
|
||||
|
||||
from shared.versioning import generate_version
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-o", "--output", type=Path)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
version = generate_version()
|
||||
if args.output:
|
||||
args.output.write_text(version)
|
||||
else:
|
||||
print(version, end="")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print(generate_version(), end="")
|
||||
|
@ -8,8 +8,8 @@ from enum import StrEnum
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from shared.ida_progress import parse_progress_file, Symbol
|
||||
from shared.common import PROGRESS_FILE
|
||||
from tr2x.ida_progress import parse_progress_file, Symbol
|
||||
from tr2x.paths import TR2X_PROGRESS_FILE
|
||||
|
||||
try:
|
||||
import idaapi
|
||||
@ -93,7 +93,7 @@ def import_symbols(symbols: list[Symbol]) -> None:
|
||||
|
||||
|
||||
def main():
|
||||
progress_file = parse_progress_file(PROGRESS_FILE)
|
||||
progress_file = parse_progress_file(TR2X_PROGRESS_FILE)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
tmpdir = Path(tmpdir)
|
||||
|
1
tools/libtrx
Symbolic link
1
tools/libtrx
Symbolic link
@ -0,0 +1 @@
|
||||
../subprojects/libtrx/tools/libtrx
|
@ -1,28 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
from pathlib import Path
|
||||
from libtrx.changelog import get_current_version_changelog
|
||||
from tr2x.paths import TR2X_REPO_DIR
|
||||
|
||||
TOOLS_DIR = Path(__file__).parent
|
||||
ROOT_DIR = TOOLS_DIR.parent
|
||||
CHANGELOG_PATH = ROOT_DIR / "CHANGELOG.md"
|
||||
|
||||
|
||||
def get_current_changelog() -> str:
|
||||
sections = [
|
||||
section
|
||||
for section in CHANGELOG_PATH.read_text().split("\n\n")
|
||||
if re.search(r"- \w", section)
|
||||
]
|
||||
if sections:
|
||||
section = sections[0]
|
||||
return "\n".join(
|
||||
line for line in section.splitlines() if not line.startswith("#")
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print(get_current_changelog())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print(get_current_version_changelog(TR2X_REPO_DIR / "CHANGELOG.md"))
|
||||
|
169
tools/release
169
tools/release
@ -1,165 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from subprocess import check_output, run
|
||||
from libtrx.cli.release import run_script
|
||||
from tr2x.paths import TR2X_REPO_DIR
|
||||
|
||||
from shared.common import REPO_DIR
|
||||
from shared.versioning import get_branch_version
|
||||
|
||||
HEADER = "## [Unreleased](https://github.com/LostArtefacts/TR2X/compare/stable...develop) - ××××-××-××"
|
||||
CHANGELOG_PATH = REPO_DIR / "CHANGELOG.md"
|
||||
|
||||
|
||||
def update_changelog(
|
||||
changelog: str, old_version: str, new_version: str
|
||||
) -> str:
|
||||
if f"[{new_version}]" in changelog:
|
||||
return changelog
|
||||
changelog = re.sub("Unreleased", new_version, changelog, count=1)
|
||||
changelog = re.sub("stable", old_version, changelog, count=1)
|
||||
changelog = re.sub("develop", new_version, changelog, count=1)
|
||||
changelog = re.sub(
|
||||
"××××-××-××", datetime.now().strftime("%Y-%m-%d"), changelog
|
||||
)
|
||||
changelog = HEADER + "\n\n" + changelog
|
||||
return changelog
|
||||
|
||||
|
||||
class Git:
|
||||
def checkout_branch(self, branch_name: str) -> None:
|
||||
if check_output(["git", "diff", "--cached", "--name-only"]):
|
||||
raise RuntimeError("Staged files")
|
||||
check_output(["git", "checkout", branch_name])
|
||||
|
||||
def reset(self, target: str, hard: bool = False) -> None:
|
||||
check_output(
|
||||
["git", "reset", "develop", *(["--hard"] if hard else [])]
|
||||
)
|
||||
|
||||
def delete_tag(self, tag_name: str) -> None:
|
||||
run(["git", "tag", "-d", tag_name])
|
||||
|
||||
def create_tag(self, tag_name: str) -> None:
|
||||
check_output(["git", "tag", tag_name])
|
||||
|
||||
def add(self, target: str) -> None:
|
||||
check_output(["git", "add", target])
|
||||
|
||||
def commit(self, message: str) -> None:
|
||||
check_output(["git", "commit", "-m", message])
|
||||
|
||||
def push(
|
||||
self, upstream: str, targets: list[str], force: bool = False
|
||||
) -> None:
|
||||
check_output(
|
||||
[
|
||||
"git",
|
||||
"push",
|
||||
upstream,
|
||||
*targets,
|
||||
*(["--force-with-lease"] if force else []),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class BaseCommand:
|
||||
name: str = NotImplemented
|
||||
help: str = NotImplemented
|
||||
|
||||
def __init__(self, git: Git) -> None:
|
||||
self.git = git
|
||||
|
||||
def decorate_parser(self, parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument("version")
|
||||
|
||||
def run(self, args: argparse.Namespace) -> None:
|
||||
raise NotImplementedError("not implemented")
|
||||
|
||||
|
||||
class CommitCommand(BaseCommand):
|
||||
name = "commit"
|
||||
help = "Create and tag a commit with the release information"
|
||||
|
||||
def decorate_parser(self, parser: argparse.ArgumentParser) -> None:
|
||||
super().decorate_parser(parser)
|
||||
parser.add_argument(
|
||||
"-d",
|
||||
"--dry-run",
|
||||
action='store_true',
|
||||
help="only output the changelog to stdout, do not commit anything",
|
||||
)
|
||||
|
||||
def run(self, args: argparse.Namespace) -> None:
|
||||
self.git.checkout_branch("develop")
|
||||
old_version = get_branch_version("origin/stable")
|
||||
new_version = args.version
|
||||
|
||||
old_changelog = CHANGELOG_PATH.read_text()
|
||||
new_changelog = update_changelog(
|
||||
old_changelog, old_version, args.version
|
||||
)
|
||||
if old_changelog == new_changelog:
|
||||
return
|
||||
|
||||
if args.dry_run:
|
||||
print(new_changelog)
|
||||
return
|
||||
|
||||
CHANGELOG_PATH.write_text(new_changelog)
|
||||
self.git.add(CHANGELOG_PATH)
|
||||
self.git.commit(f"docs: release {args.version}")
|
||||
self.git.delete_tag(args.version)
|
||||
self.git.create_tag(args.version)
|
||||
|
||||
|
||||
class BranchCommand(BaseCommand):
|
||||
name = "branch"
|
||||
help = "Merge branch to the specified tag"
|
||||
|
||||
def run(self, args: argparse.Namespace) -> None:
|
||||
self.git.checkout_branch("stable")
|
||||
self.git.reset(args.version, hard=True)
|
||||
self.git.checkout_branch("develop")
|
||||
|
||||
|
||||
class PushCommand(BaseCommand):
|
||||
name = "push"
|
||||
help = (
|
||||
"Push the develop and stable branches, and the version tag to GitHub"
|
||||
)
|
||||
|
||||
def run(self, args) -> None:
|
||||
self.git.push(
|
||||
"origin", ["develop", "stable", args.version], force=True
|
||||
)
|
||||
|
||||
|
||||
def parse_args(commands: list[BaseCommand]) -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Argument parser with subcommands"
|
||||
)
|
||||
subparsers = parser.add_subparsers(title="subcommands", dest="subcommand")
|
||||
for command in commands:
|
||||
subparser = subparsers.add_parser(command.name, help=command.help)
|
||||
command.decorate_parser(subparser)
|
||||
subparser.set_defaults(command=command)
|
||||
|
||||
result = parser.parse_args()
|
||||
if not hasattr(result, "command"):
|
||||
parser.error("missing command")
|
||||
return result
|
||||
|
||||
|
||||
def main() -> None:
|
||||
git = Git()
|
||||
commands = [
|
||||
command_cls(git) for command_cls in BaseCommand.__subclasses__()
|
||||
]
|
||||
args = parse_args(commands)
|
||||
args.command.run(args)
|
||||
|
||||
|
||||
main()
|
||||
run_script(
|
||||
project_name="TR2X",
|
||||
changelog_path=TR2X_REPO_DIR / "CHANGELOG.md",
|
||||
)
|
||||
|
@ -473,7 +473,8 @@ class FunctionTreeGrid(Container):
|
||||
// GRID_MAX_SQUARES
|
||||
)
|
||||
* (GRID_SQUARE_SIZE + GRID_SQUARE_MARGIN)
|
||||
) + GRID_SQUARE_MARGIN,
|
||||
)
|
||||
+ GRID_SQUARE_MARGIN,
|
||||
)
|
||||
|
||||
for result in squarify(
|
||||
|
@ -1,9 +0,0 @@
|
||||
from pathlib import Path
|
||||
|
||||
TOOLS_DIR = Path(__file__).parent.parent
|
||||
REPO_DIR = TOOLS_DIR.parent
|
||||
DOCS_DIR = REPO_DIR / "docs"
|
||||
DATA_DIR = REPO_DIR / "data"
|
||||
SRC_DIR = REPO_DIR / "src"
|
||||
|
||||
PROGRESS_FILE = DOCS_DIR / "progress.txt"
|
@ -1,91 +0,0 @@
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
from subprocess import check_call, run
|
||||
|
||||
from shared.common import DATA_DIR
|
||||
from shared.packaging import create_zip
|
||||
from shared.versioning import generate_version
|
||||
|
||||
SHIP_DIR = DATA_DIR / "ship"
|
||||
|
||||
|
||||
class BaseGameEntrypoint:
|
||||
BUILD_ROOT: Path = ...
|
||||
COMPILE_ARGS: list[str] = ...
|
||||
STRIP_TOOL = "strip"
|
||||
UPX_TOOL = "upx"
|
||||
RELEASE_ZIP_SUFFIX: str = ...
|
||||
RELEASE_ZIP_FILES: list[tuple[Path, str]] = ...
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.target = os.environ.get("TARGET", "debug")
|
||||
|
||||
def run(self) -> None:
|
||||
args = self.parse_args()
|
||||
args.func(args)
|
||||
|
||||
def parse_args(self) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Docker entrypoint")
|
||||
subparsers = parser.add_subparsers(dest="action", help="Subcommands")
|
||||
|
||||
compile_parser = subparsers.add_parser(
|
||||
"compile", help="Compile action"
|
||||
)
|
||||
compile_parser.set_defaults(func=self.compile)
|
||||
|
||||
package_parser = subparsers.add_parser(
|
||||
"package", help="Package action"
|
||||
)
|
||||
package_parser.add_argument("-o", "--output", type=Path)
|
||||
package_parser.set_defaults(func=self.package)
|
||||
|
||||
args = parser.parse_args()
|
||||
if not hasattr(args, "func"):
|
||||
args.action = "compile"
|
||||
args.func = self.compile
|
||||
return args
|
||||
|
||||
def compile(self, args: argparse.Namespace) -> None:
|
||||
pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
|
||||
|
||||
if not Path("/app/build/linux/build.jinja").exists():
|
||||
command = [
|
||||
"meson",
|
||||
"--buildtype",
|
||||
self.target,
|
||||
*self.COMPILE_ARGS,
|
||||
self.BUILD_ROOT,
|
||||
]
|
||||
if pkg_config_path:
|
||||
command.extend(["--pkg-config-path", pkg_config_path])
|
||||
check_call(command)
|
||||
|
||||
check_call(["meson", "compile"], cwd=self.BUILD_ROOT)
|
||||
|
||||
self.post_compile()
|
||||
|
||||
def post_compile(self) -> None:
|
||||
pass
|
||||
|
||||
def compress_exe(self, path: Path) -> None:
|
||||
if run([self.UPX_TOOL, "-t", str(path)]).returncode != 0:
|
||||
check_call([self.STRIP_TOOL, str(path)])
|
||||
check_call([self.UPX_TOOL, str(path)])
|
||||
|
||||
def package(self, args: argparse.Namespace) -> None:
|
||||
if args.output:
|
||||
zip_path = args.output
|
||||
else:
|
||||
version = generate_version()
|
||||
zip_path = Path(f"TR2X-{version}-{self.RELEASE_ZIP_SUFFIX}.zip")
|
||||
source_files = [
|
||||
*[
|
||||
(path, path.relative_to(SHIP_DIR))
|
||||
for path in SHIP_DIR.rglob("*")
|
||||
if path.is_file()
|
||||
],
|
||||
*self.RELEASE_ZIP_FILES,
|
||||
]
|
||||
create_zip(zip_path, source_files)
|
||||
print(f"Created {zip_path}")
|
@ -1,15 +0,0 @@
|
||||
import sys
|
||||
import zipfile
|
||||
from collections.abc import Iterable
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def create_zip(
|
||||
output_path: Path, source_files: Iterable[tuple[Path, str]]
|
||||
) -> None:
|
||||
with zipfile.ZipFile(output_path, "w") as handle:
|
||||
for source_path, archive_name in source_files:
|
||||
if not source_path.exists():
|
||||
print(f"WARNING: {source_path} does not exist", file=sys.stderr)
|
||||
continue
|
||||
handle.write(source_path, archive_name)
|
@ -1,27 +0,0 @@
|
||||
from subprocess import run
|
||||
|
||||
from shared.common import SRC_DIR
|
||||
|
||||
|
||||
def get_branch_version(branch: str | None) -> str:
|
||||
return run(
|
||||
[
|
||||
"git",
|
||||
"describe",
|
||||
*([branch] if branch else ["--dirty"]),
|
||||
"--always",
|
||||
"--abbrev=7",
|
||||
"--tags",
|
||||
"--exclude",
|
||||
"latest",
|
||||
],
|
||||
cwd=SRC_DIR,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
).stdout.strip()
|
||||
|
||||
|
||||
def generate_version() -> str:
|
||||
version = get_branch_version(None)
|
||||
return version or "?"
|
@ -1,104 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
from subprocess import run
|
||||
from libtrx.cli.sort_imports import run_script
|
||||
from tr2x.paths import TR2X_REPO_DIR, TR2X_SRC_DIR
|
||||
|
||||
TOOLS_DIR = Path(__file__).parent
|
||||
REPO_DIR = TOOLS_DIR.parent
|
||||
SRC_PATH = REPO_DIR / "src"
|
||||
|
||||
|
||||
def fix_imports(path: Path) -> None:
|
||||
iwyu_result = run(
|
||||
["include-what-you-use", "-I", "src", path],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
).stderr
|
||||
run(
|
||||
[which("fix_include") and "fix_include" or "iwyu-fix-includes"],
|
||||
input=iwyu_result,
|
||||
text=True,
|
||||
)
|
||||
|
||||
|
||||
def sort_import_group(includes: list[str]) -> list[str]:
|
||||
group = sorted(includes)
|
||||
FIXED_PAIRS = [
|
||||
("<ddrawi.h>", "<d3dhal.h>"),
|
||||
]
|
||||
for before, after in FIXED_PAIRS:
|
||||
if before in group and after in group:
|
||||
group.remove(after)
|
||||
group.insert(group.index(before) + 1, after)
|
||||
return group
|
||||
|
||||
|
||||
def sort_imports(path: Path) -> None:
|
||||
source = path.read_text()
|
||||
rel_path = path.relative_to(SRC_PATH)
|
||||
own_include = str(rel_path.with_suffix(".h"))
|
||||
own_include = {
|
||||
# files headers of which are not a 1:1 match with their filename
|
||||
}.get(str(rel_path), own_include)
|
||||
|
||||
def cb(match):
|
||||
includes = re.findall(r'#include (["<][^"<>]+[">])', match.group(0))
|
||||
groups = {
|
||||
"own": set(),
|
||||
"proj": set(),
|
||||
"lib": set(),
|
||||
}
|
||||
for include in includes:
|
||||
if include.strip('"') == own_include:
|
||||
groups["own"].add(include)
|
||||
elif include.startswith("<"):
|
||||
groups["lib"].add(include)
|
||||
else:
|
||||
groups["proj"].add(include)
|
||||
|
||||
groups = {key: value for key, value in groups.items() if value}
|
||||
|
||||
ret = "\n\n".join(
|
||||
"\n".join(
|
||||
f"#include {include}" for include in sort_import_group(group)
|
||||
)
|
||||
for group in groups.values()
|
||||
).strip()
|
||||
return ret
|
||||
|
||||
source = re.sub(
|
||||
"^#include [^\n]+(\n*#include [^\n]+)*",
|
||||
cb,
|
||||
source,
|
||||
flags=re.M,
|
||||
)
|
||||
if source != path.read_text():
|
||||
path.write_text(source)
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(metavar="path", type=Path, nargs="*", dest="paths")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
paths = [path.absolute() for path in args.paths]
|
||||
|
||||
if not paths:
|
||||
paths = sorted(
|
||||
path
|
||||
for path in SRC_PATH.glob("**/*.[ch]")
|
||||
if path != SRC_PATH / "init.c"
|
||||
)
|
||||
|
||||
for path in paths:
|
||||
fix_imports(path)
|
||||
sort_imports(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
run_script(
|
||||
root_dir=TR2X_SRC_DIR,
|
||||
include_dirs=[
|
||||
TR2X_SRC_DIR,
|
||||
TR2X_REPO_DIR / "build/linux",
|
||||
TR2X_REPO_DIR / "build/windows",
|
||||
],
|
||||
system_include_dirs=[TR2X_REPO_DIR / "subprojects/libtrx/include"],
|
||||
own_include_map={},
|
||||
fix_map={},
|
||||
forced_order=["<ddrawi.h>", "<d3dhal.h>"],
|
||||
)
|
||||
|
9
tools/tr2x/paths.py
Normal file
9
tools/tr2x/paths.py
Normal file
@ -0,0 +1,9 @@
|
||||
from pathlib import Path
|
||||
|
||||
TR2X_TOOLS_DIR = Path(__file__).parent.parent
|
||||
TR2X_REPO_DIR = TR2X_TOOLS_DIR.parent
|
||||
TR2X_DOCS_DIR = TR2X_REPO_DIR / "docs"
|
||||
TR2X_DATA_DIR = TR2X_REPO_DIR / "data"
|
||||
TR2X_SRC_DIR = TR2X_REPO_DIR / "src"
|
||||
|
||||
TR2X_PROGRESS_FILE = TR2X_DOCS_DIR / "progress.txt"
|
Loading…
x
Reference in New Issue
Block a user