Files
hunfabric/tools/versions.py
Julio Castillo cf173701b6 New tool versions.py to manage versions.tf/tofu (#2803)
* Add provider_metadata to all modules

* Fix linting version check

* Another way

* Fix syntax

* Add fabric prefix to all provider meta

* Fix linting.yml
2025-01-09 09:57:48 +01:00

103 lines
3.4 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright 2025 Google LLC
#
# Licensed 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
#
# https://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.
import re
from pathlib import Path
import click
HEADER = "".join(open(__file__).readlines()[2:15])
VERSIONS_TEMPLATE = """
# Fabric release: {fabric_release}
terraform {{
required_version = ">= {engine_version}"
required_providers {{
google = {{
source = "hashicorp/google"
version = ">= {provider_min_version}, < {provider_max_version}" # tftest
}}
google-beta = {{
source = "hashicorp/google-beta"
version = ">= {provider_min_version}, < {provider_max_version}" # tftest
}}
}}
provider_meta "google" {{
module_name = "fabric:{engine}:{path}:{fabric_release}"
}}
provider_meta "google-beta" {{
module_name = "fabric:{engine}:{path}:{fabric_release}"
}}
}}
"""
def extract_variables(template, interpolated_string):
# Escape doubled curly brackets in the template
escaped_template = template.replace("{{", "{{{{").replace("}}", "}}}}")
# Find all variable names in the escaped template
variable_names = re.findall(r'\{(.*?)\}', escaped_template)
# Create a regular expression pattern to match the interpolated string within the template
pattern = re.sub(r'\{(.*?)\}', r'(.*?)', escaped_template)
pattern = pattern.replace("{{{{", "{").replace("}}}}", "}")
pattern = r'.*?' + pattern + r'.*?'
# Extract the values using the pattern
match = re.search(pattern, interpolated_string)
if match:
return dict(zip(variable_names, match.groups()))
def process_file(file_path, context):
with file_path.open("w", encoding="utf-8") as f:
f.write(HEADER)
f.write(VERSIONS_TEMPLATE.format(**context))
@click.command()
@click.option("--fabric-release", help="Override provider max version")
@click.option("--provider-min-version", help="Override provider min version")
@click.option("--provider-max-version", help="Override provider max version")
@click.option("--tf-version", help="Override terraform version")
@click.option("--tofu-version", help="Override opentofu version")
@click.option("--write-defaults/--no-write-defaults", default=False,
help="Also rewrite default-versions.t*f*")
def main(write_defaults, **kwargs):
root_path = Path(__file__).parents[1]
overrides = {k: v for k, v in kwargs.items() if v is not None}
for engine in ["tf", "tofu"]:
defaults_fname = root_path / f"default-versions.{engine}"
defaults = extract_variables(VERSIONS_TEMPLATE, defaults_fname.read_text())
context = defaults | overrides
if kwargs[f'{engine}_version'] is not None:
context['engine_version'] = kwargs[f'{engine}_version']
for file_path in root_path.rglob(f"versions.{engine}"):
click.echo(f"Processing {file_path}")
process_file(file_path, context | {
"path": file_path.parent.relative_to(root_path),
})
if write_defaults:
click.echo(f"Processing {defaults_fname}")
process_file(defaults_fname, context)
if __name__ == "__main__":
main()