update_setup_requirements.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # Copyright 2021-2025 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. # --------------------------------------------------------------------------------------------------
  12. # Updates the setup.requirements.txt files for a given package.
  13. #
  14. # Invoked by workflows/build-and-release-single-package.yml and workflows/build-and-release.yml.
  15. # Working directory must be [root_dir].
  16. # --------------------------------------------------------------------------------------------------
  17. import argparse
  18. import os
  19. import re
  20. import typing as t
  21. from common import Git, Package, Version
  22. BASE_PATH = "./tools/packages"
  23. def __build_taipy_package_line(line: str, version: Version, use_pypi: bool, gh_path: t.Optional[str]) -> str:
  24. line = line.strip()
  25. if use_pypi:
  26. # Target dependency version should the latest compatible with 'version'
  27. return f"{line} >={version.major}.{version.minor},<{version.major}.{version.minor + 1}\n"
  28. tag = f"{version}-{line.split('-')[1]}"
  29. tar_name = f"{line}-{version}"
  30. return f"{line} @ https://github.com/{gh_path}/releases/download/{tag}/{tar_name}.tar.gz\n"
  31. def update_setup_requirements(
  32. package: Package, versions: dict[str, Version], publish_on_py_pi: bool, gh_path: t.Optional[str]
  33. ) -> None:
  34. path = os.path.join(BASE_PATH, package.name, "setup.requirements.txt")
  35. lines = []
  36. with open(path, mode="r") as req:
  37. for line in req:
  38. if match := re.match(r"^taipy(:?\-\w+)?\s*", line, re.MULTILINE):
  39. # Add subpackage version if not forced
  40. if not line[match.end() :] and (v := versions.get(line.strip())):
  41. if v == Version.UNKNOWN:
  42. raise ValueError(f"Missing version for dependency '{line.strip()}'.")
  43. line = __build_taipy_package_line(line, v, publish_on_py_pi, gh_path)
  44. lines.append(line)
  45. with open(path, "w") as file:
  46. file.writelines(lines)
  47. # Issue the generated files for logging information
  48. print(f"Generated setup.requirements.txt for package '{package}'") # noqa: T201
  49. for line in lines:
  50. print(line.strip()) # noqa: T201
  51. print("-" * 32) # noqa: T201
  52. def main():
  53. parser = argparse.ArgumentParser(
  54. description="Computes the Taipy package versions to be build.", formatter_class=argparse.RawTextHelpFormatter
  55. )
  56. # <package> argument
  57. parser.add_argument(
  58. "package",
  59. type=Package,
  60. action="store",
  61. help="""The name of the package to setup the build version for.
  62. This must be the short name of a Taipy package (common, core...) or 'taipy'.
  63. """,
  64. )
  65. # <common-version> argument
  66. parser.add_argument(
  67. "common_version",
  68. type=Version.check_argument,
  69. action="store",
  70. help="Full name of the target version (M.m.p) for the taipy-common package.",
  71. )
  72. # <core-version> argument
  73. parser.add_argument(
  74. "core_version",
  75. type=Version.check_argument,
  76. action="store",
  77. help="Full name of the target version (M.m.p) for the taipy-core package.",
  78. )
  79. # <gui-version> argument
  80. parser.add_argument(
  81. "gui_version",
  82. type=Version.check_argument,
  83. action="store",
  84. help="Full name of the target version (M.m.p) for the taipy-gui package.",
  85. )
  86. # <rest-version> argument
  87. parser.add_argument(
  88. "rest_version",
  89. type=Version.check_argument,
  90. action="store",
  91. help="Full name of the target version (M.m.p) for the taipy-rest package.",
  92. )
  93. # <rest-version> argument
  94. parser.add_argument(
  95. "templates_version",
  96. type=Version.check_argument,
  97. action="store",
  98. help="Full name of the target version (M.m.p) for the taipy-templates package.",
  99. )
  100. # <dependencies-location> argument
  101. parser.add_argument(
  102. "-deps",
  103. "-dl",
  104. "--dependencies-location",
  105. type=str.lower,
  106. choices=["github", "pypi"],
  107. required=True,
  108. help="Where to point dependencies to.",
  109. )
  110. # <repository_name> argument
  111. def _check_repository_name(value: str) -> str:
  112. if len(value.split("/")) != 2:
  113. raise argparse.ArgumentTypeError(f"'{value}' is not a valid '<owner>/<repo>' pair.")
  114. return value
  115. parser.add_argument(
  116. "-r",
  117. "--repository_name",
  118. type=_check_repository_name,
  119. help="""The '<owner>/<repo>' string that identifies the repository where releases are fetched.
  120. The default is the current repository.""",
  121. )
  122. args = parser.parse_args()
  123. versions = {
  124. "taipy-common": args.common_version,
  125. "taipy-core": args.core_version,
  126. "taipy-gui": args.gui_version,
  127. "taipy-rest": args.rest_version,
  128. "taipy-templates": args.templates_version,
  129. }
  130. publish_on_py_pi = args.dependencies_location == "pypi"
  131. repository_name = args.repository_name if args.repository_name else Git.get_github_path()
  132. update_setup_requirements(args.package, versions, publish_on_py_pi, repository_name)
  133. if __name__ == "__main__":
  134. main()