Verified Commit 661e2e05 authored by Adrian DC's avatar Adrian DC
Browse files

fix(yaml): implement YAML support for 'inputs:' include values

Issue: #277
---

Signed-off-by: default avatarAdrian DC <radian.dc@gmail.com>
parent 04be27d6
Loading
Loading
Loading
Loading
Loading
+4 −1
Changes for src/features/menus.py: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -170,7 +170,10 @@ class MenusFeature:
                            encoding='utf8',
                            mode='r',
                    ) as configuration_data:
                        configuration_dict = YAML.load(configuration_data)
                        configuration_dict = YAML.load(
                            configuration_data,
                            inputs={},
                        )
                        assert configuration_dict is not None
                        variable_finds = Dicts.find(
                            configuration_dict,
+18 −2
Changes for src/parsers/gitlab.py: 18 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -378,6 +378,11 @@ class GitLab:
        if resolved_path in stack:
            return

        # Parse inputs
        file_inputs: YAML.Data = {}
        if 'inputs' in include_dict and isinstance(include_dict['inputs'], dict):
            file_inputs = include_dict['inputs']

        # Existing file inclusion
        file_paths: Path = Path(working_directory) / resolved_path
        for file_path in Paths.wildcard(str(file_paths), strict=True):
@@ -388,7 +393,10 @@ class GitLab:

                # Load included file
                with open(file_path, encoding='utf8', mode='r') as include_data:
                    data_additions: Optional[YAML.Data] = YAML.load(include_data)
                    data_additions: Optional[YAML.Data] = YAML.load(
                        include_data,
                        inputs=file_inputs,
                    )
                    if data_additions:

                        # Nested includes (follow working directory)
@@ -450,6 +458,11 @@ class GitLab:
            elif isinstance(include_dict['file'], str):
                file_items = [include_dict['file']]

        # Parse inputs
        file_inputs: YAML.Data = {}
        if 'inputs' in include_dict and isinstance(include_dict['inputs'], dict):
            file_inputs = include_dict['inputs']

        # Iterate through file paths
        for file_item in file_items:

@@ -469,7 +482,10 @@ class GitLab:

                    # Load included file
                    with open(file_path, encoding='utf8', mode='r') as include_data:
                        data_additions: Optional[YAML.Data] = YAML.load(include_data)
                        data_additions: Optional[YAML.Data] = YAML.load(
                            include_data,
                            inputs=file_inputs,
                        )
                        if data_additions:

                            # Nested includes (follow working directory)
+4 −1
Changes for src/parsers/parsers.py: 4 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -37,7 +37,10 @@ class Parsers:
                    encoding='utf8',
                    mode='r',
            ) as configuration_data:
                data: Optional[YAML.Data] = YAML.load(configuration_data)
                data: Optional[YAML.Data] = YAML.load(
                    configuration_data,
                    inputs={},
                )
                if not data:
                    raise YAML.Error(
                        f'Empty YAML content found in \'{self.__options.configuration}\'...'
+25 −9
Changes for src/types/yaml.py: 25 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -101,7 +101,11 @@ class YAML:

    # Parse spec inputs
    @staticmethod
    def parse_spec_inputs(spec: Data, file_path: str) -> Dict[str, str]:
    def parse_spec_inputs(
        spec: Data,
        file_path: str,
        file_inputs: Dict[str, str],
    ) -> Dict[str, str]:

        # Variables
        inputs: Dict[str, str] = {}
@@ -111,10 +115,12 @@ class YAML:
            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'))
        for key, item in spec['spec']['inputs'].items():
            if isinstance(item, dict) and key in file_inputs:
                inputs[key] = str(file_inputs.get(key))
            elif isinstance(item, dict) and 'default' in item and isinstance(
                    item['default'], str):
                inputs[key] = str(item.get('default'))
            else:
                raise SyntaxError(f'Missing value for input \'{key}\' in \'{file_path}\'')

@@ -159,12 +165,15 @@ class YAML:

    # Load
    @staticmethod
    def load(stream: TextIOWrapper) -> Optional[Data]:
    def load(
        stream: TextIOWrapper,
        inputs: Dict[str, str],
    ) -> Optional[Data]:

        # Variables
        data: Optional[YAML.Data]
        documents: List[YAML.Data]
        inputs: Dict[str, str]
        file_inputs: Dict[str, str]

        # Prepare loader class
        loader = yaml_SafeLoader
@@ -183,8 +192,15 @@ class YAML:

        # Acquire YAML component data
        elif len(documents) == 2:
            inputs = YAML.parse_spec_inputs(documents[0], stream.name)
            data = YAML.evaluate_spec(documents[1], inputs)
            file_inputs = YAML.parse_spec_inputs(
                documents[0],
                stream.name,
                file_inputs=inputs,
            )
            data = YAML.evaluate_spec(
                documents[1],
                inputs=file_inputs,
            )

        # Unsupport YAML data
        else:
+7 −0
Changes for tests/inputs/.gitlab-ci.local.yml: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
include:
  - local: '.gitlab-ci.d/test/templates/component.yml'
    inputs:
      stage: components

stages:
  - components
Loading