From 52525735d7b45b46bf3668f87a27893dea92e30d Mon Sep 17 00:00:00 2001 From: Sindre Stephansen Date: Mon, 31 Jul 2023 15:57:36 +0200 Subject: [PATCH] Reorganize config handling code --- sync/src/config.py | 164 ------------------------------------ sync/src/config/__init__.py | 3 + sync/src/config/packages.py | 62 ++++++++++++++ sync/src/config/parse.py | 71 ++++++++++++++++ sync/src/config/plugins.py | 45 ++++++++++ 5 files changed, 181 insertions(+), 164 deletions(-) delete mode 100644 sync/src/config.py create mode 100644 sync/src/config/__init__.py create mode 100644 sync/src/config/packages.py create mode 100644 sync/src/config/parse.py create mode 100644 sync/src/config/plugins.py diff --git a/sync/src/config.py b/sync/src/config.py deleted file mode 100644 index 0b5b6c1..0000000 --- a/sync/src/config.py +++ /dev/null @@ -1,164 +0,0 @@ -from typing import Optional - -import yaml -import logging -from dataclasses import dataclass -from pathlib import Path - -logger = logging.getLogger(__name__) - - -@dataclass -class Package: - group_id: str - artifact_id: str - version: str - - def __str__(self): - return f'{self.group_id}:{self.artifact_id}:{self.version}' - - def __hash__(self): - return hash((self.group_id, self.artifact_id, self.version)) - - -@dataclass -class Plugin: - id: str - version: Optional[str] - - @property - def gradle_spec(self): - return f'id("{self.id}") version "{self.version}"' if self.version else self.id - - @property - def package(self): - return Package(self.id, self.id + '.gradle.plugin', self.version) - - def __str__(self): - return f'{self.id}:{self.version}' if self.version else self.id - - def __hash__(self): - return hash((self.id, self.version)) - - -@dataclass -class Configuration: - name: str - kotlin_version: str - gradle_version: Optional[str] - plugins: list[Plugin] - packages: list[Package] - - -@dataclass -class Config: - configurations: list[Configuration] - mirrors: list[str] - - -def handle_packages(section) -> list[Package]: - ignore = ['_versions'] - result: list[Package] = [] - - for entry in section: - if entry not in ignore: - if ':' in entry: - try: - group_id, artifact_id = entry.split(':') - except ValueError: - logger.exception( - f'Illegal package identifier "{entry}". Should be on the format "groupId:artifactId"') - continue - - value = section[entry] - if isinstance(value, str): - result.append(Package(group_id, artifact_id, value)) - elif isinstance(value, list): - for version in value: - result.append(Package(group_id, artifact_id, version)) - else: - logger.warning(f'Invalid version "{value}" for "{entry}". Should be a string or list.') - elif isinstance(section[entry], dict): - group_id = entry - group_section = section[entry] - default_versions = group_section.get('_versions', []) - - for artifact_id, value in group_section.items(): - if artifact_id not in ignore: - if not value and default_versions: - value = default_versions - - if isinstance(value, str): - result.append(Package(group_id, artifact_id, value)) - elif isinstance(value, list): - for version in value: - result.append(Package(group_id, artifact_id, version)) - else: - logger.warning(f'Invalid versions "{value}" for "{group_id}:{artifact_id}"') - else: - logger.warning(f'Invalid package spec "{entry}". Should be a full spec or a group ID') - - return result - - -def handle_plugins(section: dict[str, str | list[str] | None]) -> list[Plugin]: - result = [] - - for entry in section: - versions = section[entry] - - if isinstance(versions, str): - result.append(Plugin(entry, versions)) - elif isinstance(versions, list): - result.extend([Plugin(entry, v) for v in versions]) - elif versions is None: - result.append(Plugin(entry, None)) - else: - logger.warning(f'Invalid plugin version "{versions}" for {entry}') - - return result - - -def parse_config(path: Path) -> Optional[Config]: - with path.open('r') as f: - data = yaml.safe_load(f) - - error: list[str] = [] - configurations: list[Configuration] = [] - - for i, section in enumerate(data.get('configurations')): - if (kotlin_version := section.get('kotlin-version')) is None: - error.append(f"Configuration {i} is missing 'kotlin-version'") - - gradle_version = section.get('gradle-version') - - plugins = handle_plugins(section.get('plugins', {})) - packages = handle_packages(section.get('packages', {})) - - configurations.append(Configuration( - name=f'{kotlin_version}-packages', - kotlin_version=kotlin_version, - gradle_version=gradle_version, - plugins=[], - packages=packages - )) - - for j, plugin in enumerate(plugins): - configurations.append(Configuration( - name=f'{kotlin_version}-plugins-{j}', - kotlin_version=kotlin_version, - gradle_version=gradle_version, - plugins=[plugin], - packages=[] - )) - - if error: - for msg in error: - logger.error(msg) - - return None - else: - return Config( - configurations, - data.get('maven', {}).get('mirrors', []), - ) diff --git a/sync/src/config/__init__.py b/sync/src/config/__init__.py new file mode 100644 index 0000000..a4d47ba --- /dev/null +++ b/sync/src/config/__init__.py @@ -0,0 +1,3 @@ +from .packages import Package +from .plugins import Plugin +from .parse import Configuration, Config, parse_config diff --git a/sync/src/config/packages.py b/sync/src/config/packages.py new file mode 100644 index 0000000..7ebe912 --- /dev/null +++ b/sync/src/config/packages.py @@ -0,0 +1,62 @@ +import logging +from dataclasses import dataclass + +logger = logging.getLogger(__name__) + + +@dataclass +class Package: + group_id: str + artifact_id: str + version: str + + def __str__(self): + return f'{self.group_id}:{self.artifact_id}:{self.version}' + + def __hash__(self): + return hash((self.group_id, self.artifact_id, self.version)) + + +def handle_packages(section) -> list[Package]: + ignore = ['_versions'] + result: list[Package] = [] + + for entry in section: + if entry not in ignore: + if ':' in entry: + try: + group_id, artifact_id = entry.split(':') + except ValueError: + logger.exception( + f'Illegal package identifier "{entry}". Should be on the format "groupId:artifactId"') + continue + + value = section[entry] + if isinstance(value, str): + result.append(Package(group_id, artifact_id, value)) + elif isinstance(value, list): + for version in value: + result.append(Package(group_id, artifact_id, version)) + else: + logger.warning(f'Invalid version "{value}" for "{entry}". Should be a string or list.') + elif isinstance(section[entry], dict): + group_id = entry + group_section = section[entry] + default_versions = group_section.get('_versions', []) + + for artifact_id, value in group_section.items(): + if artifact_id not in ignore: + if not value and default_versions: + value = default_versions + + if isinstance(value, str): + result.append(Package(group_id, artifact_id, value)) + elif isinstance(value, list): + for version in value: + result.append(Package(group_id, artifact_id, version)) + else: + logger.warning(f'Invalid versions "{value}" for "{group_id}:{artifact_id}"') + else: + logger.warning(f'Invalid package spec "{entry}". Should be a full spec or a group ID') + + return result diff --git a/sync/src/config/parse.py b/sync/src/config/parse.py new file mode 100644 index 0000000..a985fc0 --- /dev/null +++ b/sync/src/config/parse.py @@ -0,0 +1,71 @@ +from typing import Optional + +import yaml +import logging +from dataclasses import dataclass +from pathlib import Path + +from .plugins import Plugin, handle_plugins +from .packages import Package, handle_packages + +logger = logging.getLogger(__name__) + + +@dataclass +class Configuration: + name: str + kotlin_version: str + gradle_version: Optional[str] + plugins: list[Plugin] + packages: list[Package] + + +@dataclass +class Config: + configurations: list[Configuration] + mirrors: list[str] + + +def parse_config(path: Path) -> Optional[Config]: + with path.open('r') as f: + data = yaml.safe_load(f) + + error: list[str] = [] + configurations: list[Configuration] = [] + + for i, section in enumerate(data.get('configurations')): + if (kotlin_version := section.get('kotlin-version')) is None: + error.append(f"Configuration {i} is missing 'kotlin-version'") + + gradle_version = section.get('gradle-version') + + plugins = handle_plugins(section.get('plugins', {})) + packages = handle_packages(section.get('packages', {})) + + configurations.append(Configuration( + name=f'{kotlin_version}-packages', + kotlin_version=kotlin_version, + gradle_version=gradle_version, + plugins=[], + packages=packages + )) + + for j, plugin in enumerate(plugins): + configurations.append(Configuration( + name=f'{kotlin_version}-plugins-{j}', + kotlin_version=kotlin_version, + gradle_version=gradle_version, + plugins=[plugin], + packages=[] + )) + + if error: + for msg in error: + logger.error(msg) + + return None + else: + return Config( + configurations, + data.get('maven', {}).get('mirrors', []), + ) diff --git a/sync/src/config/plugins.py b/sync/src/config/plugins.py new file mode 100644 index 0000000..5fd8777 --- /dev/null +++ b/sync/src/config/plugins.py @@ -0,0 +1,45 @@ +import logging +from dataclasses import dataclass +from typing import Optional + +from .packages import Package + +logger = logging.getLogger(__name__) + + +@dataclass +class Plugin: + id: str + version: Optional[str] + + @property + def gradle_spec(self): + return f'id("{self.id}") version "{self.version}"' if self.version else self.id + + @property + def package(self): + return Package(self.id, self.id + '.gradle.plugin', self.version) + + def __str__(self): + return f'{self.id}:{self.version}' if self.version else self.id + + def __hash__(self): + return hash((self.id, self.version)) + + +def handle_plugins(section: dict[str, str | list[str] | None]) -> list[Plugin]: + result = [] + + for entry in section: + versions = section[entry] + + if isinstance(versions, str): + result.append(Plugin(entry, versions)) + elif isinstance(versions, list): + result.extend([Plugin(entry, v) for v in versions]) + elif versions is None: + result.append(Plugin(entry, None)) + else: + logger.warning(f'Invalid plugin version "{versions}" for {entry}') + + return result