From 13e9f3915b79fdacb0e3e7b89ac01e9b99edb697 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Thu, 15 Aug 2024 09:13:00 +0200 Subject: [PATCH 01/15] add dependancy_check.py + test --- exasol/toolbox/tools/dependencies_check.py | 28 ++++++++++++++++ test/unit/dependency_check_test.py | 37 ++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 exasol/toolbox/tools/dependencies_check.py create mode 100644 test/unit/dependency_check_test.py diff --git a/exasol/toolbox/tools/dependencies_check.py b/exasol/toolbox/tools/dependencies_check.py new file mode 100644 index 00000000..5a73bd12 --- /dev/null +++ b/exasol/toolbox/tools/dependencies_check.py @@ -0,0 +1,28 @@ +from tomlkit import loads +from sys import exit +import pytest + + +FILTER = ['url', 'git', 'path'] + + +def _source_filter(version, filter): + output = False + if isinstance(version, dict): + for key in version.keys(): + if key in filter: + output = True + return output + + +def dependency_check(): + with open("pyproject.toml", 'r') as toml: + toml = loads(toml.read()) + for _, version in toml["tool"]["poetry"]["dependencies"].items(): + if _source_filter(version, FILTER): + exit(1) + pass + exit(0) + + +dependency_check() diff --git a/test/unit/dependency_check_test.py b/test/unit/dependency_check_test.py new file mode 100644 index 00000000..d31d7dd1 --- /dev/null +++ b/test/unit/dependency_check_test.py @@ -0,0 +1,37 @@ +from tomlkit import loads +import pytest +from exasol.toolbox.tools.dependencies_check import _source_filter + +@pytest.mark.parametrize( + "filter,source,expected", + [ + ( + ['url', 'git', 'path'], + """example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"}""", + True), + ( + ['url', 'git', 'path'], + """example-git = {git = "git@github.com:requests/requests.git"}""", + True), + ( + ['url', 'git', 'path'], + """example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"}""", + True), + ( + ['url', 'git', 'path'], + """example-url = {platform = "darwin", url = "https://example.com/my-package-0.1.0.tar.gz"}""", + True), + ( + ['url', 'git', 'path'], + """example = "^2.31.0.6" """, + False), + ( + ['url', 'git', 'path'], + """python = ">=3.8.0,<4.0" """, + False + ) + ] +) +def test_dependencies_check(filter, source, expected): + for _, version in loads(source).items(): + assert _source_filter(version, filter) == expected From d96fb65319796f2eeb68025e4ba60dde116b1b77 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 20 Aug 2024 13:26:23 +0200 Subject: [PATCH 02/15] fix dependancy_check.py --- exasol/toolbox/tools/dependencies_check.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exasol/toolbox/tools/dependencies_check.py b/exasol/toolbox/tools/dependencies_check.py index 5a73bd12..d41fa1f6 100644 --- a/exasol/toolbox/tools/dependencies_check.py +++ b/exasol/toolbox/tools/dependencies_check.py @@ -25,4 +25,5 @@ def dependency_check(): exit(0) -dependency_check() +if __name__ == "__main__": + dependency_check() From da4854e0db464500fab4b6edc86d05346f97492c Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 20 Aug 2024 15:17:17 +0200 Subject: [PATCH 03/15] add output for problematic dependencies --- exasol/toolbox/tools/dependencies_check.py | 25 +++++++++++++------ ...eck_test.py => dependencies_check_test.py} | 12 ++++----- 2 files changed, 24 insertions(+), 13 deletions(-) rename test/unit/{dependency_check_test.py => dependencies_check_test.py} (90%) diff --git a/exasol/toolbox/tools/dependencies_check.py b/exasol/toolbox/tools/dependencies_check.py index d41fa1f6..2a115600 100644 --- a/exasol/toolbox/tools/dependencies_check.py +++ b/exasol/toolbox/tools/dependencies_check.py @@ -7,22 +7,33 @@ def _source_filter(version, filter): - output = False + output = None if isinstance(version, dict): for key in version.keys(): if key in filter: - output = True + output = key return output def dependency_check(): with open("pyproject.toml", 'r') as toml: toml = loads(toml.read()) - for _, version in toml["tool"]["poetry"]["dependencies"].items(): - if _source_filter(version, FILTER): - exit(1) - pass - exit(0) + dependencies = [] + for name, version in toml["tool"]["poetry"]["dependencies"].items(): + key = _source_filter(version, FILTER) + if key: + dependencies.append(f"{[key]} | {name} : {version}") + + if not dependencies: + exit(0) + else: + if len(dependencies) == 1: + output = "One dependency is not allowed!" + else: + output = f"{len(dependencies)} dependency are not allowed!" + for dependency in dependencies: + output += f"\n{dependency}" + exit(output) if __name__ == "__main__": diff --git a/test/unit/dependency_check_test.py b/test/unit/dependencies_check_test.py similarity index 90% rename from test/unit/dependency_check_test.py rename to test/unit/dependencies_check_test.py index d31d7dd1..c1fbffff 100644 --- a/test/unit/dependency_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -8,27 +8,27 @@ ( ['url', 'git', 'path'], """example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"}""", - True), + 'url'), ( ['url', 'git', 'path'], """example-git = {git = "git@github.com:requests/requests.git"}""", - True), + 'git'), ( ['url', 'git', 'path'], """example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"}""", - True), + 'path'), ( ['url', 'git', 'path'], """example-url = {platform = "darwin", url = "https://example.com/my-package-0.1.0.tar.gz"}""", - True), + 'url'), ( ['url', 'git', 'path'], """example = "^2.31.0.6" """, - False), + None), ( ['url', 'git', 'path'], """python = ">=3.8.0,<4.0" """, - False + None ) ] ) From 767e38c6c3f727a587ee8e80bd9bdcd832ff0894 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 21 Aug 2024 12:09:55 +0200 Subject: [PATCH 04/15] output changed --- exasol/toolbox/tools/dependencies_check.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/exasol/toolbox/tools/dependencies_check.py b/exasol/toolbox/tools/dependencies_check.py index 2a115600..b2647e05 100644 --- a/exasol/toolbox/tools/dependencies_check.py +++ b/exasol/toolbox/tools/dependencies_check.py @@ -22,17 +22,12 @@ def dependency_check(): for name, version in toml["tool"]["poetry"]["dependencies"].items(): key = _source_filter(version, FILTER) if key: - dependencies.append(f"{[key]} | {name} : {version}") - - if not dependencies: - exit(0) - else: - if len(dependencies) == 1: - output = "One dependency is not allowed!" - else: - output = f"{len(dependencies)} dependency are not allowed!" - for dependency in dependencies: - output += f"\n{dependency}" + dependencies.append(f"{name} = {version}") + + if dependencies: + n = len(dependencies) + suffix = "y" if n == 1 else "ies" + output = f"{n} illegal dependenc{suffix}:\n" + "\n".join(dependencies) exit(output) From 1ffe47d9783d66b864a02c305321b4ebd4e53c06 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 3 Sep 2024 10:09:44 +0200 Subject: [PATCH 05/15] add nox task + test --- exasol/toolbox/nox/_dependencies_check.py | 69 ++++++++++++++++++ exasol/toolbox/nox/tasks.py | 3 + exasol/toolbox/tools/dependencies_check.py | 35 --------- test/unit/dependencies_check_test.py | 84 ++++++++++++++++------ 4 files changed, 135 insertions(+), 56 deletions(-) create mode 100644 exasol/toolbox/nox/_dependencies_check.py delete mode 100644 exasol/toolbox/tools/dependencies_check.py diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py new file mode 100644 index 00000000..1fda7a57 --- /dev/null +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -0,0 +1,69 @@ +import tomlkit +import sys +from pathlib import Path +import nox +from nox import Session + + +FILTERS = ['url', 'git', 'path'] + + +@nox.session(name="dependencies-check", python=False) +def dependency_check(session: Session): + file = Path("pyproject.toml") + sys.exit(_dependencies_check(file.read_text())) + + +def _source_filter(version, filters): + output = None + if isinstance(version, dict): + for key in version.keys(): + if key in filters: + output = key + return output + + +def _dependencies_check(string: str): + toml = tomlkit.loads(string) + dependencies: list = [] + dev_dependencies: list = [] + group_dependencies: dict = {} + if "tool" in toml: + if "poetry" in toml["tool"].unwrap(): + if "dependencies" in toml["tool"].unwrap()["poetry"]: + for name, version in toml["tool"].unwrap()["poetry"]["dependencies"].items(): + key = _source_filter(version, FILTERS) + if key: + dependencies.append(f"{name} = {version}") + + if "dev" in toml["tool"].unwrap()["poetry"]: + if "dependencies" in toml["tool"].unwrap()["poetry"]["dev"]: + for name, version in toml["tool"].unwrap()["poetry"]["dev"]["dependencies"].items(): + key = _source_filter(version, FILTERS) + if key: + dev_dependencies.append(f"{name} = {version}") + + if "group" in toml["tool"].unwrap()["poetry"]: + for group in toml["tool"].unwrap()["poetry"]["group"]: + if "dependencies" in toml["tool"].unwrap()["poetry"]["group"][group]: + for name, version in toml["tool"].unwrap()["poetry"]["group"][group]["dependencies"].items(): + key = _source_filter(version, FILTERS) + if key: + if f'[tool.poetry.group.{group}.dependencies]' not in group_dependencies: + group_dependencies[f'[tool.poetry.group.{group}.dependencies]'] = [] + group_dependencies[f'[tool.poetry.group.{group}.dependencies]'].append(f"{name} = {version}") + + if dependencies or dev_dependencies or group_dependencies: + l = len(dependencies) + m = len(dev_dependencies) + n = 0 + for _, dependency in group_dependencies.items(): + n += len(dependency) + suffix = "y" if l+m+n == 1 else "ies" + output = f"{l+m+n} illegal dependenc{suffix}:\n" + output += ("\n[tool.poetry.dependencies]\n"+"\n".join(dependencies)+"\n") if l > 0 else "" + output += ("\n[tool.poetry.dev.dependencies]\n"+"\n".join(dev_dependencies)+"\n") if m > 0 else "" + output += ("\n".join(f"\n{key}\n{'\n'.join(value)}"for key, value in group_dependencies.items())) if n > 0 else "" + output += "\n" + return output + return 0 diff --git a/exasol/toolbox/nox/tasks.py b/exasol/toolbox/nox/tasks.py index d9cb27d1..9161a2c1 100644 --- a/exasol/toolbox/nox/tasks.py +++ b/exasol/toolbox/nox/tasks.py @@ -51,6 +51,9 @@ integration_tests, unit_tests, ) +from exasol.toolbox.nox._dependencies_check import ( + dependency_check +) from noxconfig import PROJECT_CONFIG diff --git a/exasol/toolbox/tools/dependencies_check.py b/exasol/toolbox/tools/dependencies_check.py deleted file mode 100644 index b2647e05..00000000 --- a/exasol/toolbox/tools/dependencies_check.py +++ /dev/null @@ -1,35 +0,0 @@ -from tomlkit import loads -from sys import exit -import pytest - - -FILTER = ['url', 'git', 'path'] - - -def _source_filter(version, filter): - output = None - if isinstance(version, dict): - for key in version.keys(): - if key in filter: - output = key - return output - - -def dependency_check(): - with open("pyproject.toml", 'r') as toml: - toml = loads(toml.read()) - dependencies = [] - for name, version in toml["tool"]["poetry"]["dependencies"].items(): - key = _source_filter(version, FILTER) - if key: - dependencies.append(f"{name} = {version}") - - if dependencies: - n = len(dependencies) - suffix = "y" if n == 1 else "ies" - output = f"{n} illegal dependenc{suffix}:\n" + "\n".join(dependencies) - exit(output) - - -if __name__ == "__main__": - dependency_check() diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index c1fbffff..d934b8de 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -1,37 +1,79 @@ from tomlkit import loads import pytest -from exasol.toolbox.tools.dependencies_check import _source_filter +from exasol.toolbox.nox._dependencies_check import ( + _source_filter, + _dependencies_check +) +import pathlib + @pytest.mark.parametrize( - "filter,source,expected", + "filters,source,expected", [ ( - ['url', 'git', 'path'], - """example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"}""", - 'url'), + ['url', 'git', 'path'], + """example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"}""", + 'url'), ( - ['url', 'git', 'path'], - """example-git = {git = "git@github.com:requests/requests.git"}""", - 'git'), + ['url', 'git', 'path'], + """example-git = {git = "git@github.com:requests/requests.git"}""", + 'git'), ( - ['url', 'git', 'path'], - """example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"}""", - 'path'), + ['url', 'git', 'path'], + """example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"}""", + 'path'), ( - ['url', 'git', 'path'], - """example-url = {platform = "darwin", url = "https://example.com/my-package-0.1.0.tar.gz"}""", - 'url'), + ['url', 'git', 'path'], + """example-url = {platform = "darwin", url = "https://example.com/my-package-0.1.0.tar.gz"}""", + 'url'), ( - ['url', 'git', 'path'], - """example = "^2.31.0.6" """, - None), + ['url', 'git', 'path'], + """example = "^2.31.0.6" """, + None), ( - ['url', 'git', 'path'], - """python = ">=3.8.0,<4.0" """, - None + ['url', 'git', 'path'], + """python = ">=3.8.0,<4.0" """, + None ) ] ) -def test_dependencies_check(filter, source, expected): +def test_dependencies_check(filters, source, expected): for _, version in loads(source).items(): assert _source_filter(version, filter) == expected + + +@pytest.mark.parametrize( + "toml, expected", + [ + ( + """[tool.poetry.dependencies] +python = "^3.8" +example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"} + +[tool.poetry.dev.dependencies] +nox = ">=2022.8.7" + +[tool.poetry.group.test.dependencies] +sphinx = ">=5.3,<8" +example-git = {git = "git@github.com:requests/requests.git"} + +[tool.poetry.group.dev.dependencies] +pytest = ">=7.2.2,<9" +example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} +""", + """3 illegal dependencies: + +[tool.poetry.dependencies] +example-url = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} + +[tool.poetry.group.test.dependencies] +example-git = {'git': 'git@github.com:requests/requests.git'} + +[tool.poetry.group.dev.dependencies] +example-path = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} +""" + ), + ] +) +def test_dependencies_check(toml, expected): + assert _dependencies_check(toml) == expected From 4e13573a68c651d50a5859dfbff903f3b937d61f Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 3 Sep 2024 10:27:27 +0200 Subject: [PATCH 06/15] fix f-string new line problem --- exasol/toolbox/nox/_dependencies_check.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 1fda7a57..0eb9b6bd 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -60,10 +60,10 @@ def _dependencies_check(string: str): for _, dependency in group_dependencies.items(): n += len(dependency) suffix = "y" if l+m+n == 1 else "ies" - output = f"{l+m+n} illegal dependenc{suffix}:\n" + output = f"{l+m+n} illegal dependenc{suffix}:{chr(10)}" output += ("\n[tool.poetry.dependencies]\n"+"\n".join(dependencies)+"\n") if l > 0 else "" output += ("\n[tool.poetry.dev.dependencies]\n"+"\n".join(dev_dependencies)+"\n") if m > 0 else "" - output += ("\n".join(f"\n{key}\n{'\n'.join(value)}"for key, value in group_dependencies.items())) if n > 0 else "" + output += ("\n".join(f"{chr(10)}{key}{chr(10)}{chr(10).join(value)}"for key, value in group_dependencies.items())) if n > 0 else "" output += "\n" return output return 0 From 6d14d58acd3279f4b0ef755b086a48d97cdb04cd Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 3 Sep 2024 15:14:47 +0200 Subject: [PATCH 07/15] new version --- exasol/toolbox/nox/_dependencies_check.py | 108 +++++++++++----------- test/unit/dependencies_check_test.py | 9 +- 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 0eb9b6bd..9d504f41 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -3,67 +3,69 @@ from pathlib import Path import nox from nox import Session +from noxconfig import PROJECT_CONFIG FILTERS = ['url', 'git', 'path'] @nox.session(name="dependencies-check", python=False) -def dependency_check(session: Session): - file = Path("pyproject.toml") - sys.exit(_dependencies_check(file.read_text())) +def dependency_check(session: Session) -> None: + file = Path(PROJECT_CONFIG.root, "pyproject.toml") + output = _dependencies_check(file.read_text()) + print("\033[31m"+output) if output else print("\033[32m"+"Success: no wrong dependencies found") + sys.exit(0 if not output else 1) -def _source_filter(version, filters): - output = None - if isinstance(version, dict): - for key in version.keys(): - if key in filters: - output = key - return output +def _source_filter(version, filters) -> bool: + for f in filters: + if f in version: + return True + return False -def _dependencies_check(string: str): +def extract_dependencies(section, filters) -> list[str]: + dependencies = [] + for name, version in section.items(): + if _source_filter(version, filters): + dependencies.append(f"{name} = {version}") + return dependencies + + +def _dependencies_check(string: str) -> str: toml = tomlkit.loads(string) - dependencies: list = [] - dev_dependencies: list = [] - group_dependencies: dict = {} - if "tool" in toml: - if "poetry" in toml["tool"].unwrap(): - if "dependencies" in toml["tool"].unwrap()["poetry"]: - for name, version in toml["tool"].unwrap()["poetry"]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - dependencies.append(f"{name} = {version}") - - if "dev" in toml["tool"].unwrap()["poetry"]: - if "dependencies" in toml["tool"].unwrap()["poetry"]["dev"]: - for name, version in toml["tool"].unwrap()["poetry"]["dev"]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - dev_dependencies.append(f"{name} = {version}") - - if "group" in toml["tool"].unwrap()["poetry"]: - for group in toml["tool"].unwrap()["poetry"]["group"]: - if "dependencies" in toml["tool"].unwrap()["poetry"]["group"][group]: - for name, version in toml["tool"].unwrap()["poetry"]["group"][group]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - if f'[tool.poetry.group.{group}.dependencies]' not in group_dependencies: - group_dependencies[f'[tool.poetry.group.{group}.dependencies]'] = [] - group_dependencies[f'[tool.poetry.group.{group}.dependencies]'].append(f"{name} = {version}") - - if dependencies or dev_dependencies or group_dependencies: - l = len(dependencies) - m = len(dev_dependencies) - n = 0 - for _, dependency in group_dependencies.items(): - n += len(dependency) - suffix = "y" if l+m+n == 1 else "ies" - output = f"{l+m+n} illegal dependenc{suffix}:{chr(10)}" - output += ("\n[tool.poetry.dependencies]\n"+"\n".join(dependencies)+"\n") if l > 0 else "" - output += ("\n[tool.poetry.dev.dependencies]\n"+"\n".join(dev_dependencies)+"\n") if m > 0 else "" - output += ("\n".join(f"{chr(10)}{key}{chr(10)}{chr(10).join(value)}"for key, value in group_dependencies.items())) if n > 0 else "" - output += "\n" - return output - return 0 + group_dependencies = {} + + poetry = toml.get("tool", {}).get("poetry", {}) + + dependencies = extract_dependencies(poetry.get("dependencies", {}), FILTERS) + + dev_section = poetry.get("dev", {}).get("dependencies", {}) + dev_dependencies = extract_dependencies(dev_section, FILTERS) + + group_section = poetry.get("group", {}) + for group, content in group_section.items(): + group_deps = extract_dependencies(content.get("dependencies", {}), FILTERS) + if group_deps: + group_key = f'[tool.poetry.group.{group}.dependencies]' + group_dependencies[group_key] = group_deps + + total_count = len(dependencies) + len(dev_dependencies) + sum(len(deps) for deps in group_dependencies.values()) + if total_count > 0: + suffix = "y" if total_count == 1 else "ies" + output = [f"{total_count} illegal dependenc{suffix}:\n"] + + if dependencies: + output.append(f"\n[tool.poetry.dependencies]\n" + "\n".join(dependencies) + "\n") + if dev_dependencies: + output.append(f"\n[tool.poetry.dev.dependencies]\n" + "\n".join(dev_dependencies) + "\n") + for key, value in group_dependencies.items(): + output.append(f"\n{key}\n" + "\n".join(value) + "\n") + + return "".join(output) + + return "" + + +if __name__ == "__main__": + print(_dependencies_check(Path("pyproject.toml").read_text())) diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index d934b8de..8bce9199 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -4,7 +4,6 @@ _source_filter, _dependencies_check ) -import pathlib @pytest.mark.parametrize( @@ -59,9 +58,10 @@ def test_dependencies_check(filters, source, expected): [tool.poetry.group.dev.dependencies] pytest = ">=7.2.2,<9" -example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} +example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} +example-path2 = {path = "../my-package/dist/my-package-0.2.0.tar.gz"} """, - """3 illegal dependencies: + """4 illegal dependencies: [tool.poetry.dependencies] example-url = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} @@ -70,7 +70,8 @@ def test_dependencies_check(filters, source, expected): example-git = {'git': 'git@github.com:requests/requests.git'} [tool.poetry.group.dev.dependencies] -example-path = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} +example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} +example-path2 = {'path': '../my-package/dist/my-package-0.2.0.tar.gz'} """ ), ] From 21a7aff7ce6c72e3241ff6543bfb2e6f904ceed8 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 3 Sep 2024 15:14:47 +0200 Subject: [PATCH 08/15] new version --- exasol/toolbox/nox/_dependencies_check.py | 109 +++++++++++----------- test/unit/dependencies_check_test.py | 9 +- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 0eb9b6bd..38514632 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -3,67 +3,70 @@ from pathlib import Path import nox from nox import Session +from noxconfig import PROJECT_CONFIG +from typing import List FILTERS = ['url', 'git', 'path'] @nox.session(name="dependencies-check", python=False) -def dependency_check(session: Session): - file = Path("pyproject.toml") - sys.exit(_dependencies_check(file.read_text())) +def dependency_check(session: Session) -> None: + file = Path(PROJECT_CONFIG.root, "pyproject.toml") + output = _dependencies_check(file.read_text()) + print("\033[31m"+output) if output else print("\033[32m"+"Success: no wrong dependencies found") + sys.exit(0 if not output else 1) -def _source_filter(version, filters): - output = None - if isinstance(version, dict): - for key in version.keys(): - if key in filters: - output = key - return output +def _source_filter(version, filters) -> bool: + for f in filters: + if f in version: + return True + return False -def _dependencies_check(string: str): +def extract_dependencies(section, filters) -> List[str]: + dependencies = [] + for name, version in section.items(): + if _source_filter(version, filters): + dependencies.append(f"{name} = {version}") + return dependencies + + +def _dependencies_check(string: str) -> str: toml = tomlkit.loads(string) - dependencies: list = [] - dev_dependencies: list = [] - group_dependencies: dict = {} - if "tool" in toml: - if "poetry" in toml["tool"].unwrap(): - if "dependencies" in toml["tool"].unwrap()["poetry"]: - for name, version in toml["tool"].unwrap()["poetry"]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - dependencies.append(f"{name} = {version}") - - if "dev" in toml["tool"].unwrap()["poetry"]: - if "dependencies" in toml["tool"].unwrap()["poetry"]["dev"]: - for name, version in toml["tool"].unwrap()["poetry"]["dev"]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - dev_dependencies.append(f"{name} = {version}") - - if "group" in toml["tool"].unwrap()["poetry"]: - for group in toml["tool"].unwrap()["poetry"]["group"]: - if "dependencies" in toml["tool"].unwrap()["poetry"]["group"][group]: - for name, version in toml["tool"].unwrap()["poetry"]["group"][group]["dependencies"].items(): - key = _source_filter(version, FILTERS) - if key: - if f'[tool.poetry.group.{group}.dependencies]' not in group_dependencies: - group_dependencies[f'[tool.poetry.group.{group}.dependencies]'] = [] - group_dependencies[f'[tool.poetry.group.{group}.dependencies]'].append(f"{name} = {version}") - - if dependencies or dev_dependencies or group_dependencies: - l = len(dependencies) - m = len(dev_dependencies) - n = 0 - for _, dependency in group_dependencies.items(): - n += len(dependency) - suffix = "y" if l+m+n == 1 else "ies" - output = f"{l+m+n} illegal dependenc{suffix}:{chr(10)}" - output += ("\n[tool.poetry.dependencies]\n"+"\n".join(dependencies)+"\n") if l > 0 else "" - output += ("\n[tool.poetry.dev.dependencies]\n"+"\n".join(dev_dependencies)+"\n") if m > 0 else "" - output += ("\n".join(f"{chr(10)}{key}{chr(10)}{chr(10).join(value)}"for key, value in group_dependencies.items())) if n > 0 else "" - output += "\n" - return output - return 0 + group_dependencies = {} + + poetry = toml.get("tool", {}).get("poetry", {}) + + dependencies = extract_dependencies(poetry.get("dependencies", {}), FILTERS) + + dev_section = poetry.get("dev", {}).get("dependencies", {}) + dev_dependencies = extract_dependencies(dev_section, FILTERS) + + group_section = poetry.get("group", {}) + for group, content in group_section.items(): + group_deps = extract_dependencies(content.get("dependencies", {}), FILTERS) + if group_deps: + group_key = f'[tool.poetry.group.{group}.dependencies]' + group_dependencies[group_key] = group_deps + + total_count = len(dependencies) + len(dev_dependencies) + sum(len(deps) for deps in group_dependencies.values()) + if total_count > 0: + suffix = "y" if total_count == 1 else "ies" + output = [f"{total_count} illegal dependenc{suffix}:\n"] + + if dependencies: + output.append(f"\n[tool.poetry.dependencies]\n" + "\n".join(dependencies) + "\n") + if dev_dependencies: + output.append(f"\n[tool.poetry.dev.dependencies]\n" + "\n".join(dev_dependencies) + "\n") + for key, value in group_dependencies.items(): + output.append(f"\n{key}\n" + "\n".join(value) + "\n") + + return "".join(output) + + return "" + + +if __name__ == "__main__": + print(_dependencies_check(Path("pyproject.toml").read_text())) diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index d934b8de..8bce9199 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -4,7 +4,6 @@ _source_filter, _dependencies_check ) -import pathlib @pytest.mark.parametrize( @@ -59,9 +58,10 @@ def test_dependencies_check(filters, source, expected): [tool.poetry.group.dev.dependencies] pytest = ">=7.2.2,<9" -example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} +example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} +example-path2 = {path = "../my-package/dist/my-package-0.2.0.tar.gz"} """, - """3 illegal dependencies: + """4 illegal dependencies: [tool.poetry.dependencies] example-url = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} @@ -70,7 +70,8 @@ def test_dependencies_check(filters, source, expected): example-git = {'git': 'git@github.com:requests/requests.git'} [tool.poetry.group.dev.dependencies] -example-path = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} +example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} +example-path2 = {'path': '../my-package/dist/my-package-0.2.0.tar.gz'} """ ), ] From 7b88101ad058c0200e06d6b36d99390299518284 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 3 Sep 2024 15:23:35 +0200 Subject: [PATCH 09/15] new version --- exasol/toolbox/nox/_dependencies_check.py | 1 - 1 file changed, 1 deletion(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 38514632..21cc6e0f 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -64,7 +64,6 @@ def _dependencies_check(string: str) -> str: output.append(f"\n{key}\n" + "\n".join(value) + "\n") return "".join(output) - return "" From 5f41253677b30d5d69406104ae7c1a1e83bb2fb2 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 11 Sep 2024 14:55:44 +0200 Subject: [PATCH 10/15] resolves the conversations --- exasol/toolbox/nox/_dependencies_check.py | 135 +++++++++-------- test/unit/dependencies_check_test.py | 167 +++++++++++++++++----- 2 files changed, 202 insertions(+), 100 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 21cc6e0f..6962ac4d 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -4,68 +4,81 @@ import nox from nox import Session from noxconfig import PROJECT_CONFIG -from typing import List - - -FILTERS = ['url', 'git', 'path'] +from typing import ( + List, + Dict +) +import rich.console @nox.session(name="dependencies-check", python=False) def dependency_check(session: Session) -> None: - file = Path(PROJECT_CONFIG.root, "pyproject.toml") - output = _dependencies_check(file.read_text()) - print("\033[31m"+output) if output else print("\033[32m"+"Success: no wrong dependencies found") - sys.exit(0 if not output else 1) - - -def _source_filter(version, filters) -> bool: - for f in filters: - if f in version: - return True - return False - - -def extract_dependencies(section, filters) -> List[str]: - dependencies = [] - for name, version in section.items(): - if _source_filter(version, filters): - dependencies.append(f"{name} = {version}") - return dependencies - - -def _dependencies_check(string: str) -> str: - toml = tomlkit.loads(string) - group_dependencies = {} - - poetry = toml.get("tool", {}).get("poetry", {}) - - dependencies = extract_dependencies(poetry.get("dependencies", {}), FILTERS) - - dev_section = poetry.get("dev", {}).get("dependencies", {}) - dev_dependencies = extract_dependencies(dev_section, FILTERS) - - group_section = poetry.get("group", {}) - for group, content in group_section.items(): - group_deps = extract_dependencies(content.get("dependencies", {}), FILTERS) - if group_deps: - group_key = f'[tool.poetry.group.{group}.dependencies]' - group_dependencies[group_key] = group_deps - - total_count = len(dependencies) + len(dev_dependencies) + sum(len(deps) for deps in group_dependencies.values()) - if total_count > 0: - suffix = "y" if total_count == 1 else "ies" - output = [f"{total_count} illegal dependenc{suffix}:\n"] - - if dependencies: - output.append(f"\n[tool.poetry.dependencies]\n" + "\n".join(dependencies) + "\n") - if dev_dependencies: - output.append(f"\n[tool.poetry.dev.dependencies]\n" + "\n".join(dev_dependencies) + "\n") - for key, value in group_dependencies.items(): - output.append(f"\n{key}\n" + "\n".join(value) + "\n") - - return "".join(output) - return "" - - -if __name__ == "__main__": - print(_dependencies_check(Path("pyproject.toml").read_text())) + content = Path(PROJECT_CONFIG.root, "pyproject.toml").read_text() + dependencies = DependenciesCheck(content).parse() + console = rich.console.Console() + if dependencies.illegal(): + dependencies.report_illegal(console) + sys.exit(1) + dependencies.report_illegal(console) + sys.exit(0) + + +class DependenciesCheck: + ILLEGAL_DEPENDENCIES = ['url', 'git', 'path'] + + def __init__(self, pyproject_toml: str): + self.illegal_dict: Dict[str, List[str]] | None = None + self.content = pyproject_toml + + def parse(self) -> "DependenciesCheck": + def source_filter(version, filters) -> bool: + for f in filters: + if f in version: + return True + return False + + def extract_dependencies(section, filters) -> List[str]: + dependencies = [] + for name, version in section.items(): + if source_filter(version, filters): + dependencies.append(f"{name} = {version}") + return dependencies + + illegal: Dict[str, List[str]] = {} + toml = tomlkit.loads(self.content) + poetry = toml.get("tool", {}).get("poetry", {}) + + part = poetry.get("dependencies", {}) + dependencies_list = extract_dependencies(part, self.ILLEGAL_DEPENDENCIES) + if dependencies_list: + illegal["tool.poetry.dependencies"] = dependencies_list + + part = poetry.get("dev", {}).get("dependencies", {}) + dependencies_list = extract_dependencies(part, self.ILLEGAL_DEPENDENCIES) + if dependencies_list: + illegal["tool.poetry.dev.dependencies"] = dependencies_list + + part = poetry.get("group", {}) + for group, content in part.items(): + dependencies_list = extract_dependencies(content.get("dependencies", {}), self.ILLEGAL_DEPENDENCIES) + if dependencies_list: + illegal[f"tool.poetry.group.{group}.dependencies"] = dependencies_list + + self.illegal_dict = illegal + return self + + def report_illegal(self, console: rich.console.Console): + if self.illegal_dict: + count = sum(len(deps) for deps in self.illegal_dict.values()) + suffix = "y" if count == 1 else "ies" + console.print(f"{count} illegal dependenc{suffix}\n", style="red") + for section, dependencies in self.illegal_dict.items(): + console.print(f"\\[{section}]", style="red") + for dependency in dependencies: + console.print(dependency, style="red") + console.print("") + else: + console.print("Success: All dependencies refer to explicit pipy releases.", style="green") + + def illegal(self) -> Dict[str, List[str]] | None: + return self.illegal_dict diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index 8bce9199..ae136684 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -1,56 +1,114 @@ -from tomlkit import loads import pytest -from exasol.toolbox.nox._dependencies_check import ( - _source_filter, - _dependencies_check -) +from exasol.toolbox.nox._dependencies_check import DependenciesCheck @pytest.mark.parametrize( - "filters,source,expected", + "toml,expected", [ ( - ['url', 'git', 'path'], - """example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"}""", - 'url'), - ( - ['url', 'git', 'path'], - """example-git = {git = "git@github.com:requests/requests.git"}""", - 'git'), + """ + """, + {} + ), ( - ['url', 'git', 'path'], - """example-path = {path = "../my-package/dist/my-package-0.1.0.tar.gz"}""", - 'path'), + """ +[tool.poetry.dependencies] +python = "^3.8" +example-url1 = {url = "https://example.com/my-package-0.1.0.tar.gz"} + +[tool.poetry.dev.dependencies] +nox = ">=2022.8.7" +example-url2 = {url = "https://example.com/my-package-0.2.0.tar.gz"} + +[tool.poetry.group.test.dependencies] +sphinx = ">=5.3,<8" +example-git = {git = "git@github.com:requests/requests.git"} + +[tool.poetry.group.dev.dependencies] +pytest = ">=7.2.2,<9" +example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} + """, + { + "tool.poetry.dependencies": ["example-url1 = {'url': 'https://example.com/my-package-0.1.0.tar.gz'}"], + "tool.poetry.dev.dependencies": ["example-url2 = {'url': 'https://example.com/my-package-0.2.0.tar.gz'}"], + "tool.poetry.group.test.dependencies": ["example-git = {'git': 'git@github.com:requests/requests.git'}"], + "tool.poetry.group.dev.dependencies": ["example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'}"], + } + ), ( - ['url', 'git', 'path'], - """example-url = {platform = "darwin", url = "https://example.com/my-package-0.1.0.tar.gz"}""", - 'url'), + """ +[tool.poetry.dev.dependencies] +nox = ">=2022.8.7" +example-url2 = {url = "https://example.com/my-package-0.2.0.tar.gz"} + +[tool.poetry.group.test.dependencies] +sphinx = ">=5.3,<8" +example-git = {git = "git@github.com:requests/requests.git"} + +[tool.poetry.group.dev.dependencies] +pytest = ">=7.2.2,<9" +example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} + """, + { + "tool.poetry.dev.dependencies": ["example-url2 = {'url': 'https://example.com/my-package-0.2.0.tar.gz'}"], + "tool.poetry.group.test.dependencies": ["example-git = {'git': 'git@github.com:requests/requests.git'}"], + "tool.poetry.group.dev.dependencies": ["example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'}"], + } + ), ( - ['url', 'git', 'path'], - """example = "^2.31.0.6" """, - None), + """ +[tool.poetry.dependencies] +python = "^3.8" +example-url1 = {url = "https://example.com/my-package-0.1.0.tar.gz"} + +[tool.poetry.group.test.dependencies] +sphinx = ">=5.3,<8" +example-git = {git = "git@github.com:requests/requests.git"} + +[tool.poetry.group.dev.dependencies] +pytest = ">=7.2.2,<9" +example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} + """, + { + "tool.poetry.dependencies": ["example-url1 = {'url': 'https://example.com/my-package-0.1.0.tar.gz'}"], + "tool.poetry.group.test.dependencies": ["example-git = {'git': 'git@github.com:requests/requests.git'}"], + "tool.poetry.group.dev.dependencies": ["example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'}"], + } + ), ( - ['url', 'git', 'path'], - """python = ">=3.8.0,<4.0" """, - None + """ +[tool.poetry.dependencies] +python = "^3.8" +example-url1 = {url = "https://example.com/my-package-0.1.0.tar.gz"} + +[tool.poetry.dev.dependencies] +nox = ">=2022.8.7" +example-url2 = {url = "https://example.com/my-package-0.2.0.tar.gz"} + """, + { + "tool.poetry.dependencies": ["example-url1 = {'url': 'https://example.com/my-package-0.1.0.tar.gz'}"], + "tool.poetry.dev.dependencies": ["example-url2 = {'url': 'https://example.com/my-package-0.2.0.tar.gz'}"], + } ) ] ) -def test_dependencies_check(filters, source, expected): - for _, version in loads(source).items(): - assert _source_filter(version, filter) == expected +def test_dependency_check_parse(toml, expected): + dependencies = DependenciesCheck(toml).parse() + assert dependencies.illegal() == expected @pytest.mark.parametrize( - "toml, expected", + "toml,expected", [ ( - """[tool.poetry.dependencies] + """ +[tool.poetry.dependencies] python = "^3.8" -example-url = {url = "https://example.com/my-package-0.1.0.tar.gz"} +example-url1 = {url = "https://example.com/my-package-0.1.0.tar.gz"} [tool.poetry.dev.dependencies] nox = ">=2022.8.7" +example-url2 = {url = "https://example.com/my-package-0.2.0.tar.gz"} [tool.poetry.group.test.dependencies] sphinx = ">=5.3,<8" @@ -60,21 +118,52 @@ def test_dependencies_check(filters, source, expected): pytest = ">=7.2.2,<9" example-path1 = {path = "../my-package/dist/my-package-0.1.0.tar.gz"} example-path2 = {path = "../my-package/dist/my-package-0.2.0.tar.gz"} -""", - """4 illegal dependencies: + """, + """5 illegal dependencies -[tool.poetry.dependencies] -example-url = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} +\\[tool.poetry.dependencies] +example-url1 = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} -[tool.poetry.group.test.dependencies] +\\[tool.poetry.dev.dependencies] +example-url2 = {'url': 'https://example.com/my-package-0.2.0.tar.gz'} + +\\[tool.poetry.group.test.dependencies] example-git = {'git': 'git@github.com:requests/requests.git'} -[tool.poetry.group.dev.dependencies] +\\[tool.poetry.group.dev.dependencies] example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} example-path2 = {'path': '../my-package/dist/my-package-0.2.0.tar.gz'} + +""" + ), + ( + """ +[tool.poetry.dependencies] +python = "^3.8" + +[tool.poetry.dev.dependencies] +nox = ">=2022.8.7" + +[tool.poetry.group.test.dependencies] +sphinx = ">=5.3,<8" + +[tool.poetry.group.dev.dependencies] +pytest = ">=7.2.2,<9" + """, + """Success: All dependencies refer to explicit pipy releases. """ ), ] ) -def test_dependencies_check(toml, expected): - assert _dependencies_check(toml) == expected +def test_dependencies_check_report(toml, expected): + class Console: + def __init__(self): + self.output = "" + + def print(self, output: str, style: str = None): + self.output += output + "\n" + + console = Console() + dependencies = DependenciesCheck(toml).parse() + dependencies.report_illegal(console) + assert console.output == expected From 06d6594ea7eee8b12fe9d3c1354ab279b7ef2f1c Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 17 Sep 2024 10:15:51 +0200 Subject: [PATCH 11/15] fix type error --- exasol/toolbox/nox/_dependencies_check.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 6962ac4d..7e744e62 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -27,7 +27,7 @@ class DependenciesCheck: ILLEGAL_DEPENDENCIES = ['url', 'git', 'path'] def __init__(self, pyproject_toml: str): - self.illegal_dict: Dict[str, List[str]] | None = None + self.illegal_dict: Dict[str, List[str]] = {} self.content = pyproject_toml def parse(self) -> "DependenciesCheck": @@ -80,5 +80,5 @@ def report_illegal(self, console: rich.console.Console): else: console.print("Success: All dependencies refer to explicit pipy releases.", style="green") - def illegal(self) -> Dict[str, List[str]] | None: + def illegal(self) -> Dict[str, List[str]]: return self.illegal_dict From 1757ed017c752aea076ef988f84e02a5c776d4c2 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 17 Sep 2024 10:50:30 +0200 Subject: [PATCH 12/15] add capsys to dependencies check test --- test/unit/dependencies_check_test.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index ae136684..f31c7b1b 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -1,4 +1,6 @@ import pytest +import rich.console + from exasol.toolbox.nox._dependencies_check import DependenciesCheck @@ -121,16 +123,16 @@ def test_dependency_check_parse(toml, expected): """, """5 illegal dependencies -\\[tool.poetry.dependencies] +[tool.poetry.dependencies] example-url1 = {'url': 'https://example.com/my-package-0.1.0.tar.gz'} -\\[tool.poetry.dev.dependencies] +[tool.poetry.dev.dependencies] example-url2 = {'url': 'https://example.com/my-package-0.2.0.tar.gz'} -\\[tool.poetry.group.test.dependencies] +[tool.poetry.group.test.dependencies] example-git = {'git': 'git@github.com:requests/requests.git'} -\\[tool.poetry.group.dev.dependencies] +[tool.poetry.group.dev.dependencies] example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} example-path2 = {'path': '../my-package/dist/my-package-0.2.0.tar.gz'} @@ -155,15 +157,8 @@ def test_dependency_check_parse(toml, expected): ), ] ) -def test_dependencies_check_report(toml, expected): - class Console: - def __init__(self): - self.output = "" - - def print(self, output: str, style: str = None): - self.output += output + "\n" - - console = Console() +def test_dependencies_check_report(toml, expected, capsys): + console = rich.console.Console() dependencies = DependenciesCheck(toml).parse() dependencies.report_illegal(console) - assert console.output == expected + assert capsys.readouterr().out == expected From 2a11ca037d85cddaf14ff576f27958660c440832 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Tue, 24 Sep 2024 14:05:42 +0200 Subject: [PATCH 13/15] resolves the conversations --- exasol/toolbox/nox/_dependencies_check.py | 54 +++++++++++------------ test/unit/dependencies_check_test.py | 8 ++-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index 7e744e62..e3dd9e64 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -14,33 +14,32 @@ @nox.session(name="dependencies-check", python=False) def dependency_check(session: Session) -> None: content = Path(PROJECT_CONFIG.root, "pyproject.toml").read_text() - dependencies = DependenciesCheck(content).parse() + dependencies = Dependencies(content).parse() console = rich.console.Console() - if dependencies.illegal(): - dependencies.report_illegal(console) + illegal = dependencies.illegal() + report_illegal(illegal, console) + if illegal: sys.exit(1) - dependencies.report_illegal(console) - sys.exit(0) -class DependenciesCheck: +class Dependencies: ILLEGAL_DEPENDENCIES = ['url', 'git', 'path'] def __init__(self, pyproject_toml: str): self.illegal_dict: Dict[str, List[str]] = {} self.content = pyproject_toml - def parse(self) -> "DependenciesCheck": - def source_filter(version, filters) -> bool: - for f in filters: + def parse(self) -> "Dependencies": + def source_filter(version) -> bool: + for f in self.ILLEGAL_DEPENDENCIES: if f in version: return True return False - def extract_dependencies(section, filters) -> List[str]: + def extract_dependencies(section) -> List[str]: dependencies = [] for name, version in section.items(): - if source_filter(version, filters): + if source_filter(version): dependencies.append(f"{name} = {version}") return dependencies @@ -49,36 +48,37 @@ def extract_dependencies(section, filters) -> List[str]: poetry = toml.get("tool", {}).get("poetry", {}) part = poetry.get("dependencies", {}) - dependencies_list = extract_dependencies(part, self.ILLEGAL_DEPENDENCIES) + dependencies_list = extract_dependencies(part) if dependencies_list: illegal["tool.poetry.dependencies"] = dependencies_list part = poetry.get("dev", {}).get("dependencies", {}) - dependencies_list = extract_dependencies(part, self.ILLEGAL_DEPENDENCIES) + dependencies_list = extract_dependencies(part) if dependencies_list: illegal["tool.poetry.dev.dependencies"] = dependencies_list part = poetry.get("group", {}) for group, content in part.items(): - dependencies_list = extract_dependencies(content.get("dependencies", {}), self.ILLEGAL_DEPENDENCIES) + dependencies_list = extract_dependencies(content.get("dependencies", {})) if dependencies_list: illegal[f"tool.poetry.group.{group}.dependencies"] = dependencies_list self.illegal_dict = illegal return self - def report_illegal(self, console: rich.console.Console): - if self.illegal_dict: - count = sum(len(deps) for deps in self.illegal_dict.values()) - suffix = "y" if count == 1 else "ies" - console.print(f"{count} illegal dependenc{suffix}\n", style="red") - for section, dependencies in self.illegal_dict.items(): - console.print(f"\\[{section}]", style="red") - for dependency in dependencies: - console.print(dependency, style="red") - console.print("") - else: - console.print("Success: All dependencies refer to explicit pipy releases.", style="green") - def illegal(self) -> Dict[str, List[str]]: return self.illegal_dict + + +def report_illegal(illegal: Dict[str, List[str]], console: rich.console.Console): + if illegal: + count = sum(len(deps) for deps in illegal.values()) + suffix = "y" if count == 1 else "ies" + console.print(f"{count} illegal dependenc{suffix}\n", style="red") + for section, dependencies in illegal.items(): + console.print(f"\\[{section}]", style="red") + for dependency in dependencies: + console.print(dependency, style="red") + console.print("") + else: + console.print("Success: All dependencies refer to explicit pipy releases.", style="green") diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index f31c7b1b..788e3e95 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -1,7 +1,7 @@ import pytest import rich.console -from exasol.toolbox.nox._dependencies_check import DependenciesCheck +from exasol.toolbox.nox._dependencies_check import Dependencies, report_illegal @pytest.mark.parametrize( @@ -95,7 +95,7 @@ ] ) def test_dependency_check_parse(toml, expected): - dependencies = DependenciesCheck(toml).parse() + dependencies = Dependencies(toml).parse() assert dependencies.illegal() == expected @@ -159,6 +159,6 @@ def test_dependency_check_parse(toml, expected): ) def test_dependencies_check_report(toml, expected, capsys): console = rich.console.Console() - dependencies = DependenciesCheck(toml).parse() - dependencies.report_illegal(console) + dependencies = Dependencies(toml).parse() + report_illegal(dependencies.illegal(), console) assert capsys.readouterr().out == expected From cbd41dad1735f2d2db986e82967fff420fc4a0da Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 25 Sep 2024 11:45:51 +0200 Subject: [PATCH 14/15] update changelog --- doc/changes/unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 42c338f3..86cff55e 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -3,6 +3,7 @@ ## ✨ Added * Added cookiecutter-template for creating new project +* #233: Added nox task to verify dependency-declarations ## 🔩 Internal From 44d6cd5c3cdf6043a27e64d7bbc64aa984c4df70 Mon Sep 17 00:00:00 2001 From: Jannis Mittenzwei Date: Wed, 25 Sep 2024 12:18:32 +0200 Subject: [PATCH 15/15] resolves the conversations --- exasol/toolbox/nox/_dependencies_check.py | 25 ++++++++++------------- test/unit/dependencies_check_test.py | 21 ++----------------- 2 files changed, 13 insertions(+), 33 deletions(-) diff --git a/exasol/toolbox/nox/_dependencies_check.py b/exasol/toolbox/nox/_dependencies_check.py index e3dd9e64..d5085761 100644 --- a/exasol/toolbox/nox/_dependencies_check.py +++ b/exasol/toolbox/nox/_dependencies_check.py @@ -16,9 +16,8 @@ def dependency_check(session: Session) -> None: content = Path(PROJECT_CONFIG.root, "pyproject.toml").read_text() dependencies = Dependencies(content).parse() console = rich.console.Console() - illegal = dependencies.illegal() - report_illegal(illegal, console) - if illegal: + if illegal := dependencies.illegal: + report_illegal(illegal, console) sys.exit(1) @@ -66,19 +65,17 @@ def extract_dependencies(section) -> List[str]: self.illegal_dict = illegal return self + @property def illegal(self) -> Dict[str, List[str]]: return self.illegal_dict def report_illegal(illegal: Dict[str, List[str]], console: rich.console.Console): - if illegal: - count = sum(len(deps) for deps in illegal.values()) - suffix = "y" if count == 1 else "ies" - console.print(f"{count} illegal dependenc{suffix}\n", style="red") - for section, dependencies in illegal.items(): - console.print(f"\\[{section}]", style="red") - for dependency in dependencies: - console.print(dependency, style="red") - console.print("") - else: - console.print("Success: All dependencies refer to explicit pipy releases.", style="green") + count = sum(len(deps) for deps in illegal.values()) + suffix = "y" if count == 1 else "ies" + console.print(f"{count} illegal dependenc{suffix}\n", style="red") + for section, dependencies in illegal.items(): + console.print(f"\\[{section}]", style="red") + for dependency in dependencies: + console.print(dependency, style="red") + console.print("") diff --git a/test/unit/dependencies_check_test.py b/test/unit/dependencies_check_test.py index 788e3e95..db76c195 100644 --- a/test/unit/dependencies_check_test.py +++ b/test/unit/dependencies_check_test.py @@ -96,7 +96,7 @@ ) def test_dependency_check_parse(toml, expected): dependencies = Dependencies(toml).parse() - assert dependencies.illegal() == expected + assert dependencies.illegal == expected @pytest.mark.parametrize( @@ -136,23 +136,6 @@ def test_dependency_check_parse(toml, expected): example-path1 = {'path': '../my-package/dist/my-package-0.1.0.tar.gz'} example-path2 = {'path': '../my-package/dist/my-package-0.2.0.tar.gz'} -""" - ), - ( - """ -[tool.poetry.dependencies] -python = "^3.8" - -[tool.poetry.dev.dependencies] -nox = ">=2022.8.7" - -[tool.poetry.group.test.dependencies] -sphinx = ">=5.3,<8" - -[tool.poetry.group.dev.dependencies] -pytest = ">=7.2.2,<9" - """, - """Success: All dependencies refer to explicit pipy releases. """ ), ] @@ -160,5 +143,5 @@ def test_dependency_check_parse(toml, expected): def test_dependencies_check_report(toml, expected, capsys): console = rich.console.Console() dependencies = Dependencies(toml).parse() - report_illegal(dependencies.illegal(), console) + report_illegal(dependencies.illegal, console) assert capsys.readouterr().out == expected