Files
docker-py-revanced/src/patches_gen.py
T
Nikhil Badyal c436c4bc98 🚨 Lint Fixes
2025-06-25 09:32:44 +05:30

105 lines
4.1 KiB
Python

"""Generate patches using cli."""
import json
import re
import subprocess
from pathlib import Path
from typing import Any
def convert_command_output_to_json(
jar_file_name: str,
patches_file: str,
) -> list[dict[Any, Any]]:
"""
Runs the ReVanced CLI command, processes the output, and saves it as a sorted JSON file.
Args:
jar_file_name (str): Name or path of the JAR file to run.
patches_file (str): The patches file name or path to pass to the command.
"""
def run_command_and_capture_output(patches_command: list[str]) -> Any:
result = subprocess.run(patches_command, capture_output=True, text=True, check=True)
return result.stdout
def parse_text_to_json(text: str) -> list[dict[Any, Any]]:
# Split the data into individual sections based on "Name:"
sections = re.split(r"(?=Name:)", text)
result = []
for section in sections:
# Extract the name
name_match = re.search(r"Name: (.*?)\n", section)
name = name_match.group(1).strip() if name_match else None
# Extract the description
description_match = re.search(r"Description: (.*?)\n", section)
description = description_match.group(1).strip() if description_match else ""
# Extract the enabled state
enabled_match = re.search(r"Enabled: (true|false)", section, re.IGNORECASE)
enabled = enabled_match.group(1).lower() == "true" if enabled_match else False
# Extract compatible packages
compatible_packages = []
if "Compatible packages:" in section:
package_sections = re.split(r"\s*Package name: ", section.split("Compatible packages:")[1])
for package_section in package_sections[1:]: # Skip the initial split
package_name = package_section.split("\n")[0].strip()
versions_match = re.search(r"Compatible versions:\s*((?:\d+\.\d+\.\d+\s*)+)", package_section)
versions = versions_match.group(1).split() if versions_match else []
compatible_packages.append({"name": package_name, "versions": versions if versions else None})
# Extract options
options = []
if "Options:" in section:
options_section = section.split("Options:")[1]
option_matches = re.findall(
r"Title: (.*?)\n\s*Description: (.*?)\n\s*Required: (true|false)\n\s*Key: (.*?)\n\s*Default: (.*?)\n(?:\s*Possible values:\s*(.*?))?\s*Type: (.*?)\n", # noqa: E501
options_section,
re.DOTALL,
)
for match in option_matches:
option = {
"title": match[0].strip(),
"description": match[1].strip(),
"required": match[2].lower() == "true",
"key": match[3].strip(),
"default": match[4].strip(),
"possible_values": [v.strip() for v in match[5].split() if v.strip()] if match[5] else [],
"type": match[6].strip(),
}
options.append(option)
# Append the parsed data
result.append(
{
"name": name,
"description": description,
"compatiblePackages": compatible_packages if compatible_packages else None,
"use": enabled,
"options": options,
},
)
return result
# Run the command
command = ["java", "-jar", jar_file_name, "list-patches", "-ipuvo", patches_file]
output = run_command_and_capture_output(command)
parsed_data = parse_text_to_json(output)
# Filter out invalid entries where "name" is None
parsed_data = [entry for entry in parsed_data if entry["name"] is not None]
# Sort the data by the "name" field
parsed_data.sort(key=lambda x: x["name"])
with Path("patches.json").open("w") as file:
json.dump(parsed_data, file, indent=2)
return parsed_data