diff --git a/.import_linter_config b/.import_linter_config index 22194ffe2..03b655cc7 100644 --- a/.import_linter_config +++ b/.import_linter_config @@ -1,5 +1,6 @@ [importlinter] root_package = exasol.toolbox +include_external_packages = True [importlinter:contract:security-contract] name = Security module should not import from toolbox @@ -14,3 +15,15 @@ ignore_imports = # importlinter lacks an option to ignore a specific line, so we must ignore this in # total, as this is needed for Python security audits. exasol.toolbox.tools.security -> exasol.toolbox.util.dependencies.audit + +[importlinter:contract:restrict-noxconfig] +name = Only exasol.toolbox.nox submodules can import noxconfig +type = forbidden +source_modules = + exasol.toolbox +forbidden_modules = + noxconfig +ignore_imports = + # To reduce the effort in using nox sessions (i.e. having to pass the config path + # in each CLI usage), we allow the noxconfig to be imported within these modules. + exasol.toolbox.nox.* -> noxconfig diff --git a/doc/changes/unreleased.md b/doc/changes/unreleased.md index 79e701b84..18c65e34c 100644 --- a/doc/changes/unreleased.md +++ b/doc/changes/unreleased.md @@ -1 +1,5 @@ # Unreleased + +## Features + +* #649: Restricted noxconfig usage throughout exasol.toolbox to only exasol.toolbox.nox.* diff --git a/exasol/toolbox/util/dependencies/audit.py b/exasol/toolbox/util/dependencies/audit.py index a5724b6b5..1e6281df3 100644 --- a/exasol/toolbox/util/dependencies/audit.py +++ b/exasol/toolbox/util/dependencies/audit.py @@ -227,6 +227,6 @@ def get_vulnerabilities(working_directory: Path) -> list[Vulnerability]: ).vulnerabilities -def get_vulnerabilities_from_latest_tag(): - with poetry_files_from_latest_tag() as tmp_dir: +def get_vulnerabilities_from_latest_tag(root_path: Path): + with poetry_files_from_latest_tag(root_path=root_path) as tmp_dir: return get_vulnerabilities(working_directory=tmp_dir) diff --git a/exasol/toolbox/util/dependencies/poetry_dependencies.py b/exasol/toolbox/util/dependencies/poetry_dependencies.py index 222159778..5caeca15d 100644 --- a/exasol/toolbox/util/dependencies/poetry_dependencies.py +++ b/exasol/toolbox/util/dependencies/poetry_dependencies.py @@ -159,8 +159,8 @@ def get_dependencies( ).direct_dependencies -def get_dependencies_from_latest_tag() -> ( - OrderedDict[str, dict[NormalizedPackageStr, Package]] -): - with poetry_files_from_latest_tag() as tmp_dir: +def get_dependencies_from_latest_tag( + root_path: Path, +) -> OrderedDict[str, dict[NormalizedPackageStr, Package]]: + with poetry_files_from_latest_tag(root_path=root_path) as tmp_dir: return get_dependencies(working_directory=tmp_dir) diff --git a/exasol/toolbox/util/dependencies/shared_models.py b/exasol/toolbox/util/dependencies/shared_models.py index c928d49c4..8caf1d7f6 100644 --- a/exasol/toolbox/util/dependencies/shared_models.py +++ b/exasol/toolbox/util/dependencies/shared_models.py @@ -19,7 +19,6 @@ ) from exasol.toolbox.util.git import Git -from noxconfig import PROJECT_CONFIG NormalizedPackageStr = NewType("NormalizedPackageStr", str) @@ -63,10 +62,10 @@ def files(self) -> tuple[str, ...]: @contextmanager -def poetry_files_from_latest_tag() -> Generator[Path]: +def poetry_files_from_latest_tag(root_path: Path) -> Generator[Path]: """Context manager to set up a temporary directory with poetry files from the latest tag""" latest_tag = Git.get_latest_tag() - path = PROJECT_CONFIG.root_path.relative_to(Git.toplevel()) + path = root_path.relative_to(Git.toplevel()) with tempfile.TemporaryDirectory() as tmpdir_str: tmp_dir = Path(tmpdir_str) for file in PoetryFiles().files: diff --git a/exasol/toolbox/util/release/changelog.py b/exasol/toolbox/util/release/changelog.py index fad6f5b1d..e2df8aa6f 100644 --- a/exasol/toolbox/util/release/changelog.py +++ b/exasol/toolbox/util/release/changelog.py @@ -68,7 +68,9 @@ def _describe_dependency_changes(self) -> str: Describe the dependency changes between the latest tag and the current version for use in the versioned changes file. """ - previous_dependencies_in_groups = get_dependencies_from_latest_tag() + previous_dependencies_in_groups = get_dependencies_from_latest_tag( + root_path=self.root_path + ) current_dependencies_in_groups = get_dependencies( working_directory=self.root_path ) diff --git a/test/unit/util/dependencies/audit_test.py b/test/unit/util/dependencies/audit_test.py index bc84ff5e0..8f2affd09 100644 --- a/test/unit/util/dependencies/audit_test.py +++ b/test/unit/util/dependencies/audit_test.py @@ -251,7 +251,9 @@ def test_with_mock(self, sample_vulnerability): "exasol.toolbox.util.dependencies.audit.audit_poetry_files", return_value=sample_vulnerability.pip_audit_json, ): - result = get_vulnerabilities_from_latest_tag() + result = get_vulnerabilities_from_latest_tag( + root_path=PROJECT_CONFIG.root_path + ) # if successful, no errors & should be 1 due to mock assert isinstance(result, list) diff --git a/test/unit/util/dependencies/poetry_dependencies_test.py b/test/unit/util/dependencies/poetry_dependencies_test.py index 3207473e4..679c7abe9 100644 --- a/test/unit/util/dependencies/poetry_dependencies_test.py +++ b/test/unit/util/dependencies/poetry_dependencies_test.py @@ -142,7 +142,7 @@ def test_get_dependencies(): def test_get_dependencies_from_latest_tag(): - result = get_dependencies_from_latest_tag() + result = get_dependencies_from_latest_tag(root_path=PROJECT_CONFIG.root_path) # if successful, no errors & should be non-empty dictionary assert isinstance(result, dict) diff --git a/test/unit/util/dependencies/shared_models_test.py b/test/unit/util/dependencies/shared_models_test.py index 03e90f192..c59dbc8e4 100644 --- a/test/unit/util/dependencies/shared_models_test.py +++ b/test/unit/util/dependencies/shared_models_test.py @@ -10,6 +10,7 @@ poetry_files_from_latest_tag, ) from exasol.toolbox.util.git import Git +from noxconfig import PROJECT_CONFIG class Dummy(BaseModel): @@ -57,7 +58,7 @@ def test_coordinates(): def test_poetry_files_from_latest_tag(): latest_tag = Git.get_latest_tag() - with poetry_files_from_latest_tag() as tmp_dir: + with poetry_files_from_latest_tag(root_path=PROJECT_CONFIG.root_path) as tmp_dir: for file in PoetryFiles().files: assert (tmp_dir / file).is_file() diff --git a/test/unit/util/release/changelog_test.py b/test/unit/util/release/changelog_test.py index bd332612c..4c2df00a4 100644 --- a/test/unit/util/release/changelog_test.py +++ b/test/unit/util/release/changelog_test.py @@ -76,7 +76,7 @@ def unreleased_md(changelogs): def mock_dependencies(dependencies, previous_dependencies): with mock.patch.multiple( "exasol.toolbox.util.release.changelog", - get_dependencies_from_latest_tag=lambda: previous_dependencies, + get_dependencies_from_latest_tag=lambda root_path: previous_dependencies, get_dependencies=lambda working_directory: dependencies, ): yield @@ -86,7 +86,7 @@ def mock_dependencies(dependencies, previous_dependencies): def mock_no_dependencies(): with mock.patch.multiple( "exasol.toolbox.util.release.changelog", - get_dependencies_from_latest_tag=lambda: {}, + get_dependencies_from_latest_tag=lambda root_path: {}, get_dependencies=lambda working_directory: {}, ): yield