From 0f7cb85739f8cd0f64dd1b57e4d786d7be47cb77 Mon Sep 17 00:00:00 2001 From: Jakub Frejlach Date: Tue, 27 Jun 2023 17:35:44 +0200 Subject: [PATCH 1/4] Implement Flaw Comment operations retrieve, list, create --- griffon/commands/entities/osidb.py | 123 ++++++++++++++++++++++++++++- griffon/output.py | 3 +- 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/griffon/commands/entities/osidb.py b/griffon/commands/entities/osidb.py index ff58168..824caf8 100644 --- a/griffon/commands/entities/osidb.py +++ b/griffon/commands/entities/osidb.py @@ -11,6 +11,9 @@ osidb_api_v1_affects_list, osidb_api_v1_affects_retrieve, osidb_api_v1_affects_update, + osidb_api_v1_flaws_comments_create, + osidb_api_v1_flaws_comments_list, + osidb_api_v1_flaws_comments_retrieve, osidb_api_v1_flaws_create, osidb_api_v1_flaws_list, osidb_api_v1_flaws_retrieve, @@ -18,7 +21,12 @@ osidb_api_v1_trackers_list, osidb_api_v1_trackers_retrieve, ) -from osidb_bindings.bindings.python_client.models import Affect, Flaw, Tracker +from osidb_bindings.bindings.python_client.models import ( + Affect, + Flaw, + FlawComment, + Tracker, +) from requests import HTTPError from griffon import OSIDB_API_URL, OSIDBService, progress_bar @@ -201,6 +209,119 @@ def create_flaw(ctx, **params): return cprint(data, ctx=ctx) +# flaw comments +@flaws.group(help=f"{OSIDB_API_URL}/osidb/api/v1/flaws//comments", name="comments") +@click.pass_context +def flaw_comments(ctx): + """OSIDB Flaw Comments.""" + pass + + +@flaw_comments.command(name="get") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@click.option("--uuid", "comment_uuid", help="Comment UUID.", required=True) +@query_params_options( + entity="Flaw Comment", + endpoint_module=osidb_api_v1_flaws_comments_retrieve, + options_overrides={ + "include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))}, + "exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))}, + "include_meta_attr": {"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawComment))}, + }, +) +@click.pass_context +@progress_bar +def get_flaw_comment(ctx, flaw_id, comment_uuid, **params): + params = multivalue_params_to_csv(params) + + session = OSIDBService.create_session() + data = session.flaws.comments.retrieve(flaw_id, comment_uuid, **params) + return cprint(data, ctx=ctx) + + +@flaw_comments.command(name="list") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@query_params_options( + entity="Flaw Comments", + endpoint_module=osidb_api_v1_flaws_comments_list, + options_overrides={ + "include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))}, + "exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))}, + "include_meta_attr": {"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawComment))}, + }, +) +@click.pass_context +@progress_bar +def list_flaw_comments(ctx, flaw_id, **params): + # TODO: handle pagination + # TODO: handle output + session = OSIDBService.create_session() + + params = multivalue_params_to_csv(params) + data = session.flaws.comments.retrieve_list(flaw_id, **params).results + return cprint(data, ctx=ctx) + + +@flaw_comments.command(name="create") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@request_body_options( + endpoint_module=osidb_api_v1_flaws_comments_create, + exclude=["uuid", "created_dt"], +) +@click.pass_context +def create_flaw_comment(ctx, flaw_id, **params): + request_body_type = getattr(osidb_api_v1_flaws_comments_create, "REQUEST_BODY_TYPE", None) + if request_body_type is None: + raise click.ClickException( + "No request body template for Flaw Comment create. " + "Is correct version of osidb-bindings installed?" + ) + + fields = filter_request_fields( + request_body_type.get_fields(), + exclude=["uuid", "created_dt"], + ) + params = multivalue_params_to_csv(params) + + session = OSIDBService.create_session() + + data = {field: "" for field in fields} + data.update((field, value) for field, value in params.items() if value is not None) + + if ctx.obj["EDITOR"]: + data = click.edit( + text=json.dumps(data, indent=4, default=str), editor=get_editor(), require_save=False + ) + data = json.loads(data) + + try: + data = session.flaws.comments.create(data, flaw_id=flaw_id) + except HTTPError as e: + if ctx.obj["VERBOSE"]: + console.log(e, e.response.json()) + raise click.ClickException( + "Failed to create Flaw Comment. " + "You might have insufficient permission or you've supplied malformed data. " + "Consider running griffon with -v option for verbose error log." + ) + return cprint(data, ctx=ctx) + + # affects @osidb_grp.group(help=f"{OSIDB_API_URL}/osidb/api/v1/affects") @click.pass_context diff --git a/griffon/output.py b/griffon/output.py index 078cc28..ba79afa 100644 --- a/griffon/output.py +++ b/griffon/output.py @@ -272,7 +272,6 @@ def text_output_products_contain_component( no_wrap=no_wrap, ) else: - if ctx.obj["VERBOSE"] == 0: # product_version X component_name for pv in result_tree.keys(): component_names = set() @@ -920,7 +919,7 @@ def text_output_list(ctx, output, format, exclude_components, no_wrap=False): ) # handle trackers - if "external_system_id" in output["results"][0]: + if all(key in output["results"][0] for key in ("external_system_id", "status")): for row in output["results"]: console.print( row["external_system_id"], From 477113905e12182591cf38d23ef93464ea96df14 Mon Sep 17 00:00:00 2001 From: Jakub Frejlach Date: Tue, 27 Jun 2023 19:09:24 +0200 Subject: [PATCH 2/4] Implement Flaw Reference operations create, retrieve, list, update, delete --- griffon/commands/entities/osidb.py | 210 +++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) diff --git a/griffon/commands/entities/osidb.py b/griffon/commands/entities/osidb.py index 824caf8..95450ba 100644 --- a/griffon/commands/entities/osidb.py +++ b/griffon/commands/entities/osidb.py @@ -16,6 +16,10 @@ osidb_api_v1_flaws_comments_retrieve, osidb_api_v1_flaws_create, osidb_api_v1_flaws_list, + osidb_api_v1_flaws_references_create, + osidb_api_v1_flaws_references_list, + osidb_api_v1_flaws_references_retrieve, + osidb_api_v1_flaws_references_update, osidb_api_v1_flaws_retrieve, osidb_api_v1_flaws_update, osidb_api_v1_trackers_list, @@ -25,6 +29,7 @@ Affect, Flaw, FlawComment, + FlawReference, Tracker, ) from requests import HTTPError @@ -322,6 +327,211 @@ def create_flaw_comment(ctx, flaw_id, **params): return cprint(data, ctx=ctx) +# flaw references +@flaws.group(help=f"{OSIDB_API_URL}/osidb/api/v1/flaws//references", name="references") +@click.pass_context +def flaw_references(ctx): + """OSIDB Flaw References.""" + pass + + +@flaw_references.command(name="get") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True) +@query_params_options( + entity="Flaw Reference", + endpoint_module=osidb_api_v1_flaws_references_retrieve, + options_overrides={ + "include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))}, + "exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))}, + "include_meta_attr": { + "type": click.Choice(OSIDBService.get_meta_attr_fields(FlawReference)) + }, + }, +) +@click.pass_context +@progress_bar +def get_flaw_reference(ctx, flaw_id, reference_uuid, **params): + params = multivalue_params_to_csv(params) + + session = OSIDBService.create_session() + data = session.flaws.references.retrieve(flaw_id, reference_uuid, **params) + return cprint(data, ctx=ctx) + + +@flaw_references.command(name="list") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@query_params_options( + entity="Flaw References", + endpoint_module=osidb_api_v1_flaws_references_list, + options_overrides={ + "include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))}, + "exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))}, + "include_meta_attr": { + "type": click.Choice(OSIDBService.get_meta_attr_fields(FlawReference)) + }, + }, +) +@click.pass_context +@progress_bar +def list_flaw_references(ctx, flaw_id, **params): + # TODO: handle pagination + # TODO: handle output + session = OSIDBService.create_session() + + params = multivalue_params_to_csv(params) + data = session.flaws.references.retrieve_list(flaw_id, **params).results + return cprint(data, ctx=ctx) + + +@flaw_references.command(name="create") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@request_body_options( + endpoint_module=osidb_api_v1_flaws_references_create, + exclude=["uuid", "created_dt"], +) +@click.pass_context +def create_flaw_reference(ctx, flaw_id, **params): + request_body_type = getattr(osidb_api_v1_flaws_references_create, "REQUEST_BODY_TYPE", None) + if request_body_type is None: + raise click.ClickException( + "No request body template for Flaw Reference create. " + "Is correct version of osidb-bindings installed?" + ) + + fields = filter_request_fields( + request_body_type.get_fields(), + exclude=["uuid", "created_dt"], + ) + params = multivalue_params_to_csv(params) + + session = OSIDBService.create_session() + + data = {field: "" for field in fields} + data.update((field, value) for field, value in params.items() if value is not None) + + if ctx.obj["EDITOR"]: + data = click.edit( + text=json.dumps(data, indent=4, default=str), editor=get_editor(), require_save=False + ) + data = json.loads(data) + + try: + data = session.flaws.references.create(data, flaw_id=flaw_id) + except HTTPError as e: + if ctx.obj["VERBOSE"]: + console.log(e, e.response.json()) + raise click.ClickException( + "Failed to create Flaw Reference. " + "You might have insufficient permission or you've supplied malformed data. " + "Consider running griffon with -v option for verbose error log." + ) + return cprint(data, ctx=ctx) + + +@flaw_references.command(name="update") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True) +@request_body_options(endpoint_module=osidb_api_v1_flaws_references_update, exclude=["uuid"]) +@click.pass_context +def update_flaw_references(ctx, flaw_id, reference_uuid, **params): + request_body_type = getattr(osidb_api_v1_flaws_references_update, "REQUEST_BODY_TYPE", None) + if request_body_type is None: + raise click.ClickException( + "No request body template for Flaw Reference update. " + "Is correct version of osidb-bindings installed?" + ) + + fields = filter_request_fields(request_body_type.get_fields(), exclude=["uuid"]) + params = multivalue_params_to_csv(params) + + session = OSIDBService.create_session() + + try: + data = session.flaws.references.retrieve( + flaw_id, reference_uuid, include_fields=",".join(fields) + ) + except Exception as e: + if ctx.obj["VERBOSE"]: + console.log(e, e.response.json()) + raise click.ClickException( + f"Failed to fetch Flaw Reference with ID '{reference_uuid}'. " + "Flaw or Flaw Reference either does not exist or you have insufficient permissions. " + "Consider running griffon with -v option for verbose error log." + ) + + data = data.to_dict() + # remove status data from OSIDB server + [data.pop(key) for key in ["dt", "env", "revision", "version"]] + data.update((field, value) for field, value in params.items() if value is not None) + + if ctx.obj["EDITOR"]: + data = click.edit(text=json.dumps(data, indent=4), editor=get_editor(), require_save=False) + data = json.loads(data) + + try: + data = session.flaws.references.update(flaw_id, data, reference_uuid) + except HTTPError as e: + if ctx.obj["VERBOSE"]: + console.log(e, e.response.json()) + raise click.ClickException( + f"Failed to update Flaw Reference with ID '{reference_uuid}'. " + "You might have insufficient permission or you've supplied malformed data. " + "Consider running griffon with -v option for verbose error log." + ) + return cprint(data, ctx=ctx) + + +@flaw_references.command(name="delete") +@click.option( + "--flaw-id", + "flaw_id", + help="Flaw CVE-ID or UUID.", + required=True, +) +@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True) +@click.option( + "--yes", + is_flag=True, + callback=abort_if_false, + expose_value=False, + prompt="Are you sure you want to delete Flaw Reference?", +) +@click.pass_context +def delete_flaw_references(ctx, flaw_id, reference_uuid, **params): + session = OSIDBService.create_session() + try: + data = session.flaws.references.delete(flaw_id, reference_uuid) + except HTTPError as e: + if ctx.obj["VERBOSE"]: + console.log(e, e.response.json()) + raise click.ClickException( + f"Failed to delete Flaw Reference {reference_uuid}. " + "It either does not exist or you have insufficient permissions." + ) + return cprint(data, ctx=ctx) + + # affects @osidb_grp.group(help=f"{OSIDB_API_URL}/osidb/api/v1/affects") @click.pass_context From c7865d74275c8c4fab85c2c65de1c2357b150458 Mon Sep 17 00:00:00 2001 From: Jakub Frejlach Date: Tue, 27 Jun 2023 19:11:36 +0200 Subject: [PATCH 3/4] Update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45e7b17..1985c02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased - +### Added +- CRUD operations for OSIDB entities Flaw Comment (create, retreive, list), + Flaw Reference (create, retrieve, list, update, delete) ## [0.2.7] - 2023-06-14 ### Changed - ensure we choose latest version of component using products-contains-component From 584de3926d9cd4678c89cef97ac1aadca1fd1b05 Mon Sep 17 00:00:00 2001 From: Jakub Frejlach Date: Wed, 28 Jun 2023 13:30:25 +0200 Subject: [PATCH 4/4] Update cryptography package to comply with GitHub Dependabot reported vulnerability --- requirements/dev.txt | 229 ++++++++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 113 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index bfa8427..14da222 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,8 +1,8 @@ # -# This file is autogenerated by pip-compile with Python 3.11 +# This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --allow-unsafe --generate-hashes requirements/dev.in +# pip-compile --allow-unsafe --generate-hashes dev.in # asttokens==2.2.1 \ --hash=sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3 \ @@ -12,8 +12,8 @@ attrs==22.2.0 \ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # component-registry-bindings # osidb-bindings # pytest @@ -24,7 +24,7 @@ backcall==0.2.0 \ behave==1.2.6 \ --hash=sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86 \ --hash=sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c - # via -r requirements/test.txt + # via -r test.txt bleach==6.0.0 \ --hash=sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414 \ --hash=sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4 @@ -37,9 +37,9 @@ certifi==2022.12.7 \ --hash=sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3 \ --hash=sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18 # via - # -r requirements/base.txt - # -r requirements/lint.txt - # -r requirements/test.txt + # -r base.txt + # -r lint.txt + # -r test.txt # requests cffi==1.15.1 \ --hash=sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5 \ @@ -197,29 +197,29 @@ charset-normalizer==3.0.1 \ --hash=sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7 \ --hash=sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8 # via - # -r requirements/base.txt - # -r requirements/lint.txt - # -r requirements/test.txt + # -r base.txt + # -r lint.txt + # -r test.txt # requests click==8.1.3 \ --hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \ --hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # click-completion # pip-tools click-completion==0.5.2 \ --hash=sha256:5bf816b81367e638a190b6e91b50779007d14301b3f9f3145d68e3cade7bce86 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt component-registry-bindings==1.3.4 \ --hash=sha256:9ea5e1f83123ed6712e15c487caf50216b865677d5054a0932afc4ad73f6c5be \ --hash=sha256:d85d140b53a6a7ba7ff08d55a5990d9199ecead107e54013b5128d7e4e628ce8 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt coverage[toml]==7.2.0 \ --hash=sha256:049806ae2df69468c130f04f0fab4212c46b34ba5590296281423bb1ae379df2 \ --hash=sha256:08e3dd256b8d3e07bb230896c8c96ec6c5dffbe5a133ba21f8be82b275b900e8 \ @@ -273,46 +273,42 @@ coverage[toml]==7.2.0 \ --hash=sha256:f3ff4205aff999164834792a3949f82435bc7c7655c849226d5836c3242d7451 \ --hash=sha256:ffa637a2d5883298449a5434b699b22ef98dd8e2ef8a1d9e60fa9cfe79813411 # via - # -r requirements/test.txt + # -r test.txt # pytest-cov -cryptography==39.0.1 \ - --hash=sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4 \ - --hash=sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f \ - --hash=sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885 \ - --hash=sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502 \ - --hash=sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41 \ - --hash=sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965 \ - --hash=sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e \ - --hash=sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc \ - --hash=sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad \ - --hash=sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505 \ - --hash=sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388 \ - --hash=sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6 \ - --hash=sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2 \ - --hash=sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef \ - --hash=sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac \ - --hash=sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695 \ - --hash=sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6 \ - --hash=sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336 \ - --hash=sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0 \ - --hash=sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c \ - --hash=sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106 \ - --hash=sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a \ - --hash=sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8 +cryptography==41.0.0 \ + --hash=sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55 \ + --hash=sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895 \ + --hash=sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be \ + --hash=sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928 \ + --hash=sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d \ + --hash=sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8 \ + --hash=sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237 \ + --hash=sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9 \ + --hash=sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78 \ + --hash=sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d \ + --hash=sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0 \ + --hash=sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46 \ + --hash=sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5 \ + --hash=sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4 \ + --hash=sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d \ + --hash=sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75 \ + --hash=sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb \ + --hash=sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2 \ + --hash=sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be # via secretstorage decorator==5.1.1 \ --hash=sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330 \ --hash=sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # gssapi # ipdb # ipython detect-secrets==1.4.0 \ --hash=sha256:d08ecabeee8b68c0acb0e8a354fb98d822a653f6ed05e520cead4c6fc1fc02cd \ --hash=sha256:d56787e339758cef48c9ccd6692f7a094b9963c979c9813580b0169e41132833 - # via -r requirements/lint.txt + # via -r lint.txt docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc @@ -321,8 +317,9 @@ exceptiongroup==1.1.0 \ --hash=sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e \ --hash=sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23 # via - # -r requirements/lint.txt - # -r requirements/test.txt + # -r lint.txt + # -r test.txt + # pytest executing==1.2.0 \ --hash=sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc \ --hash=sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107 @@ -330,7 +327,7 @@ executing==1.2.0 \ flake8==6.0.0 \ --hash=sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7 \ --hash=sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181 - # via -r requirements/lint.txt + # via -r lint.txt gssapi==1.8.2 \ --hash=sha256:02e0a8f35e1f5b1c0eada646e3da1af3022c25e8df26ded3fd18ee78abb155ea \ --hash=sha256:13aba9a947994f5f5f1fb6f425b397a359b191cee2983fa33911cf5e212d6cfb \ @@ -353,16 +350,16 @@ gssapi==1.8.2 \ --hash=sha256:f75b094913a1757e5e634b70b03e808cab0eb02c802ec50b760636b23b0aa50c \ --hash=sha256:fac7d1f4b14383bd29d3996cf5f6f23d0dc50ffd7965d2bc35bcc0849da24152 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # requests-gssapi idna==3.4 \ --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 # via - # -r requirements/base.txt - # -r requirements/lint.txt - # -r requirements/test.txt + # -r base.txt + # -r lint.txt + # -r test.txt # requests # yarl importlib-metadata==6.0.0 \ @@ -375,22 +372,22 @@ iniconfig==2.0.0 \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 # via - # -r requirements/test.txt + # -r test.txt # pytest ipdb==0.13.11 \ --hash=sha256:c23b6736f01fd4586cc2ecbebdf79a5eb454796853e1cd8f2ed3b7b91d4a3e93 \ --hash=sha256:f74c2f741c18b909eaf89f19fde973f745ac721744aa1465888ce45813b63a9c - # via -r requirements/dev.in + # via -r dev.in ipython==8.10.0 \ --hash=sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e \ --hash=sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345 # via - # -r requirements/dev.in + # -r dev.in # ipdb isort==5.11.4 \ --hash=sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6 \ --hash=sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b - # via -r requirements/lint.txt + # via -r lint.txt jaraco-classes==3.2.3 \ --hash=sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158 \ --hash=sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a @@ -409,8 +406,8 @@ jinja2==3.1.2 \ --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \ --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # click-completion keyring==23.13.1 \ --hash=sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd \ @@ -494,13 +491,13 @@ lxml==4.9.2 \ --hash=sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9 \ --hash=sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f \ --hash=sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c - # via -r requirements/test.txt + # via -r test.txt markdown-it-py==2.2.0 \ --hash=sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30 \ --hash=sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # rich markupsafe==2.1.2 \ --hash=sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed \ @@ -554,8 +551,8 @@ markupsafe==2.1.2 \ --hash=sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6 \ --hash=sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # jinja2 matplotlib-inline==0.1.6 \ --hash=sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311 \ @@ -565,14 +562,14 @@ mccabe==0.7.0 \ --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \ --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e # via - # -r requirements/lint.txt + # -r lint.txt # flake8 mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # markdown-it-py more-itertools==9.0.0 \ --hash=sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41 \ @@ -654,7 +651,7 @@ multidict==6.0.4 \ --hash=sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d \ --hash=sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba # via - # -r requirements/test.txt + # -r test.txt # yarl mypy==1.0.1 \ --hash=sha256:0af4f0e20706aadf4e6f8f8dc5ab739089146b83fd53cb4a7e0e850ef3de0bb6 \ @@ -683,43 +680,43 @@ mypy==1.0.1 \ --hash=sha256:e64f48c6176e243ad015e995de05af7f22bbe370dbb5b32bd6988438ec873919 \ --hash=sha256:e831662208055b006eef68392a768ff83596035ffd6d846786578ba1714ba8f6 \ --hash=sha256:eda5c8b9949ed411ff752b9a01adda31afe7eae1e53e946dbdf9db23865e66c4 - # via -r requirements/test.txt + # via -r test.txt mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 # via - # -r requirements/test.txt + # -r test.txt # mypy osidb-bindings==3.1.0 \ --hash=sha256:38e62d3210ba2ede9da82af0d713e19602f41b2e212641d04f17e71941394e99 \ --hash=sha256:6b222623bfdf2a90f75dcf621ec0d1c949c7b109e6ff572eb6431184b9c5154d # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt packageurl-python==0.10.4 \ --hash=sha256:5c91334f942cd55d45eb0c67dd339a535ef90e25f05b9ec016ad188ed0ef9048 \ --hash=sha256:bf8a1ffe755634776f6563904d792fb0aa13b377fc86115c36fe17f69b6e59db # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt packaging==23.0 \ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97 # via - # -r requirements/test.txt + # -r test.txt # build # pytest parse==1.19.0 \ --hash=sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b # via - # -r requirements/test.txt + # -r test.txt # behave # parse-type parse-type==0.6.0 \ --hash=sha256:20b43c660e48ed47f433bce5873a2a3d4b9b6a7ba47bd7f7d2a7cec4bec5551f \ --hash=sha256:c148e88436bd54dab16484108e882be3367f44952c649c9cd6b82a7370b650cb # via - # -r requirements/test.txt + # -r test.txt # behave parso==0.8.3 \ --hash=sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0 \ @@ -736,7 +733,7 @@ pickleshare==0.7.5 \ pip-tools==6.12.2 \ --hash=sha256:6a51f4fd67140d5e83703ebfa9610fb61398727151f56a1be02a972d062e4679 \ --hash=sha256:8b903696df4598b10d469026ef9995c5f9a874b416e88e7a214884ebe4a70245 - # via -r requirements/dev.in + # via -r dev.in pkginfo==1.9.6 \ --hash=sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546 \ --hash=sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046 @@ -745,7 +742,7 @@ pluggy==1.0.0 \ --hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \ --hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3 # via - # -r requirements/test.txt + # -r test.txt # pytest prompt-toolkit==3.0.37 \ --hash=sha256:6a2948ec427dfcc7c983027b1044b355db6aaa8be374f54ad2015471f7d81c5b \ @@ -763,7 +760,7 @@ pycodestyle==2.10.0 \ --hash=sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053 \ --hash=sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610 # via - # -r requirements/lint.txt + # -r lint.txt # flake8 pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ @@ -773,14 +770,14 @@ pyflakes==3.0.1 \ --hash=sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf \ --hash=sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd # via - # -r requirements/lint.txt + # -r lint.txt # flake8 pygments==2.14.0 \ --hash=sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297 \ --hash=sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # ipython # readme-renderer # rich @@ -792,18 +789,18 @@ pytest==7.2.1 \ --hash=sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5 \ --hash=sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42 # via - # -r requirements/test.txt + # -r test.txt # pytest-cov pytest-cov==4.0.0 \ --hash=sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b \ --hash=sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470 - # via -r requirements/test.txt + # via -r test.txt python-dateutil==2.8.2 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # component-registry-bindings # osidb-bindings pyyaml==6.0 \ @@ -848,8 +845,8 @@ pyyaml==6.0 \ --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 # via - # -r requirements/lint.txt - # -r requirements/test.txt + # -r lint.txt + # -r test.txt # detect-secrets # vcrpy readme-renderer==37.3 \ @@ -860,9 +857,9 @@ requests==2.31.0 \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 # via - # -r requirements/base.txt - # -r requirements/lint.txt - # -r requirements/test.txt + # -r base.txt + # -r lint.txt + # -r test.txt # component-registry-bindings # detect-secrets # osidb-bindings @@ -872,8 +869,8 @@ requests==2.31.0 \ requests-gssapi==1.2.3 \ --hash=sha256:20784508981401f7153c933eed095338933a40818da65a259dbf2d80dccb150e # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # osidb-bindings requests-toolbelt==0.10.1 \ --hash=sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7 \ @@ -887,8 +884,8 @@ rich==13.3.1 \ --hash=sha256:125d96d20c92b946b983d0d392b84ff945461e5a06d3867e9f9e575f8697b67f \ --hash=sha256:8aa57747f3fc3e977684f0176a88e789be314a99f99b43b75d1e9cb5dc6db9e9 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # twine secretstorage==3.3.3 \ --hash=sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77 \ @@ -898,15 +895,15 @@ shellingham==1.5.0.post1 \ --hash=sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744 \ --hash=sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # click-completion six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 # via - # -r requirements/base.txt - # -r requirements/test.txt + # -r base.txt + # -r test.txt # asttokens # behave # bleach @@ -922,8 +919,14 @@ tomli==2.0.1 \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f # via - # -r requirements/lint.txt - # -r requirements/test.txt + # -r lint.txt + # -r test.txt + # build + # coverage + # ipdb + # mypy + # pyproject-hooks + # pytest traitlets==5.9.0 \ --hash=sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8 \ --hash=sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9 @@ -933,37 +936,37 @@ traitlets==5.9.0 \ twine==4.0.2 \ --hash=sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8 \ --hash=sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8 - # via -r requirements/dev.in + # via -r dev.in types-requests==2.28.11.14 \ --hash=sha256:232792870b60adb07d23175451ab4e6190021b0c584edf052d92d9b993118f06 \ --hash=sha256:f84613b0d4c5d0eeb7879dfa05e14a3702b9c1f7a4ee81dfe9b4321b13fe93a1 - # via -r requirements/test.txt + # via -r test.txt types-urllib3==1.26.25.7 \ --hash=sha256:28d2d7f5c31ff8ed4d9d2e396ce906c49d37523c3ec207d03d3b1695755a7199 \ --hash=sha256:df4d3e5472bf8830bd74eac12d56e659f88662ba040c7d106bf3a5bee26fff28 # via - # -r requirements/test.txt + # -r test.txt # types-requests typing-extensions==4.5.0 \ --hash=sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb \ --hash=sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4 # via - # -r requirements/lint.txt - # -r requirements/test.txt + # -r lint.txt + # -r test.txt # mypy urllib3==1.26.14 \ --hash=sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72 \ --hash=sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1 # via - # -r requirements/base.txt - # -r requirements/lint.txt - # -r requirements/test.txt + # -r base.txt + # -r lint.txt + # -r test.txt # requests # twine vcrpy==4.2.1 \ --hash=sha256:7cd3e81a2c492e01c281f180bcc2a86b520b173d2b656cb5d89d99475423e013 \ --hash=sha256:efac3e2e0b2af7686f83a266518180af7a048619b2f696e7bad9520f5e2eac09 - # via -r requirements/test.txt + # via -r test.txt wcwidth==0.2.6 \ --hash=sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e \ --hash=sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0 @@ -1042,7 +1045,7 @@ wrapt==1.14.1 \ --hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \ --hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af # via - # -r requirements/test.txt + # -r test.txt # vcrpy yarl==1.8.2 \ --hash=sha256:009a028127e0a1755c38b03244c0bea9d5565630db9c4cf9572496e947137a87 \ @@ -1120,7 +1123,7 @@ yarl==1.8.2 \ --hash=sha256:fc77086ce244453e074e445104f0ecb27530d6fd3a46698e33f6c38951d5a0f1 \ --hash=sha256:ff205b58dc2929191f68162633d5e10e8044398d7a45265f90a0f1d51f85f72c # via - # -r requirements/test.txt + # -r test.txt # vcrpy zipp==3.14.0 \ --hash=sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7 \