Commit 09a7ce92 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

fix: change colouring impl

parent e9128831
Loading
Loading
Loading
Loading
+264 −338

File changed.

Preview size limit exceeded, changes collapsed.

+1 −2
Original line number Diff line number Diff line
@@ -8,10 +8,9 @@ readme = "README.md"
packages = [{include = "tbc"}]

[tool.poetry.dependencies]
python = "^3.9"
python = "^3.10"
pyyaml = "^6.0.1"
pydantic = "^2.4.2"
rich = "^13.7.0"

[build-system]
requires = ["poetry-core"]
+45 −23
Original line number Diff line number Diff line
@@ -5,13 +5,35 @@ from logging import Logger
from pathlib import Path
import re
from typing import Optional, Union
from rich import print

import yaml
from pydantic import BaseModel

LOGGER = Logger(__name__)

class bcolors:
    BLACK   = "\033[0;30m"
    RED     = "\033[0;31m"
    GREEN   = "\033[0;32m"
    YELLOW  = "\033[0;33m"
    BLUE = '\033[0;34m'
    PURPLE = '\033[0;35m'
    CYAN = '\033[0;36m'
    WHITE   = "\033[0;37m"

    HGRAY = '\033[90m'
    HRED = '\033[91m'
    HGREEN = '\033[92m'
    HYELLOW = '\033[93m'
    HBLUE = '\033[94m'
    HPURPLE = '\033[95m'
    HCYAN = '\033[96m'
    HWHITE = '\033[97m'

    RESET = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


class GlInputType(str, Enum):
    """GitLab CI/CD component input type."""
@@ -117,14 +139,14 @@ def _check_var(tbc_var: TbcVar, var_prefix: str, tpl_spec: dict[str, any], tpl_i
    # check variable is declared in doc
    doc_var = next(filter(lambda dv: dv.var_name == tbc_var.name, doc_vars), None)
    if doc_var == None:
        print(f"  [yellow]'{tbc_var.name}': not documented in README[/yellow]")
        print(f"  {bcolors.YELLOW}<{tbc_var.name}>: not documented in README{bcolors.RESET}")
    else:
        if doc_var.lock and not tbc_var.secret:
            print(f"  [yellow]'{tbc_var.name}': is not declared as a secret but has a lock in README[/yellow]")
            print(f"  {bcolors.YELLOW}<{tbc_var.name}>: is not declared as a secret but has a lock in README{bcolors.RESET}")
        elif not doc_var.lock and tbc_var.secret:
            print(f"  [yellow]'{tbc_var.name}': is declared as a secret but has no lock in README[/yellow]")
            print(f"  {bcolors.YELLOW}<{tbc_var.name}>: is declared as a secret but has no lock in README{bcolors.RESET}")
        elif not has_no_input and expected_input_name != doc_var.input_name:
            print(f"  [yellow]'{tbc_var.name}''{expected_input_name}': has wrong input declared in README ({doc_var.input_name})[/yellow]")
            print(f"  {bcolors.YELLOW}<{tbc_var.name}/{expected_input_name}>: has wrong input declared in README ({doc_var.input_name}){bcolors.RESET}")

    # retrieve declared input from template specs
    declared_input = tpl_spec["spec"]["inputs"].get(expected_input_name)
@@ -132,31 +154,31 @@ def _check_var(tbc_var: TbcVar, var_prefix: str, tpl_spec: dict[str, any], tpl_i
    if tbc_var.secret:
        # secrets should not be inputs
        if declared_input:
            print(f"  [red]'{tbc_var.name}' is a secret: must not be declared[/red]")
            print(f"  {bcolors.RED}<{tbc_var.name}> is a secret: must not be declared{bcolors.RESET}")
            return 1
        else:
            print(f"  [bright_black]'{tbc_var.name}' is a secret: skip[/bright_black]")
            print(f"  {bcolors.HGRAY}<{tbc_var.name}> is a secret: skip{bcolors.RESET}")
            return 0
    if main_tpl_desc and _get_var(main_tpl_desc, tbc_var.name):
        # a variant is overriding a variable from the main template: skip
        if declared_input:
            print(f"  [red]'{tbc_var.name}' is an override: must not be declared[/red]")
            print(f"  {bcolors.RED}<{tbc_var.name}> is an override: must not be declared{bcolors.RESET}")
            return 1
        else:
            print(f"  [bright_black]'{tbc_var.name}' is an override: skip[/bright_black]")
            print(f"  {bcolors.HGRAY}<{tbc_var.name}> is an override: skip{bcolors.RESET}")
            return 0
    if tbc_var.name.startswith("TBC_"):
        # global TBC variable: skip
        if declared_input:
            print(f"  [red]'{tbc_var.name}' is global TBC: must not be declared[/red]")
            print(f"  {bcolors.RED}<{tbc_var.name}> is global TBC: must not be declared{bcolors.RESET}")
            return 1
        else:
            print(f"  [bright_black]'{tbc_var.name}' is global TBC: skip[/bright_black]")
            print(f"  {bcolors.HGRAY}<{tbc_var.name}> is global TBC: skip{bcolors.RESET}")
            return 0

    # check if mapped GitLab input is declared
    if not declared_input:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': input not found[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: input not found{bcolors.RESET}")
        return 1

    err_count = 0
@@ -165,32 +187,32 @@ def _check_var(tbc_var: TbcVar, var_prefix: str, tpl_spec: dict[str, any], tpl_i
    expected_gl_input = tbc_var.to_gl()

    if actual_gl_input.type != expected_gl_input.type:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': type ({actual_gl_input.type}) doesn't match expected ({expected_gl_input.type})[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: type ({actual_gl_input.type}) doesn't match Kicker's ({expected_gl_input.type}){bcolors.RESET}")
        err_count +=1

    if actual_gl_input.description != expected_gl_input.description:
        print(f"  [yellow]'{tbc_var.name}''{expected_input_name}': description doesn't match Kicker's[/yellow]")
        print(f"  {bcolors.YELLOW}<{tbc_var.name}/{expected_input_name}>: description doesn't match Kicker's{bcolors.RESET}")

    if actual_gl_input.default != expected_gl_input.default:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': default ({actual_gl_input.default}) doesn't match expected ({expected_gl_input.default})[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: default ({actual_gl_input.default}) doesn't match Kicker's ({expected_gl_input.default}){bcolors.RESET}")
        err_count +=1

    if actual_gl_input.options != expected_gl_input.options:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': options ({actual_gl_input.options}) doesn't match expected ({expected_gl_input.options})[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: options ({actual_gl_input.options}) doesn't match Kicker's ({expected_gl_input.options}){bcolors.RESET}")
        err_count +=1

    # check variable is initialized from input
    actual_variable_value = tpl_impl["variables"].get(tbc_var.name)
    expected_variable_value = f"$[[ inputs.{expected_input_name} ]]"
    if not actual_variable_value:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': variable not declared[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: variable not declared{bcolors.RESET}")
        err_count +=1
    elif actual_variable_value != expected_variable_value:
        print(f"  [red]'{tbc_var.name}''{expected_input_name}': value ({actual_variable_value}) doesn't match expected ({expected_variable_value})[/red]")
        print(f"  {bcolors.RED}<{tbc_var.name}/{expected_input_name}>: value ({actual_variable_value}) doesn't match Kicker's ({expected_variable_value}){bcolors.RESET}")
        err_count +=1

    if err_count == 0:
        print(f"  [green]✓[/green] '{tbc_var.name}''{expected_input_name}': OK")
        print(f"  {bcolors.GREEN}{bcolors.RESET} <{tbc_var.name}/{expected_input_name}>: OK")
    
    return err_count

@@ -245,7 +267,7 @@ def _check_tpl(tpl_desc, main_tpl_desc, project_dir: Path, var_prefix: str, doc_
    
    # remaining inputs are unmapped inputs
    for input_name in inputs:
        print(f"  [red]✕ unmapped declared input '{input_name}'[/red]")
        print(f"  {bcolors.RED}✕ unmapped declared input '{input_name}'{bcolors.RESET}")
    
    err_count += len(inputs)
    return err_count
@@ -304,15 +326,15 @@ def run():
    var_prefix = prefix.upper() + "_"

    print("=============================================================")
    print(f"Checking template [bright_black]{kicker['name']}[/bright_black] (vars prefix [bright_black]\"{var_prefix}\"[/bright_black])")
    print(f"Checking template {bcolors.CYAN}{kicker['name']}{bcolors.RESET} (vars prefix {bcolors.CYAN}\"{var_prefix}\"{bcolors.RESET})")
    print("=============================================================")
    # Check main template
    print(f"[blue bold]→ Main template ({kicker['template_path']})[/blue bold]")
    print(f"{bcolors.BLUE}{bcolors.BOLD}→ Main template ({kicker['template_path']}){bcolors.RESET}")
    err_count = _check_tpl(kicker, None, project_dir, var_prefix, doc_vars)

    # Check variants
    for variant in kicker.get("variants", []):
        print(f"[blue bold]{variant['name']} variant ({variant['template_path']})[/blue bold]")
        print(f"{bcolors.BLUE}{bcolors.BOLD}{variant['name']} variant ({variant['template_path']}){bcolors.RESET}")
        err_count += _check_tpl(variant, kicker, project_dir, var_prefix, doc_vars)

    if err_count > 0: