Loading src/types/yaml.py +65 −0 Changes for src/types/yaml.py: 65 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ # Standard libraries from copy import deepcopy from io import TextIOWrapper from re import sub as regex_sub from sys import maxsize from typing import Any, Dict, List, Optional Loading Loading @@ -98,6 +99,64 @@ class YAML: # Result return changed # Parse spec inputs @staticmethod def parse_spec_inputs(spec: Data, file_path: str) -> Dict[str, str]: # Variables inputs: Dict[str, str] = {} # Validate YAML spec syntax if 'spec' not in spec or 'inputs' not in spec['spec']: return inputs # Parse YAML spec inputs for key, value in spec['spec']['inputs'].items(): if isinstance(value, dict) and 'default' in value and isinstance( value['default'], str): inputs[key] = str(value.get('default')) else: raise SyntaxError(f'Missing value for input \'{key}\' in \'{file_path}\'') # Result return inputs # Evaluate string @staticmethod def evaluate_spec_field(field: str, inputs: Dict[str, str]) -> str: # Variables result: str = field # Evaluate inputs for variable, value in inputs.items(): result = regex_sub(fr'\$\[\[\s*inputs\.{variable}\s*\]\]', value, result) # Result return result # Evaluate spec @staticmethod def evaluate_spec(data: Data, inputs: Dict[str, str]) -> Data: # Recurse on keys if isinstance(data, dict): return { YAML.evaluate_spec_field(key, inputs): YAML.evaluate_spec(value, inputs) for key, value in data.items() } # Recurse on items if isinstance(data, list): return [YAML.evaluate_spec(value, inputs) for value in data] # Evaluate string items if isinstance(data, str): return YAML.evaluate_spec_field(data, inputs) # Fallback return data # pragma: no cover # Load @staticmethod def load(stream: TextIOWrapper) -> Optional[Data]: Loading @@ -105,6 +164,7 @@ class YAML: # Variables data: Optional[YAML.Data] documents: List[YAML.Data] inputs: Dict[str, str] # Prepare loader class loader = yaml_SafeLoader Loading @@ -121,6 +181,11 @@ class YAML: elif len(documents) == 1: data = documents[0] # Acquire YAML component data elif len(documents) == 2: inputs = YAML.parse_spec_inputs(documents[0], stream.name) data = YAML.evaluate_spec(documents[1], inputs) # Unsupport YAML data else: raise SyntaxError( Loading tests/components/.gitlab-ci.d/test/templates/component.yml 0 → 100644 +14 −0 Changes for tests/components/.gitlab-ci.d/test/templates/component.yml: 14 added lines, 0 removed lines. Original line number Diff line number Diff line spec: inputs: stage: default: test description: 'Defines the commits job name (Default: commits)' name: default: component description: 'Defines the commits stage (Default: test)' --- $[[ inputs.name ]]: stage: $[[ inputs.stage ]] script: - echo ' [Job] Component' tests/components/.gitlab-ci.d/test/templates/documents.0.yml 0 → 100644 +0 −0 Empty file added. tests/components/.gitlab-ci.d/test/templates/documents.3.yml 0 → 100644 +10 −0 Changes for tests/components/.gitlab-ci.d/test/templates/documents.3.yml: 10 added lines, 0 removed lines. Original line number Diff line number Diff line stages: - components --- stages: - components --- stages: - components tests/components/.gitlab-ci.d/test/templates/mandatory.yml 0 → 100644 +12 −0 Changes for tests/components/.gitlab-ci.d/test/templates/mandatory.yml: 12 added lines, 0 removed lines. Original line number Diff line number Diff line spec: inputs: stage: description: 'Defines the commits job name (Default: commits)' name: description: 'Defines the commits stage (Default: test)' --- $[[ inputs.name ]]: stage: $[[ inputs.stage ]] script: - echo ' [Job] Component' Loading
src/types/yaml.py +65 −0 Changes for src/types/yaml.py: 65 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ # Standard libraries from copy import deepcopy from io import TextIOWrapper from re import sub as regex_sub from sys import maxsize from typing import Any, Dict, List, Optional Loading Loading @@ -98,6 +99,64 @@ class YAML: # Result return changed # Parse spec inputs @staticmethod def parse_spec_inputs(spec: Data, file_path: str) -> Dict[str, str]: # Variables inputs: Dict[str, str] = {} # Validate YAML spec syntax if 'spec' not in spec or 'inputs' not in spec['spec']: return inputs # Parse YAML spec inputs for key, value in spec['spec']['inputs'].items(): if isinstance(value, dict) and 'default' in value and isinstance( value['default'], str): inputs[key] = str(value.get('default')) else: raise SyntaxError(f'Missing value for input \'{key}\' in \'{file_path}\'') # Result return inputs # Evaluate string @staticmethod def evaluate_spec_field(field: str, inputs: Dict[str, str]) -> str: # Variables result: str = field # Evaluate inputs for variable, value in inputs.items(): result = regex_sub(fr'\$\[\[\s*inputs\.{variable}\s*\]\]', value, result) # Result return result # Evaluate spec @staticmethod def evaluate_spec(data: Data, inputs: Dict[str, str]) -> Data: # Recurse on keys if isinstance(data, dict): return { YAML.evaluate_spec_field(key, inputs): YAML.evaluate_spec(value, inputs) for key, value in data.items() } # Recurse on items if isinstance(data, list): return [YAML.evaluate_spec(value, inputs) for value in data] # Evaluate string items if isinstance(data, str): return YAML.evaluate_spec_field(data, inputs) # Fallback return data # pragma: no cover # Load @staticmethod def load(stream: TextIOWrapper) -> Optional[Data]: Loading @@ -105,6 +164,7 @@ class YAML: # Variables data: Optional[YAML.Data] documents: List[YAML.Data] inputs: Dict[str, str] # Prepare loader class loader = yaml_SafeLoader Loading @@ -121,6 +181,11 @@ class YAML: elif len(documents) == 1: data = documents[0] # Acquire YAML component data elif len(documents) == 2: inputs = YAML.parse_spec_inputs(documents[0], stream.name) data = YAML.evaluate_spec(documents[1], inputs) # Unsupport YAML data else: raise SyntaxError( Loading
tests/components/.gitlab-ci.d/test/templates/component.yml 0 → 100644 +14 −0 Changes for tests/components/.gitlab-ci.d/test/templates/component.yml: 14 added lines, 0 removed lines. Original line number Diff line number Diff line spec: inputs: stage: default: test description: 'Defines the commits job name (Default: commits)' name: default: component description: 'Defines the commits stage (Default: test)' --- $[[ inputs.name ]]: stage: $[[ inputs.stage ]] script: - echo ' [Job] Component'
tests/components/.gitlab-ci.d/test/templates/documents.3.yml 0 → 100644 +10 −0 Changes for tests/components/.gitlab-ci.d/test/templates/documents.3.yml: 10 added lines, 0 removed lines. Original line number Diff line number Diff line stages: - components --- stages: - components --- stages: - components
tests/components/.gitlab-ci.d/test/templates/mandatory.yml 0 → 100644 +12 −0 Changes for tests/components/.gitlab-ci.d/test/templates/mandatory.yml: 12 added lines, 0 removed lines. Original line number Diff line number Diff line spec: inputs: stage: description: 'Defines the commits job name (Default: commits)' name: description: 'Defines the commits stage (Default: test)' --- $[[ inputs.name ]]: stage: $[[ inputs.stage ]] script: - echo ' [Job] Component'