diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index e80ad31cfd..43d0cfbe66 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -11,429 +11,14 @@ env: IS_CI_WORKFLOW: True jobs: - common_checks_1: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install pipenv - - name: Pipenv install requirements and check it can be locked - run: | - pipenv --clear - time pipenv install --verbose --dev --skip-lock - time pipenv run pip install -e .[all] - time pipenv run pip install --no-deps file:plugins/aea-ledger-ethereum - time pipenv run pip install --no-deps file:plugins/aea-ledger-ethereum-flashbots - time pipenv run pip install --no-deps file:plugins/aea-ledger-cosmos - time pipenv run pip install --no-deps file:plugins/aea-ledger-fetchai - time pipenv run pip install --no-deps file:plugins/aea-ledger-solana - time pipenv lock - - name: Check plugin consistency - run: | - # check diff between plugins' LICENSE and main LICENSE - diff LICENSE plugins/aea-ledger-ethereum/LICENSE - diff LICENSE plugins/aea-ledger-cosmos/LICENSE - diff LICENSE plugins/aea-ledger-fetchai/LICENSE - common_checks_2: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - - name: Security Check - run: tox -e bandit - - name: Safety Check - run: tox -e safety - - name: Code style check - run: | - tox -e black-check - tox -e isort-check - tox -e flake8 - - name: Docstring check - run: tox -e darglint - - name: Unused code check - run: tox -e vulture - - name: Static type check - run: tox -e mypy - - name: Golang code style check (aealite) - uses: golangci/golangci-lint-action@v3.1.0 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - with: - version: v1.45.2 - args: --version - working-directory: libs/go/aealite - - common_checks_3: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - - name: Pylint check - run: | - tox -e pylint - common_checks_4: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - pip install --user --upgrade setuptools - # install Protobuf compiler - wget https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip - unzip protoc-24.3-linux-x86_64.zip -d protoc - sudo mv protoc/bin/protoc /usr/local/bin/protoc - # install IPFS - sudo apt-get install -y wget - wget -O ./go-ipfs.tar.gz https://dist.ipfs.tech/go-ipfs/v0.6.0/go-ipfs_v0.6.0_linux-amd64.tar.gz - tar xvfz go-ipfs.tar.gz - sudo mv go-ipfs/ipfs /usr/local/bin/ipfs - ipfs init - make protolint_install - - name: License Check - run: tox -e liccheck - - name: AEA Package Hashes Check - run: tox -e hash-check - - name: Check package versions in documentation - run: tox -e package-version-checks - - name: Check package dependencies - run: tox -e package-dependencies-checks - - name: Check dependencies - run: tox -e check-dependencies - - name: Check generate protocols - run: tox -e check-generate-all-protocols - - name: Generate Documentation - run: tox -e docs - - copyright_check: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - pip install --user --upgrade setuptools - - name: Copyright Check - run: tox -e check-copyright - - common_checks_5: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - if: github.base_ref == 'main' - steps: - - uses: actions/checkout@master - with: - fetch-depth: 0 - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-node@v1 - with: - node-version: 12.x - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - - name: Install markdown-spellcheck - run: sudo npm install -g markdown-spellcheck - - name: Check API Docs updated - run: tox -e check-api-docs - - name: Check spelling - run: tox -e spell-check - - docs_link_check: - continue-on-error: True - runs-on: ubuntu-latest - timeout-minutes: 5 - if: github.base_ref == 'main' - steps: - - uses: actions/checkout@master - with: - fetch-depth: 0 - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-node@v1 - with: - node-version: 12.x - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - - name: Check Docs links and IPFS hashes - run: tox -e check-doc-links-hashes - - scan: - name: gitleaks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - run: | - wget https://github.com/zricethezav/gitleaks/releases/download/v8.10.1/gitleaks_8.10.1_linux_x64.tar.gz && \ - tar -xzf gitleaks_8.10.1_linux_x64.tar.gz && \ - sudo install gitleaks /usr/bin && \ - gitleaks detect --report-format json --report-path leak_report - dependencies_checks: - continue-on-error: False - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python_version: ["3.10",] - timeout-minutes: 10 - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python_version }} - - name: Install tox - run: | - pip install tomte[tox]==0.2.13 - - name: Check Pipfile and tox.ini consistency - run: | - python ./scripts/check_pipfile_and_toxini.py - - name: Install current aea - run: | - pip install -e .[all] - - name: Check aea dependencies and imports - run: | - tox -e dependencies-check - plugins_install_check: - continue-on-error: False - runs-on: ${{ matrix.sys.os }} - env: - PYTHONUTF8: 1 - strategy: - matrix: - sys: - - { os: windows-latest, shell: "msys2 {0}" } - - { os: ubuntu-latest, shell: bash } -# - { os: macos-latest, shell: bash } - python_version: ["3.10",] - timeout-minutes: 15 - steps: - - uses: actions/checkout@master - - if: matrix.sys.os == 'windows-latest' - uses: msys2/setup-msys2@v2 - - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python_version }} - - name: Install tox - run: | - pip install tomte[tox]==0.2.13 - - name: Check plugin aea-ledger-cosmos - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-ledger-cosmos && aea generate-key cosmos && echo aea-ledger-cosmos checked!" - - name: Check plugin aea-ledger-ethereum - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-ledger-ethereum && aea generate-key ethereum && echo aea-ledger-ethereum checked!" - - name: Check plugin aea-ledger-ethereum-hwi - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-ledger-ethereum && pip install ./plugins/aea-ledger-ethereum-hwi && echo aea-ledger-hwi checked!" - - name: Check plugin aea-ledger-fetchai - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-ledger-cosmos && pip install ./plugins/aea-ledger-fetchai && aea generate-key fetchai && echo aea-ledger-fetchai checked!" - - name: Check plugin aea-cli-ipfs - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-cli-ipfs && aea ipfs --help && echo aea-cli-ipfs checked!" - - name: Check plugin aea-ledger-solana - run: | - tox -r -e plugins_env -- sh -c "pip install ./plugins/aea-ledger-solana && aea generate-key solana && echo aea-ledger-solana checked!" - protolint: - continue-on-error: False - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - name: Install protolint (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - make protolint_install - - name: Protolint check - run: | - make protolint - integration_checks: - continue-on-error: True - needs: - - common_checks_1 - - common_checks_2 - - common_checks_3 - - common_checks_4 - - dependencies_checks - - plugins_install_check - runs-on: ubuntu-latest - timeout-minutes: 50 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - # install Protobuf compiler - wget https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip - unzip protoc-24.3-linux-x86_64.zip -d protoc - sudo mv protoc/bin/protoc /usr/local/bin/protoc - - # pull pre-built images - docker pull valory/open-acn-node:latest - - name: Framework integration tests - run: tox -e py3.10 -- -m 'integration and not unstable and not ledger and not profiling' - - name: Packages integration tests - run: tox -e packages-py3.10 -- -m 'integration and not unstable and not ledger and not profiling' - - profiling_checks: - continue-on-error: True - needs: - - common_checks_1 - - common_checks_2 - - common_checks_3 - - common_checks_4 - - dependencies_checks - - plugins_install_check - runs-on: ubuntu-latest - timeout-minutes: 50 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - # install Protobuf compiler - wget https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip - unzip protoc-24.3-linux-x86_64.zip -d protoc - sudo mv protoc/bin/protoc /usr/local/bin/protoc - - name: Framework integration tests - run: tox -e py3.10 -- -m 'profiling' - - integration_checks_ledger: - continue-on-error: True - needs: - - common_checks_1 - - common_checks_2 - - common_checks_3 - - common_checks_4 - - dependencies_checks - - plugins_install_check - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: "3.10" - - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - - name: Framework integration tests - run: tox -e py3.10 -- -m 'integration and not unstable and ledger and not profiling' - - name: Packages integration tests - run: tox -e packages-py3.10 -- -m 'integration and not unstable and ledger and not profiling' - platform_checks: continue-on-error: True - needs: - - common_checks_1 - - common_checks_2 - - common_checks_3 - - common_checks_4 - - dependencies_checks - - plugins_install_check env: PYTHONUTF8: 1 # mostly for windows to work properly with utf8 files runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [macos-latest] python_version: ['3.8', '3.9', '3.10', '3.11'] timeout-minutes: 120 steps: @@ -444,31 +29,6 @@ jobs: - uses: actions/setup-go@v3 with: go-version: "1.17.7" - - if: matrix.os == 'ubuntu-latest' - name: Install dependencies (ubuntu-latest) - run: | - sudo apt-get update --fix-missing - sudo apt-get autoremove - sudo apt-get autoclean - pip install tomte[tox]==0.2.13 - # install Protobuf compiler - wget https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip - unzip protoc-24.3-linux-x86_64.zip -d protoc - sudo mv protoc/bin/protoc /usr/local/bin/protoc - make protolint_install - # install ipfs - wget https://dist.ipfs.tech/go-ipfs/v0.6.0/go-ipfs_v0.6.0_linux-amd64.tar.gz - tar -xvzf go-ipfs_v0.6.0_linux-amd64.tar.gz - cd go-ipfs - sudo ./install.sh - cd .. - rm -rf go-ipfs - ipfs init - mkdir ~/.config/solana - echo "[6,206,143,203,220,22,227,247,237,23,114,181,56,70,53,98,224,64,192,221,134,115,153,146,252,81,8,41,237,224,225,176,195,11,129,62,207,146,39,47,172,98,101,87,102,166,105,202,33,169,134,76,27,149,148,68,4,15,215,47,196,227,216,48]" > ~/.config/solana/id.json - # sudo apt-get install -y protobuf-compiler - # use sudo rm /var/lib/apt/lists/lock above in line above update if dependency install failures persist - # use sudo apt-get dist-upgrade above in line below update if dependency install failures persist - if: matrix.os == 'macos-latest' name: Install dependencies (macos-latest) run: | @@ -491,32 +51,6 @@ jobs: ipfs init mkdir ~/.config/solana echo "[6,206,143,203,220,22,227,247,237,23,114,181,56,70,53,98,224,64,192,221,134,115,153,146,252,81,8,41,237,224,225,176,195,11,129,62,207,146,39,47,172,98,101,87,102,166,105,202,33,169,134,76,27,149,148,68,4,15,215,47,196,227,216,48]" > ~/.config/solana/id.json - - if: matrix.os == 'windows-latest' - name: Install dependencies (windows-latest) - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - run: | - python -m pip install -U pip - echo "::add-path::C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64" - choco install protoc --version 24.3 - choco install mingw -y - choco install make -y - # to check make was installed - make --version - pip install tomte[tox]==0.2.13 - # wget https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-win64.zip - # unzip protoc-24.3-win64.zip -d protoc - # sudo mv protoc/bin/protoc /usr/local/bin/protoc - python scripts/update_symlinks_cross_platform.py - make protolint_install_win - # just check protolint runs - protolint version - curl https://dist.ipfs.tech/go-ipfs/v0.6.0/go-ipfs_v0.6.0_windows-amd64.zip -o go-ipfs_v0.6.0.zip - Expand-Archive -Path go-ipfs_v0.6.0.zip -DestinationPath ~\Apps\ - cp ~\Apps\go-ipfs\ipfs.exe C:\Users\runneradmin\go\bin\ - ipfs init - - - if: True name: Framework unit tests run: | @@ -529,43 +63,3 @@ jobs: - name: Plugin unit tests run: | tox -e plugins-py${{ matrix.python_version }} -- -m 'not integration and not unstable and not profiling' - - - if: matrix.os == 'ubuntu-latest' && matrix.python_version == '3.10' - name: Show full coverage report - run: | - pip install tomte[tests]==0.2.13 - coverage report -m -i - - - if: matrix.os == 'ubuntu-latest' && matrix.python_version == '3.10' - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - file: ./coverage.xml - flags: unittests - name: codecov-umbrella - fail_ci_if_error: false - - golang_checks: - continue-on-error: True - needs: - - common_checks_1 - - common_checks_2 - - common_checks_3 - - common_checks_4 - - dependencies_checks - - plugins_install_check - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.10"] - timeout-minutes: 45 - steps: - - uses: actions/checkout@master - - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - - uses: actions/setup-go@v3 - with: - go-version: "1.17.7" diff --git a/aea/cli/check_packages.py b/aea/cli/check_packages.py index 5a8e4b3b00..385df44e92 100644 --- a/aea/cli/check_packages.py +++ b/aea/cli/check_packages.py @@ -361,45 +361,62 @@ def check_public_id(configuration_file: Path) -> None: content = module_path_to_load.read_text() # check number of definitions of PUBLIC_ID. Required exactly one match. - assignments_to_public_id = re.findall("^PUBLIC_ID = (.*)", content, re.MULTILINE) + assignments_to_public_id = find_public_id_assignments(content) if len(assignments_to_public_id) != 1: raise PublicIdDefinitionError( package_type, expected_public_id, len(assignments_to_public_id) ) - # check first pattern of public id: PublicId.from_str(...) + # check for valid PUBLIC_ID patterns + public_id_match = find_public_id_from_str(content) + if public_id_match: + if str(expected_public_id) != public_id_match: + raise WrongPublicIdError(package_type, expected_public_id, public_id_match) + return + + public_id_components = find_public_id_components(content) + if public_id_components: + author, name, version = public_id_components + actual_public_id_str = f"{author}/{name}:{version}" + if str(expected_public_id) != actual_public_id_str: + raise WrongPublicIdError( + package_type, expected_public_id, actual_public_id_str + ) + return + + # if no valid pattern is found + raise WrongPublicIdError(package_type, expected_public_id, content) + + +def find_public_id_assignments(content: str) -> list: + """Find assignments to PUBLIC_ID.""" + return re.findall(r"^PUBLIC_ID = (.*)", content, re.MULTILINE) + + +def find_public_id_from_str(content: str) -> Optional[str]: + """Find public_id using the `PublicId.from_str` pattern.""" matches = re.findall( r"^PUBLIC_ID = PublicId.from_str\( *(\"(.*)\"|'(.*)') *\)$", content, re.MULTILINE, ) if len(matches) == 1: - # process the result _, match1, match2 = matches[0] - match = match1 if match1 != "" else match2 - if str(expected_public_id) != match: - raise WrongPublicIdError(package_type, expected_public_id, match) - return + # return the non-empty match + return match1 or match2 + return None - # check second pattern of public id: PublicId('...', '...', '...') + +def find_public_id_components(content: str) -> Optional[tuple]: + """Find public_id components using the `PublicId('...', '...', '...')` pattern.""" matches = re.findall( r"^PUBLIC_ID = PublicId\( *['\"](.*)['\"] *, *['\"](.*)['\"] *, *['\"](.*)['\"] *\)$", content, re.MULTILINE, ) if len(matches) == 1: - # process the result - author, name, version = matches[0] - actual_public_id_str = f"{author}/{name}:{version}" - if str(expected_public_id) != actual_public_id_str: - raise WrongPublicIdError( - package_type, expected_public_id, actual_public_id_str - ) - return - - public_id_code = matches[0] - if str(expected_public_id) not in public_id_code: - raise WrongPublicIdError(package_type, expected_public_id, public_id_code) + return matches[0] + return None class DependenciesTool: diff --git a/tests/test_cli/test_check_packages.py b/tests/test_cli/test_check_packages.py index 86747cd420..914ea13529 100644 --- a/tests/test_cli/test_check_packages.py +++ b/tests/test_cli/test_check_packages.py @@ -20,14 +20,16 @@ """Test check packages command module.""" +from contextlib import ExitStack from dataclasses import dataclass from pathlib import Path -from typing import Any, List +from typing import Any, List, Dict, Union from unittest import mock import pytest -from aea.cli.check_packages import find_all_configuration_files, get_public_id_from_yaml +from aea.cli.check_packages import find_all_configuration_files, get_public_id_from_yaml, find_public_id_assignments, \ + find_public_id_from_str, find_public_id_components from aea.test_tools.test_cases import BaseAEATestCase @@ -56,7 +58,7 @@ def _find_all_configuration_files_patch(config_files: List) -> Any: class _TestPublicIdParameters: """Dataclass to store parameters for a public id check test.""" - side_effect: List + mocked_values: Dict[str, Union[List, str]] exit_code: int message: str @@ -187,39 +189,54 @@ def test_check_public_id_failure( "test_param", [ _TestPublicIdParameters( - side_effect=[ - [(None,)], - [(None, None, None)], - ], + mocked_values={ + "find_public_id_assignments": "", + }, exit_code=1, - message="found 'None'", + message="expected unique definition of PUBLIC_ID for package fetchai/gym:0.19.0 of type connection; found 0", ), _TestPublicIdParameters( - side_effect=[ - [(None,)], - [], - [(None, None, None)], - ], + mocked_values={ + "find_public_id_assignments": [None], + "find_public_id_from_str": "match", + }, exit_code=1, - message="found 'None/None:None'", + message="expected fetchai/gym:0.19.0 for package of type connection; found 'match'", ), _TestPublicIdParameters( - side_effect=[ - [(None,)], - [], - [("fetchai", "gym", "0.19.0")], - ], + mocked_values={ + "find_public_id_assignments": [None], + "find_public_id_from_str": "fetchai/gym:0.19.0", + }, exit_code=0, message="OK!", ), _TestPublicIdParameters( - side_effect=[ - [(None,)], - [], - ["", ()], - ], + mocked_values={ + "find_public_id_assignments": [None], + "find_public_id_from_str": None, + "find_public_id_components": (None, None, None), + }, exit_code=1, - message="found ''", + message="expected fetchai/gym:0.19.0 for package of type connection; found 'None/None:None'", + ), + _TestPublicIdParameters( + mocked_values={ + "find_public_id_assignments": [None], + "find_public_id_from_str": None, + "find_public_id_components": ("fetchai", "gym", "0.19.0"), + }, + exit_code=0, + message="OK!", + ), + _TestPublicIdParameters( + mocked_values={ + "find_public_id_assignments": [None], + "find_public_id_from_str": None, + "find_public_id_components": None, + }, + exit_code=1, + message="expected fetchai/gym:0.19.0 for package of type connection; found ", ), ], ) @@ -228,12 +245,12 @@ def test_check_public_id_failure_wrong_public_id( ) -> None: """Test `check_public_id` failure.""" - with mock.patch( - "re.findall", - side_effect=test_param.side_effect, - ), _find_all_configuration_files_patch( + patches = [mock.patch(f"aea.cli.check_packages.{method}", return_value=mocked_value) for method, mocked_value in test_param.mocked_values.items()] + patches.extend([_find_all_configuration_files_patch( [self.test_connection_config] - ), check_dependencies_patch: + ), check_dependencies_patch]) + with ExitStack() as stack: + [stack.enter_context(patch) for patch in patches] result = self.invoke( "--registry-path", str(self.packages_dir_path), @@ -243,6 +260,21 @@ def test_check_public_id_failure_wrong_public_id( assert result.exit_code == test_param.exit_code, result.output assert test_param.message in result.output + def test_find_public_id_assignments(self): + content = "PUBLIC_ID = PublicId('author', 'name', '0.1.0')" + result = find_public_id_assignments(content) + assert result == ["PublicId('author', 'name', '0.1.0')"] + + def test_find_public_id_from_str(self): + content = "PUBLIC_ID = PublicId.from_str('author/name:0.1.0')" + result = find_public_id_from_str(content) + assert result == "author/name:0.1.0" + + def test_find_public_id_components(self): + content = "PUBLIC_ID = PublicId('author', 'name', '0.1.0')" + result = find_public_id_components(content) + assert result == ("author", "name", "0.1.0") + def test_check_pypi_dependencies_failure( self, ) -> None: