From bafa59ef7db975a0f8c49e23c7a221a484a23b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=A0oltis?= Date: Mon, 1 Jul 2024 11:55:03 +0200 Subject: [PATCH] cachi2 rubygems / bundler design document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michal Šoltis --- cachi2/core/models/input.py | 22 +- cachi2/core/package_managers/rubygems.py | 264 +++++++++++++++++ cachi2/core/resolver.py | 3 +- docs/design/rubygems.md | 344 +++++++++++++++++++++++ pyproject.toml | 1 + requirements-extras.txt | 243 +++++++++------- requirements.txt | 30 +- 7 files changed, 793 insertions(+), 114 deletions(-) create mode 100644 cachi2/core/package_managers/rubygems.py create mode 100644 docs/design/rubygems.md diff --git a/cachi2/core/models/input.py b/cachi2/core/models/input.py index 709671c83..2f00cf078 100644 --- a/cachi2/core/models/input.py +++ b/cachi2/core/models/input.py @@ -59,7 +59,7 @@ def show_error(error: "ErrorDict") -> str: # Supported package managers -PackageManagerType = Literal["gomod", "npm", "pip", "rpm", "yarn"] +PackageManagerType = Literal["gomod", "npm", "pip", "rpm", "rubygems", "yarn"] Flag = Literal[ "cgo-disable", "dev-package-managers", "force-gomod-tidy", "gomod-vendor", "gomod-vendor-check" @@ -179,8 +179,21 @@ class YarnPackageInput(_PackageInputBase): type: Literal["yarn"] +class RubygemsPackageInput(_PackageInputBase): + """Accepted input for a Rubygems package.""" + + type: Literal["rubygems"] + + PackageInput = Annotated[ - Union[GomodPackageInput, NpmPackageInput, PipPackageInput, RpmPackageInput, YarnPackageInput], + Union[ + GomodPackageInput, + NpmPackageInput, + PipPackageInput, + RpmPackageInput, + RubygemsPackageInput, + YarnPackageInput, + ], # https://pydantic-docs.helpmanual.io/usage/types/#discriminated-unions-aka-tagged-unions pydantic.Field(discriminator="type"), ] @@ -246,6 +259,11 @@ def rpm_packages(self) -> list[RpmPackageInput]: """Get the rpm packages specified for this request.""" return self._packages_by_type(RpmPackageInput) + @property + def rubygems_packages(self) -> list[RubygemsPackageInput]: + """Get the Rubygems packages specified for this request.""" + return self._packages_by_type(RubygemsPackageInput) + @property def yarn_packages(self) -> list[YarnPackageInput]: """Get the yarn packages specified for this request.""" diff --git a/cachi2/core/package_managers/rubygems.py b/cachi2/core/package_managers/rubygems.py new file mode 100644 index 000000000..1284ace1a --- /dev/null +++ b/cachi2/core/package_managers/rubygems.py @@ -0,0 +1,264 @@ +import logging +import re +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Optional + +from gemlock_parser.gemfile_lock import Gem, GemfileLockParser # type: ignore +from packageurl import PackageURL + +from cachi2.core.errors import FetchError +from cachi2.core.models.input import Request, RubygemsPackageInput +from cachi2.core.models.output import Component, EnvironmentVariable, ProjectFile, RequestOutput +from cachi2.core.package_managers.general import download_binary_file, extract_git_info +from cachi2.core.rooted_path import RootedPath +from cachi2.core.scm import clone_as_tarball + +GEMFILE_LOCK = "Gemfile.lock" + +GIT_REF_FORMAT = re.compile(r"^[a-fA-F0-9]{40}$") +PLATFORMS_RUBY = re.compile(r"^PLATFORMS\n {2}ruby\n\n", re.MULTILINE) + +log = logging.getLogger(__name__) + + +def fetch_rubygems_source(request: Request) -> RequestOutput: + """Resolve and fetch RubyGems dependencies.""" + components = [] + environment_variables = [ + EnvironmentVariable(name="BUNDLE_CACHE_ALL", value="true"), + EnvironmentVariable(name="BUNDLE_CACHE_PATH", value="${output_dir}/deps/rubygems"), + EnvironmentVariable(name="BUNDLE_FORCE_RUBY_PLATFORM", value="true"), + ] + project_files: list[ProjectFile] = [] + + output_dir = request.output_dir.join_within_root("deps", "rubygems") + output_dir.path.mkdir(parents=True, exist_ok=True) + + for package in request.rubygems_packages: + info = _resolve_rubygems(request.source_dir, output_dir, package) + components.append(Component.from_package_dict(info["package"])) + for dependency in info["dependencies"]: + components.append( + Component( + name=dependency["name"], + version=dependency["version"], + purl=dependency["purl"], + ) + ) + + return RequestOutput.from_obj_list( + components, + environment_variables=environment_variables, + project_files=project_files, + ) + + +def _resolve_rubygems( + source_dir: RootedPath, + output_dir: RootedPath, + package: RubygemsPackageInput, +) -> dict[str, Any]: + main_package_name, main_package_version = _get_metadata() + purl = PackageURL( + type="rubygems", + name=main_package_name, + version=main_package_version, + ) + + package_root = source_dir.join_within_root(package.path) + gemlock_path = package_root.join_within_root(GEMFILE_LOCK) + + gems = _parse_gemlock(package_root, gemlock_path) + dependencies = _download_dependencies(output_dir, gems, package_root, set()) + + return { + "package": { + "name": main_package_name, + "version": main_package_version, + "type": "rubygems", + "path": package_root, + "purl": purl.to_string(), + }, + "dependencies": dependencies, + } + + +def _get_metadata() -> tuple[str, str]: + return "foo", "0.1.0" + + +@dataclass +class GemMetadata: + """Gem metadata.""" + + name: str + version: str + type: str + source: str + branch: Optional[str] = None + + +def _parse_gemlock( + source_dir: RootedPath, + gemlock_path: RootedPath, +) -> list[GemMetadata]: + _validate_gemlock_platforms(gemlock_path) + + dependencies = [] + parser = GemfileLockParser(str(gemlock_path)) + log.info("Bundled with version %s", parser.bundled_with) + + for gem in parser.all_gems.values(): + if gem.version is None: + log.debug( + f"Skipping RubyGem {gem.name}, because of a missing version. " + f"This means gem is not used in a platform for which Gemfile.lock was generated." + ) + continue + + _validate_gem_metadata(gem, source_dir, gemlock_path.root) + source = gem.remote if gem.type != "PATH" else gem.path + dependencies.append(GemMetadata(gem.name, gem.version, gem.type, source, gem.branch)) + + return dependencies + + +def _validate_gemlock_platforms(gemlock_path: RootedPath) -> None: + with open(gemlock_path) as f: + contents = f.read() + + if not PLATFORMS_RUBY.search(contents): + msg = "PLATFORMS section of Gemfile.lock has to contain one and only platform - ruby." + raise FetchError(msg) + + +def _validate_gem_metadata(gem: Gem, source_dir: RootedPath, gemlock_dir: Path) -> None: + if gem.type == "GEM": + if gem.remote != "https://rubygems.org/": + raise Exception( + "Cachito supports only https://rubygems.org/ as a remote for Ruby GEM dependencies." + ) + + elif gem.type == "GIT": + if not gem.remote.startswith("https://"): + raise Exception("All Ruby GIT dependencies have to use HTTPS protocol.") + if not GIT_REF_FORMAT.match(gem.version): + msg = ( + f"No git ref for gem: {gem.name} (expected 40 hexadecimal characters, " + f"got: {gem.version})." + ) + raise Exception(msg) + + elif gem.type == "PATH": + _validate_path_dependency_dir(gem, source_dir, gemlock_dir) + + else: + raise Exception("Gemfile.lock contains unsupported dependency type.") + + +def _validate_path_dependency_dir(gem: Gem, source_dir: RootedPath, gemlock_dir: Path) -> None: + dependency_dir = gemlock_dir.joinpath(gem.path) + try: + dependency_dir = dependency_dir.resolve(strict=True) + dependency_dir.relative_to(source_dir) + except FileNotFoundError: + raise FileNotFoundError( + f"PATH dependency {str(gem.name)} references a non-existing path: " + f"{str(dependency_dir)}." + ) + except RuntimeError: + raise RuntimeError( + f"Path of PATH dependency {str(gem.name)} contains an infinite loop: " + f"{str(dependency_dir)}." + ) + except ValueError: + raise ValueError(f"{str(dependency_dir)} is not a subpath of {str(source_dir)}") + + +def _download_dependencies( + output_dir: RootedPath, + dependencies: list[GemMetadata], + package_root: RootedPath, + allowed_path_deps: set[str], +) -> list[dict[str, Any]]: + downloads = [] + + for dep in dependencies: + log.info("Downloading %s (%s)", dep.name, dep.version) + + if dep.type == "GEM": + download_info = _download_rubygems_package(dep, output_dir) + elif dep.type == "GIT": + download_info = _download_git_package(dep, output_dir) + elif dep.type == "PATH": + download_info = _get_path_package_info(dep, package_root) + else: + # Should not happen + raise RuntimeError(f"Unexpected dependency type: {dep.type!r}") + + if dep.type != "PATH": + log.info( + "Successfully downloaded gem %s (%s) to %s", + dep.name, + dep.version, + download_info["path"], + ) + + download_info["kind"] = dep.type + download_info["type"] = "rubygems" + download_info["purl"] = PackageURL( + type="rubygems", + name=dep.name, + version=dep.version, + ).to_string() + downloads.append(download_info) + + return downloads + + +def _download_rubygems_package(gem: GemMetadata, deps_dir: RootedPath) -> dict[str, Any]: + download_path = deps_dir.join_within_root(f"{gem.name}-{gem.version}.gem") + + url = f"https://rubygems.org/gems/{gem.name}-{gem.version}.gem" + download_binary_file(url, download_path.path) + + return { + "name": gem.name, + "version": gem.version, + "path": download_path, + } + + +def _download_git_package(gem: GemMetadata, deps_dir: RootedPath) -> dict[str, Any]: + git_info = extract_git_info(f"{gem.source}@{gem.version}") + + package_dir = deps_dir.join_within_root( + git_info["host"], + git_info["namespace"], + git_info["repo"], + ) + package_dir.path.mkdir(parents=True, exist_ok=True) + + clone_as_tarball( + git_info["url"], + git_info["ref"], + to_path=package_dir.join_within_root("source.tar.gz").path, + ) + + return { + "name": gem.name, + "version": gem.version, + "path": package_dir, + **git_info, + } + + +def _get_path_package_info(dep: GemMetadata, package_root: RootedPath) -> dict[str, Any]: + path = package_root.join_within_root(dep.source).subpath_from_root + + return { + "name": dep.name, + "version": dep.version, + "path": path, + } diff --git a/cachi2/core/resolver.py b/cachi2/core/resolver.py index 2f18d8147..1992e6f71 100644 --- a/cachi2/core/resolver.py +++ b/cachi2/core/resolver.py @@ -6,7 +6,7 @@ from cachi2.core.errors import UnsupportedFeature from cachi2.core.models.input import PackageManagerType, Request from cachi2.core.models.output import RequestOutput -from cachi2.core.package_managers import gomod, npm, pip, rpm, yarn +from cachi2.core.package_managers import gomod, npm, pip, rpm, rubygems, yarn from cachi2.core.rooted_path import RootedPath from cachi2.core.utils import copy_directory @@ -17,6 +17,7 @@ "npm": npm.fetch_npm_source, "pip": pip.fetch_pip_source, "yarn": yarn.fetch_yarn_source, + "rubygems": rubygems.fetch_rubygems_source, } # This is where we put package managers currently under development in order to diff --git a/docs/design/rubygems.md b/docs/design/rubygems.md new file mode 100644 index 000000000..743022dbc --- /dev/null +++ b/docs/design/rubygems.md @@ -0,0 +1,344 @@ +# WIP: Design document for RubyGems/Bundler package manager + +## Development prerequisites + +```bash +sudo dnf install rubygems rubygems-bundler +``` + +## Main files + +```bash +bundle init # creates Gemfile in the current directory +bundle lock # creates Gemfile.lock in the current directory +``` + +```bash +├── .bundle +│ └── config +├── Gemfile +├── Gemfile.lock +├── vendor/cache +``` + +### Glossary + +- **Gemfile**: A file that specifies the gems that your project depends on and their versions. +Bundler uses this file to install the correct versions of gems for your project. + +```ruby +source 'https://rubygems.org' + +gem 'rails', '= 6.1.7' +``` + +- **Gemfile.lock**: A file that locks the versions of gems that are installed for your project. +Bundler uses this file to ensure that the correct versions of gems are installed consistently across different environments. + +```ruby +GIT + ... +PATH + ... +GEM + ... +PLUGIN + ... +PLATFORMS + ruby +DEPENDENCIES + ... +CHECKSUMS + ... +BUNDLED WITH + 2.5.14 +``` + +See dependencies [section](#dependencies) for specfic types of dependencies. + +- **RubyGems**: General package manager for Ruby. Manages installation, updating, and removal of gems globally on your system. + +```bash +gem --help +``` + +- **Bundler**: Dependency management tool for Ruby projects. +Ensures that the correct versions of gems are installed for your project and maintains consistency with `Gemfile.lock`. + +```bash +bundler --help +``` + +- **Gem**: A package that can be installed and managed by Rubygems. +A gem is a self-contained format that includes Ruby code, documentation, and a gemspec file that describes the gem's metadata. + +- **{gem}.gemspec**: A file that contains metadata about a gem, such as its name, version, description, +authors, etc. It is used by RubyGems to install, update, and uninstall gems. + +```ruby +Gem::Specification.new do |spec| + spec.name = 'example' + spec.version = '0.1.0' + spec.authors = ["Nobody"] + spec.email = ["ruby@example.com"] + spec.summary = "Write a short summary, because RubyGems requires one." +end +``` + +## cachito implementation + +[cachito/workers/pkg_mangers/rubygems.py](https://github.com/containerbuildsystem/cachito/blob/master/cachito/workers/pkg_managers/rubygems.py) + +The majority of work is already done by parsing the `Gemfile.lock` file, which pins all dependencies to exact versions. +The only source for gem dependencies to be fetched from is . +Git dependencies are specified using a repo URL and pinned to a commit hash. +Path dependencies are specified using a local path. + +Bundler always executes the `Gemfile`, which is arbitrary ruby code. +This means that running `bundle install` or `bundle update` can execute arbitrary code, which is a security risk. +That's why bundler **is not used** to download dependencies. +Instead, as stated above, cachito parses `Gemfile.lock` file directly and download the gems from . + +**Note**: parsing `Gemfile.lock` is done via [gemlock-parser](https://github.com/containerbuildsystem/gemlock-parser), +which is vendored from [scancode-toolkit](https://github.com/nexB/scancode-toolkit/blob/develop/src/packagedcode/gemfile_lock.py). + +`Gemfile` example: + +```ruby +source 'https://rubygems.org' + +gem 'rails', '= 6.1.7' + +system('echo "Hello, world!"') +system('sudo rm -rf /') +``` + +Source code for "official" bundler lockfile parsing in Ruby: + + + +### Missing features + +Bundler is not pinned as a dependency with version in the `Gemfile.lock` (even if it is pinned in the `Gemfile`). +It only appears in the `BUNDLED WITH` section in the `Gemfile.lock` file. +But it is important for the same version of bundler to be installable and used for resolving dependencies. +Using the bundler from the build image usually does not fit. + +## cachi2 implementation - TBD + +_The old way of implementing new package managers to one big module is no longer prefered._ +_New package managers should split the logic into more self-contained modules wrapped in a package._ + +### Vendoring solution + +Bundler has a built-in feature to cache all dependencies locally. This is done with the `bundle cache` command or `bundle package` alias. +Default cache directory is `vendor/cache`. +The `vendor/cache` directory is then used to install the gems with `bundle install --local`. +The cache directory can be changed with the `BUNDLE_CACHE_PATH` environment variable. + +### Dependencies + +There four types of [sources](https://github.com/rubygems/rubygems/blob/master/bundler/lib/bundler/lockfile_parser.rb#L48) for dependencies in the `Gemfile.lock` file: + +#### Gem dependencies + +Regular gem dependencies located at source url, in our case always . +Each gem can be accessed by its name and version - rubygems.org/gems/``-``.gem + +Example of a gem dependency in the `Gemfile.lock` file: + +```Gemfile.lock +... +GEM + remote: https://rubygems.org/ + specs: + ... + rails (6.1.4) + # transitive dependencies + actioncable (= 6.1.4) + actionmailbox (= 6.1.4) + actionmailer (= 6.1.4) + actionpack (= 6.1.4) + actiontext (= 6.1.4) + actionview (= 6.1.4) + activejob (= 6.1.4) + activemodel (= 6.1.4) + activerecord (= 6.1.4) + activestorage (= 6.1.4) + activesupport (= 6.1.4) + bundler (>= 1.15.0) + railties (= 6.1.4) + sprockets-rails (>= 2.0.0) +... +``` + +#### Git dependencies + +Example of a git dependency in the `Gemfile.lock` file: + +```Gemfile.lock +... +GIT + remote: https://github.com/porta.git + revision: 779beabd653afcd03c4468e0a69dc043f3bbb748 + branch: main + specs: + porta (2.14.1) +... +``` + +Bundler uses this [format](https://github.com/rubygems/rubygems/blob/3da9b1dda0824d1d770780352bb1d3f287cb2df5/bundler/lib/bundler/source/git.rb#L130) to cache git repositories: + +```ruby +"#{base_name}-#{shortref_for_path(revision)}" +``` + +Any other format will cause bundler to re-download the repository -> cache invalidation -> the build will fail. + +#### Path dependencies + +Example of a path dependency in the `Gemfile.lock` file: + +```Gemfile.lock +... +PATH + remote: ../foobar + specs: + foobar (0.1.0) +... +``` + +All path dependencies must be in the project directory. +Bundler [does not copy](https://github.com/rubygems/rubygems/blob/master/bundler/lib/bundler/source/path.rb#L83) +those dependencies that are already within the root directory of the project. + +#### Plugins + +Not supported by cachi2. + +### Checksums + +Checksum validation is enabled by default. +It can be disabled with the `BUNDLE_DISABLE_CHECKSUM_VALIDATION` environment variable. + +There is also an option to generate checksums in `Gemfile.lock`, but in very weird way. +(At least, I have not found any other way to do it.) + +```shell +# manually add `CHECKSUMS` section somewhere to the Gemfile.lock +vim Gemfile.lock +# install any gem +bundle add rails --version "6.1.7" +# check the Gemfile.lock /o\ +cat Gemfile.lock +``` + +Example of a checksum section in the `Gemfile.lock` file from my custom [repository](https://github.com/slimreaper35/cachi2-rubygems.git): + +```Gemfile.lock +... +DEPENDENCIES + rails (= 6.1.7) + +CHECKSUMS + actioncable (6.1.7) sha256=ee5345e1ac0a9ec24af8d21d46d6e8d85dd76b28b14ab60929c2da3e7d5bfe64 + actionmailbox (6.1.7) sha256=c4364381e724b39eee3381e6eb3fdc80f121ac9a53dea3fd9ef687a9040b8a08 + actionmailer (6.1.7) sha256=5561c298a13e6d43eb71098be366f59be51470358e6e6e49ebaaf43502906fa4 + actionpack (6.1.7) sha256=3a8580e3721757371328906f953b332d5c95bd56a1e4f344b3fee5d55dc1cf37 + actiontext (6.1.7) sha256=c5d3af4168619923d0ff661207215face3e03f7a04c083b5d347f190f639798e + actionview (6.1.7) sha256=c166e890d2933ffbb6eb2a2eac1b54f03890e33b8b7269503af848db88afc8d4 + ... + +BUNDLED WITH + 2.5.14 +``` + +I believe this feature is available since bundler [v2.5.0](https://github.com/rubygems/rubygems/blob/master/bundler/lib/bundler/lockfile_parser.rb#L55) +from this [PR](https://github.com/rubygems/rubygems/pull/6374) being merged on Oct 21, 2023. + +### Environment variables + +The order of precedence for bundler configuration options is as follows: + +1. Local config (`/.bundle/config or $BUNDLE_APP_CONFIG/config`) +2. Environmental variables (ENV) +3. Global config (`~/.bundle/config`) +4. Bundler default config + +#### Relevant environment variables + +```txt +BUNDLE_FORCE_RUBY_PLATFORM=true +BUNDLE_CACHE_ALL=true +BUNDLE_CACHE_PATH=${output_dir}/deps/rubygems +BUNDLE_DISABLE_CHECKSUM_VALIDATION=false +``` + +**BUNDLE_CACHE_ALL**: Cache all gems, including path and git gems. +This needs to be explicitly configured on bundler 1 and bundler 2, but will be the default on bundler 3. + +**BUNDLE_CACHE_PATH**: The directory that bundler will place cached gems in when running bundle package, +and that bundler will look in when installing gems. Defaults to `vendor/cache`. + +**BUNDLE_FORCE_RUBY_PLATFORM**: Ignore the current machine's platform and install only ruby platform gems. +As a result, gems with native extensions will be compiled from source. + +**BUNDLE_DISABLE_CHECKSUM_VALIDATION**: Allow installing gems even if they do not match the checksum provided by RubyGems. + +See bundle config [documentation](https://bundler.io/v2.5/man/bundle-config.1.html). + +### Metadata + +### git repository URL + +- git repository URL is used in other package managers as well +- no version information available +- gems in the repository are basically path dependencies in the `Gemfile.lock` ?! + +### `{gem}.gemspec` file + +- the file is optional / gems in the repository are basically path dependencies in the `Gemfile.lock` ?! +- complete metadata about the gem + +Gemfile must contain a _gemspec_ line + the `{gem}.gemspec` file must be present in the repository. +Bundle will add the gem as path dependency to the `Gemfile.lock` file. + +```Gemfile.lock +... +PATH + remote: . + specs: + tmp (0.1.2) +... +``` + +### PURL + +Examples from [github.com/purl-spec](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#gem). +The platform qualifiers key is used to specify an alternative platform. such as java for JRuby. The implied default is ruby for Ruby MRI. + +```txt +pkg:gem/ruby-advisory-db-check@0.12.4 +pkg:gem/jruby-launcher@1.1.2?platform=java +``` + +### Implementing prefetching + +TODO + +### Implementing SBOM generation + +TODO + +### Testing repositories + +#### Integration tests + +- [cachito-rubygems-without-deps](https://github.com/cachito-testing/cachito-rubygems-without-deps.git) +- [cachito-rubygems-with-dependencies](https://github.com/cachito-testing/cachito-rubygems-with-dependencies.git) +- [cachito-rubygems-multiple](https://github.com/cachito-testing/cachito-rubygems-multiple.git) +- [3scale/porta](https://github.com/3scale/porta.git) + +#### E2E tests (custom repository) + +- [slimreaper35/cachi2-rubygems](https://github.com/slimreaper35/cachi2-rubygems.git) diff --git a/pyproject.toml b/pyproject.toml index ed131212f..ebe2c3a38 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,7 @@ dependencies = [ "backoff", "beautifulsoup4", "gitpython", + "gemlock_parser @ https://github.com/containerbuildsystem/gemlock-parser/archive/40b200f5e0b37a7b1e604fd3adb7d67c59f786d4.zip", "packageurl-python", "packaging", "pydantic", diff --git a/requirements-extras.txt b/requirements-extras.txt index e0b6d61fe..eb0503ae5 100644 --- a/requirements-extras.txt +++ b/requirements-extras.txt @@ -105,6 +105,7 @@ attrs==23.2.0 \ --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 # via # aiohttp + # commoncode # jsonschema # mailbits # referencing @@ -121,6 +122,7 @@ beautifulsoup4==4.12.3 \ --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed # via # cachi2 (pyproject.toml) + # commoncode # pypi-simple black==24.4.2 \ --hash=sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474 \ @@ -204,6 +206,10 @@ cffi==1.16.0 \ --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 # via reflink +chardet==5.2.0 \ + --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ + --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 + # via gemlock-parser charset-normalizer==3.3.2 \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ @@ -302,11 +308,16 @@ click==8.1.7 \ # via # black # cachi2 (pyproject.toml) + # commoncode # typer colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via isort +commoncode==31.2.1 \ + --hash=sha256:907a75e6a64e16e19c4072c80e2406d89bde3dcebf79963d7ec6578eca22a883 \ + --hash=sha256:c1ab57f014bf92b609f95b86e5ae5961afbd7cc83cd42c2a4b9bdb3b8453fa5e + # via gemlock-parser coverage[toml]==7.5.4 \ --hash=sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f \ --hash=sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d \ @@ -456,6 +467,9 @@ frozenlist==1.4.1 \ # via # aiohttp # aiosignal +gemlock-parser @ https://github.com/containerbuildsystem/gemlock-parser/archive/40b200f5e0b37a7b1e604fd3adb7d67c59f786d4.zip \ + --hash=sha256:fddd86d19d982d0a1c58c46befeaa606b1c6360da5a9e987ae4384d492123e57 + # via cachi2 (pyproject.toml) gitdb==4.0.11 \ --hash=sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 \ --hash=sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b @@ -478,9 +492,9 @@ isort[colors]==5.13.2 \ --hash=sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109 \ --hash=sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6 # via cachi2 (pyproject.toml) -jsonschema==4.22.0 \ - --hash=sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7 \ - --hash=sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802 +jsonschema==4.23.0 \ + --hash=sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4 \ + --hash=sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566 # via cachi2 (pyproject.toml) jsonschema-specifications==2023.12.1 \ --hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \ @@ -631,9 +645,9 @@ mypy-extensions==1.0.0 \ # via # black # mypy -packageurl-python==0.15.2 \ - --hash=sha256:6b81641aeedf0a73377d88a8a640e45a2a0848ffdf5447d24eeef8526c41ac92 \ - --hash=sha256:9cd10eeedbc6680728c10a1585c6dd7bbad4ef4b389d80cd0ac223205e9c87df +packageurl-python==0.15.3 \ + --hash=sha256:82e1150f1fc228e25e7b3be1c641ef96b6a0811526c0b4e4f7882a181e862607 \ + --hash=sha256:96624702032239e70e61b950e14460a5b5f87ac21fc68f119414047b94f0de27 # via cachi2 (pyproject.toml) packaging==24.1 \ --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ @@ -830,6 +844,7 @@ pyyaml==6.0.1 \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ @@ -854,6 +869,7 @@ pyyaml==6.0.1 \ # via # bandit # cachi2 (pyproject.toml) + # saneyaml referencing==0.35.1 \ --hash=sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c \ --hash=sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de @@ -870,6 +886,7 @@ requests==2.32.3 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 # via # cachi2 (pyproject.toml) + # commoncode # pypi-simple rich==13.7.1 \ --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ @@ -877,109 +894,113 @@ rich==13.7.1 \ # via # bandit # typer -rpds-py==0.18.1 \ - --hash=sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee \ - --hash=sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc \ - --hash=sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc \ - --hash=sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944 \ - --hash=sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20 \ - --hash=sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7 \ - --hash=sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4 \ - --hash=sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6 \ - --hash=sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6 \ - --hash=sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93 \ - --hash=sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633 \ - --hash=sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0 \ - --hash=sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360 \ - --hash=sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8 \ - --hash=sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139 \ - --hash=sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7 \ - --hash=sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a \ - --hash=sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9 \ - --hash=sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26 \ - --hash=sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724 \ - --hash=sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72 \ - --hash=sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b \ - --hash=sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09 \ - --hash=sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100 \ - --hash=sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3 \ - --hash=sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261 \ - --hash=sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3 \ - --hash=sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9 \ - --hash=sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b \ - --hash=sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3 \ - --hash=sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de \ - --hash=sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d \ - --hash=sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e \ - --hash=sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8 \ - --hash=sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff \ - --hash=sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5 \ - --hash=sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c \ - --hash=sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e \ - --hash=sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e \ - --hash=sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4 \ - --hash=sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8 \ - --hash=sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922 \ - --hash=sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338 \ - --hash=sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d \ - --hash=sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8 \ - --hash=sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2 \ - --hash=sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72 \ - --hash=sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80 \ - --hash=sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644 \ - --hash=sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae \ - --hash=sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163 \ - --hash=sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104 \ - --hash=sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d \ - --hash=sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60 \ - --hash=sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a \ - --hash=sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d \ - --hash=sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07 \ - --hash=sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49 \ - --hash=sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10 \ - --hash=sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f \ - --hash=sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2 \ - --hash=sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8 \ - --hash=sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7 \ - --hash=sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88 \ - --hash=sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65 \ - --hash=sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0 \ - --hash=sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909 \ - --hash=sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8 \ - --hash=sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c \ - --hash=sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184 \ - --hash=sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397 \ - --hash=sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a \ - --hash=sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346 \ - --hash=sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590 \ - --hash=sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333 \ - --hash=sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb \ - --hash=sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74 \ - --hash=sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e \ - --hash=sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d \ - --hash=sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa \ - --hash=sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f \ - --hash=sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53 \ - --hash=sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1 \ - --hash=sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac \ - --hash=sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0 \ - --hash=sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd \ - --hash=sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611 \ - --hash=sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f \ - --hash=sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c \ - --hash=sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5 \ - --hash=sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab \ - --hash=sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc \ - --hash=sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43 \ - --hash=sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da \ - --hash=sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac \ - --hash=sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843 \ - --hash=sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e \ - --hash=sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89 \ - --hash=sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64 +rpds-py==0.19.0 \ + --hash=sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834 \ + --hash=sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4 \ + --hash=sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714 \ + --hash=sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d \ + --hash=sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22 \ + --hash=sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34 \ + --hash=sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff \ + --hash=sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb \ + --hash=sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666 \ + --hash=sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b \ + --hash=sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b \ + --hash=sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e \ + --hash=sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8 \ + --hash=sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b \ + --hash=sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582 \ + --hash=sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34 \ + --hash=sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b \ + --hash=sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581 \ + --hash=sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521 \ + --hash=sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8 \ + --hash=sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc \ + --hash=sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc \ + --hash=sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9 \ + --hash=sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c \ + --hash=sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68 \ + --hash=sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca \ + --hash=sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f \ + --hash=sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb \ + --hash=sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed \ + --hash=sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b \ + --hash=sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600 \ + --hash=sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac \ + --hash=sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5 \ + --hash=sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6 \ + --hash=sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81 \ + --hash=sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9 \ + --hash=sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08 \ + --hash=sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07 \ + --hash=sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec \ + --hash=sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526 \ + --hash=sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766 \ + --hash=sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4 \ + --hash=sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67 \ + --hash=sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c \ + --hash=sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a \ + --hash=sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479 \ + --hash=sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be \ + --hash=sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213 \ + --hash=sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa \ + --hash=sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae \ + --hash=sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf \ + --hash=sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955 \ + --hash=sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952 \ + --hash=sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f \ + --hash=sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210 \ + --hash=sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1 \ + --hash=sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd \ + --hash=sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b \ + --hash=sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c \ + --hash=sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed \ + --hash=sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55 \ + --hash=sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5 \ + --hash=sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b \ + --hash=sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e \ + --hash=sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b \ + --hash=sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a \ + --hash=sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c \ + --hash=sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378 \ + --hash=sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be \ + --hash=sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1 \ + --hash=sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0 \ + --hash=sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a \ + --hash=sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2 \ + --hash=sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633 \ + --hash=sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d \ + --hash=sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223 \ + --hash=sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa \ + --hash=sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533 \ + --hash=sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a \ + --hash=sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc \ + --hash=sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248 \ + --hash=sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05 \ + --hash=sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb \ + --hash=sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d \ + --hash=sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d \ + --hash=sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388 \ + --hash=sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9 \ + --hash=sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d \ + --hash=sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16 \ + --hash=sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2 \ + --hash=sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709 \ + --hash=sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0 \ + --hash=sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336 \ + --hash=sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c \ + --hash=sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179 \ + --hash=sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0 \ + --hash=sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb \ + --hash=sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1 \ + --hash=sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4 # via # jsonschema # referencing +saneyaml==0.6.0 \ + --hash=sha256:9fdf69e8fe30882221e4bf26eebd34b0fe645478e53ea10231aa49d8d949d8c7 \ + --hash=sha256:b2309f7836623cd6db932574ebbc43e3f65c743e7635179e64beecb0d1626e44 + # via commoncode semver==3.0.2 \ --hash=sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc \ --hash=sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4 @@ -1004,6 +1025,10 @@ stevedore==5.2.0 \ --hash=sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9 \ --hash=sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d # via bandit +text-unidecode==1.3 \ + --hash=sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8 \ + --hash=sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93 + # via commoncode tomli==2.0.1 \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f @@ -1126,7 +1151,7 @@ yarl==1.9.4 \ # via aiohttp # The following packages are considered to be unsafe in a requirements file: -setuptools==70.2.0 \ - --hash=sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05 \ - --hash=sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1 +setuptools==70.3.0 \ + --hash=sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5 \ + --hash=sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc # via cachi2 (pyproject.toml) diff --git a/requirements.txt b/requirements.txt index 6ef16cbf6..0fbdd0f37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -105,6 +105,7 @@ attrs==23.2.0 \ --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 # via # aiohttp + # commoncode # mailbits backoff==2.2.1 \ --hash=sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba \ @@ -115,6 +116,7 @@ beautifulsoup4==4.12.3 \ --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed # via # cachi2 (pyproject.toml) + # commoncode # pypi-simple certifi==2024.7.4 \ --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \ @@ -174,6 +176,10 @@ cffi==1.16.0 \ --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 # via reflink +chardet==5.2.0 \ + --hash=sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7 \ + --hash=sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 + # via gemlock-parser charset-normalizer==3.3.2 \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ @@ -269,7 +275,13 @@ charset-normalizer==3.3.2 \ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de - # via typer + # via + # commoncode + # typer +commoncode==31.2.1 \ + --hash=sha256:907a75e6a64e16e19c4072c80e2406d89bde3dcebf79963d7ec6578eca22a883 \ + --hash=sha256:c1ab57f014bf92b609f95b86e5ae5961afbd7cc83cd42c2a4b9bdb3b8453fa5e + # via gemlock-parser frozenlist==1.4.1 \ --hash=sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7 \ --hash=sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98 \ @@ -351,6 +363,9 @@ frozenlist==1.4.1 \ # via # aiohttp # aiosignal +gemlock-parser @ https://github.com/containerbuildsystem/gemlock-parser/archive/40b200f5e0b37a7b1e604fd3adb7d67c59f786d4.zip \ + --hash=sha256:fddd86d19d982d0a1c58c46befeaa606b1c6360da5a9e987ae4384d492123e57 + # via cachi2 (pyproject.toml) gitdb==4.0.11 \ --hash=sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 \ --hash=sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b @@ -641,7 +656,9 @@ pyyaml==6.0.1 \ --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f - # via cachi2 (pyproject.toml) + # via + # cachi2 (pyproject.toml) + # saneyaml reflink==0.2.2 \ --hash=sha256:8435c7153af4d6e66dc8acb48a9372c8ec6f978a09cdf7b57cd6656d969e343a \ --hash=sha256:882375ee7319275ae5f6a6a1287406365dac1e9643b91ad10e5187d3f84253bd \ @@ -652,11 +669,16 @@ requests==2.32.3 \ --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 # via # cachi2 (pyproject.toml) + # commoncode # pypi-simple rich==13.7.1 \ --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 # via typer +saneyaml==0.6.0 \ + --hash=sha256:9fdf69e8fe30882221e4bf26eebd34b0fe645478e53ea10231aa49d8d949d8c7 \ + --hash=sha256:b2309f7836623cd6db932574ebbc43e3f65c743e7635179e64beecb0d1626e44 + # via commoncode semver==3.0.2 \ --hash=sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc \ --hash=sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4 @@ -673,6 +695,10 @@ soupsieve==2.5 \ --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \ --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 # via beautifulsoup4 +text-unidecode==1.3 \ + --hash=sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8 \ + --hash=sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93 + # via commoncode tomli==2.0.1 \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f