From 65f733b959309e5b72f652d2332b44297eababa0 Mon Sep 17 00:00:00 2001 From: Christian Cwienk Date: Tue, 3 Dec 2024 20:44:25 +0100 Subject: [PATCH] refactor/cleanup: mv `main_source` -> ocm.util As another step towards discarding `cnudie` package, mv cnudie.util's main_source to ocm.util. Slightly overhaul while doing so (give callers more control about lookup/raising behaviour). Replace usages within this repository (there outside usages, hence keeping legacies in cnudie.util for smooth migration). Also, rm some unused imports. --- cli/gardener_ci/compliance.py | 4 +- cnudie/util.py | 3 ++ concourse/steps/release.mako | 3 +- concourse/steps/update_component_deps.py | 3 +- github/compliance/report.py | 4 +- mailutil.py | 7 ++- ocm/util.py | 58 ++++++++++++++++++++++++ release_notes/fetch.py | 6 +-- release_notes/model.py | 13 +++--- 9 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 ocm/util.py diff --git a/cli/gardener_ci/compliance.py b/cli/gardener_ci/compliance.py index 62a3728a1..e270c33fa 100644 --- a/cli/gardener_ci/compliance.py +++ b/cli/gardener_ci/compliance.py @@ -26,9 +26,9 @@ import ci.util import cnudie.iter import cnudie.retrieve -import cnudie.util import ctx import ocm +import ocm.util import reutil @@ -196,7 +196,7 @@ def iter_resources_with_ids(components): ] def resource_as_dict(component, resource, resource_id): - if (main_src := cnudie.util.main_source(component, absent_ok=True)): + if (main_src := ocm.util.main_source(component, no_source_ok=True)): src_url = main_src.access.repoUrl elif isinstance(resource.access, ocm.OciAccess): src_url = resource.access.imageReference diff --git a/cnudie/util.py b/cnudie/util.py index eb54d8d09..95a5f2513 100644 --- a/cnudie/util.py +++ b/cnudie/util.py @@ -3,6 +3,8 @@ import graphlib import textwrap +import deprecated + import ci.util import ocm import oci.model as om @@ -260,6 +262,7 @@ def target_oci_ref( ) +@deprecated.deprecated('use ocm.util.main_source instead') def main_source( component: ocm.Component, absent_ok: bool=True, diff --git a/concourse/steps/release.mako b/concourse/steps/release.mako index 4f7b7fedc..8387ed6bb 100644 --- a/concourse/steps/release.mako +++ b/concourse/steps/release.mako @@ -111,6 +111,7 @@ import concourse.model.traits.release import concourse.util import ocm import ocm.upload +import ocm.util import github.util import gitutil @@ -217,7 +218,7 @@ build_plan = current_build.plan() ## assuming buildlogs are typically not of interest for gh-releases, hardcode to omit those github_assets = [] -main_source = cnudie.util.main_source(component) +main_source = ocm.util.main_source(component) main_source_ref = { 'name': main_source.name, 'version': main_source.version, diff --git a/concourse/steps/update_component_deps.py b/concourse/steps/update_component_deps.py index bc9939f81..c2efd85be 100644 --- a/concourse/steps/update_component_deps.py +++ b/concourse/steps/update_component_deps.py @@ -7,6 +7,7 @@ import traceback import ocm +import ocm.util import github3.exceptions import github3.repos.repo @@ -357,7 +358,7 @@ def _import_release_notes( ) return None - main_source = cnudie.util.determine_main_source_for_component(component) + main_source = ocm.util.main_source(component) github_cfg = ccc.github.github_cfg_for_repo_url(main_source.access.repoUrl) org_name = main_source.access.org_name() repository_name = main_source.access.repository_name() diff --git a/github/compliance/report.py b/github/compliance/report.py index bc12f22a3..bf1d1c3a1 100644 --- a/github/compliance/report.py +++ b/github/compliance/report.py @@ -14,13 +14,13 @@ import github3.repos import ocm +import ocm.util import requests import ccc.github import checkmarx.model import cfg_mgmt.model as cmm import ci.util -import cnudie.util import concourse.model.traits.image_scan as image_scan import delivery.client import delivery.model @@ -340,7 +340,7 @@ def _scanned_element_repository( scanned_element: gcm.Target, ) -> github3.repos.repo.Repository: if gcm.is_ocm_artefact_node(scanned_element): - source = cnudie.util.main_source(component=scanned_element.component) + source = ocm.util.main_source(component=scanned_element.component) if not source.access.type is ocm.AccessType.GITHUB: raise NotImplementedError(source) diff --git a/mailutil.py b/mailutil.py index af3114ef2..407f54497 100644 --- a/mailutil.py +++ b/mailutil.py @@ -8,9 +8,8 @@ import typing import ocm +import ocm.util -import cnudie.retrieve -import cnudie.util from model.email import EmailConfig from ci.util import ( existing_dir, @@ -275,9 +274,9 @@ def _codeowners_parser_from_component( component: ocm.Component, branch_name: str='master', ): - main_source = cnudie.util.main_source( + main_source = ocm.util.main_source( component=component, - absent_ok=False, + no_source_ok=False, ) if not main_source.access.type is ocm.AccessType.GITHUB: raise NotImplementedError(main_source.access.type) diff --git a/ocm/util.py b/ocm/util.py new file mode 100644 index 000000000..efa77cbed --- /dev/null +++ b/ocm/util.py @@ -0,0 +1,58 @@ +import ocm + + +def as_component( + component: ocm.Component | ocm.ComponentDescriptor, + /, +) -> ocm.Component: + if isinstance(component, ocm.Component): + return component + if isinstance(component, ocm.ComponentDescriptor): + return component.component + + raise ValueError(component) + + +def main_source( + component: ocm.Component | ocm.ComponentDescriptor, + *, + no_source_ok: bool=True, + ambiguous_ok: bool=True, + honour_label: bool=False, +) -> ocm.Source | None: + ''' + returns the "main source" of the given OCM Component. Typically, components will have exactly + one source, in which the applied logic is to return the sole source-artefact. + + For other cases, behaviour can be controlled via kw-(only-)params: + + no_source_ok: if component has _no_ sources, return None + ambiguous_ok: if component has more than one source, return first + honour_label: check for presence of source-label `cloud.gardener/cicd/source` + + In cases where no main-source can be determined, raises ValueError. + + Note: `honour_label` is crafted specifically for Gardener-CICD, and relies on the contract that + at most one source in a component may bear it w/ repository-classification main. + ''' + component = as_component(component) + + if len(component.sources) == 1: + return component.sources[0] + elif not component.sources: + if no_source_ok: + return None + else: + raise ValueError('no sources', component) + + # more than one source + if honour_label: + for source in component.sources: + if label := source.find_label('cloud.gardener/cicd/source'): + if label.value.get('repository-classification') == 'main': + return source + + if ambiguous_ok: + return component.sources[0] + + raise ValueError('could not umambiguosly determine main-source', component) diff --git a/release_notes/fetch.py b/release_notes/fetch.py index bac7775b8..31a28b268 100644 --- a/release_notes/fetch.py +++ b/release_notes/fetch.py @@ -4,11 +4,11 @@ import enum import ocm +import ocm.util import git import github3.repos import cnudie.retrieve -import cnudie.util import gitutil import github.util import release_notes.model as rnm @@ -257,7 +257,7 @@ def fetch_draft_release_notes( f'Creating draft-release notes from {previous_version} to current HEAD' ) - source = cnudie.util.determine_main_source_for_component(component) + source = ocm.util.main_source(component) github_helper = rnu.github_helper_from_github_access(source.access) git_helper = rnu.git_helper_from_github_access(source.access, repo_path) @@ -364,7 +364,7 @@ def fetch_release_notes( current_version or SpecialVersion.HEAD ) - source = cnudie.util.determine_main_source_for_component(component) + source = ocm.util.main_source(component) github_helper = rnu.github_helper_from_github_access(source.access) git_helper = rnu.git_helper_from_github_access(source.access, repo_path) diff --git a/release_notes/model.py b/release_notes/model.py index fdc93dd08..6a7538c9c 100644 --- a/release_notes/model.py +++ b/release_notes/model.py @@ -5,11 +5,10 @@ import typing import ocm +import ocm.util import git import github3.pulls -import cnudie.util -import cnudie.retrieve import version logger = logging.getLogger(__name__) @@ -326,14 +325,16 @@ def create_release_notes_obj( ) # access - source_component_access = cnudie.util.determine_main_source_for_component( + source_component_access = ocm.util.main_source( component=source_component, - absent_ok=False + no_source_ok=False, + honour_label=True, ).access - current_src_access = cnudie.util.determine_main_source_for_component( + current_src_access = ocm.util.main_source( component=current_component, - absent_ok=False + no_source_ok=False, + honour_label=True, ).access from_same_github_instance = current_src_access.hostname() in source_component_access.hostname()