Skip to content
This repository has been archived by the owner on Dec 18, 2022. It is now read-only.

Commit

Permalink
Merge pull request #43 from MousaZeidBaker/feat/version-constraints
Browse files Browse the repository at this point in the history
Add support for other version constraints
  • Loading branch information
MousaZeidBaker authored May 9, 2022
2 parents ea4b188 + a5d8047 commit dab454d
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 51 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "poetryup"
version = "0.6.4"
version = "0.7.0"
description = "Update dependencies and bump their version in the pyproject.toml file"
authors = ["Mousa Zeid Baker"]
packages = [
Expand Down
47 changes: 40 additions & 7 deletions src/poetryup/core/pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import tomlkit
from packaging import version as version_

from poetryup.models.dependency import Dependency
from poetryup.models.dependency import Constraint, Dependency


class Pyproject:
Expand Down Expand Up @@ -117,21 +117,54 @@ def bumped_dependencies(self) -> List[Dependency]:

bumped_dependencies: List[Dependency] = []
for dependency in self.dependencies:
constraint = dependency.constraint

# check for dependencies whom version can't be bumped
if (
constraint == Constraint.MULTIPLE_CONSTRAINTS
or constraint == Constraint.MULTIPLE_REQUIREMENTS
or constraint == Constraint.WILDCARD
):
bumped_dependencies.append(dependency)
continue

# search for lock dependency
lock_dependency = self.search_dependency(
lock_dependencies,
dependency.name,
)
if lock_dependency is None:
# lock dependency not found, dependency stays unchanged
bumped_dependencies.append(dependency)
continue

bumped_version = None
if constraint == Constraint.CARET:
bumped_version = "^" + lock_dependency.version
elif constraint == Constraint.TILDE:
bumped_version = "~" + lock_dependency.version
elif constraint == Constraint.INEQUALITY:
version_str = ""
if isinstance(dependency.version, str):
version_str = dependency.version
elif isinstance(dependency.version, Dict):
version_str = dependency.version.get("version", "")

if version_str[:2] == ">=":
bumped_version = ">=" + lock_dependency.version
elif constraint == Constraint.EXACT:
bumped_version = lock_dependency.version

version = dependency.version
if isinstance(version, str):
version = dependency.constraint + lock_dependency.version
if bumped_version is None:
# bump version can't be determined, version stays unchanged
pass
elif isinstance(version, str):
version = bumped_version
elif (
isinstance(version, Dict) and version.get("version") is not None
):
version["version"] = (
dependency.constraint + lock_dependency.version
)
version["version"] = bumped_version

bumped_dependencies.append(
Dependency(
Expand Down Expand Up @@ -186,7 +219,7 @@ def update_dependencies(
# other
groups = {}
for dependency in self.dependencies:
if skip_exact and dependency.constraint == "":
if skip_exact and dependency.constraint == Constraint.EXACT:
# skip dependencies with an exact version
continue
if isinstance(dependency.version, str):
Expand Down
42 changes: 34 additions & 8 deletions src/poetryup/models/dependency.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
from dataclasses import dataclass
from enum import Enum
from typing import Dict, List, Union


class Constraint(str, Enum):
# https://python-poetry.org/docs/dependency-specification
CARET = "caret"
TILDE = "tilde"
WILDCARD = "wildcard"
INEQUALITY = "inequality"
EXACT = "exact"
MULTIPLE_REQUIREMENTS = "multiple_requirements"
MULTIPLE_CONSTRAINTS = "multiple_constraint"


@dataclass(frozen=True)
class Dependency:
"""A class to represent a dependency
Expand All @@ -22,11 +34,25 @@ def normalized_name(self) -> str:
return self.name.replace("_", "-").lower()

@property
def constraint(self) -> str:
if isinstance(self.version, str):
if self.version[0].startswith(("^", "~")):
return self.version[0]
elif isinstance(self.version, Dict):
if self.version.get("version", "").startswith(("^", "~")):
return self.version["version"][0]
return "" # dependencies with exact version or multiple versions
def constraint(self) -> Constraint:
if isinstance(self.version, List):
return Constraint.MULTIPLE_CONSTRAINTS

version = (
self.version
if isinstance(self.version, str)
else self.version.get("version", "")
)

if "," in version:
return Constraint.MULTIPLE_REQUIREMENTS
elif version[:1] == "^":
return Constraint.CARET
elif version[:1] == "~":
return Constraint.TILDE
elif "*" in version:
return Constraint.WILDCARD
elif version.startswith((">", "<", ">=", "<=", "!=")):
return Constraint.INEQUALITY
elif version[:1].isdigit():
return Constraint.EXACT
48 changes: 22 additions & 26 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,31 @@ def mock_poetry_commands(mocker: MockerFixture) -> None:
return_value="1.1.0",
)

dependencies = [
"poetryup",
"poetryup-caret",
"poetryup-tilde",
"poetryup-wildcard",
"poetryup-inequality-greater-than",
"poetryup-inequality-greater-than-or-equal",
"poetryup-inequality-less-than",
"poetryup-inequality-less-than-or-equal",
"poetryup-inequality-not-equal",
"poetryup-exact",
"poetryup-multiple-requirements",
"poetryup-multiple-constraints",
"poetryup-restricted",
"poetryup-git",
"poetryup-underscore",
"poetryup-capital",
]
s = " 0.2.0 Some description\n└── some-package >=0.10.2,<0.11.0\n"
return_value = s.join(dependencies) + s

mocker.patch.object(
Pyproject,
"_Pyproject__run_poetry_show",
return_value=(
"poetryup 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-caret 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-tilde 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-exact 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-restricted 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-git 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-underscore 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
"poetryup-capital 0.2.0 "
"pyproject.toml file"
"\n└── toml >=0.10.2,<0.11.0\n"
),
return_value=return_value,
)

mocker.patch.object(
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/fixtures/expected_pyproject/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@ poetryup = "^0.2.0"
[tool.poetry.group.main.dependencies]
poetryup_caret = "^0.2.0"
poetryup_tilde = "~0.2.0"
poetryup_wildcard = "*"
poetryup_inequality_greater_than = ">0.1.0"
poetryup_inequality_greater_than_or_equal = ">=0.2.0"
poetryup_inequality_less_than = "<0.1.0"
poetryup_inequality_less_than_or_equal = "<=0.1.0"
poetryup_inequality_not_equal = "!=0.1.0"
poetryup_exact = "0.2.0"
poetryup_multiple_requirements = ">=0.1.0,<0.2.0"
poetryup_multiple_constraints = [
{version = "0.1.0", python = "^2.7"},
{version = ">=0.2.0", python = ">=3.7"},
]
poetryup_restricted = { version = "^0.2.0", python = "<3.7" }
poetryup_git = { git = "https://github.com/MousaZeidBaker/poetryup.git" }
poetryup_underscore = "^0.2.0"
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/fixtures/input_pyproject/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,18 @@ poetryup = "^0.1.0"
[tool.poetry.group.main.dependencies]
poetryup_caret = "^0.1.0"
poetryup_tilde = "~0.1.0"
poetryup_wildcard = "*"
poetryup_inequality_greater_than = ">0.1.0"
poetryup_inequality_greater_than_or_equal = ">=0.1.0"
poetryup_inequality_less_than = "<0.1.0"
poetryup_inequality_less_than_or_equal = "<=0.1.0"
poetryup_inequality_not_equal = "!=0.1.0"
poetryup_exact = "0.1.0"
poetryup_multiple_requirements = ">=0.1.0,<0.2.0"
poetryup_multiple_constraints = [
{version = "0.1.0", python = "^2.7"},
{version = ">=0.2.0", python = ">=3.7"},
]
poetryup_restricted = { version = "^0.1.0", python = "<3.7" }
poetryup_git = { git = "https://github.com/MousaZeidBaker/poetryup.git" }
poetryup_underscore = "^0.1.0"
Expand Down
49 changes: 40 additions & 9 deletions tests/unit/test_dependency.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from poetryup.models.dependency import Dependency
from poetryup.models.dependency import Constraint, Dependency


def test_normalized_name() -> None:
Expand All @@ -12,22 +12,53 @@ def test_normalized_name() -> None:

def test_constraint() -> None:
dependency = Dependency(
name="poetry_up",
name="poetryup",
version="^0.1.0",
group="default",
)
assert dependency.constraint == "^"
assert dependency.constraint == Constraint.CARET

dependency = Dependency(
name="poetry_up",
version={"version": "^0.1.0"},
name="poetryup",
version="~0.1.0",
group="default",
)
assert dependency.constraint == "^"
assert dependency.constraint == Constraint.TILDE

dependency = Dependency(
name="poetry_up",
version=[],
name="poetryup",
version="0.*",
group="default",
)
assert dependency.constraint == Constraint.WILDCARD

dependency = Dependency(
name="poetryup",
version="!=0.1.0",
group="default",
)
assert dependency.constraint == Constraint.INEQUALITY

dependency = Dependency(
name="poetryup",
version="0.1.0",
group="default",
)
assert dependency.constraint == Constraint.EXACT

dependency = Dependency(
name="poetryup",
version=">=0.1.0,<0.2.0",
group="default",
)
assert dependency.constraint == Constraint.MULTIPLE_REQUIREMENTS

dependency = Dependency(
name="poetryup",
version=[
{"version": "0.1.0", "python": "^2.7"},
{"version": ">=0.2.0", "python": ">=3.7"},
],
group="default",
)
assert dependency.constraint == ""
assert dependency.constraint == Constraint.MULTIPLE_CONSTRAINTS
18 changes: 18 additions & 0 deletions tests/unit/test_pyproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,18 @@ def test_update_dependencies(
]
assert table["poetryup_caret"] == "^0.2.0"
assert table["poetryup_tilde"] == "~0.2.0"
assert table["poetryup_wildcard"] == "*"
assert table["poetryup_inequality_greater_than"] == ">0.1.0"
assert table["poetryup_inequality_greater_than_or_equal"] == ">=0.2.0"
assert table["poetryup_inequality_less_than"] == "<0.1.0"
assert table["poetryup_inequality_less_than_or_equal"] == "<=0.1.0"
assert table["poetryup_inequality_not_equal"] == "!=0.1.0"
assert table["poetryup_exact"] == "0.2.0"
assert table["poetryup_multiple_requirements"] == ">=0.1.0,<0.2.0"
assert table["poetryup_multiple_constraints"] == [
{"version": "0.1.0", "python": "^2.7"},
{"version": ">=0.2.0", "python": ">=3.7"},
]
assert table["poetryup_restricted"] == {
"version": "^0.2.0",
"python": "<3.7",
Expand Down Expand Up @@ -68,7 +79,14 @@ def test_update_dependencies_latest(
packages=[
"poetryup_caret@latest",
"poetryup_tilde@latest",
"poetryup_wildcard@latest",
"poetryup_inequality_greater_than@latest",
"poetryup_inequality_greater_than_or_equal@latest",
"poetryup_inequality_less_than@latest",
"poetryup_inequality_less_than_or_equal@latest",
"poetryup_inequality_not_equal@latest",
"poetryup_exact@latest",
"poetryup_multiple_requirements@latest",
"poetryup_underscore@latest",
"Poetryup_Capital@latest",
],
Expand Down

0 comments on commit dab454d

Please sign in to comment.