Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ For example:
* Chandler Anderson (zenibako)
* Ben French (BenjaminFrench)
* Rupert Barrow (rupertbarrow)
* Rupesh J (rupeshjSFDC)
10 changes: 5 additions & 5 deletions cumulusci/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import os
import sys
from importlib.metadata import PackageNotFoundError, version

from simple_salesforce import api, bulk

from cumulusci.__about__ import __version__

__import__("pkg_resources").declare_namespace("cumulusci")

__location__ = os.path.dirname(os.path.realpath(__file__))

__version__ = __version__
try:
__version__ = version("cumulusci")
except PackageNotFoundError:
__version__ = "unknown"

if sys.version_info < (3, 8): # pragma: no cover
raise Exception("CumulusCI requires Python 3.8+.")
Expand Down
9 changes: 6 additions & 3 deletions cumulusci/cli/robot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import importlib.metadata
import sys

import click
import pkg_resources
import sarge

from .runtime import pass_runtime
Expand Down Expand Up @@ -109,5 +109,8 @@ def _require_npm():

def _is_package_installed(package_name):
"""Return True if the given package is installed"""
# technique shamelessly stolen from https://stackoverflow.com/a/44210735/7432
return package_name in {pkg.key for pkg in pkg_resources.working_set}
try:
importlib.metadata.distribution(package_name)
return True
except importlib.metadata.PackageNotFoundError:
return False
4 changes: 2 additions & 2 deletions cumulusci/cli/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import click
import keyring
import pkg_resources
from packaging import version

from cumulusci.cli.utils import get_installed_version
from cumulusci.core.exceptions import ConfigError, KeychainKeyNotFound, OrgNotFound
Expand Down Expand Up @@ -143,7 +143,7 @@ def check_cumulusci_version(self):
if self.project_config:
min_cci_version = self.project_config.minimum_cumulusci_version
if min_cci_version:
parsed_version = pkg_resources.parse_version(min_cci_version)
parsed_version = version.parse(min_cci_version)
if get_installed_version() < parsed_version:
raise click.UsageError(
f"This project requires CumulusCI version {min_cci_version} or later. "
Expand Down
6 changes: 3 additions & 3 deletions cumulusci/cli/tests/test_cci.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from unittest import mock

import click
import pkg_resources
import pytest
from packaging import version
from requests.exceptions import ConnectionError
from rich.console import Console

Expand Down Expand Up @@ -402,7 +402,7 @@ def test_cli():

@mock.patch(
"cumulusci.cli.cci.get_latest_final_version",
mock.Mock(return_value=pkg_resources.parse_version("100")),
mock.Mock(return_value=version.parse("100")),
)
def test_version(capsys):
run_click_command(cci.version)
Expand All @@ -413,7 +413,7 @@ def test_version(capsys):

@mock.patch(
"cumulusci.cli.cci.get_latest_final_version",
mock.Mock(return_value=pkg_resources.parse_version("1")),
mock.Mock(return_value=version.parse("1")),
)
def test_version__latest(capsys):
run_click_command(cci.version)
Expand Down
30 changes: 12 additions & 18 deletions cumulusci/cli/tests/test_robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,11 @@
from .utils import run_cli_command


class MockWorkingSet(list):
"""Mocks a pkg_resources.workingset object
class MockDistribution:
"""Mocks an importlib.metadata.Distribution object"""

Basically, a list of mock packages representing all of the packages
installed in the current environment
"""

def __init__(self, *package_names):
super().__init__()
for package_name in package_names:
pkg = mock.Mock()
pkg.key = package_name
self.append(pkg)
def __init__(self, name):
self.name = name


def mock_Command(returncodes={}):
Expand Down Expand Up @@ -49,16 +41,18 @@ def run():
return the_real_mock


@mock.patch("cumulusci.cli.robot.pkg_resources")
def test_is_package_installed(pkg_resources):
@mock.patch("cumulusci.cli.robot.importlib.metadata.distribution")
def test_is_package_installed(mock_distribution):
"""Verify that the helper _is_package_installed returns the correct result"""
pkg_resources.working_set = MockWorkingSet(
"robotframework", "robotframework-browser", "snowfakery"
)
# Test when package is installed
mock_distribution.return_value = MockDistribution("robotframework-browser")
result = _is_package_installed("robotframework-browser")
assert result is True

pkg_resources.working_set = MockWorkingSet("robotframework", "snowfakery")
# Test when package is not installed
from importlib.metadata import PackageNotFoundError

mock_distribution.side_effect = PackageNotFoundError("Package not found")
result = _is_package_installed("robotframework-browser")
assert result is False

Expand Down
6 changes: 3 additions & 3 deletions cumulusci/cli/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import time
from unittest import mock

import pkg_resources
import pytest
import requests
import responses
from packaging import version

import cumulusci

Expand Down Expand Up @@ -46,8 +46,8 @@ def test_get_latest_final_version():
def test_check_latest_version(click, get_latest_final_version, get_installed_version):
with utils.timestamp_file() as f:
f.write(str(time.time() - 4000))
get_latest_final_version.return_value = pkg_resources.parse_version("2")
get_installed_version.return_value = pkg_resources.parse_version("1")
get_latest_final_version.return_value = version.parse("2")
get_installed_version.return_value = version.parse("1")

utils.check_latest_version()
if sys.version_info > utils.LOWEST_SUPPORTED_VERSION:
Expand Down
15 changes: 10 additions & 5 deletions cumulusci/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from collections import defaultdict

import click
import pkg_resources
import requests
from packaging import version as packaging_version
from rich.console import Console

from cumulusci import __version__
Expand Down Expand Up @@ -74,7 +74,7 @@ def get_latest_final_version():
for versionstring in res["releases"].keys():
if not is_final_release(versionstring):
continue
versions.append(pkg_resources.parse_version(versionstring))
versions.append(packaging_version.parse(versionstring))
versions.sort(reverse=True)
return versions[0]

Expand Down Expand Up @@ -110,9 +110,14 @@ def check_latest_version():
)


def get_installed_version():
"""returns the version name (e.g. 2.0.0b58) that is installed"""
return pkg_resources.parse_version(__version__)
def parse_version(versionstring: str) -> packaging_version.Version:
"""Parse a version string into a Version object."""
return packaging_version.parse(versionstring)


def get_installed_version() -> packaging_version.Version:
"""Get the installed version of CumulusCI."""
return parse_version(__version__)


def win32_long_paths_enabled() -> bool:
Expand Down
8 changes: 3 additions & 5 deletions cumulusci/tasks/salesforce/update_profile.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from collections import defaultdict

import pkg_resources
from packaging import version

from cumulusci.core.exceptions import CumulusCIException, TaskOptionsError
from cumulusci.core.utils import process_bool_arg, process_list_arg
Expand Down Expand Up @@ -69,10 +69,8 @@ def _init_options(self, kwargs):
# not be using a custom `package.xml`
min_cci_version = self.project_config.minimum_cumulusci_version
if min_cci_version and "package_xml" not in self.options:
parsed_version = pkg_resources.parse_version(min_cci_version)
default_packages_arg = parsed_version >= pkg_resources.parse_version(
"3.9.0"
)
parsed_version = version.parse(min_cci_version)
default_packages_arg = parsed_version >= version.parse("3.9.0")
else:
default_packages_arg = False

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies = [
"defusedxml",
"lxml",
"MarkupSafe",
"packaging>=23.0",
"psutil",
"pydantic<2",
"PyJWT",
Expand Down
Loading