blob: f8bc68a4899152d4633e72da28b59be9270e9821 [file]
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Build release versions for native TsFile packages."""
from __future__ import annotations
import argparse
import json
import re
from pathlib import Path
from typing import Sequence
_SOURCE_VERSION_RE = re.compile(
r"^(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)$"
)
_CMAKE_VERSION_RE = re.compile(
r"^\s*set\(\s*TsFile_CPP_VERSION\s+(?P<version>[^\s)]+)\s*\)\s*(?:#.*)?$",
re.MULTILINE,
)
def read_cpp_version(path: Path) -> str:
"""Read the release version declared by CMake."""
match = _CMAKE_VERSION_RE.search(path.read_text(encoding="utf-8"))
if match is None or _SOURCE_VERSION_RE.fullmatch(match.group("version")) is None:
raise ValueError(
f"{path} must declare a release TsFile_CPP_VERSION as MAJOR.MINOR.PATCH"
)
return match.group("version")
def build_versions(source_version: str) -> dict[str, str]:
"""Create matching archive, Python, DEB, RPM, and Homebrew release versions."""
if _SOURCE_VERSION_RE.fullmatch(source_version) is None:
raise ValueError("source_version must be a release version MAJOR.MINOR.PATCH")
return {
"base_version": source_version,
"python_version": source_version,
"logical_version": source_version,
"deb_version": f"{source_version}-1",
"rpm_version": source_version,
"rpm_release": "1.el9",
"archive_version": source_version,
"homebrew_version": source_version,
}
def _argument_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--cmake-file", type=Path, required=True)
parser.add_argument("--json-out", type=Path, required=True)
parser.add_argument("--github-output", type=Path)
return parser
def main(argv: Sequence[str] | None = None) -> int:
"""Write release versions to JSON and, optionally, GitHub outputs."""
arguments = _argument_parser().parse_args(argv)
versions = build_versions(read_cpp_version(arguments.cmake_file))
arguments.json_out.write_text(
json.dumps(versions, indent=2) + "\n", encoding="utf-8"
)
if arguments.github_output is not None:
with arguments.github_output.open("a+b") as github_output:
if github_output.tell():
github_output.seek(-1, 2)
if github_output.read(1) != b"\n":
github_output.write(b"\n")
github_output.write(
(
"\n".join(f"{key}={value}" for key, value in versions.items())
+ "\n"
).encode("utf-8")
)
return 0
if __name__ == "__main__":
raise SystemExit(main())