From 3dfeb9d5a0fc4201555f5c4fcbc034cec22efd2b Mon Sep 17 00:00:00 2001 From: Jon Chen Date: Wed, 25 Oct 2023 04:47:42 +0900 Subject: [PATCH] fix vars set on yaml arrays --- solutions_builder/cli/cli.py | 3 +- solutions_builder/cli/cli_constants.py | 18 ++++++++++++ solutions_builder/cli/cli_utils.py | 8 ++++-- solutions_builder/cli/vars.py | 24 +++++++++------- solutions_builder/cli/vars_test.py | 40 ++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 solutions_builder/cli/cli_constants.py diff --git a/solutions_builder/cli/cli.py b/solutions_builder/cli/cli.py index 83f05981..135a94e7 100644 --- a/solutions_builder/cli/cli.py +++ b/solutions_builder/cli/cli.py @@ -25,6 +25,7 @@ from .set import set_app from .vars import vars_app from .cli_utils import * +from .cli_constants import DEBUG __version__ = importlib.metadata.version("solutions-builder") DEFAULT_DEPLOY_PROFILE = "default-deploy" @@ -236,7 +237,7 @@ def main(): print() except Exception as e: - if os.getenv("DEBUG", False): + if DEBUG: traceback.print_exc() print_error(e) diff --git a/solutions_builder/cli/cli_constants.py b/solutions_builder/cli/cli_constants.py new file mode 100644 index 00000000..e8300b5f --- /dev/null +++ b/solutions_builder/cli/cli_constants.py @@ -0,0 +1,18 @@ +# Copyright 2023 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 os + +# Global DEBUG flag for all CLI routes. +DEBUG = (os.environ.get("SB_DEBUG", "").lower() == "true") diff --git a/solutions_builder/cli/cli_utils.py b/solutions_builder/cli/cli_utils.py index bffacce9..8fcc6176 100644 --- a/solutions_builder/cli/cli_utils.py +++ b/solutions_builder/cli/cli_utils.py @@ -14,7 +14,11 @@ limitations under the License. """ -import os, yaml, typer, subprocess, re +import os +import yaml +import typer +import subprocess +import re def confirm(msg, skip=False, default=True): @@ -139,7 +143,7 @@ def list_subfolders(path): def check_git_url(url): - regex_str = "((git|ssh|http(s)?)|(git@[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?" + regex_str = "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\.\\@\\:/\\-~]+)(\\.git)(/)?" regex = re.compile(regex_str) match = regex.match(url) return match is not None diff --git a/solutions_builder/cli/vars.py b/solutions_builder/cli/vars.py index 2edb32bf..fc15fb77 100644 --- a/solutions_builder/cli/vars.py +++ b/solutions_builder/cli/vars.py @@ -20,39 +20,40 @@ from typing_extensions import Annotated from copier import run_auto from .cli_utils import * +from .cli_constants import DEBUG + vars_app = typer.Typer() INCLUDE_PATTERNS = [ - "*.yaml", "*.yml", "*.env", "*.tfvars", "*.tf", "*.sh", "*.md" + "*.yaml", "*.yml", "*.env", "*.tfvars", "*.tf", "*.sh" ] EXCLUDE_PATTERNS = ["**/.terraform/**/*.*", "**/node_modules/**/*.*", "**/.venv/**/*.*"] # Replace a variable with a given text content. -def replace_var_to_template(var_name, text, custom_template=False, debug=False): - # This pattern matches lines with sb-var anchor in the comment at the end. +def replace_var_to_template(var_name, text, custom_template=False): + # Regex test: https://regex101.com/r/XtnJQI/4 + # match_pattern matches lines with sb-var anchor in the comment at the end. # For example: # PROJECT_ID: 12345 # sb-var:project_id # GCP_REGION = "us-central1" # sb-var:gcp_region - match_pattern = f"^([^\\r]*[:|=][\\s\-]*)([\"\']?)([^\"^\']*)([\"\']?)\\s*#\\s*sb-var:{var_name}" + match_pattern = f"(\\s*[\":=-][ ]*)(-[ ]*)?([\"\']?)([^\"^\'^\r^\n]*)([\"\']?)\\s*#\\s*sb-var:{var_name}" - # This output patterh print the jinja2 template for the specific variable name. + # output_pattern prints the jinja2 template for the specific variable name. # For example: # PROJECT_ID: {{project_id}} # sb-var:project_id - output_pattern = f"\\1\\2{{{{{var_name}}}}}\\4 # sb-var:{var_name}" + output_pattern = f"\\1\\2\\3{{{{{var_name}}}}}\\5 # sb-var:{var_name}" # In addition, if custom_template is true, the pattern will extend to the custom # template string at the end of the anchor. For example: # BUCKET_NAME: my-project-bucket # sb-var:project_id:{{project_id}}-bucket if custom_template: match_pattern = match_pattern + ":(.*)" - output_pattern = f"\\1\\2\\5\\4 # sb-var:{var_name}:\\5" - - if debug: - print(f"match_pattern = {match_pattern}") + output_pattern = f"\\1\\2\\3\\6\\5 # sb-var:{var_name}:\\6" # Replace with regex pattern and returns new text and count of changes. text, count = re.subn(match_pattern, output_pattern, text) + return (text, count) def restore_template_in_comment(var_name, var_value, text): @@ -109,6 +110,9 @@ def apply_var_to_folder(solution_path, var_name, var_value): modified_files_list = [] for filename in list(file_set): + if DEBUG: + print(filename) + with open(filename, "r") as file: # Replace variable filedata = file.read() diff --git a/solutions_builder/cli/vars_test.py b/solutions_builder/cli/vars_test.py index d8ae75a2..f977cc8e 100644 --- a/solutions_builder/cli/vars_test.py +++ b/solutions_builder/cli/vars_test.py @@ -74,3 +74,43 @@ def test_replace_var_to_value_custom_template(): # FIXME: it double-counted the changes, as both simple template and custom # template both counts. assert count == 2 + +def test_replace_with_multiple_occurances(): + text = """ + env: + PROJECT_ID: old-value-1 # sb-var:project_id + PROJECT_ID_2: old-value-2 # sb-var:project_id + """ + text, count = replace_var_to_value("project_id", "fake-id", text) + assert text == """ + env: + PROJECT_ID: fake-id # sb-var:project_id + PROJECT_ID_2: fake-id # sb-var:project_id + """ + assert count == 2 + + +def test_replace_with_yaml_arrays(): + text = """ + array: + - not-replaced-yet # sb-var:project_id + """ + text, count = replace_var_to_value("project_id", "fake-id", text) + assert text == """ + array: + - fake-id # sb-var:project_id + """ + assert count == 1 + + text = """ + array: + - "not-replaced-yet" # sb-var:project_id + - "not-replaced-yet" # sb-var:project_id + """ + text, count = replace_var_to_value("project_id", "fake-id", text) + assert text == """ + array: + - "fake-id" # sb-var:project_id + - "fake-id" # sb-var:project_id + """ + assert count == 2