import re import subprocess import sys from datetime import datetime from typing import Tuple VERSION_NAME_REGEX = r'versionName: "(.+?)"' VERSION_CODE_REGEX = r"versionCode: ([0-9]+)" VERSION_NAME_FORMAT = 'versionName: "{}"' VERSION_CODE_FORMAT = "versionCode: {}" def get_project_dir() -> str: project_dir = sys.argv[1] if project_dir[-1:] == "/" or project_dir[-1:] == "\\": project_dir = project_dir[:-1] return project_dir def read_gradle_version(project_dir: str) -> Tuple[int, str]: GRADLE_PATH = f"{project_dir}/build.gradle" with open(GRADLE_PATH, "r") as f: gradle = f.read() version_name = re.search(VERSION_NAME_REGEX, gradle).group(1) version_code = int(re.search(VERSION_CODE_REGEX, gradle).group(1)) return (version_code, version_name) def write_gradle_version(project_dir: str, version_code: int, version_name: str): GRADLE_PATH = f"{project_dir}/build.gradle" with open(GRADLE_PATH, "r") as f: gradle = f.read() gradle = re.sub( VERSION_NAME_REGEX, VERSION_NAME_FORMAT.format(version_name), gradle ) gradle = re.sub( VERSION_CODE_REGEX, VERSION_CODE_FORMAT.format(version_code), gradle ) with open(GRADLE_PATH, "w") as f: f.write(gradle) def build_version_code(version_name: str) -> int: version = version_name.split("+")[0].split("-") version_base = version[0] version_suffix = version[1] if len(version) == 2 else "" base_parts = version_base.split(".") major = int(base_parts[0]) or 0 minor = int(base_parts[1]) if len(base_parts) > 1 else 0 patch = int(base_parts[2]) if len(base_parts) > 2 else 0 beta = 9 rc = 9 if "dev" in version_suffix: beta = 0 rc = 0 elif "beta." in version_suffix: beta = int(version_suffix.split(".")[1]) rc = 0 elif "rc." in version_suffix: beta = 0 rc = int(version_suffix.split(".")[1]) version_code = beta + rc * 10 + patch * 100 + minor * 10000 + major * 1000000 return version_code def get_changelog(project_dir: str, format: str) -> Tuple[str, str]: with open( f"{project_dir}/app/src/main/assets/pl-changelog.html", "r", encoding="utf-8" ) as f: changelog = f.read() title = re.search(r"

(.+?)

", changelog).group(1) content = re.search(r"(?s)", changelog).group(1).strip() content = "\n".join(line.strip() for line in content.split("\n")) if format != "html": content = content.replace("
  • ", "- ") content = content.replace("
    ", "\n") if format == "markdown": content = re.sub(r"(.+?)", "__\\1__", content) content = re.sub(r"(.+?)", "*\\1*", content) content = re.sub(r"(.+?)", "**\\1**", content) content = re.sub(r"", "", content) return (title, content) def get_commit_log(project_dir: str, format: str, max_lines: int = None) -> str: last_tag = ( subprocess.check_output("git describe --tags --abbrev=0".split(" ")) .decode() .strip() ) log = subprocess.run( args=f"git log {last_tag}..HEAD --format=%an%x00%at%x00%h%x00%s%x00%D".split(" "), cwd=project_dir, stdout=subprocess.PIPE, ) log = log.stdout.strip().decode() commits = [line.split("\x00") for line in log.split("\n")] if max_lines: commits = commits[:max_lines] output = [] valid = False for commit in commits: if not commit[0]: continue if "origin/" in commit[4]: valid = True if not valid: continue date = datetime.fromtimestamp(float(commit[1])) date = date.strftime("%Y-%m-%d %H:%M:%S") if format == "html": output.append(f"
  • {commit[3]} - {commit[0]}
  • ") elif format == "markdown": output.append(f"[{date}] {commit[0]}\n {commit[3]}") elif format == "markdown_full": output.append( f"_[{date}] {commit[0]}_\n` `__`{commit[2]}`__ **{commit[3]}**" ) elif format == "plain": output.append(f"- {commit[3]}") if format == "markdown": output.insert(0, "```") output.append("```") return "\n".join(output)