This is an automated email from the ASF dual-hosted git repository. arm pushed a commit to branch arm in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
commit ece11fd32d1c115e9140f26a340030d4cd3ac337 Author: Alastair McFarlane <[email protected]> AuthorDate: Mon Mar 16 15:27:59 2026 +0000 #840: rename types to *Key --- atr/admin/__init__.py | 12 +++---- atr/api/__init__.py | 32 ++++++++--------- atr/attestable.py | 32 ++++++++--------- atr/blueprints/common.py | 12 +++---- atr/blueprints/post.py | 2 +- atr/cache.py | 2 +- atr/construct.py | 18 +++++----- atr/datasources/apache.py | 2 +- atr/db/__init__.py | 2 +- atr/db/interaction.py | 16 ++++----- atr/get/announce.py | 6 ++-- atr/get/checklist.py | 4 +-- atr/get/checks.py | 6 ++-- atr/get/compose.py | 4 +-- atr/get/distribution.py | 28 +++++++-------- atr/get/download.py | 26 +++++++------- atr/get/draft.py | 4 +-- atr/get/file.py | 8 ++--- atr/get/finish.py | 6 ++-- atr/get/ignores.py | 2 +- atr/get/manual.py | 8 ++--- atr/get/projects.py | 2 +- atr/get/release.py | 4 +-- atr/get/report.py | 4 +-- atr/get/result.py | 4 +-- atr/get/revisions.py | 4 +-- atr/get/sbom.py | 6 ++-- atr/get/start.py | 2 +- atr/get/test.py | 8 ++--- atr/get/upload.py | 4 +-- atr/get/vote.py | 6 ++-- atr/get/voting.py | 4 +-- atr/merge.py | 16 ++++----- atr/models/api.py | 68 +++++++++++++++++------------------ atr/models/distribution.py | 2 +- atr/models/safe.py | 8 ++--- atr/models/sql.py | 32 ++++++++--------- atr/paths.py | 4 +-- atr/post/announce.py | 4 +-- atr/post/distribution.py | 28 +++++++-------- atr/post/draft.py | 28 +++++++-------- atr/post/finish.py | 18 +++++----- atr/post/ignores.py | 8 ++--- atr/post/keys.py | 4 +-- atr/post/manual.py | 8 ++--- atr/post/projects.py | 2 +- atr/post/resolve.py | 10 +++--- atr/post/revisions.py | 12 +++---- atr/post/sbom.py | 8 ++--- atr/post/start.py | 4 +-- atr/post/upload.py | 20 +++++------ atr/post/vote.py | 4 +-- atr/post/voting.py | 8 ++--- atr/shared/distribution.py | 20 +++++------ atr/shared/projects.py | 18 +++++----- atr/shared/web.py | 2 +- atr/ssh.py | 24 ++++++------- atr/storage/__init__.py | 14 ++++---- atr/storage/readers/checks.py | 4 +-- atr/storage/writers/announce.py | 4 +-- atr/storage/writers/checks.py | 2 +- atr/storage/writers/distributions.py | 18 +++++----- atr/storage/writers/keys.py | 2 +- atr/storage/writers/policy.py | 2 +- atr/storage/writers/project.py | 2 +- atr/storage/writers/release.py | 34 +++++++++--------- atr/storage/writers/revision.py | 28 +++++++-------- atr/storage/writers/sbom.py | 12 +++---- atr/storage/writers/ssh.py | 2 +- atr/storage/writers/vote.py | 14 ++++---- atr/storage/writers/workflowstatus.py | 2 +- atr/tasks/__init__.py | 12 +++---- atr/tasks/checks/__init__.py | 18 +++++----- atr/tasks/checks/compare.py | 2 +- atr/tasks/gha.py | 4 +-- atr/tasks/keys.py | 4 +-- atr/tasks/quarantine.py | 4 +-- atr/tasks/sbom.py | 16 ++++----- atr/tasks/svn.py | 4 +-- atr/tasks/vote.py | 2 +- atr/web.py | 6 ++-- atr/worker.py | 4 +-- tests/unit/test_create_revision.py | 2 +- tests/unit/test_ignores_api_models.py | 10 +++--- tests/unit/test_quarantine_task.py | 12 +++---- tests/unit/test_safe_types.py | 10 +++--- 86 files changed, 445 insertions(+), 445 deletions(-) diff --git a/atr/admin/__init__.py b/atr/admin/__init__.py index 7538287f..bd1fa57f 100644 --- a/atr/admin/__init__.py +++ b/atr/admin/__init__.py @@ -599,8 +599,8 @@ async def logs(session: web.Committer) -> web.QuartResponse: async def ongoing_tasks_get( session: web.Committer, project_name: str, version_name: str, revision: str ) -> web.QuartResponse: - project = safe.ProjectName(project_name) - version = safe.VersionName(version_name) + project = safe.ProjectKey(project_name) + version = safe.VersionKey(version_name) revision_number = safe.RevisionNumber(revision) return await _ongoing_tasks(session, project, version, revision_number) @@ -609,8 +609,8 @@ async def ongoing_tasks_get( async def ongoing_tasks_post( session: web.Committer, project_name: str, version_name: str, revision: str ) -> web.QuartResponse: - project = safe.ProjectName(project_name) - version = safe.VersionName(version_name) + project = safe.ProjectKey(project_name) + version = safe.VersionKey(version_name) revision_number = safe.RevisionNumber(revision) return await _ongoing_tasks(session, project, version, revision_number) @@ -1177,8 +1177,8 @@ async def _get_filesystem_dirs_unfinished(filesystem_dirs: list[str]) -> None: async def _ongoing_tasks( session: web.Committer, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, ) -> web.QuartResponse: try: diff --git a/atr/api/__init__.py b/atr/api/__init__.py index 820f9b60..7ab2d1bd 100644 --- a/atr/api/__init__.py +++ b/atr/api/__init__.py @@ -65,8 +65,8 @@ ROUTES_MODULE: Final[Literal[True]] = True @quart_schema.validate_response(models.api.ChecksListResults, 200) async def checks_list( _checks_list: Literal["checks/list"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> DictResponse: """ URL: GET /checks/list/<project_name>/<version_name> @@ -99,8 +99,8 @@ async def checks_list( @quart_schema.validate_response(models.api.ChecksListResults, 200) async def checks_list_revision( _checks_list: Literal["checks/list"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, ) -> DictResponse: """ @@ -140,8 +140,8 @@ async def checks_list_revision( @quart_schema.validate_response(models.api.ChecksOngoingResults, 200) async def checks_ongoing( _checks_ongoing: Literal["checks/ongoing"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber | None = None, ) -> DictResponse: """ @@ -462,7 +462,7 @@ async def ignore_delete( @quart_schema.validate_response(models.api.IgnoreListResults, 200) async def ignore_list( _ignore_list: Literal["ignore/list"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> DictResponse: """ URL: GET /ignore/list/<project_name> @@ -692,7 +692,7 @@ async def keys_user( @quart_schema.validate_response(models.api.ProjectGetResults, 200) async def project_get( _project_get: Literal["project/get"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> DictResponse: """ URL: GET /project/get/<project_name> @@ -711,7 +711,7 @@ async def project_get( @quart_schema.validate_response(models.api.ProjectPolicyResults, 200) async def project_policy( _project_policy: Literal["project/policy"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> DictResponse: """ URL: GET /project/policy/<project_name> @@ -755,7 +755,7 @@ async def project_policy( @quart_schema.validate_response(models.api.ProjectReleasesResults, 200) async def project_releases( _project_releases: Literal["project/releases"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> DictResponse: """ URL: GET /project/releases/<project_name> @@ -1049,8 +1049,8 @@ async def release_delete( @quart_schema.validate_response(models.api.ReleaseGetResults, 200) async def release_get( _release_get: Literal["release/get"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> DictResponse: """ URL: GET /release/get/<project_name>/<version_name> @@ -1070,8 +1070,8 @@ async def release_get( @quart_schema.validate_response(models.api.ReleasePathsResults, 200) async def release_paths( _release_paths: Literal["release/paths"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber | None = None, ) -> DictResponse: """ @@ -1101,8 +1101,8 @@ async def release_paths( @quart_schema.validate_response(models.api.ReleaseRevisionsResults, 200) async def release_revisions( _release_revisions: Literal["release/revisions"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> DictResponse: """ URL: GET /release/revisions/<project_name>/<version_name> diff --git a/atr/attestable.py b/atr/attestable.py index 1cf40c08..03a08e16 100644 --- a/atr/attestable.py +++ b/atr/attestable.py @@ -35,32 +35,32 @@ import atr.util as util def attestable_checks_path( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber ) -> pathlib.Path: return paths.get_attestable_dir() / str(project_name) / str(version_name) / f"{revision_number!s}.checks.json" def attestable_path( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber ) -> pathlib.Path: return paths.get_attestable_dir() / str(project_name) / str(version_name) / f"{revision_number!s}.json" def attestable_paths_path( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber ) -> pathlib.Path: return paths.get_attestable_dir() / str(project_name) / str(version_name) / f"{revision_number!s}.paths.json" def github_tp_payload_path( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber ) -> pathlib.Path: return paths.get_attestable_dir() / str(project_name) / str(version_name) / f"{revision_number!s}.github-tp.json" async def github_tp_payload_write( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, github_payload: dict[str, Any], ) -> None: @@ -69,8 +69,8 @@ async def github_tp_payload_write( async def load( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, ) -> models.Attestable | None: file_path = attestable_path(project_name, version_name, revision_number) @@ -86,8 +86,8 @@ async def load( async def load_checks( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, ) -> dict[str, dict[str, str]]: file_path = attestable_checks_path(project_name, version_name, revision_number) @@ -108,8 +108,8 @@ async def load_checks( async def load_paths( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, ) -> dict[str, str] | None: file_path = attestable_paths_path(project_name, version_name, revision_number) @@ -194,8 +194,8 @@ async def paths_to_hashes_and_sizes(directory: pathlib.Path) -> tuple[dict[str, async def write_checks_data( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, rel_path: str, checks: dict[str, str], @@ -218,8 +218,8 @@ async def write_checks_data( async def write_files_data( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, release_policy: dict[str, Any] | None, uploader_uid: str, diff --git a/atr/blueprints/common.py b/atr/blueprints/common.py index 1382e90c..6801ce9c 100644 --- a/atr/blueprints/common.py +++ b/atr/blueprints/common.py @@ -41,9 +41,9 @@ QUART_CONVERTERS: dict[Any, str] = { VALIDATED_TYPES: set[Any] = { safe.Alphanumeric, safe.CommitteeKey, - safe.ProjectName, + safe.ProjectKey, safe.RevisionNumber, - safe.VersionName, + safe.VersionKey, unsafe.UnsafeStr, } @@ -196,14 +196,14 @@ async def validate_params(kwargs: dict[str, Any], known_params: list[tuple[str, """Validate URL parameters in order, using the type-specific validators.""" for param_name, param_type in known_params: raw = kwargs[param_name] - if param_type is safe.ProjectName: + if param_type is safe.ProjectKey: try: - kwargs[param_name] = safe.ProjectName(raw) + kwargs[param_name] = safe.ProjectKey(raw) except ValueError: raise base.ASFQuartException(f"Project name {param_name!r} is invalid. ") - elif param_type is safe.VersionName: + elif param_type is safe.VersionKey: try: - kwargs[param_name] = safe.VersionName(raw) + kwargs[param_name] = safe.VersionKey(raw) except ValueError: raise base.ASFQuartException(f"Version name {param_name!r} is invalid. ") elif param_type is safe.RevisionNumber: diff --git a/atr/blueprints/post.py b/atr/blueprints/post.py index 6c585507..0d08f5db 100644 --- a/atr/blueprints/post.py +++ b/atr/blueprints/post.py @@ -64,7 +64,7 @@ def typed(func: Callable[..., Any]) -> web.RouteFunction[Any]: - check_access is called automatically for committer routes with project_name """ path, validated_params, literal_params, form_param, public = common.build_path(func) - project_name_var = next((name for name, t in validated_params if t is safe.ProjectName), None) + project_name_var = next((name for name, t in validated_params if t is safe.ProjectKey), None) check_access = (not public) and (project_name_var is not None) form_safe_params = common.safe_params_for_type(form_param[1]) if form_param is not None else [] diff --git a/atr/cache.py b/atr/cache.py index e578f0aa..354411b4 100644 --- a/atr/cache.py +++ b/atr/cache.py @@ -105,7 +105,7 @@ def project_version_has_project(project_name: str) -> bool: return project_name in project_version_get() -def project_version_has_version(project_name: safe.ProjectName, version_name: str) -> bool: +def project_version_has_version(project_name: safe.ProjectKey, version_name: str) -> bool: projects = project_version_get() if str(project_name) not in projects: return False diff --git a/atr/construct.py b/atr/construct.py index 32a18770..e7e1ac80 100644 --- a/atr/construct.py +++ b/atr/construct.py @@ -54,8 +54,8 @@ TEMPLATE_VARIABLES: list[tuple[str, str, set[Context]]] = [ class AnnounceReleaseOptions: asfuid: str fullname: str - project_name: safe.ProjectName - version_name: safe.VersionName + project_name: safe.ProjectKey + version_name: safe.VersionKey revision_number: safe.RevisionNumber @@ -63,13 +63,13 @@ class AnnounceReleaseOptions: class StartVoteOptions: asfuid: str fullname: str - project_name: safe.ProjectName - version_name: safe.VersionName + project_name: safe.ProjectKey + version_name: safe.VersionKey revision_number: safe.RevisionNumber vote_duration: int -async def announce_release_default(project_name: safe.ProjectName) -> str: +async def announce_release_default(project_name: safe.ProjectKey) -> str: async with db.session() as data: project = await data.project( name=str(project_name), status=sql.ProjectStatus.ACTIVE, _release_policy=True @@ -132,7 +132,7 @@ async def announce_release_subject_and_body( return subject, body -async def announce_release_subject_default(project_name: safe.ProjectName) -> str: +async def announce_release_subject_default(project_name: safe.ProjectKey) -> str: async with db.session() as data: project = await data.project( name=str(project_name), status=sql.ProjectStatus.ACTIVE, _release_policy=True @@ -152,7 +152,7 @@ def announce_template_variables() -> list[tuple[str, str]]: def checklist_body( markdown: str, project: sql.Project, - version_name: safe.VersionName, + version_name: safe.VersionKey, committee: sql.Committee, revision: sql.Revision | None, ) -> str: @@ -181,7 +181,7 @@ def checklist_template_variables() -> list[tuple[str, str]]: return [(name, desc) for (name, desc, contexts) in TEMPLATE_VARIABLES if "checklist" in contexts] -async def start_vote_default(project_name: safe.ProjectName) -> str: +async def start_vote_default(project_name: safe.ProjectKey) -> str: async with db.session() as data: project = await data.project( name=str(project_name), status=sql.ProjectStatus.ACTIVE, _release_policy=True @@ -280,7 +280,7 @@ async def start_vote_subject_and_body(subject: str, body: str, options: StartVot return subject, body -async def start_vote_subject_default(project_name: safe.ProjectName) -> str: +async def start_vote_subject_default(project_name: safe.ProjectKey) -> str: async with db.session() as data: project = await data.project( name=str(project_name), status=sql.ProjectStatus.ACTIVE, _release_policy=True diff --git a/atr/datasources/apache.py b/atr/datasources/apache.py index 674cd912..0045ae92 100644 --- a/atr/datasources/apache.py +++ b/atr/datasources/apache.py @@ -484,7 +484,7 @@ async def _update_projects(data: db.Session, projects: ProjectsData) -> tuple[in updated_count += 1 # Pass the project name through the validator - safe.ProjectName(project_model.name) + safe.ProjectKey(project_model.name) project_model.full_name = str(project_status.name) project_model.category = project_status.category project_model.description = project_status.description diff --git a/atr/db/__init__.py b/atr/db/__init__.py index 83011f38..38e3260b 100644 --- a/atr/db/__init__.py +++ b/atr/db/__init__.py @@ -896,7 +896,7 @@ def ensure_session(caller_data: Session | None) -> Session | contextlib.nullcont return contextlib.nullcontext(caller_data) -async def get_project_release_policy(data: Session, project_name: safe.ProjectName) -> sql.ReleasePolicy | None: +async def get_project_release_policy(data: Session, project_name: safe.ProjectKey) -> sql.ReleasePolicy | None: """Fetch the ReleasePolicy for a project.""" project = await data.project(name=str(project_name), status=sql.ProjectStatus.ACTIVE, _release_policy=True).demand( RuntimeError(f"Project {project_name} not found") diff --git a/atr/db/interaction.py b/atr/db/interaction.py index 35f86a8b..87259277 100644 --- a/atr/db/interaction.py +++ b/atr/db/interaction.py @@ -250,7 +250,7 @@ async def has_failing_checks( async def latest_info( - project_name: safe.ProjectName, version_name: safe.VersionName + project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> tuple[safe.RevisionNumber, str, datetime.datetime] | None: """Get the name, editor, and timestamp of the latest revision.""" release_name = sql.release_name(project_name, version_name) @@ -303,8 +303,8 @@ async def release_latest_vote_task(release: sql.Release, caller_data: db.Session async def release_ready_for_vote( # noqa: C901 session: web.Committer, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, data: db.Session, manual_vote: bool = False, @@ -404,7 +404,7 @@ def task_recipient_get(latest_vote_task: sql.Task) -> str | None: async def tasks_ongoing( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber | None = None + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber | None = None ) -> int: tasks = sqlmodel.select(sqlalchemy.func.count()).select_from(sql.Task) async with db.session() as data: @@ -420,8 +420,8 @@ async def tasks_ongoing( async def tasks_ongoing_revision( - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber | None = None, ) -> tuple[int, str | None]: via = sql.validate_instrumented_attribute @@ -471,8 +471,8 @@ async def trusted_jwt_for_dist( jwt: str, asf_uid: str, phase: TrustedProjectPhase, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> tuple[dict[str, Any], str, sql.Project, sql.Release]: payload, asf_uid_from_jwt = await validate_trusted_jwt(publisher, jwt) if asf_uid_from_jwt is not None: diff --git a/atr/get/announce.py b/atr/get/announce.py index 5054f68d..8035b927 100644 --- a/atr/get/announce.py +++ b/atr/get/announce.py @@ -40,8 +40,8 @@ import atr.web as web async def selected( session: web.Committer, _announce: Literal["announce"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str | web.WerkzeugResponse: """ URL: /announce/<project_name>/<version_name> @@ -111,7 +111,7 @@ async def selected( async def _get_page_data( - session: web.Committer, project_name: safe.ProjectName, version_name: safe.VersionName + session: web.Committer, project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> sql.Release: release = await session.release( project_name, diff --git a/atr/get/checklist.py b/atr/get/checklist.py index d5ba2e3c..087a1573 100644 --- a/atr/get/checklist.py +++ b/atr/get/checklist.py @@ -37,8 +37,8 @@ import atr.web as web async def selected( _session: web.Public, _checklist: Literal["checklist"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: async with db.session() as data: release = await data.release( diff --git a/atr/get/checks.py b/atr/get/checks.py index 52ef3a6d..b601d808 100644 --- a/atr/get/checks.py +++ b/atr/get/checks.py @@ -100,7 +100,7 @@ async def get_file_totals(release: sql.Release, session: web.Committer | None) - @get.typed async def selected( - session: web.Public, _checks: Literal["checks"], project_name: safe.ProjectName, version_name: safe.VersionName + session: web.Public, _checks: Literal["checks"], project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> str: """ URL: /checks/<project_name>/<version_name> @@ -144,8 +144,8 @@ async def selected( async def selected_revision( session: web.Committer, _checks: Literal["checks"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, ) -> web.QuartResponse: """ diff --git a/atr/get/compose.py b/atr/get/compose.py index 38d2e1fb..28b329cc 100644 --- a/atr/get/compose.py +++ b/atr/get/compose.py @@ -32,8 +32,8 @@ import atr.web as web async def selected( session: web.Committer, _compose: Literal["compose"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse | str: """ URL: /compose/<project_name>/<version_name> diff --git a/atr/get/distribution.py b/atr/get/distribution.py index a8742e58..fae6eed2 100644 --- a/atr/get/distribution.py +++ b/atr/get/distribution.py @@ -39,8 +39,8 @@ from atr.tasks import gha async def automate( session: web.Committer, _distribution: Literal["distribution/automate"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /distribution/automate/<project_name>/<version> @@ -53,8 +53,8 @@ async def automate( async def list_get( _session: web.Committer, _distribution: Literal["distribution/list"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /distribution/list/<project_name>/<version_name> @@ -147,8 +147,8 @@ async def list_get( async def record( session: web.Committer, _distribution: Literal["distribution/record"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /distribution/record/<project_name>/<version_name> @@ -161,8 +161,8 @@ async def record( async def stage_automate( session: web.Committer, _distribution: Literal["distribution/stage/automate"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /distribution/stage/automate/<project_name>/<version_name> @@ -175,8 +175,8 @@ async def stage_automate( async def stage_record( session: web.Committer, _distribution: Literal["distribution/stage/record"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /distribution/stage/record/<project_name>/<version_name> @@ -185,7 +185,7 @@ async def stage_record( return await _record_form_page(project_name, version_name, staging=True) -async def _automate_form_page(project: safe.ProjectName, version: safe.VersionName, staging: bool) -> str: +async def _automate_form_page(project: safe.ProjectKey, version: safe.VersionKey, staging: bool) -> str: """Helper to render the distribution automation form page.""" await shared.distribution.release_validated(project, version, staging=staging) @@ -228,7 +228,7 @@ async def _automate_form_page(project: safe.ProjectName, version: safe.VersionNa async def _get_page_data( - project_name: safe.ProjectName, version_name: safe.VersionName + project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> tuple[Sequence[sql.Distribution], Sequence[sql.Task]]: """Get all the data needed to render the finish page.""" async with db.session() as data: @@ -261,7 +261,7 @@ async def _get_page_data( return distributions, tasks -async def _record_form_page(project: safe.ProjectName, version: safe.VersionName, staging: bool) -> str: +async def _record_form_page(project: safe.ProjectKey, version: safe.VersionKey, staging: bool) -> str: """Helper to render the distribution recording form page.""" await shared.distribution.release_validated(project, version, staging=staging) @@ -304,7 +304,7 @@ async def _record_form_page(project: safe.ProjectName, version: safe.VersionName def _render_distribution_tasks( - tasks: Sequence[sql.Task], block: htm.Block, project_name: safe.ProjectName, version_name: safe.VersionName + tasks: Sequence[sql.Task], block: htm.Block, project_name: safe.ProjectKey, version_name: safe.VersionKey ): failed_tasks = [ t for t in tasks if (t.status == sql.TaskStatus.FAILED) or (t.workflow and (t.workflow.status == "failed")) diff --git a/atr/get/download.py b/atr/get/download.py index 801adcd7..97f4419c 100644 --- a/atr/get/download.py +++ b/atr/get/download.py @@ -44,8 +44,8 @@ import atr.web as web async def all_selected( session: web.Committer, _download_all: Literal["download/all"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse | str: """ URL: /download/all/<project_name>/<version_name> @@ -83,8 +83,8 @@ async def all_selected( async def path( _session: web.Public, _download_path: Literal["download/path"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, ) -> web.Response: """ @@ -98,8 +98,8 @@ async def path( async def path_empty( _session: web.Public, _download_path: Literal["download/path"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.Response: """ URL: /download/path/<project_name>/<version_name>/ @@ -112,8 +112,8 @@ async def path_empty( async def sh_selected( _session: web.Public, _download_sh: Literal["download/sh"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.Response: """ URL: /download/sh/<project_name>/<version_name> @@ -137,8 +137,8 @@ async def sh_selected( async def urls_selected( _session: web.Public, _download_urls: Literal["download/urls"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.Response: """ URL: /download/urls/<project_name>/<version_name> @@ -160,8 +160,8 @@ async def urls_selected( async def zip_selected( session: web.Committer, _download_zip: Literal["download/zip"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.Response: """ URL: /download/zip/<project_name>/<version_name> @@ -196,7 +196,7 @@ async def zip_selected( async def _download_or_list( - project_name: safe.ProjectName, version_name: safe.VersionName, file_path: str + project_name: safe.ProjectKey, version_name: safe.VersionKey, file_path: str ) -> web.Response: """Download a file or list a directory from a release in any phase.""" import atr.get.root as root diff --git a/atr/get/draft.py b/atr/get/draft.py index 64a5a94a..e565fbf4 100644 --- a/atr/get/draft.py +++ b/atr/get/draft.py @@ -39,8 +39,8 @@ import atr.web as web async def tools( session: web.Committer, _draft_tools: Literal["draft/tools"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, ) -> str: """ diff --git a/atr/get/file.py b/atr/get/file.py index 2cad45f1..9e9f56e8 100644 --- a/atr/get/file.py +++ b/atr/get/file.py @@ -39,8 +39,8 @@ type Phase = Literal["COMPOSE", "VOTE", "FINISH"] async def selected( session: web.Committer, _file: Literal["file"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /file/<project_name>/<version_name> @@ -141,8 +141,8 @@ async def selected( async def selected_path( session: web.Committer, _file: Literal["file"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, ) -> str: """ diff --git a/atr/get/finish.py b/atr/get/finish.py index 3690c739..13e1ac43 100644 --- a/atr/get/finish.py +++ b/atr/get/finish.py @@ -62,8 +62,8 @@ class RCTagAnalysisResult: async def selected( session: web.Committer, _finish: Literal["finish"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str: """ URL: /finish/<project_name>/<version_name> @@ -155,7 +155,7 @@ async def _deletable_choices( async def _get_page_data( - project_name: safe.ProjectName, version_name: safe.VersionName + project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> tuple[ sql.Release, list[pathlib.Path], set[pathlib.Path], list[tuple[str, str]], RCTagAnalysisResult, Sequence[sql.Task] ]: diff --git a/atr/get/ignores.py b/atr/get/ignores.py index fd07bd53..9e70d464 100644 --- a/atr/get/ignores.py +++ b/atr/get/ignores.py @@ -34,7 +34,7 @@ import atr.web as web async def ignores( session: web.Committer, _ignores: Literal["ignores"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> str | web.WerkzeugResponse: """ URL: /ignores/<project_name> diff --git a/atr/get/manual.py b/atr/get/manual.py index e9ba1162..61e8d47a 100644 --- a/atr/get/manual.py +++ b/atr/get/manual.py @@ -38,8 +38,8 @@ import atr.web as web async def resolve_selected( session: web.Committer, _manual_resolve: Literal["manual/resolve"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /manual/resolve/<project_name>/<version_name> @@ -69,8 +69,8 @@ async def resolve_selected( async def start_selected_revision( session: web.Committer, _manual_start: Literal["manual/start"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, ) -> web.WerkzeugResponse | str: """ diff --git a/atr/get/projects.py b/atr/get/projects.py index 20cb2a77..63cc2c7a 100644 --- a/atr/get/projects.py +++ b/atr/get/projects.py @@ -149,7 +149,7 @@ async def select(session: web.Committer, _project_select: Literal["project/selec @get.typed async def view( - session: web.Committer, _projects: Literal["projects"], project_name: safe.ProjectName + session: web.Committer, _projects: Literal["projects"], project_name: safe.ProjectKey ) -> web.WerkzeugResponse | str: """ URL: /projects/<project_name> diff --git a/atr/get/release.py b/atr/get/release.py index cf610872..bb031be1 100644 --- a/atr/get/release.py +++ b/atr/get/release.py @@ -32,7 +32,7 @@ import atr.web as web @get.typed async def finished( - _session: web.Public, _releases_finished: Literal["releases/finished"], project_name: safe.ProjectName + _session: web.Public, _releases_finished: Literal["releases/finished"], project_name: safe.ProjectKey ) -> str: """ URL: /releases/finished/<project_name> @@ -89,7 +89,7 @@ async def releases(_session: web.Public, _releases: Literal["releases"]) -> str: @get.typed async def select( - session: web.Committer, _release_select: Literal["release/select"], project_name: safe.ProjectName + session: web.Committer, _release_select: Literal["release/select"], project_name: safe.ProjectKey ) -> str: """ URL: /release/select/<project_name> diff --git a/atr/get/report.py b/atr/get/report.py index 15d81be6..e074afe9 100644 --- a/atr/get/report.py +++ b/atr/get/report.py @@ -37,8 +37,8 @@ import atr.web as web async def selected_path( session: web.Committer, _report: Literal["report"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, rel_path: unsafe.Path, ) -> str: """ diff --git a/atr/get/result.py b/atr/get/result.py index eaf52f8a..7c82a889 100644 --- a/atr/get/result.py +++ b/atr/get/result.py @@ -31,8 +31,8 @@ import atr.web as web async def data( session: web.Committer, _result_data: Literal["result/data"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, check_id: int, ) -> web.TextResponse: """ diff --git a/atr/get/revisions.py b/atr/get/revisions.py index c75e93bc..8fddc451 100644 --- a/atr/get/revisions.py +++ b/atr/get/revisions.py @@ -53,8 +53,8 @@ class FilesDiff(schema.Strict): async def selected( session: web.Committer, _revisions: Literal["revisions"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /revisions/<project_name>/<version_name> diff --git a/atr/get/sbom.py b/atr/get/sbom.py index a8ef42cc..986bd2a5 100644 --- a/atr/get/sbom.py +++ b/atr/get/sbom.py @@ -49,8 +49,8 @@ if TYPE_CHECKING: async def report( session: web.Committer, _sbom_report: Literal["sbom/report"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, ) -> str: """ @@ -245,7 +245,7 @@ def _extract_vulnerability_severity(vuln: results.VulnerabilityDetails) -> str: async def _fetch_tasks( - file_path: str, project: safe.ProjectName, release: sql.Release, version: safe.VersionName + file_path: str, project: safe.ProjectKey, release: sql.Release, version: safe.VersionKey ) -> tuple[sql.Task | None, Sequence[sql.Task], Sequence[sql.Task]]: # TODO: Abstract this code and the sbomtool.MissingAdapter validators async with db.session() as data: diff --git a/atr/get/start.py b/atr/get/start.py index 7e33a0fb..7150db9a 100644 --- a/atr/get/start.py +++ b/atr/get/start.py @@ -35,7 +35,7 @@ import atr.web as web @get.typed -async def selected(session: web.Committer, _start: Literal["start"], project_name: safe.ProjectName) -> str: +async def selected(session: web.Committer, _start: Literal["start"], project_name: safe.ProjectKey) -> str: """ URL: /start/<project_name> """ diff --git a/atr/get/test.py b/atr/get/test.py index a8075c23..88d4f5c9 100644 --- a/atr/get/test.py +++ b/atr/get/test.py @@ -89,8 +89,8 @@ async def test_login(_session: web.Public, _test_login: Literal["test/login"]) - async def test_merge( session: web.Committer, _test_merge: Literal["test/merge"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: """ URL: /test/merge/<project_name>/<version_name> @@ -206,8 +206,8 @@ async def test_vote( session: web.Public, _test_vote: Literal["test/vote"], category: unsafe.UnsafeStr, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /test/vote/<category>/<project_name>/<version_name> diff --git a/atr/get/upload.py b/atr/get/upload.py index 3ff14a15..823fb901 100644 --- a/atr/get/upload.py +++ b/atr/get/upload.py @@ -41,8 +41,8 @@ import atr.web as web async def selected( session: web.Committer, _upload: Literal["upload"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> str: """ URL: /upload/<project_name>/<version_name> diff --git a/atr/get/vote.py b/atr/get/vote.py index 7adc5aaf..24fe552c 100644 --- a/atr/get/vote.py +++ b/atr/get/vote.py @@ -59,7 +59,7 @@ class UserCategory(enum.StrEnum): async def category_and_release( - session: web.Committer | None, project_name: safe.ProjectName, version_name: safe.VersionName + session: web.Committer | None, project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> tuple[UserCategory, sql.Release, sql.Task | None]: async with db.session() as data: release = await data.release( @@ -176,8 +176,8 @@ async def render_vote_closed_page(release: sql.Release) -> str: async def selected( session: web.Public, _vote: Literal["vote"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse | str: """ URL: /vote/<project_name>/<version_name> diff --git a/atr/get/voting.py b/atr/get/voting.py index 90db36ff..ad0c1de1 100644 --- a/atr/get/voting.py +++ b/atr/get/voting.py @@ -45,8 +45,8 @@ import atr.web as web async def selected_revision( session: web.Committer, _voting: Literal["voting"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, ) -> web.WerkzeugResponse | str: """ diff --git a/atr/merge.py b/atr/merge.py index 84e7a050..0e108fb3 100644 --- a/atr/merge.py +++ b/atr/merge.py @@ -36,8 +36,8 @@ async def merge( base_inodes: dict[str, int], base_hashes: dict[str, str], prior_dir: pathlib.Path, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, prior_revision_number: safe.RevisionNumber, temp_dir: pathlib.Path, n_inodes: dict[str, int], @@ -120,8 +120,8 @@ async def _add_from_prior( n_hashes: dict[str, str], n_sizes: dict[str, int], prior_hashes: dict[str, str] | None, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, prior_revision_number: safe.RevisionNumber, ) -> dict[str, str] | None: target = temp_dir / path @@ -177,8 +177,8 @@ async def _merge_all_present( n_hashes: dict[str, str], n_sizes: dict[str, int], prior_hashes: dict[str, str] | None, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, prior_revision_number: safe.RevisionNumber, ) -> dict[str, str] | None: # Cases 6, 8: prior and new share an inode so they already agree @@ -238,8 +238,8 @@ async def _replace_with_prior( n_hashes: dict[str, str], n_sizes: dict[str, int], prior_hashes: dict[str, str] | None, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, prior_revision_number: safe.RevisionNumber, ) -> dict[str, str] | None: await aiofiles.os.remove(temp_dir / path) diff --git a/atr/models/api.py b/atr/models/api.py index 514a7f6d..3c38ec3d 100644 --- a/atr/models/api.py +++ b/atr/models/api.py @@ -73,14 +73,14 @@ class DistributeSshRegisterArgs(schema.Strict): ssh_key: str = schema.example("ssh-ed25519 AAAAC3NzaC1lZDI1NTEgH5C9okWi0dh25AAAAIOMqqnkVzrm0SdG6UOoqKLsabl9GKJl") phase: str = schema.Field(strict=False, default="compose", json_schema_extra={"examples": ["compose", "finish"]}) asf_uid: str = schema.example("user") - project_name: safe.ProjectName = schema.example("tooling") - version: safe.VersionName = schema.example("0.0.1") + project_name: safe.ProjectKey = schema.example("tooling") + version: safe.VersionKey = schema.example("0.0.1") class DistributeSshRegisterResults(schema.Strict): endpoint: Literal["/distribute/ssh/register"] = schema.alias("endpoint") fingerprint: str = schema.example("SHA256:0123456789abcdef0123456789abcdef01234567") - project: safe.ProjectName = schema.example("example") + project: safe.ProjectKey = schema.example("example") expires: int = schema.example(1713547200) @@ -89,7 +89,7 @@ class DistributeStatusUpdateArgs(schema.Strict): jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=") workflow: str = schema.description("Workflow name") run_id: str = schema.description("Workflow run ID") - project_name: safe.ProjectName = schema.description("Project name in ATR") + project_name: safe.ProjectKey = schema.description("Project name in ATR") status: str = schema.description("Workflow status") message: str = schema.description("Workflow message") @@ -100,12 +100,12 @@ class DistributeStatusUpdateResults(schema.Strict): class DistributionRecordArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") platform: sql.DistributionPlatform = schema.example(sql.DistributionPlatform.ARTIFACT_HUB) distribution_owner_namespace: safe.Alphanumeric | None = schema.default_example(None, "example") distribution_package: safe.Alphanumeric = schema.example("example") - distribution_version: safe.VersionName = schema.example("0.0.1") + distribution_version: safe.VersionKey = schema.example("0.0.1") staging: bool = schema.example(False) details: bool = schema.example(False) @@ -128,12 +128,12 @@ class DistributionRecordFromWorkflowArgs(schema.Strict): asf_uid: str = schema.example("user") publisher: str = schema.example("user") jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=") - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") platform: sql.DistributionPlatform = schema.example(sql.DistributionPlatform.ARTIFACT_HUB) distribution_owner_namespace: safe.Alphanumeric | None = schema.default_example(None, "example") distribution_package: safe.Alphanumeric = schema.example("example") - distribution_version: safe.VersionName = schema.example("0.0.1") + distribution_version: safe.VersionKey = schema.example("0.0.1") phase: str = schema.Field(strict=False, default="compose", json_schema_extra={"examples": ["compose", "finish"]}) staging: bool = schema.example(False) details: bool = schema.example(False) @@ -164,7 +164,7 @@ class DistributionRecordResults(schema.Strict): class IgnoreAddArgs(schema.Strict): - project_name: safe.ProjectName = schema.example("example") + project_name: safe.ProjectKey = schema.example("example") release_glob: str | None = schema.default_example(None, "example-0.0.*") revision_number: safe.RevisionNumber | None = schema.default_example(None, "00001") checker_glob: str | None = schema.default_example(None, "atr.tasks.checks.license.files") @@ -194,7 +194,7 @@ class IgnoreAddResults(schema.Strict): class IgnoreDeleteArgs(schema.Strict): - project_name: safe.ProjectName = schema.example("example") + project_name: safe.ProjectKey = schema.example("example") id: int = schema.example(1) @@ -289,7 +289,7 @@ class ProjectGetResults(schema.Strict): class ProjectPolicyResults(schema.Strict): endpoint: Literal["/project/policy"] = schema.alias("endpoint") - project_name: safe.ProjectName + project_name: safe.ProjectKey policy_announce_release_subject: str policy_announce_release_template: str policy_binary_artifact_paths: list[str] @@ -325,11 +325,11 @@ class ProjectsListResults(schema.Strict): class PublisherDistributionRecordArgs(schema.Strict): publisher: str = schema.example("user") jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=") - version: safe.VersionName = schema.example("0.0.1") + version: safe.VersionKey = schema.example("0.0.1") platform: sql.DistributionPlatform = schema.example(sql.DistributionPlatform.ARTIFACT_HUB) distribution_owner_namespace: safe.Alphanumeric | None = schema.default_example(None, "example") distribution_package: safe.Alphanumeric = schema.example("example") - distribution_version: safe.VersionName = schema.example("0.0.1") + distribution_version: safe.VersionKey = schema.example("0.0.1") staging: bool = schema.example(False) details: bool = schema.example(False) @@ -356,7 +356,7 @@ class PublisherDistributionRecordResults(schema.Strict): class PublisherReleaseAnnounceArgs(schema.Strict): publisher: str = schema.example("user") jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=") - version: safe.VersionName = schema.example("0.0.1") + version: safe.VersionKey = schema.example("0.0.1") revision: safe.RevisionNumber = schema.example("00005") email_to: str = schema.example("[email protected]") body: str = schema.example("The Apache Example team is pleased to announce the release of Example 1.0.0...") @@ -377,14 +377,14 @@ class PublisherSshRegisterArgs(schema.Strict): class PublisherSshRegisterResults(schema.Strict): endpoint: Literal["/publisher/ssh/register"] = schema.alias("endpoint") fingerprint: str = schema.example("SHA256:0123456789abcdef0123456789abcdef01234567") - project: safe.ProjectName = schema.example("example") + project: safe.ProjectKey = schema.example("example") expires: int = schema.example(1713547200) class PublisherVoteResolveArgs(schema.Strict): publisher: str = schema.example("user") jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=") - version: safe.VersionName = schema.example("0.0.1") + version: safe.VersionKey = schema.example("0.0.1") resolution: Literal["passed", "failed"] = schema.example("passed") @@ -394,8 +394,8 @@ class PublisherVoteResolveResults(schema.Strict): class ReleaseAnnounceArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("1.0.0") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("1.0.0") revision: safe.RevisionNumber = schema.example("00005") email_to: str = schema.example("[email protected]") body: str = schema.example("The Apache Example team is pleased to announce the release of Example 1.0.0...") @@ -408,8 +408,8 @@ class ReleaseAnnounceResults(schema.Strict): class ReleaseDraftDeleteArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") class ReleaseDraftDeleteResults(schema.Strict): @@ -418,8 +418,8 @@ class ReleaseDraftDeleteResults(schema.Strict): class ReleaseCreateArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") class ReleaseCreateResults(schema.Strict): @@ -428,8 +428,8 @@ class ReleaseCreateResults(schema.Strict): class ReleaseDeleteArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") class ReleaseDeleteResults(schema.Strict): @@ -466,8 +466,8 @@ class ReleaseRevisionsResults(schema.Strict): class ReleaseUploadArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") relpath: str = schema.example("example/0.0.1/example-0.0.1-bin.tar.gz") content: str = schema.example("This is the content of the file.") @@ -568,8 +568,8 @@ class UsersListResults(schema.Strict): class VoteResolveArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") resolution: Literal["passed", "failed"] = schema.example("passed") @@ -579,8 +579,8 @@ class VoteResolveResults(schema.Strict): class VoteStartArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") revision: safe.RevisionNumber = schema.example("00005") email_to: str = schema.example("[email protected]") vote_duration: int = schema.example(10) @@ -594,8 +594,8 @@ class VoteStartResults(schema.Strict): class VoteTabulateArgs(schema.Strict): - project: safe.ProjectName = schema.example("example") - version: safe.VersionName = schema.example("0.0.1") + project: safe.ProjectKey = schema.example("example") + version: safe.VersionKey = schema.example("0.0.1") class VoteTabulateResults(schema.Strict): diff --git a/atr/models/distribution.py b/atr/models/distribution.py index 7e5f3149..c805a894 100644 --- a/atr/models/distribution.py +++ b/atr/models/distribution.py @@ -95,7 +95,7 @@ class Data(schema.Subset): platform: sql.DistributionPlatform owner_namespace: safe.Alphanumeric | None = None package: safe.Alphanumeric - version: safe.VersionName + version: safe.VersionKey details: bool @pydantic.field_validator("owner_namespace", mode="before") diff --git a/atr/models/safe.py b/atr/models/safe.py index e72cfb21..a69750dd 100644 --- a/atr/models/safe.py +++ b/atr/models/safe.py @@ -102,12 +102,12 @@ class Numeric(SafeType): return _NUMERIC -class ProjectName(Alphanumeric): +class ProjectKey(Alphanumeric): """A project name that has been validated for safety.""" -class ReleaseName(Alphanumeric): - """A release name composed from a validated ProjectName and VersionName.""" +class ReleaseKey(Alphanumeric): + """A release name composed from a validated ProjectKey and VersionKey.""" @classmethod def _valid_chars(cls) -> frozenset[str]: @@ -118,7 +118,7 @@ class RevisionNumber(Numeric): """A revision number that has been validated for safety.""" -class VersionName(Alphanumeric): +class VersionKey(Alphanumeric): """A version name that has been validated for safety""" @classmethod diff --git a/atr/models/sql.py b/atr/models/sql.py index d583b363..d2767bd2 100644 --- a/atr/models/sql.py +++ b/atr/models/sql.py @@ -613,9 +613,9 @@ class Project(sqlmodel.SQLModel, table=True): return base @property - def safe_name(self) -> safe.ProjectName: + def safe_name(self) -> safe.ProjectKey: """Get the typesafe validated name for the Project""" - return safe.ProjectName(self.name) + return safe.ProjectKey(self.name) @property def short_display_name(self) -> str: @@ -942,19 +942,19 @@ class Release(sqlmodel.SQLModel, table=True): return safe.RevisionNumber(self.unwrap_revision_number) @property - def safe_name(self) -> safe.ReleaseName: + def safe_name(self) -> safe.ReleaseKey: """Get the typesafe validated name for the Release""" - return safe.ReleaseName(self.name) + return safe.ReleaseKey(self.name) @property - def safe_project_name(self) -> safe.ProjectName: + def safe_project_name(self) -> safe.ProjectKey: """Get the typesafe validated name for the release project""" - return safe.ProjectName(self.project_name) + return safe.ProjectKey(self.project_name) @property - def safe_version_name(self) -> safe.VersionName: + def safe_version_name(self) -> safe.VersionKey: """Get the typesafe validated name for the release version""" - return safe.VersionName(self.version) + return safe.VersionKey(self.version) @property def short_display_name(self) -> str: @@ -1087,7 +1087,7 @@ class Distribution(sqlmodel.SQLModel, table=True): platform=self.platform, owner_namespace=safe.Alphanumeric(self.owner_namespace), package=safe.Alphanumeric(self.package), - version=safe.VersionName(self.version), + version=safe.VersionKey(self.version), details=details, ) @@ -1102,9 +1102,9 @@ class Distribution(sqlmodel.SQLModel, table=True): return f"{name}-{package}-{version}" @property - def safe_release_name(self) -> safe.ReleaseName: + def safe_release_name(self) -> safe.ReleaseKey: """Get the typesafe validated name for the distribution release""" - return safe.ReleaseName(self.release_name) + return safe.ReleaseKey(self.release_name) @property def title(self) -> str: @@ -1409,7 +1409,7 @@ class WorkflowStatus(sqlmodel.SQLModel, table=True): message: str | None = sqlmodel.Field(default=None) -def revision_name(release_name: safe.ReleaseName | str, number: str) -> str: +def revision_name(release_name: safe.ReleaseKey | str, number: str) -> str: return f"{release_name} {number}" @@ -1481,18 +1481,18 @@ def latest_revision_number_query(release_name: str | None = None) -> expression. @overload -def release_name(project_name: safe.ProjectName, version_name: safe.VersionName) -> safe.ReleaseName: ... +def release_name(project_name: safe.ProjectKey, version_name: safe.VersionKey) -> safe.ReleaseKey: ... @overload def release_name(project_name: str, version_name: str) -> str: ... -def release_name(project_name: safe.ProjectName | str, version_name: safe.VersionName | str) -> safe.ReleaseName | str: +def release_name(project_name: safe.ProjectKey | str, version_name: safe.VersionKey | str) -> safe.ReleaseKey | str: """Return the release name for a given project and version.""" name = f"{project_name}-{version_name}" - if isinstance(project_name, safe.ProjectName) and isinstance(version_name, safe.VersionName): - return safe.ReleaseName(name) + if isinstance(project_name, safe.ProjectKey) and isinstance(version_name, safe.VersionKey): + return safe.ReleaseKey(name) return name diff --git a/atr/paths.py b/atr/paths.py index 38ced9e8..b19dae61 100644 --- a/atr/paths.py +++ b/atr/paths.py @@ -23,7 +23,7 @@ import atr.models.sql as sql def base_path_for_revision( - project_name: safe.ProjectName, version_name: safe.VersionName, revision: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision: safe.RevisionNumber ) -> pathlib.Path: return pathlib.Path(get_unfinished_dir(), str(project_name), str(version_name), str(revision)) @@ -135,6 +135,6 @@ def release_directory_version(release: sql.Release) -> pathlib.Path: def revision_path_for_file( - project_name: safe.ProjectName, version_name: safe.VersionName, revision: safe.RevisionNumber, file_name: str + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision: safe.RevisionNumber, file_name: str ) -> pathlib.Path: return base_path_for_revision(project_name, version_name, revision) / file_name diff --git a/atr/post/announce.py b/atr/post/announce.py index 23ea535f..a65f47f9 100644 --- a/atr/post/announce.py +++ b/atr/post/announce.py @@ -34,8 +34,8 @@ import atr.web as web async def selected( session: web.Committer, _announce: Literal["announce"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, announce_form: shared.announce.AnnounceForm, ) -> web.WerkzeugResponse: """ diff --git a/atr/post/distribution.py b/atr/post/distribution.py index 5680c02f..d58633b8 100644 --- a/atr/post/distribution.py +++ b/atr/post/distribution.py @@ -41,8 +41,8 @@ _AUTOMATED_PLATFORMS_STAGE: Final[tuple[shared.distribution.DistributionPlatform async def automate_form_process_page( session: web.Committer, form_data: shared.distribution.DistributionAutomateForm, - project: safe.ProjectName, - version: safe.VersionName, + project: safe.ProjectKey, + version: safe.VersionKey, /, staging: bool = False, ) -> web.WerkzeugResponse: @@ -112,8 +112,8 @@ async def automate_form_process_page( async def automate_selected( session: web.Committer, _distribution_automate: Literal["distribution/automate"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, distribute_form: shared.distribution.DistributionAutomateForm, ) -> web.WerkzeugResponse: """ @@ -127,8 +127,8 @@ async def automate_selected( async def delete( session: web.Committer, _distribution_delete: Literal["distribution/delete"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, delete_form: shared.distribution.DeleteForm, ) -> web.WerkzeugResponse: """ @@ -170,8 +170,8 @@ async def delete( async def record_form_process_page( session: web.Committer, form_data: shared.distribution.DistributionRecordForm, - project: safe.ProjectName, - version: safe.VersionName, + project: safe.ProjectKey, + version: safe.VersionKey, /, staging: bool = False, ) -> web.WerkzeugResponse: @@ -220,8 +220,8 @@ async def record_form_process_page( async def record_selected( session: web.Committer, _distribution_record: Literal["distribution/record"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, distribute_form: shared.distribution.DistributionRecordForm, ) -> web.WerkzeugResponse: """ @@ -234,8 +234,8 @@ async def record_selected( async def stage_automate_selected( session: web.Committer, _distribution_stage_automate: Literal["distribution/stage/automate"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, distribute_form: shared.distribution.DistributionAutomateForm, ) -> web.WerkzeugResponse: """ @@ -248,8 +248,8 @@ async def stage_automate_selected( async def stage_record_selected( session: web.Committer, _distribution_stage_record: Literal["distribution/stage/record"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, distribute_form: shared.distribution.DistributionRecordForm, ) -> web.WerkzeugResponse: """ diff --git a/atr/post/draft.py b/atr/post/draft.py index dcfa6add..afbe408f 100644 --- a/atr/post/draft.py +++ b/atr/post/draft.py @@ -44,8 +44,8 @@ if TYPE_CHECKING: async def cache_reset( session: web.Committer, _draft_reset: Literal["draft/reset"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, _form: form.Empty, ) -> web.WerkzeugResponse: """ @@ -81,8 +81,8 @@ async def cache_reset( async def delete( session: web.Committer, _compose: Literal["compose"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, _form: form.Empty, ) -> web.WerkzeugResponse: """ @@ -112,8 +112,8 @@ async def delete( async def delete_file( session: web.Committer, _draft_delete_file: Literal["draft/delete-file"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, delete_file_form: shared.draft.DeleteFileForm, ) -> web.WerkzeugResponse: """ @@ -150,8 +150,8 @@ async def delete_file( async def hashgen( session: web.Committer, _draft_hashgen: Literal["draft/hashgen"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, empty_form: form.Empty, ) -> web.WerkzeugResponse: @@ -190,8 +190,8 @@ async def hashgen( async def quarantine_clear( session: web.Committer, _draft_quarantine_clear: Literal["draft/quarantine/clear"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, clear_form: shared.draft.ClearQuarantineForm, ) -> web.WerkzeugResponse: """URL: /draft/quarantine/clear/<project_name>/<version_name>""" @@ -211,8 +211,8 @@ async def quarantine_clear( async def recheck( session: web.Committer, _draft_recheck: Literal["draft/recheck"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, empty_form: form.Empty, ) -> web.WerkzeugResponse: """ @@ -248,8 +248,8 @@ async def recheck( async def sbomgen( session: web.Committer, _draft_sbomgen: Literal["draft/sbomgen"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, empty_form: form.Empty, ) -> web.WerkzeugResponse: diff --git a/atr/post/finish.py b/atr/post/finish.py index 74c26a13..115ad85b 100644 --- a/atr/post/finish.py +++ b/atr/post/finish.py @@ -32,8 +32,8 @@ import atr.web as web async def selected( session: web.Committer, _finish: Literal["finish"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, finish_form: shared.finish.FinishForm, ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse: """ @@ -54,8 +54,8 @@ async def selected( async def _delete_empty_directory( delete_form: shared.finish.DeleteEmptyDirectoryForm, session: web.Committer, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, respond: shared.finish.Respond, ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse: dir_to_delete_rel = delete_form.directory_to_delete @@ -77,8 +77,8 @@ async def _delete_empty_directory( async def _move_file_to_revision( move_form: shared.finish.MoveFileForm, session: web.Committer, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, respond: shared.finish.Respond, ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse: source_files_rel = move_form.source_files @@ -122,8 +122,8 @@ async def _move_file_to_revision( async def _remove_rc_tags( session: web.Committer, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, respond: shared.finish.Respond, ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse: try: @@ -154,7 +154,7 @@ async def _remove_rc_tags( def _respond_helper( - session: web.Committer, project_name: safe.ProjectName, version_name: safe.VersionName, wants_json: bool + session: web.Committer, project_name: safe.ProjectKey, version_name: safe.VersionKey, wants_json: bool ) -> shared.finish.Respond: """Create a response helper function for the finish route.""" import atr.get as get diff --git a/atr/post/ignores.py b/atr/post/ignores.py index 92f37734..e5384eec 100644 --- a/atr/post/ignores.py +++ b/atr/post/ignores.py @@ -30,7 +30,7 @@ import atr.web as web async def ignores( session: web.Committer, _ignores: Literal["ignores"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ignore_form: shared.ignores.IgnoreForm, ) -> web.WerkzeugResponse: """ @@ -50,7 +50,7 @@ async def ignores( async def _add_ignore( - session: web.Committer, add_form: shared.ignores.AddIgnoreForm, project_name: safe.ProjectName + session: web.Committer, add_form: shared.ignores.AddIgnoreForm, project_name: safe.ProjectKey ) -> web.WerkzeugResponse: """Add a new ignore.""" status = shared.ignores.ignore_status_to_sql(add_form.status) # pyright: ignore[reportArgumentType] @@ -76,7 +76,7 @@ async def _add_ignore( async def _delete_ignore( - session: web.Committer, delete_form: shared.ignores.DeleteIgnoreForm, project_name: safe.ProjectName + session: web.Committer, delete_form: shared.ignores.DeleteIgnoreForm, project_name: safe.ProjectKey ) -> web.WerkzeugResponse: """Delete an ignore.""" async with storage.write() as write: @@ -91,7 +91,7 @@ async def _delete_ignore( async def _update_ignore( - session: web.Committer, update_form: shared.ignores.UpdateIgnoreForm, project_name: safe.ProjectName + session: web.Committer, update_form: shared.ignores.UpdateIgnoreForm, project_name: safe.ProjectKey ) -> web.WerkzeugResponse: """Update an ignore.""" status = shared.ignores.ignore_status_to_sql(update_form.status) # pyright: ignore[reportArgumentType] diff --git a/atr/post/keys.py b/atr/post/keys.py index 92b678a3..478c4d72 100644 --- a/atr/post/keys.py +++ b/atr/post/keys.py @@ -146,8 +146,8 @@ async def details( async def import_selected_revision( session: web.Committer, _keys_import: Literal["keys/import"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, _form: form.Empty, ) -> web.WerkzeugResponse: """ diff --git a/atr/post/manual.py b/atr/post/manual.py index 591b323d..2643518e 100644 --- a/atr/post/manual.py +++ b/atr/post/manual.py @@ -34,8 +34,8 @@ import atr.web as web async def resolve_selected( session: web.Committer, _manual_resolve: Literal["manual/resolve"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, resolve_vote_form: shared.manual.ResolveVoteForm, ) -> web.WerkzeugResponse | str: """ @@ -85,8 +85,8 @@ async def resolve_selected( async def start_selected_revision( session: web.Committer, _manual_start: Literal["manual/start"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, _form: form.Empty, ) -> web.WerkzeugResponse | str: diff --git a/atr/post/projects.py b/atr/post/projects.py index 9896834a..868db28c 100644 --- a/atr/post/projects.py +++ b/atr/post/projects.py @@ -47,7 +47,7 @@ async def add_project( label = project_form.label async with storage.write(session) as write: - wacm = await write.as_project_committee_member(safe.ProjectName(str(committee_name))) + wacm = await write.as_project_committee_member(safe.ProjectKey(str(committee_name))) try: await wacm.project.create(committee_name, display_name, label) except storage.AccessError as e: diff --git a/atr/post/resolve.py b/atr/post/resolve.py index dee53b50..ae7ae1af 100644 --- a/atr/post/resolve.py +++ b/atr/post/resolve.py @@ -37,8 +37,8 @@ import atr.web as web async def selected( session: web.Committer, _resolve: Literal["resolve"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, resolve_form: shared.resolve.ResolveForm, ) -> web.WerkzeugResponse | str: """ @@ -55,8 +55,8 @@ async def selected( async def _submit( session: web.Committer, submit_form: shared.resolve.SubmitForm, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: email_body = submit_form.email_body vote_result = submit_form.vote_result @@ -85,7 +85,7 @@ async def _submit( ) -async def _tabulate(session: web.Committer, project_name: safe.ProjectName, version_name: safe.VersionName) -> str: +async def _tabulate(session: web.Committer, project_name: safe.ProjectKey, version_name: safe.VersionKey) -> str: asf_uid = session.uid full_name = session.fullname diff --git a/atr/post/revisions.py b/atr/post/revisions.py index 1acd8d9c..992914a0 100644 --- a/atr/post/revisions.py +++ b/atr/post/revisions.py @@ -32,8 +32,8 @@ import atr.web as web async def selected_post( session: web.Committer, _revisions: Literal["revisions"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_form: shared.revisions.RevisionForm, ) -> web.WerkzeugResponse: """ @@ -49,8 +49,8 @@ async def selected_post( async def _set_revision( session: web.Committer, set_revision_form: shared.revisions.SetRevisionForm, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: """Set a specific revision as the latest for a candidate draft or release preview.""" selected_revision_number = set_revision_form.revision_number @@ -91,8 +91,8 @@ async def _set_revision( async def _set_tag( session: web.Committer, set_tag_form: shared.revisions.SetTagForm, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: """Set a tag on a specific revision.""" revision_number = set_tag_form.revision_number diff --git a/atr/post/sbom.py b/atr/post/sbom.py index d3aeb28b..8dcf1014 100644 --- a/atr/post/sbom.py +++ b/atr/post/sbom.py @@ -42,8 +42,8 @@ if TYPE_CHECKING: async def report( session: web.Committer, _sbom_report: Literal["sbom/report"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, file_path: unsafe.Path, sbom_form: shared.sbom.SBOMForm, ) -> web.WerkzeugResponse: @@ -64,7 +64,7 @@ async def report( async def _augment( - session: web.Committer, project_name: safe.ProjectName, version_name: safe.VersionName, rel_path: pathlib.Path + session: web.Committer, project_name: safe.ProjectKey, version_name: safe.VersionKey, rel_path: pathlib.Path ) -> web.WerkzeugResponse: """Augment a CycloneDX SBOM file.""" # Check that the file is a .cdx.json archive before creating a revision @@ -108,7 +108,7 @@ async def _augment( async def _scan( - session: web.Committer, project_name: safe.ProjectName, version_name: safe.VersionName, rel_path: pathlib.Path + session: web.Committer, project_name: safe.ProjectKey, version_name: safe.VersionKey, rel_path: pathlib.Path ) -> web.WerkzeugResponse: """Scan a CycloneDX SBOM file for vulnerabilities using OSV.""" if not (rel_path.name.endswith(".cdx.json")): diff --git a/atr/post/start.py b/atr/post/start.py index b4c7fcde..26af3d4c 100644 --- a/atr/post/start.py +++ b/atr/post/start.py @@ -31,7 +31,7 @@ import atr.web as web async def selected( session: web.Committer, _start: Literal["start"], - project_name: safe.ProjectName, + project_name: safe.ProjectKey, start_release_form: shared.start.StartReleaseForm, ) -> web.WerkzeugResponse: """ @@ -43,7 +43,7 @@ async def selected( wacp = await write.as_project_committee_participant(project_name) new_release, _project = await wacp.release.start( project_name, - safe.VersionName(start_release_form.version_name), + safe.VersionKey(start_release_form.version_name), ) return await session.redirect( diff --git a/atr/post/upload.py b/atr/post/upload.py index 9e914cdf..ba46aa2f 100644 --- a/atr/post/upload.py +++ b/atr/post/upload.py @@ -46,8 +46,8 @@ import atr.web as web async def finalise( session: web.Committer, _upload_finalise: Literal["upload/finalise"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, upload_session: unsafe.UnsafeStr, ) -> web.WerkzeugResponse: """ @@ -120,8 +120,8 @@ async def finalise( async def selected( session: web.Committer, _upload: Literal["upload"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, upload_form: shared.upload.UploadForm, ) -> web.WerkzeugResponse: """ @@ -140,8 +140,8 @@ async def selected( async def stage( _session: web.Committer, _upload_stage: Literal["upload/stage"], - _project_name: safe.ProjectName, - _version_name: safe.VersionName, + _project_name: safe.ProjectKey, + _version_name: safe.VersionKey, upload_session: unsafe.UnsafeStr, ) -> web.WerkzeugResponse: """ @@ -188,8 +188,8 @@ async def stage( async def _add_files( session: web.Committer, add_form: shared.upload.AddFilesForm, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: try: file_data = add_form.file_data @@ -251,8 +251,8 @@ def _json_success(data: dict[str, str], status: int = 200) -> web.WerkzeugRespon async def _svn_import( session: web.Committer, svn_form: shared.upload.SvnImportForm, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, ) -> web.WerkzeugResponse: # audit_guidance any file uploads are from known and managed repositories so file size is not an issue try: diff --git a/atr/post/vote.py b/atr/post/vote.py index b6d99c87..003f1bfb 100644 --- a/atr/post/vote.py +++ b/atr/post/vote.py @@ -32,8 +32,8 @@ import atr.web as web async def selected_post( session: web.Committer, _vote: Literal["vote"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, cast_vote_form: shared.vote.CastVoteForm, ) -> web.WerkzeugResponse: """ diff --git a/atr/post/voting.py b/atr/post/voting.py index cac23325..3a0ea8b5 100644 --- a/atr/post/voting.py +++ b/atr/post/voting.py @@ -41,8 +41,8 @@ class BodyPreviewForm(form.Form): async def body_preview( session: web.Committer, _voting_body_preview: Literal["voting/body/preview"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, preview_form: BodyPreviewForm, ) -> web.QuartResponse: @@ -70,8 +70,8 @@ async def body_preview( async def selected_revision( session: web.Committer, _voting: Literal["voting"], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision: safe.RevisionNumber, start_voting_form: shared.voting.StartVotingForm, ) -> web.WerkzeugResponse | str: diff --git a/atr/shared/distribution.py b/atr/shared/distribution.py index 922e02db..d83a8c44 100644 --- a/atr/shared/distribution.py +++ b/atr/shared/distribution.py @@ -115,7 +115,7 @@ class DistributionPlatform(enum.Enum): class DeleteForm(form.Form): - release_name: safe.ReleaseName = form.label("Release name", widget=form.Widget.HIDDEN) + release_name: safe.ReleaseKey = form.label("Release name", widget=form.Widget.HIDDEN) platform: form.Enum[DistributionPlatform] = form.label("Platform", widget=form.Widget.HIDDEN) owner_namespace: str = form.label("Owner namespace", widget=form.Widget.HIDDEN) package: str = form.label("Package", widget=form.Widget.HIDDEN) @@ -132,7 +132,7 @@ class DistributionAutomateForm(form.Form): "GitHub owner, ArtifactHub repo). Leave blank if not used.", ) package: safe.Alphanumeric = form.label("Package") - version: safe.VersionName = form.label("Version") + version: safe.VersionKey = form.label("Version") details: form.Bool = form.label( "Include details", "Include the details of the distribution in the response", @@ -165,7 +165,7 @@ class DistributionRecordForm(form.Form): "GitHub owner, ArtifactHub repo). Leave blank if not used.", ) package: safe.Alphanumeric = form.label("Package") - version: safe.VersionName = form.label("Version") + version: safe.VersionKey = form.label("Version") details: form.Bool = form.label( "Include details", "Include the details of the distribution in the response", @@ -193,7 +193,7 @@ class DistributionRecordForm(form.Form): def distribution_upload_date( # noqa: C901 platform: sql.DistributionPlatform, data: basic.JSON, - version_name: safe.VersionName, + version_name: safe.VersionKey, ) -> datetime.datetime | None: version = str(version_name) match platform: @@ -237,7 +237,7 @@ def distribution_upload_date( # noqa: C901 def distribution_web_url( # noqa: C901 platform: sql.DistributionPlatform, data: basic.JSON, - version: safe.VersionName, + version: safe.VersionKey, ) -> str | None: match platform: case sql.DistributionPlatform.ARTIFACT_HUB: @@ -319,7 +319,7 @@ def html_tr_a(label: str, value: str | None) -> htm.Element: async def json_from_distribution_platform( - api_url: str, platform: sql.DistributionPlatform, version_name: safe.VersionName + api_url: str, platform: sql.DistributionPlatform, version_name: safe.VersionKey ) -> outcome.Outcome[basic.JSON]: version = str(version_name) try: @@ -338,7 +338,7 @@ async def json_from_distribution_platform( return outcome.Result(result) -async def json_from_maven_xml(api_url: str, version_name: safe.VersionName) -> outcome.Outcome[basic.JSON]: +async def json_from_maven_xml(api_url: str, version_name: safe.VersionKey) -> outcome.Outcome[basic.JSON]: import datetime import defusedxml.ElementTree as ElementTree @@ -404,8 +404,8 @@ async def json_from_maven_xml(api_url: str, version_name: safe.VersionName) -> o async def release_validated( - project: safe.ProjectName, - version: safe.VersionName, + project: safe.ProjectKey, + version: safe.VersionKey, committee: bool = False, staging: bool | None = None, release_policy: bool = False, @@ -432,7 +432,7 @@ async def release_validated( async def release_validated_and_committee( - project: safe.ProjectName, version: safe.VersionName, *, staging: bool | None = None, release_policy: bool = False + project: safe.ProjectKey, version: safe.VersionKey, *, staging: bool | None = None, release_policy: bool = False ) -> tuple[sql.Release, sql.Committee]: release = await release_validated(project, version, committee=True, staging=staging, release_policy=release_policy) committee = release.committee diff --git a/atr/shared/projects.py b/atr/shared/projects.py index f09f0d81..c8e6ff84 100644 --- a/atr/shared/projects.py +++ b/atr/shared/projects.py @@ -106,7 +106,7 @@ class AddProjectForm(form.Form): class ComposePolicyForm(form.Form): variant: COMPOSE = form.value(COMPOSE) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) source_artifact_paths: str = form.label( "Source artifact paths", "Paths to source artifacts to be included in the release.", @@ -182,7 +182,7 @@ class ComposePolicyForm(form.Form): class VotePolicyForm(form.Form): variant: VOTE = form.value(VOTE) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) github_vote_workflow_path: str = form.label( "GitHub vote workflow paths", "The full paths to the GitHub workflows to use for the release, including the .github/workflows/ prefix.", @@ -244,7 +244,7 @@ class VotePolicyForm(form.Form): class FinishPolicyForm(form.Form): variant: FINISH = form.value(FINISH) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) github_finish_workflow_path: str = form.label( "GitHub finish workflow paths", "The full paths to the GitHub workflows to use for the release, including the .github/workflows/ prefix.", @@ -278,35 +278,35 @@ class FinishPolicyForm(form.Form): class AddCategoryForm(form.Form): variant: ADD_CATEGORY = form.value(ADD_CATEGORY) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) category_to_add: str = form.label("New category name") class RemoveCategoryForm(form.Form): variant: REMOVE_CATEGORY = form.value(REMOVE_CATEGORY) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) category_to_remove: str = form.label("Category to remove", widget=form.Widget.HIDDEN) class AddLanguageForm(form.Form): variant: ADD_LANGUAGE = form.value(ADD_LANGUAGE) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) language_to_add: str = form.label("New language name") class RemoveLanguageForm(form.Form): variant: REMOVE_LANGUAGE = form.value(REMOVE_LANGUAGE) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) language_to_remove: str = form.label("Language to remove", widget=form.Widget.HIDDEN) class DeleteProjectForm(form.Form): variant: DELETE_PROJECT = form.value(DELETE_PROJECT) - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) class DeleteSelectedProject(form.Form): - project_name: safe.ProjectName = form.label("Project name", widget=form.Widget.HIDDEN) + project_name: safe.ProjectKey = form.label("Project name", widget=form.Widget.HIDDEN) type ProjectViewForm = Annotated[ diff --git a/atr/shared/web.py b/atr/shared/web.py index 93089cf3..21f047d9 100644 --- a/atr/shared/web.py +++ b/atr/shared/web.py @@ -214,7 +214,7 @@ async def check( def render_checks_summary( - info: types.PathInfo | None, project_name: safe.ProjectName, version_name: safe.VersionName + info: types.PathInfo | None, project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> htm.Element | None: if (info is None) or (not info.checker_stats): return None diff --git a/atr/ssh.py b/atr/ssh.py index 9ca7a650..7ad0be81 100644 --- a/atr/ssh.py +++ b/atr/ssh.py @@ -341,7 +341,7 @@ def _step_03_command_simple_validate(argv: list[str]) -> bool: async def _step_04_command_validate( process: asyncssh.SSHServerProcess, argv: list[str], is_read_request: bool, server: SSHServer -) -> tuple[safe.ProjectName, safe.VersionName, list[str] | None, sql.Release | None]: +) -> tuple[safe.ProjectKey, safe.VersionKey, list[str] | None, sql.Release | None]: """Validate the path and user permissions for read or write.""" ############################################ ### Calls _step_05a/b_command_path_validate ### @@ -377,7 +377,7 @@ async def _step_04_command_validate( return project_name, version_name, None, None -async def _step_05a_command_path_validate_read(path: str) -> tuple[safe.ProjectName, safe.VersionName, str | None]: +async def _step_05a_command_path_validate_read(path: str) -> tuple[safe.ProjectKey, safe.VersionKey, str | None]: """Validate the path argument for rsync read commands, returning safe types.""" # READ: rsync --server --sender -vlogDtpre.iLsfxCIvu . /proj/v1/ # Validating path: /proj/v1/ @@ -388,11 +388,11 @@ async def _step_05a_command_path_validate_read(path: str) -> tuple[safe.ProjectN path_project, path_version, *rest = path.strip("/").split("/", 2) tag = rest[0] if rest else None try: - project_name = safe.ProjectName(path_project) + project_name = safe.ProjectKey(path_project) except ValueError: raise RsyncArgsError("Project is invalid") try: - version_name = safe.VersionName(path_version) + version_name = safe.VersionKey(path_version) except ValueError: raise RsyncArgsError("Version is invalid") if tag: @@ -408,7 +408,7 @@ async def _step_05a_command_path_validate_read(path: str) -> tuple[safe.ProjectN return project_name, version_name, tag -async def _step_05b_command_path_validate_write(path: str) -> tuple[safe.ProjectName, safe.VersionName, None]: +async def _step_05b_command_path_validate_write(path: str) -> tuple[safe.ProjectKey, safe.VersionKey, None]: """Validate the path argument for rsync write commands, returning safe types.""" # WRITE: rsync --server -vlogDtpre.iLsfxCIvu . /proj/v1/ # Validating path: /proj/v1/ @@ -418,11 +418,11 @@ async def _step_05b_command_path_validate_write(path: str) -> tuple[safe.Project path_project, path_version = path.strip("/").split("/", 1) try: - project_name = safe.ProjectName(path_project) + project_name = safe.ProjectKey(path_project) except ValueError: raise RsyncArgsError("Project is invalid") try: - version_name = safe.VersionName(path_version) + version_name = safe.VersionKey(path_version) except ValueError: raise RsyncArgsError("Version is invalid") @@ -455,8 +455,8 @@ async def _step_06a_validate_read_permissions( ssh_uid: str, project: sql.Project, release: sql.Release | None, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, tag: str | None, ) -> tuple[sql.Release | None, list[str] | None]: """Validate permissions for a read request.""" @@ -564,8 +564,8 @@ async def _step_07a_process_validated_rsync_read( async def _step_07b_process_validated_rsync_write( process: asyncssh.SSHServerProcess, argv: list[str], - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, server: SSHServer, ) -> None: """Handle a validated rsync write request.""" @@ -636,7 +636,7 @@ async def _step_07b_process_validated_rsync_write( async def _step_07c_ensure_release_object_for_write( - project_name: safe.ProjectName, version_name: safe.VersionName + project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> None: """Ensure the release object exists or create it for a write operation.""" release_name = sql.release_name(str(project_name), str(version_name)) diff --git a/atr/storage/__init__.py b/atr/storage/__init__.py index e0b5852e..4979fb6e 100644 --- a/atr/storage/__init__.py +++ b/atr/storage/__init__.py @@ -333,12 +333,12 @@ class Write: # async def as_key_owner(self) -> types.Outcome[WriteAsKeyOwner]: # ... - async def as_project_committee_admin(self, project_name: safe.ProjectName) -> WriteAsCommitteeAdmin: + async def as_project_committee_admin(self, project_name: safe.ProjectKey) -> WriteAsCommitteeAdmin: write_as_outcome = await self.as_project_committee_admin_outcome(project_name) return write_as_outcome.result_or_raise() async def as_project_committee_admin_outcome( - self, project_name: safe.ProjectName + self, project_name: safe.ProjectKey ) -> outcome.Outcome[WriteAsCommitteeAdmin]: project = await self.__data.project(str(project_name), _committee=True).demand( AccessError(f"Project not found: {project_name}") @@ -355,12 +355,12 @@ class Write: return outcome.Error(e) return outcome.Result(waca) - async def as_project_committee_member(self, project_name: safe.ProjectName) -> WriteAsCommitteeMember: + async def as_project_committee_member(self, project_name: safe.ProjectKey) -> WriteAsCommitteeMember: write_as_outcome = await self.as_project_committee_member_outcome(project_name) return write_as_outcome.result_or_raise() async def as_project_committee_member_outcome( - self, project_name: safe.ProjectName + self, project_name: safe.ProjectKey ) -> outcome.Outcome[WriteAsCommitteeMember]: project = await self.__data.project(str(project_name), _committee=True).demand( AccessError(f"Project not found: {project_name}") @@ -377,12 +377,12 @@ class Write: return outcome.Error(e) return outcome.Result(wacm) - async def as_project_committee_participant(self, project_name: safe.ProjectName) -> WriteAsCommitteeParticipant: + async def as_project_committee_participant(self, project_name: safe.ProjectKey) -> WriteAsCommitteeParticipant: write_as_outcome = await self.as_project_committee_participant_outcome(project_name) return write_as_outcome.result_or_raise() async def as_project_committee_participant_outcome( - self, project_name: safe.ProjectName + self, project_name: safe.ProjectKey ) -> outcome.Outcome[WriteAsCommitteeParticipant]: project = await self.__data.project(str(project_name), _committee=True).demand( AccessError(f"Project not found: {project_name!s}") @@ -514,7 +514,7 @@ async def write_as_committee_participant( @contextlib.asynccontextmanager async def write_as_project_committee_member( - project_name: safe.ProjectName, + project_name: safe.ProjectKey, asf_uid: principal.UID = principal.ArgumentNone, ) -> AsyncGenerator[WriteAsCommitteeMember]: async with write(asf_uid) as w: diff --git a/atr/storage/readers/checks.py b/atr/storage/readers/checks.py index 466e2fc7..b87777d8 100644 --- a/atr/storage/readers/checks.py +++ b/atr/storage/readers/checks.py @@ -79,7 +79,7 @@ class GeneralPublic: member_results_list[member_rel_path].sort(key=lambda r: r.checker) return types.CheckResults(primary_results_list, member_results_list, ignored_checks) - async def ignores(self, project_name: safe.ProjectName) -> list[sql.CheckResultIgnore]: + async def ignores(self, project_name: safe.ProjectKey) -> list[sql.CheckResultIgnore]: results = await self.__data.check_result_ignore( project_name=str(project_name), ).all() @@ -87,7 +87,7 @@ class GeneralPublic: async def ignores_matcher( self, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, ) -> Callable[[sql.CheckResult], bool]: ignores = await self.__data.check_result_ignore( project_name=str(project_name), diff --git a/atr/storage/writers/announce.py b/atr/storage/writers/announce.py index 69f10aa5..3124fda4 100644 --- a/atr/storage/writers/announce.py +++ b/atr/storage/writers/announce.py @@ -104,8 +104,8 @@ class CommitteeMember(CommitteeParticipant): async def release( # noqa: C901 self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, preview_revision_number: safe.RevisionNumber, recipient: str, body: str, diff --git a/atr/storage/writers/checks.py b/atr/storage/writers/checks.py index 36094fdd..c4016e06 100644 --- a/atr/storage/writers/checks.py +++ b/atr/storage/writers/checks.py @@ -93,7 +93,7 @@ class CommitteeMember(CommitteeParticipant): async def ignore_add( self, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release_glob: str | None = None, revision_number: safe.RevisionNumber | None = None, checker_glob: str | None = None, diff --git a/atr/storage/writers/distributions.py b/atr/storage/writers/distributions.py index f9707c83..21f2ef7d 100644 --- a/atr/storage/writers/distributions.py +++ b/atr/storage/writers/distributions.py @@ -94,16 +94,16 @@ class CommitteeMember(CommitteeParticipant): async def automate( self, - release_name: models.safe.ReleaseName, + release_name: models.safe.ReleaseKey, platform: models.sql.DistributionPlatform, committee_name: str, owner_namespace: models.safe.Alphanumeric | None, - project_name: models.safe.ProjectName, - version_name: models.safe.VersionName, + project_name: models.safe.ProjectKey, + version_name: models.safe.VersionKey, phase: str, revision_number: str | None, package: models.safe.Alphanumeric, - version: models.safe.VersionName, + version: models.safe.VersionKey, staging: bool, ) -> models.sql.Task: dist_task = models.sql.Task( @@ -136,11 +136,11 @@ class CommitteeMember(CommitteeParticipant): async def record( self, - release_name: models.safe.ReleaseName, + release_name: models.safe.ReleaseKey, platform: models.sql.DistributionPlatform, owner_namespace: models.safe.Alphanumeric | None, package: models.safe.Alphanumeric, - version: models.safe.VersionName, + version: models.safe.VersionKey, staging: bool, pending: bool, upload_date: datetime.datetime | None, @@ -197,7 +197,7 @@ class CommitteeMember(CommitteeParticipant): async def record_from_data( self, - release_name: models.safe.ReleaseName, + release_name: models.safe.ReleaseKey, staging: bool, dd: models.distribution.Data, allow_retries: bool = False, @@ -253,7 +253,7 @@ class CommitteeMember(CommitteeParticipant): async def __upgrade_staging_to_final( self, - release_name: models.safe.ReleaseName, + release_name: models.safe.ReleaseKey, platform: models.sql.DistributionPlatform, owner_namespace: str | None, package: str, @@ -284,7 +284,7 @@ class CommitteeMember(CommitteeParticipant): async def delete_distribution( self, - release_name: models.safe.ReleaseName, + release_name: models.safe.ReleaseKey, platform: models.sql.DistributionPlatform, owner_namespace: str, package: str, diff --git a/atr/storage/writers/keys.py b/atr/storage/writers/keys.py index cfc07d5e..32df96b6 100644 --- a/atr/storage/writers/keys.py +++ b/atr/storage/writers/keys.py @@ -467,7 +467,7 @@ class CommitteeParticipant(FoundationCommitter): return outcomes async def import_keys_file( - self, project_name: safe.ProjectName, version_name: safe.VersionName + self, project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> outcome.List[types.Key]: release = await self.__data.release( project_name=str(project_name), diff --git a/atr/storage/writers/policy.py b/atr/storage/writers/policy.py index 79f0f6f8..d243d1dd 100644 --- a/atr/storage/writers/policy.py +++ b/atr/storage/writers/policy.py @@ -170,7 +170,7 @@ class CommitteeMember(CommitteeParticipant): ) async def __get_or_create_policy( - self, project_name: models.safe.ProjectName + self, project_name: models.safe.ProjectKey ) -> tuple[models.sql.Project, models.sql.ReleasePolicy]: project = await self.__data.project( name=str(project_name), status=models.sql.ProjectStatus.ACTIVE, _release_policy=True, _committee=True diff --git a/atr/storage/writers/project.py b/atr/storage/writers/project.py index 031be6d7..3bcb471b 100644 --- a/atr/storage/writers/project.py +++ b/atr/storage/writers/project.py @@ -175,7 +175,7 @@ class CommitteeMember(CommitteeParticipant): project_name=label, ) - async def delete(self, project_name: safe.ProjectName) -> None: + async def delete(self, project_name: safe.ProjectKey) -> None: project = await self.__data.project( name=str(project_name), status=sql.ProjectStatus.ACTIVE, _releases=True, _distribution_channels=True ).get() diff --git a/atr/storage/writers/release.py b/atr/storage/writers/release.py index 8503e1c3..2aee86fc 100644 --- a/atr/storage/writers/release.py +++ b/atr/storage/writers/release.py @@ -96,8 +96,8 @@ class CommitteeParticipant(FoundationCommitter): async def delete( self, - project_name: safe.ProjectName, - version: safe.VersionName, + project_name: safe.ProjectKey, + version: safe.VersionKey, phase: db.Opt[sql.ReleasePhase] = db.NOT_SET, include_downloads: bool = True, ) -> str | None: @@ -158,7 +158,7 @@ class CommitteeParticipant(FoundationCommitter): return error async def delete_empty_directory( - self, project_name: safe.ProjectName, version_name: safe.VersionName, dir_to_delete_rel: pathlib.Path + self, project_name: safe.ProjectKey, version_name: safe.VersionKey, dir_to_delete_rel: pathlib.Path ) -> str | None: description = f"Delete empty directory {dir_to_delete_rel} via web interface" @@ -181,7 +181,7 @@ class CommitteeParticipant(FoundationCommitter): return None async def delete_file( - self, project_name: safe.ProjectName, version: safe.VersionName, rel_path_to_delete: pathlib.Path + self, project_name: safe.ProjectKey, version: safe.VersionKey, rel_path_to_delete: pathlib.Path ) -> int: metadata_files_deleted = 0 description = "File deletion through web interface" @@ -221,7 +221,7 @@ class CommitteeParticipant(FoundationCommitter): return metadata_files_deleted async def generate_hash_file( - self, project_name: safe.ProjectName, version_name: safe.VersionName, rel_path: pathlib.Path + self, project_name: safe.ProjectKey, version_name: safe.VersionKey, rel_path: pathlib.Path ) -> None: description = "Hash generation through web interface" @@ -262,8 +262,8 @@ class CommitteeParticipant(FoundationCommitter): async def import_from_svn( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, svn_url: str, revision: str, target_subdirectory: str | None, @@ -292,8 +292,8 @@ class CommitteeParticipant(FoundationCommitter): async def move_file( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, source_files_rel: list[pathlib.Path], target_dir_rel: pathlib.Path, ) -> tuple[str | None, list[str], list[str]]: @@ -320,7 +320,7 @@ class CommitteeParticipant(FoundationCommitter): async def promote_to_candidate( self, - release_name: safe.ReleaseName, + release_name: safe.ReleaseKey, selected_revision_number: safe.RevisionNumber, vote_manual: bool = False, ) -> str | None: @@ -384,7 +384,7 @@ class CommitteeParticipant(FoundationCommitter): return None async def remove_rc_tags( - self, project_name: safe.ProjectName, version_name: safe.VersionName + self, project_name: safe.ProjectKey, version_name: safe.VersionKey ) -> tuple[str | None, int, list[str]]: description = "Remove RC tags from paths via web interface" error_messages: list[str] = [] @@ -402,7 +402,7 @@ class CommitteeParticipant(FoundationCommitter): return str(e), renamed_count, error_messages return None, renamed_count, error_messages - async def start(self, project_name: safe.ProjectName, version: safe.VersionName) -> tuple[sql.Release, sql.Project]: # noqa: C901 + async def start(self, project_name: safe.ProjectKey, version: safe.VersionKey) -> tuple[sql.Release, sql.Project]: # noqa: C901 """Creates the initial release draft record and revision directory.""" # Get the project from the project name project = await self.__data.project( @@ -503,8 +503,8 @@ class CommitteeParticipant(FoundationCommitter): async def upload_files( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, files: Sequence[datastructures.FileStorage], ) -> tuple[str | None, int, bool]: """Process and save the uploaded files into a new draft revision.""" @@ -565,7 +565,7 @@ class CommitteeParticipant(FoundationCommitter): continue async def __delete_release_data_filesystem( - self, release_dirs: Sequence[pathlib.Path], project_name: safe.ProjectName, version: safe.VersionName + self, release_dirs: Sequence[pathlib.Path], project_name: safe.ProjectKey, version: safe.VersionKey ) -> str | None: delete_errors: list[str] = [] for release_dir in release_dirs: @@ -756,8 +756,8 @@ class CommitteeParticipant(FoundationCommitter): async def __tasks_ongoing( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber | None = None, ) -> int: tasks = sqlmodel.select(sqlalchemy.func.count()).select_from(sql.Task) diff --git a/atr/storage/writers/revision.py b/atr/storage/writers/revision.py index 0acf071a..f55b4290 100644 --- a/atr/storage/writers/revision.py +++ b/atr/storage/writers/revision.py @@ -83,12 +83,12 @@ async def finalise_revision( path_to_hash: dict[str, str], path_to_size: dict[str, int], previous_attestable: atr.models.attestable.Attestable | None, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release: sql.Release, - release_name: safe.ReleaseName, + release_name: safe.ReleaseKey, temp_dir: str, temp_dir_path: pathlib.Path, - version_name: safe.VersionName, + version_name: safe.VersionKey, was_quarantined: bool = False, ) -> sql.Revision: try: @@ -138,11 +138,11 @@ async def _commit_new_revision( path_to_hash: dict[str, str], path_to_size: dict[str, int], previous_attestable: atr.models.attestable.Attestable | None, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release: sql.Release, release_name: str, temp_dir: str, - version_name: safe.VersionName, + version_name: safe.VersionKey, was_quarantined: bool = False, ) -> sql.Revision: try: @@ -243,11 +243,11 @@ async def _lock_and_merge( path_to_hash: dict[str, str], path_to_size: dict[str, int], previous_attestable: atr.models.attestable.Attestable | None, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release: sql.Release, - _release_name: safe.ReleaseName, + _release_name: safe.ReleaseKey, temp_dir_path: pathlib.Path, - version_name: safe.VersionName, + version_name: safe.VersionKey, ) -> tuple[atr.models.attestable.Attestable | None, str | None, str | None, sql.Release]: # Acquire the write lock # We need this write lock for moving the directory afterwards atomically @@ -334,8 +334,8 @@ class CommitteeParticipant(FoundationCommitter): async def clear_quarantine( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, quarantined_id: int, ) -> None: release_name = sql.release_name(str(project_name), str(version_name)) @@ -355,8 +355,8 @@ class CommitteeParticipant(FoundationCommitter): async def create_revision_with_quarantine( # noqa: C901 self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, asf_uid: str, description: str | None = None, set_local_cache: bool = False, @@ -514,10 +514,10 @@ class CommitteeParticipant(FoundationCommitter): description: str | None, path_to_size: dict[str, int], prior_revision_name: str | None, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release_name: str, temp_dir: str, - version_name: safe.VersionName, + version_name: safe.VersionKey, ) -> sql.Quarantined: file_metadata = [ sql.QuarantineFileEntryV1( diff --git a/atr/storage/writers/sbom.py b/atr/storage/writers/sbom.py index 91088e1b..13a6f7bd 100644 --- a/atr/storage/writers/sbom.py +++ b/atr/storage/writers/sbom.py @@ -78,8 +78,8 @@ class CommitteeParticipant(FoundationCommitter): async def augment_cyclonedx( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: str, rel_path: pathlib.Path, ) -> sql.Task: @@ -107,8 +107,8 @@ class CommitteeParticipant(FoundationCommitter): async def generate_cyclonedx( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: str, path_in_new_revision: pathlib.Path, sbom_path_in_new_revision: pathlib.Path, @@ -137,8 +137,8 @@ class CommitteeParticipant(FoundationCommitter): async def osv_scan_cyclonedx( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: str, rel_path: pathlib.Path, ) -> sql.Task: diff --git a/atr/storage/writers/ssh.py b/atr/storage/writers/ssh.py index 3354ab28..8bd2a140 100644 --- a/atr/storage/writers/ssh.py +++ b/atr/storage/writers/ssh.py @@ -86,7 +86,7 @@ class CommitteeParticipant(FoundationCommitter): self.__committee_name = committee_name async def add_workflow_key( - self, github_uid: str, github_nid: int, project_name: safe.ProjectName, key: str, github_payload: dict[str, Any] + self, github_uid: str, github_nid: int, project_name: safe.ProjectKey, key: str, github_payload: dict[str, Any] ) -> tuple[str, int]: now = int(time.time()) # Twenty minutes to upload all files diff --git a/atr/storage/writers/vote.py b/atr/storage/writers/vote.py index fb8e7c59..0e8ddeaa 100644 --- a/atr/storage/writers/vote.py +++ b/atr/storage/writers/vote.py @@ -137,8 +137,8 @@ class CommitteeParticipant(FoundationCommitter): async def start( self, email_to: str, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, selected_revision_number: safe.RevisionNumber, vote_duration_choice: int, subject: str, @@ -229,8 +229,8 @@ class CommitteeMember(CommitteeParticipant): async def resolve( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, vote_result: Literal["passed", "failed"], asf_fullname: str, resolution_body: str, @@ -269,8 +269,8 @@ class CommitteeMember(CommitteeParticipant): async def resolve_manually( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, vote_result: Literal["passed", "failed"], ) -> str: release = await self.__data.release( @@ -318,7 +318,7 @@ class CommitteeMember(CommitteeParticipant): async def resolve_release( self, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release: sql.Release, voting_round: int | None, vote_result: Literal["passed", "failed"], diff --git a/atr/storage/writers/workflowstatus.py b/atr/storage/writers/workflowstatus.py index 1730afe0..2783f9b3 100644 --- a/atr/storage/writers/workflowstatus.py +++ b/atr/storage/writers/workflowstatus.py @@ -104,7 +104,7 @@ class CommitteeMember(CommitteeParticipant): self, workflow_id: str, run_id: int, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, task_id: int | None = None, status: str | None = None, message: str | None = None, diff --git a/atr/tasks/__init__.py b/atr/tasks/__init__.py index db144349..34106535 100644 --- a/atr/tasks/__init__.py +++ b/atr/tasks/__init__.py @@ -133,8 +133,8 @@ async def distribution_status_check( async def draft_checks( asf_uid: str, - project_name: safe.ProjectName, - release_version: safe.VersionName, + project_name: safe.ProjectKey, + release_version: safe.VersionKey, revision_number: safe.RevisionNumber, caller_data: db.Session | None = None, ) -> int: @@ -206,8 +206,8 @@ async def draft_checks( async def keys_import_file( asf_uid: str, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: str, caller_data: db.Session | None = None, ) -> None: @@ -569,9 +569,9 @@ async def _draft_file_checks( data: db.Session, path: pathlib.Path, previous_version: sql.Release | None, - project_name: safe.ProjectName, + project_name: safe.ProjectKey, release: sql.Release, - release_version: safe.VersionName, + release_version: safe.VersionKey, revision_number: safe.RevisionNumber, ): path_str = str(path) diff --git a/atr/tasks/checks/__init__.py b/atr/tasks/checks/__init__.py index d10dd4a8..6fea3baa 100644 --- a/atr/tasks/checks/__init__.py +++ b/atr/tasks/checks/__init__.py @@ -52,8 +52,8 @@ import atr.util as util class FunctionArguments: recorder: Callable[[], Awaitable[Recorder]] asf_uid: str - project_name: safe.ProjectName - version_name: safe.VersionName + project_name: safe.ProjectKey + version_name: safe.VersionKey revision_number: safe.RevisionNumber primary_rel_path: str | None extra_args: dict[str, Any] @@ -61,9 +61,9 @@ class FunctionArguments: class Recorder: checker: str - release_name: safe.ReleaseName - project_name: safe.ProjectName - version_name: safe.VersionName + release_name: safe.ReleaseKey + project_name: safe.ProjectKey + version_name: safe.VersionKey primary_rel_path: str | None member_rel_path: str | None revision_number: safe.RevisionNumber @@ -75,8 +75,8 @@ class Recorder: self, checker: str | Callable[..., Any], inputs_hash: str | None, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, primary_rel_path: str | None = None, member_rel_path: str | None = None, @@ -101,8 +101,8 @@ class Recorder: cls, checker: str | Callable[..., Any], inputs_hash: str, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, revision_number: safe.RevisionNumber, primary_rel_path: str | None = None, member_rel_path: str | None = None, diff --git a/atr/tasks/checks/compare.py b/atr/tasks/checks/compare.py index dec520a3..47f5c2a7 100644 --- a/atr/tasks/checks/compare.py +++ b/atr/tasks/checks/compare.py @@ -335,7 +335,7 @@ async def _find_archive_root(archive_path: pathlib.Path, extract_dir: pathlib.Pa async def _load_tp_payload( - project_name: safe.ProjectName, version_name: safe.VersionName, revision_number: safe.RevisionNumber + project_name: safe.ProjectKey, version_name: safe.VersionKey, revision_number: safe.RevisionNumber ) -> github_models.TrustedPublisherPayload | None: payload_path = attestable.github_tp_payload_path(project_name, version_name, revision_number) if not await aiofiles.os.path.isfile(payload_path): diff --git a/atr/tasks/gha.py b/atr/tasks/gha.py index 5fc42607..f5698db0 100644 --- a/atr/tasks/gha.py +++ b/atr/tasks/gha.py @@ -142,8 +142,8 @@ async def status_check(args: WorkflowStatusCheck) -> DistributionWorkflowStatus: @checks.with_model(DistributionWorkflow) async def trigger_workflow(args: DistributionWorkflow, *, task_id: int | None = None) -> results.Results | None: unique_id = f"atr-dist-{args.name}-{uuid.uuid4()}" - project = safe.ProjectName(args.project_name) - safe.VersionName(args.version_name) + project = safe.ProjectKey(args.project_name) + safe.VersionKey(args.version_name) try: sql_platform = sql.DistributionPlatform[args.platform] except KeyError: diff --git a/atr/tasks/keys.py b/atr/tasks/keys.py index 79c6e773..b8210fae 100644 --- a/atr/tasks/keys.py +++ b/atr/tasks/keys.py @@ -33,8 +33,8 @@ class ImportFile(schema.Strict): @checks.with_model(ImportFile) async def import_file(args: ImportFile) -> results.Results | None: """Import a KEYS file from a draft release candidate revision.""" - project = safe.ProjectName(args.project_name) - version = safe.VersionName(args.version_name) + project = safe.ProjectKey(args.project_name) + version = safe.VersionKey(args.version_name) async with storage.write(args.asf_uid) as write: wacm = await write.as_project_committee_member(project) outcomes = await wacm.keys.import_keys_file(project, version) diff --git a/atr/tasks/quarantine.py b/atr/tasks/quarantine.py index d042df0c..bbad7415 100644 --- a/atr/tasks/quarantine.py +++ b/atr/tasks/quarantine.py @@ -297,8 +297,8 @@ async def _mark_failed( async def _promote( quarantined: sql.Quarantined, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, release_name: str, quarantine_dir: str, ) -> None: diff --git a/atr/tasks/sbom.py b/atr/tasks/sbom.py index 159da434..032eaa97 100644 --- a/atr/tasks/sbom.py +++ b/atr/tasks/sbom.py @@ -83,8 +83,8 @@ class ScoreArgs(FileArgs): @checks.with_model(FileArgs) async def augment(args: FileArgs) -> results.Results | None: - project = safe.ProjectName(args.project_name) - version = safe.VersionName(args.version_name) + project = safe.ProjectKey(args.project_name) + version = safe.VersionKey(args.version_name) base_dir = paths.get_unfinished_dir() / args.project_name / args.version_name / args.revision_number if not await aiofiles.os.path.isdir(base_dir): @@ -146,8 +146,8 @@ async def generate_cyclonedx(args: GenerateCycloneDX) -> results.Results | None: @checks.with_model(FileArgs) async def osv_scan(args: FileArgs) -> results.Results | None: - project = safe.ProjectName(args.project_name) - version = safe.VersionName(args.version_name) + project = safe.ProjectKey(args.project_name) + version = safe.VersionKey(args.version_name) base_dir = paths.get_unfinished_dir() / args.project_name / args.version_name / args.revision_number if not await aiofiles.os.path.isdir(base_dir): @@ -206,8 +206,8 @@ async def osv_scan(args: FileArgs) -> results.Results | None: @checks.with_model(FileArgs) async def score_qs(args: FileArgs) -> results.Results | None: - safe.ProjectName(args.project_name) - safe.VersionName(args.version_name) + safe.ProjectKey(args.project_name) + safe.VersionKey(args.version_name) base_dir = paths.get_unfinished_dir() / args.project_name / args.version_name / args.revision_number if not await aiofiles.os.path.isdir(base_dir): @@ -245,8 +245,8 @@ async def score_qs(args: FileArgs) -> results.Results | None: @checks.with_model(ScoreArgs) async def score_tool(args: ScoreArgs) -> results.Results | None: - safe.ProjectName(args.project_name) - safe.VersionName(args.version_name) + safe.ProjectKey(args.project_name) + safe.VersionKey(args.version_name) base_dir = paths.get_unfinished_dir() / args.project_name / args.version_name / args.revision_number previous_base_dir = None diff --git a/atr/tasks/svn.py b/atr/tasks/svn.py index d5c2033e..6d4f4403 100644 --- a/atr/tasks/svn.py +++ b/atr/tasks/svn.py @@ -73,8 +73,8 @@ async def import_files(args: SvnImport) -> results.Results | None: async def _import_files_core(args: SvnImport) -> str: """Core logic to perform the SVN export.""" - project = safe.ProjectName(args.project_name) - version = safe.VersionName(args.version_name) + project = safe.ProjectKey(args.project_name) + version = safe.VersionKey(args.version_name) log.info(f"Starting SVN import for {args.project_name}-{args.version_name}") # We have to use a temporary directory otherwise SVN thinks it's a pegged revision diff --git a/atr/tasks/vote.py b/atr/tasks/vote.py index 3f6ea9a2..997e0b3f 100644 --- a/atr/tasks/vote.py +++ b/atr/tasks/vote.py @@ -62,7 +62,7 @@ async def initiate(args: Initiate) -> results.Results | None: async def _initiate_core_logic(args: Initiate) -> results.Results | None: """Get arguments, create an email, and then send it to the recipient.""" log.info("Starting initiate_core") - safe.ReleaseName(args.release_name) + safe.ReleaseKey(args.release_name) # Validate arguments if not (args.email_to.endswith("@apache.org") or args.email_to.endswith(".apache.org")): diff --git a/atr/web.py b/atr/web.py index 2d79589d..76c727bb 100644 --- a/atr/web.py +++ b/atr/web.py @@ -88,7 +88,7 @@ class Committer: def is_admin(self) -> bool: return user.is_admin(self.uid) - async def check_access(self, project_name: str | safe.ProjectName) -> None: + async def check_access(self, project_name: str | safe.ProjectKey) -> None: if not any((str(p.name) == str(project_name)) for p in (await self.user_projects)): if self.is_admin: # Admins can view all projects @@ -162,8 +162,8 @@ class Committer: async def release( self, - project_name: safe.ProjectName, - version_name: safe.VersionName, + project_name: safe.ProjectKey, + version_name: safe.VersionKey, phase: sql.ReleasePhase | db.NotSet | None = db.NOT_SET, latest_revision_number: safe.RevisionNumber | db.NotSet | None = db.NOT_SET, data: db.Session | None = None, diff --git a/atr/worker.py b/atr/worker.py index 1f65865a..56f18f56 100644 --- a/atr/worker.py +++ b/atr/worker.py @@ -119,8 +119,8 @@ async def _execute_check_task( f"Task {task_id} ({task_type}) has non-dict raw args {task_args} which should represent keyword_args" ) - project_name = safe.ProjectName(task_obj.project_name) - version_name = safe.VersionName(task_obj.version_name) + project_name = safe.ProjectKey(task_obj.project_name) + version_name = safe.VersionKey(task_obj.version_name) revision_number = safe.RevisionNumber(task_obj.revision_number) async def recorder_factory() -> checks.Recorder: diff --git a/tests/unit/test_create_revision.py b/tests/unit/test_create_revision.py index 82d07ad3..1b8a7ff0 100644 --- a/tests/unit/test_create_revision.py +++ b/tests/unit/test_create_revision.py @@ -157,7 +157,7 @@ async def test_clone_from_older_revision_skips_merge_without_intervening_change( mock.patch.object(revision.paths, "release_directory_base", return_value=tmp_path / "releases"), ): await participant.create_revision_with_quarantine( - safe.ProjectName("proj"), safe.VersionName("1.0"), "test", clone_from=safe.RevisionNumber("00002") + safe.ProjectKey("proj"), safe.VersionKey("1.0"), "test", clone_from=safe.RevisionNumber("00002") ) if merge_mock.called: diff --git a/tests/unit/test_ignores_api_models.py b/tests/unit/test_ignores_api_models.py index 8d12aa8f..d77a83aa 100644 --- a/tests/unit/test_ignores_api_models.py +++ b/tests/unit/test_ignores_api_models.py @@ -32,7 +32,7 @@ def test_check_result_ignore_has_project_name_field() -> None: def test_ignore_add_args_accepts_all_fields() -> None: args = api.IgnoreAddArgs( - project_name=safe.ProjectName("example"), + project_name=safe.ProjectKey("example"), release_glob="example-1.0.*", revision_number="00001", checker_glob="atr.tasks.checks.rat.*", @@ -41,22 +41,22 @@ def test_ignore_add_args_accepts_all_fields() -> None: status=sql.CheckResultStatusIgnore.WARNING, message_glob="*warning*", ) - assert args.project_name == safe.ProjectName("example") + assert args.project_name == safe.ProjectKey("example") assert args.release_glob == "example-1.0.*" assert args.status == sql.CheckResultStatusIgnore.WARNING def test_ignore_add_args_rejects_invalid_pattern() -> None: with pytest.raises(ValueError): - api.IgnoreAddArgs(project_name=safe.ProjectName("test"), checker_glob="^(?=lookahead)$") + api.IgnoreAddArgs(project_name=safe.ProjectKey("test"), checker_glob="^(?=lookahead)$") def test_ignore_add_args_requires_project_name() -> None: - args = api.IgnoreAddArgs(project_name=safe.ProjectName("test"), checker_glob="atr.tasks.*") + args = api.IgnoreAddArgs(project_name=safe.ProjectKey("test"), checker_glob="atr.tasks.*") assert str(args.project_name) == "test" def test_ignore_delete_args_requires_project_name() -> None: - args = api.IgnoreDeleteArgs(project_name=safe.ProjectName("test"), id=1) + args = api.IgnoreDeleteArgs(project_name=safe.ProjectKey("test"), id=1) assert str(args.project_name) == "test" assert args.id == 1 diff --git a/tests/unit/test_quarantine_task.py b/tests/unit/test_quarantine_task.py index 74b0f8d8..e03f5376 100644 --- a/tests/unit/test_quarantine_task.py +++ b/tests/unit/test_quarantine_task.py @@ -41,7 +41,7 @@ async def test_clear_quarantine_raises_when_not_found(): writer = _make_revision_writer(mock_data) with pytest.raises(RuntimeError, match="not found"): - await writer.clear_quarantine(safe.ProjectName("proj"), safe.VersionName("1.0"), 999) + await writer.clear_quarantine(safe.ProjectKey("proj"), safe.VersionKey("1.0"), 999) mock_data.commit.assert_not_awaited() @@ -58,7 +58,7 @@ async def test_clear_quarantine_transitions_failed_to_acknowledged(): mock_data.quarantined = mock.MagicMock(return_value=mock_query) writer = _make_revision_writer(mock_data) - await writer.clear_quarantine(safe.ProjectName("proj"), safe.VersionName("1.0"), 7) + await writer.clear_quarantine(safe.ProjectKey("proj"), safe.VersionKey("1.0"), 7) assert quarantined_row.status == sql.QuarantineStatus.ACKNOWLEDGED mock_data.commit.assert_awaited_once() @@ -490,7 +490,7 @@ async def test_validate_success_calls_promote(tmp_path: pathlib.Path): assert result is None mock_promote.assert_awaited_once_with( - row, safe.ProjectName("proj"), safe.VersionName("1.0"), row.release.name, str(quarantine_dir) + row, safe.ProjectKey("proj"), safe.VersionKey("1.0"), row.release.name, str(quarantine_dir) ) mock_mark.assert_not_awaited() @@ -521,11 +521,11 @@ def _make_quarantined_row() -> mock.MagicMock: row.status = sql.QuarantineStatus.PENDING row.release = mock.MagicMock() row.release.name = "proj-1.0" - row.release.safe_name = safe.ReleaseName(row.release.name) + row.release.safe_name = safe.ReleaseKey(row.release.name) row.release.project_name = "proj" - row.release.safe_project_name = safe.ProjectName(row.release.project_name) + row.release.safe_project_name = safe.ProjectKey(row.release.project_name) row.release.version = "1.0" - row.release.safe_version_name = safe.VersionName(row.release.version) + row.release.safe_version_name = safe.VersionKey(row.release.version) return row diff --git a/tests/unit/test_safe_types.py b/tests/unit/test_safe_types.py index af24b0fb..593d8250 100644 --- a/tests/unit/test_safe_types.py +++ b/tests/unit/test_safe_types.py @@ -19,7 +19,7 @@ import pytest import atr.models.safe as safe [email protected]("cls", [safe.Alphanumeric, safe.ProjectName, safe.VersionName, safe.ReleaseName]) [email protected]("cls", [safe.Alphanumeric, safe.ProjectKey, safe.VersionKey, safe.ReleaseKey]) @pytest.mark.parametrize( "bad", ["\n", "\t", "\r", "\x1f", "\x7f", "\u200b", "e\u0301"], @@ -29,7 +29,7 @@ def test_safe_types_reject_bad_bytes(cls: type[safe.Alphanumeric], bad: str): cls("abc" + bad + "def") [email protected]("cls", [safe.Alphanumeric, safe.ProjectName, safe.VersionName, safe.ReleaseName]) [email protected]("cls", [safe.Alphanumeric, safe.ProjectKey, safe.VersionKey, safe.ReleaseKey]) @pytest.mark.parametrize( "bad", [ @@ -44,19 +44,19 @@ def test_safe_types_reject_invalid_characters(cls: type[safe.Alphanumeric], bad: cls(bad) [email protected]("cls", [safe.Alphanumeric, safe.ProjectName, safe.VersionName, safe.ReleaseName]) [email protected]("cls", [safe.Alphanumeric, safe.ProjectKey, safe.VersionKey, safe.ReleaseKey]) def test_safe_types_accept_valid_alpha(cls: type[safe.Alphanumeric]): value = cls("abcdef") assert str(value) == "abcdef" [email protected]("cls", [safe.VersionName, safe.ReleaseName]) [email protected]("cls", [safe.VersionKey, safe.ReleaseKey]) def test_safe_version_types_accept_valid_version(cls: type[safe.Alphanumeric]): value = cls("0.1+def") assert str(value) == "0.1+def" [email protected]("cls", [safe.Alphanumeric, safe.ProjectName]) [email protected]("cls", [safe.Alphanumeric, safe.ProjectKey]) def test_safe_alpha_types_reject_valid_version(cls: type[safe.Alphanumeric]): with pytest.raises(ValueError): cls("0.1+def") --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
