multi inheritance requires more than one build extension

This commit is contained in:
Michael Jerger 2023-04-29 14:53:59 +02:00
parent e2c0ae3a54
commit 634e89407e
7 changed files with 47 additions and 38 deletions

View file

@ -43,8 +43,8 @@ classDiagram
current_branch current_branch
} }
Devops *-- Image: spcialized_build Devops *-- "0..1" Image: spcialized_builds
Devops *-- C4k: spcialized_build Devops *-- "0..1" C4k: spcialized_builds
Devops *-- Release: release Devops *-- Release: release
C4k *-- DnsRecord C4k *-- DnsRecord
Release *-- "0..1" ReleaseContext Release *-- "0..1" ReleaseContext

View file

@ -37,8 +37,8 @@ class DevopsImageBuild(DevopsBuild):
super().__init__(project, input) super().__init__(project, input)
self.image_build_service = ImageBuildService() self.image_build_service = ImageBuildService()
devops = self.repo.get_devops(self.project) devops = self.repo.get_devops(self.project)
if devops.build_type != BuildType.IMAGE: if BuildType.IMAGE not in devops.specialized_builds:
raise ValueError(f"ImageBuild requires BuildType.IMAGE but was: {devops.build_type}") raise ValueError(f"ImageBuild requires BuildType.IMAGE")
def initialize_build_dir(self): def initialize_build_dir(self):
super().initialize_build_dir() super().initialize_build_dir()

View file

@ -1,6 +1,6 @@
import deprecation import deprecation
from enum import Enum from enum import Enum
from typing import List from typing import List, TypedDict
import logging import logging
import deprecation import deprecation
@ -12,11 +12,16 @@ class BuildType(Enum):
C4K = 1 C4K = 1
class Validateable: class Validateable:
def __validate_is_not_none__(self, field_name: str) -> List[str]:
value = self.__dict__[field_name]
if value is None:
return [f"Field '{field_name}' must not be None."]
return []
def __validate_is_not_empty__(self, field_name: str) -> List[str]: def __validate_is_not_empty__(self, field_name: str) -> List[str]:
value = self.__dict__[field_name] value = self.__dict__[field_name]
if value is None or value == "": if value is None or value == "":
return [f"Field '{field_name}' must not be empty."] return [f"Field '{field_name}' must not be empty."]
return [] return []
def validate(self) -> List[str]: def validate(self) -> List[str]:
@ -45,14 +50,13 @@ class DnsRecord(Validateable):
class Devops(Validateable): class Devops(Validateable):
def __init__(self, input: dict, build_type: BuildType, specialized_build: Validateable): def __init__(self, input: dict, specialized_builds: dict[BuildType, Validateable]):
self.stage = input.get('stage') self.stage = input.get('stage')
self.project_root_path = input.get('project_root_path') self.project_root_path = input.get('project_root_path')
self.module = input.get('module') self.module = input.get('module')
self.name = input.get('name', self.module) self.name = input.get('name', self.module)
self.build_dir_name = input.get('build_dir_name', 'target') self.build_dir_name = input.get('build_dir_name', 'target')
self.build_type = build_type self.specialized_builds=specialized_builds
self.specialized_build=specialized_build
def build_path(self): def build_path(self):
path = [self.project_root_path, self.build_dir_name, self.name, self.module] path = [self.project_root_path, self.build_dir_name, self.name, self.module]
@ -63,9 +67,10 @@ class Devops(Validateable):
result += self.__validate_is_not_empty__("stage") result += self.__validate_is_not_empty__("stage")
result += self.__validate_is_not_empty__("project_root_path") result += self.__validate_is_not_empty__("project_root_path")
result += self.__validate_is_not_empty__("module") result += self.__validate_is_not_empty__("module")
result += self.__validate_is_not_empty__("specialized_build") result += self.__validate_is_not_none__("specialized_builds")
if self.specialized_build: if self.specialized_builds:
result += self.specialized_build.validate() for build in self.specialized_builds:
result += self.specialized_builds[build].validate()
return result return result
def __put__(self, key, value): def __put__(self, key, value):

View file

@ -12,20 +12,24 @@ class DevopsFactory:
pass pass
def build_devops(self, input) -> Devops: def build_devops(self, input) -> Devops:
build_type = BuildType[input["build_type"]] build_types = self.__parse_build_types__(input["build_types"])
specialized_build = None specialized_builds = {}
if build_type == BuildType.IMAGE: if BuildType.IMAGE in build_types:
specialized_build = Image(input) specialized_builds[BuildType.IMAGE] = Image(input)
elif build_type == BuildType.C4K: elif BuildType.C4K in build_types:
pass pass
devops = Devops( devops = Devops(input, specialized_builds=specialized_builds)
input, build_type=build_type, specialized_build=specialized_build
)
devops.throw_if_invalid() devops.throw_if_invalid()
return devops return devops
def merge(input, autorization, context) -> dict: def merge(self, input, autorization, context) -> dict:
pass pass
def __parse_build_types__(self, build_types: List[str]) -> List[BuildType]:
result = []
for build_type in build_types:
result += [BuildType[build_type]]
return result

View file

@ -3,25 +3,24 @@ from src.main.python.ddadevops.domain.devops_factory import (
DevopsFactory, DevopsFactory,
) )
def test_devops_factory(): def test_devops_factory():
with pytest.raises(Exception): with pytest.raises(Exception):
DevopsFactory().build_devops( DevopsFactory().build_devops({"build_types": ["NOTEXISTING"]})
{'build_type': 'NOTEXISTING'}
)
with pytest.raises(Exception): with pytest.raises(Exception):
DevopsFactory().build_devops( DevopsFactory().build_devops({'build_types': ['IMAGE'],})
{'build_type': 'IMAGE'}
)
sut = DevopsFactory().build_devops( sut = DevopsFactory().build_devops(
{'build_type': 'IMAGE', {
'stage': 'test', "build_types": ["IMAGE"],
'project_root_path': "../../..", "stage": "test",
'name': 'mybuild', "project_root_path": "../../..",
'module': 'test_image', "name": "mybuild",
'dockerhub_user': 'dockerhub_user', "module": "test_image",
'dockerhub_password': 'dockerhub_password', "dockerhub_user": "dockerhub_user",
'docker_image_tag': 'docker_image_tag',} "dockerhub_password": "dockerhub_password",
) "docker_image_tag": "docker_image_tag",
}
)
assert sut != None assert sut != None

View file

@ -4,6 +4,7 @@ from src.main.python.ddadevops.domain.common import (
Validateable, Validateable,
DnsRecord, DnsRecord,
Devops, Devops,
BuildType,
) )
from src.main.python.ddadevops.domain import ( from src.main.python.ddadevops.domain import (
Version, Version,
@ -222,4 +223,4 @@ def test_release(tmp_path):
def test_devops_build_commons_path(): def test_devops_build_commons_path():
sut = build_devops({}) sut = build_devops({})
assert "docker/" == sut.specialized_build.docker_build_commons_path() assert "docker/" == sut.specialized_builds[BuildType.IMAGE].docker_build_commons_path()

View file

@ -2,7 +2,7 @@ from src.main.python.ddadevops.domain import DevopsFactory, Devops
def devops_config(overrides: dict) -> dict: def devops_config(overrides: dict) -> dict:
default = { default = {
"build_type": "IMAGE", "build_types": ["IMAGE"],
"stage": "test", "stage": "test",
"project_root_path": "../../..", "project_root_path": "../../..",
"name": "mybuild", "name": "mybuild",