From c7a68b6d7791a2eab7661850a5334aed6f9a2adb Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Mon, 29 Jan 2024 11:01:16 +0100 Subject: [PATCH] feat: add validation for valid topic names --- otterdog/models/repository.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/otterdog/models/repository.py b/otterdog/models/repository.py index c4a2d197..4c7161b4 100644 --- a/otterdog/models/repository.py +++ b/otterdog/models/repository.py @@ -9,6 +9,7 @@ from __future__ import annotations import dataclasses +import re from typing import Any, Callable, ClassVar, Iterator, Optional, cast from jsonbender import F, Forall, If, K, OptionalS, S, bend # type: ignore @@ -235,11 +236,20 @@ def validate(self, context: ValidationContext, parent_object: Any) -> None: f"{self.get_model_header()} has 'description' that exceeds the maximum allowed length of 350 chars.", ) - if is_set_and_valid(self.topics) and len(self.topics) > 20: - context.add_failure( - FailureType.ERROR, - f"{self.get_model_header()} has more than 20 'topics' defined.", - ) + if is_set_and_valid(self.topics): + if len(self.topics) > 20: + context.add_failure( + FailureType.ERROR, + f"{self.get_model_header()} has more than 20 'topics' defined.", + ) + + for topic in self.topics: + if not self._valid_topic(topic): + context.add_failure( + FailureType.ERROR, + f"{self.get_model_header()} has defined an invalid topic '{topic}'. " + f"Only lower-case, numbers and '-' are allowed characters.", + ) if is_public and disallow_forking: context.add_failure( @@ -387,6 +397,10 @@ def validate(self, context: ValidationContext, parent_object: Any) -> None: for env in self.environments: env.validate(context, self) + @staticmethod + def _valid_topic(topic, search=re.compile(r"[^a-z0-9\-]").search): + return not bool(search(topic)) + def include_field_for_diff_computation(self, field: dataclasses.Field) -> bool: # private repos don't support security analysis. if self.private is True: