Skip to content

Commit

Permalink
feat: calculate library version differences (#234)
Browse files Browse the repository at this point in the history
* feat: calculate library version differences

* feat(poly check): calculate and print library version differences

* bump Poetry plugin to 1.25.0

* bump CLI to 1.12.0
  • Loading branch information
DavidVujic authored Jul 18, 2024
1 parent 05d8532 commit 1784d91
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 22 deletions.
10 changes: 7 additions & 3 deletions bases/polylith/cli/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,21 @@ def check_command(

cli_options = {
"verbose": verbose,
"short": False,
"quiet": quiet,
"strict": strict,
"alias": str.split(alias, ",") if alias else [],
}

filtered_projects = filtered_projects_data(only_projects_data, directory)
projects_data = enriched_with_lock_files_data(filtered_projects, verbose)
enriched_projects = enriched_with_lock_files_data(filtered_projects, verbose)

results = {commands.check.run(root, ns, p, cli_options) for p in projects_data}
results = {commands.check.run(root, ns, p, cli_options) for p in enriched_projects}
libs_result = commands.check.check_libs_versions(
filtered_projects, all_projects_data, cli_options
)

if not all(results):
if not all(results) or not libs_result:
raise Exit(code=1)


Expand Down
3 changes: 2 additions & 1 deletion bases/polylith/cli/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

short = Option(help="Print short view.")
short_workspace = Option(help="Display Workspace Info adjusted for many projects.")

strict = Option(
help="More strict checks when matching name of third-party libraries and imports"
help="More strict checks when matching name and version of third-party libraries and imports."
)

verbose = Option(help="More verbose output.")
Expand Down
29 changes: 27 additions & 2 deletions components/polylith/commands/check.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import Set
from typing import List, Set

from polylith import check, distributions, libs

Expand Down Expand Up @@ -27,7 +27,32 @@ def collect_known_aliases(project_data: dict, options: dict) -> Set[str]:
deps = project_data["deps"]
library_alias = options["alias"]

return distributions.known_aliases_and_sub_dependencies(deps, library_alias, options)
return distributions.known_aliases_and_sub_dependencies(
deps, library_alias, options
)


def check_libs_versions(
projects_data: List[dict], all_projects_data: List[dict], options: dict
) -> bool:
is_strict = options["strict"]
is_quiet = options["quiet"]

if not is_strict:
return True

development_data = next(p for p in all_projects_data if p["type"] == "development")

libraries = libs.report.libs_with_different_versions(
development_data, projects_data
)

if not is_quiet:
libs.report.print_libs_with_different_versions(
libraries, development_data, projects_data, options
)

return False if libraries else True


def run(root: Path, ns: str, project_data: dict, options: dict) -> bool:
Expand Down
44 changes: 43 additions & 1 deletion components/polylith/libs/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,14 @@ def libs_in_projects_table(
return table


def flattened_lib_names(projects_data: List[dict]) -> Set[str]:
return {k for proj in projects_data for k, _v in proj["deps"]["items"].items()}


def print_libs_in_projects(
development_data: dict, projects_data: List[dict], options: dict
) -> None:
flattened = {k for proj in projects_data for k, _v in proj["deps"]["items"].items()}
flattened = flattened_lib_names(projects_data)

if not flattened:
return
Expand All @@ -193,3 +197,41 @@ def print_libs_in_projects(

console.print(Padding("[data]Library versions in projects[/]", (1, 0, 0, 0)))
console.print(table, overflow="ellipsis")


def has_different_version(
lib: str, development_data: dict, projects_data: List[dict]
) -> bool:
proj_versions = [get_version(lib, p) for p in projects_data]
dev_version = get_version(lib, development_data)

return not is_same_version(proj_versions + [dev_version])


def libs_with_different_versions(
development_data: dict, projects_data: List[dict]
) -> Set[str]:
flattened = flattened_lib_names(projects_data)
return {
f
for f in flattened
if has_different_version(f, development_data, projects_data)
}


def print_libs_with_different_versions(
libraries: Set[str],
development_data: dict,
projects_data: List[dict],
options: dict,
) -> None:
if not libraries:
return

table = libs_in_projects_table(development_data, projects_data, libraries, options)

console = Console(theme=theme.poly_theme)
console.print(
Padding("[data]Different library versions in projects[/]", (1, 0, 0, 0))
)
console.print(table, overflow="ellipsis")
33 changes: 20 additions & 13 deletions components/polylith/poetry/commands/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
command_options = [
option(
long_name="strict",
description="More strict checks when matching name of third-party libraries and imports",
description="More strict checks when matching name and version of third-party libraries and imports.",
flag=True,
),
option(
Expand All @@ -27,18 +27,11 @@ class CheckCommand(Command):

options = command_options

def print_report(self, root: Path, ns: str, project_data: dict) -> bool:
def print_report(
self, root: Path, ns: str, project_data: dict, options: dict
) -> bool:
path = project_data["path"]
name = project_data["name"]
dists_fn = partial(internals.distributions, None, root)

options = {
"verbose": True if self.option("verbose") else False,
"quiet": True if self.option("quiet") else False,
"strict": True if self.option("strict") else False,
"alias": self.option("alias") or [],
"dists_fn": dists_fn,
}

try:
third_party_libs = internals.find_third_party_libs(self.poetry, path)
Expand All @@ -64,6 +57,20 @@ def handle(self) -> int:
self.poetry, directory, only_projects_data
)

results = {self.print_report(root, ns, data) for data in projects_data}
dists_fn = partial(internals.distributions, None, root)
options = {
"verbose": True if self.option("verbose") else False,
"short": False,
"quiet": True if self.option("quiet") else False,
"strict": True if self.option("strict") else False,
"alias": self.option("alias") or [],
"dists_fn": dists_fn,
}

results = {self.print_report(root, ns, data, options) for data in projects_data}

libs_result = commands.check.check_libs_versions(
projects_data, all_projects_data, options
)

return 0 if all(results) else 1
return 0 if all(results) and libs_result else 1
2 changes: 1 addition & 1 deletion projects/poetry_polylith_plugin/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "poetry-polylith-plugin"
version = "1.24.0"
version = "1.25.0"
description = "A Poetry plugin that adds tooling support for the Polylith Architecture"
authors = ["David Vujic"]
homepage = "https://davidvujic.github.io/python-polylith-docs/"
Expand Down
2 changes: 1 addition & 1 deletion projects/polylith_cli/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "polylith-cli"
version = "1.11.0"
version = "1.12.0"
description = "Python tooling support for the Polylith Architecture"
authors = ['David Vujic']
homepage = "https://davidvujic.github.io/python-polylith-docs/"
Expand Down
32 changes: 32 additions & 0 deletions test/components/polylith/libs/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,35 @@ def test_calculate_diff_strict_should_identify_close_match_for_dash_and_low_dash
res = report.calculate_diff(brick_imports, third_party_libs, True)

assert len(res) == 0


def test_libs_versions_diff():
dev_data = {"deps": {"items": {"rich": "13.*"}}}
projects_data = [{"name": "one", "deps": {"items": {"rich": "13.*"}}}]

assert report.libs_with_different_versions(dev_data, projects_data) == set()


def test_libs_versions_diff_should_return_libs_with_different_versions():
dev_data = {"deps": {"items": {"rich": "13.*"}}}

proj_one = {"name": "one", "deps": {"items": {"rich": "13.*"}}}
proj_two = {"name": "two", "deps": {"items": {"rich": "11.*"}}}
projects_data = [proj_one, proj_two]

res = report.libs_with_different_versions(dev_data, projects_data)

assert res == {"rich"}


def test_libs_versions_diff_should_only_return_libs_with_different_versions():
dev_data = {"deps": {"items": {"rich": "13.*"}}}

proj_one = {"name": "one", "deps": {"items": {"rich": "13.*"}}}
proj_two = {"name": "two", "deps": {"items": {}}}

projects_data = [proj_one, proj_two]

res = report.libs_with_different_versions(dev_data, projects_data)

assert res == set()

0 comments on commit 1784d91

Please sign in to comment.