summaryrefslogtreecommitdiffstats
path: root/ansible_collections/hetzner/hcloud/scripts/vendor.py
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/hetzner/hcloud/scripts/vendor.py')
-rwxr-xr-xansible_collections/hetzner/hcloud/scripts/vendor.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/ansible_collections/hetzner/hcloud/scripts/vendor.py b/ansible_collections/hetzner/hcloud/scripts/vendor.py
new file mode 100755
index 000000000..b55a66577
--- /dev/null
+++ b/ansible_collections/hetzner/hcloud/scripts/vendor.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+
+"""
+Fetch and bundles the hcloud package inside the collection.
+
+Fetch the desired version `HCLOUD_VERSION` from https://github.com/hetznercloud/hcloud-python
+`HCLOUD_SOURCE_URL` using git, apply some code modifications to comply with ansible,
+move the modified files at the vendor location `HCLOUD_VENDOR_PATH`.
+"""
+
+from __future__ import annotations
+
+import logging
+import re
+from argparse import ArgumentParser
+from pathlib import Path
+from shutil import move, rmtree
+from subprocess import check_call
+from tempfile import TemporaryDirectory
+from textwrap import dedent
+
+logger = logging.getLogger("vendor")
+
+HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python"
+HCLOUD_VERSION = "v1.33.2"
+HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"
+
+
+def apply_code_modifications(source_path: Path):
+ # The ansible galaxy-importer consider __version___.py to be an invalid filename in module_utils/
+ # Move the __version__.py file to _version.py
+ move(source_path / "__version__.py", source_path / "_version.py")
+
+ for file in source_path.rglob("*.py"):
+ content = file.read_text()
+ content_orig = content
+
+ # Move the __version__.py file to _version.py
+ content = re.sub(
+ r"from .__version__ import VERSION",
+ r"from ._version import VERSION",
+ content,
+ )
+
+ # Wrap requests imports
+ content = re.sub(
+ r"import requests",
+ dedent(
+ r"""
+ try:
+ import requests
+ except ImportError:
+ requests = None
+ """
+ ).strip(),
+ content,
+ )
+
+ # Wrap dateutil imports
+ content = re.sub(
+ r"from dateutil.parser import isoparse",
+ dedent(
+ r"""
+ try:
+ from dateutil.parser import isoparse
+ except ImportError:
+ isoparse = None
+ """
+ ).strip(),
+ content,
+ )
+
+ # Remove requests.Response typings
+ content = re.sub(
+ r": requests\.Response",
+ r"",
+ content,
+ )
+
+ if content != content_orig:
+ logger.info("Applied code modifications on %s", file)
+
+ file.write_text(content)
+
+
+def main(check: bool = False) -> int:
+ with TemporaryDirectory() as tmp_dir:
+ tmp_dir_path = Path(tmp_dir)
+ logger.info("Created temporary directory %s", tmp_dir_path)
+
+ check_call(["git", "clone", "--depth=1", "--branch", HCLOUD_VERSION, HCLOUD_SOURCE_URL, tmp_dir_path])
+ logger.info("Cloned the source files in %s", tmp_dir_path)
+
+ apply_code_modifications(tmp_dir_path / "hcloud")
+ logger.info("Applied code modifications on the source files")
+
+ rmtree(HCLOUD_VENDOR_PATH)
+ move(tmp_dir_path / "hcloud", HCLOUD_VENDOR_PATH)
+ logger.info("Bundled the modified sources files in the collection")
+
+ if check:
+ check_call(["git", "diff", "--exit-code", "--", HCLOUD_VENDOR_PATH])
+
+ return 0
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.INFO, format="%(levelname)-8s: %(message)s")
+
+ parser = ArgumentParser()
+ parser.add_argument("--check", action="store_true", default=False)
+ args = parser.parse_args()
+
+ raise SystemExit(main(check=args.check))