From cd8de4ff44badce9933f6fae07e228792e77351f Mon Sep 17 00:00:00 2001 From: Tim Jaacks <tim.jaacks@seco.com> Date: Mon, 27 Mar 2023 15:51:06 +0200 Subject: [PATCH] .gitlab-ci: add analyze stage for limiting YAML script blocks --- .gitlab-ci.yml | 8 +++ scripts/check_yaml_value_length.py | 91 ++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100755 scripts/check_yaml_value_length.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c2f0b9a..8f1f88ef 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,6 +62,14 @@ pylint: - cd scripts - pylint --rcfile=pylintrc *.py +script_limit: + extends: .analyze + script: + - scripts/check_yaml_value_length.py *.yml --limit 800 + --key script + --key before_script + --key after_script + yamllint: extends: .analyze script: diff --git a/scripts/check_yaml_value_length.py b/scripts/check_yaml_value_length.py new file mode 100755 index 00000000..6e0e5338 --- /dev/null +++ b/scripts/check_yaml_value_length.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +import argparse +import glob +import sys +from collections import OrderedDict + +from ruamel.yaml import YAML, CommentedMap + +from colors import colors + + +def check_value_length(filename: str, data: OrderedDict, keys: list[str], limit: int): + """Check if values of given YAML keys exceed a given limit. + + Args: + filename: name of the file where data has been read from (used for debug output) + data: ordered dictionary containing YAML elements + keys: list of keys to check values of + limit: maximum number of allowed characters for any of the keys' values + + Returns: + True if a limit exceedence has been found + False else + """ + + exceeded = False + for key, value in data.items(): + if key in keys: + count = 0 + for item in value: + count += len(item) + if count > limit: + exceeded = True + print( + colors.fg.purple + + filename + + ":" + + colors.fg.green + + str(data[key].lc.line) + + colors.reset + + " value of '%s' exceeds character limit (%d > %d)" + % (key, count, limit) + ) + if type(value) is CommentedMap: + exceeded = check_value_length(filename, value, keys, limit) | exceeded + return exceeded + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + "--key", + help="""YAML key to check (can be passed multiple times for multiple keys)""", + dest="key", + action="append", + required=True, + ) + parser.add_argument( + "--limit", + help="""Character limit for given key(s)""", + dest="limit", + type=int, + required=True, + ) + parser.add_argument( + "filename", + help="""File(s) to check""", + nargs="+", + ) + + args, _ = parser.parse_known_args() + + files = [] + for filename in args.filename: + for f in glob.glob(filename): + files.append(f) + + exceeded = False + for f in files: + with open(f, "r", encoding="utf8") as fp: + yaml = YAML() + data = yaml.load(fp) + exceeded = check_value_length(f, data, args.key, args.limit) | exceeded + + if exceeded: + sys.exit(1) + + +if __name__ == "__main__": + main() -- GitLab