diff --git a/pyproject.toml b/pyproject.toml index b4706845..483f9dd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,32 @@ [tool.ruff] +target-version = "py311" line-length = 88 +select = ["ALL"] +ignore = [ + # pydocstyle + "D", + # Missing type annotation for `self` in method + "ANN101", + # Trailing comma missing + "COM812", + # Unnecessary `dict` call (rewrite as a literal) + "C408", + # Boolean-typed positional argument in function definition + "FBT001", + # Logging statement uses f-string + "G004", + # disabled on ruff's recommendation as causes problems with the formatter + "ISC001", + # Use of `assert` detected + "S101", + # `subprocess` call: check for execution of untrusted input + "S603", -select = ["E", "F", "I"] -ignore = [ "E501" ] + # FIXME? Maybe we should enable these? + "PLR0913", # Too many arguments in function definition (7 > 5) + "PLR2004", # Magic value used in comparison, consider replacing 4 with a constant variable + "FBT002", # Boolean default positional argument in function definition +] [tool.mypy] python_version = "3.10" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 1294fa55..00000000 --- a/setup.cfg +++ /dev/null @@ -1,23 +0,0 @@ -[wheel] -universal = 1 - -[pycodestyle] -max-line-length = 88 -ignore = E501,E741,W503 - -[flake8] -max-line-length = 88 -ignore = E501,E741,W503 -exclude = .git,__pycache__,docs/source/conf.py,old,build,dist - -[mypy] -warn_redundant_casts = true -disallow_untyped_calls = true -disallow_untyped_defs = true -no_implicit_optional = true - -[mypy-pytest.*] -ignore_missing_imports = True - -[isort] -profile = black diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/conftest.py b/tests/conftest.py index 8a849bf1..1f74975b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ pytest_plugins = [ - "direnv_project", - "root", + "tests.direnv_project", + "tests.root", ] diff --git a/tests/direnv_project.py b/tests/direnv_project.py index ebca0172..f2166fef 100644 --- a/tests/direnv_project.py +++ b/tests/direnv_project.py @@ -1,22 +1,23 @@ import shutil import textwrap +from collections.abc import Iterator from dataclasses import dataclass from pathlib import Path from tempfile import TemporaryDirectory -from typing import Iterator import pytest -from procs import run + +from .procs import run @dataclass class DirenvProject: - dir: Path + directory: Path nix_direnv: Path @property def envrc(self) -> Path: - return self.dir / ".envrc" + return self.directory / ".envrc" def setup_envrc(self, content: str, strict_env: bool) -> None: text = textwrap.dedent( @@ -27,23 +28,23 @@ def setup_envrc(self, content: str, strict_env: bool) -> None: """ ) self.envrc.write_text(text) - run(["direnv", "allow"], cwd=self.dir) + run(["direnv", "allow"], cwd=self.directory) -@pytest.fixture +@pytest.fixture() def direnv_project(test_root: Path, project_root: Path) -> Iterator[DirenvProject]: """ Setups a direnv test project """ with TemporaryDirectory() as _dir: - dir = Path(_dir) / "proj" - shutil.copytree(test_root / "testenv", dir) - shutil.copyfile(project_root / "flake.nix", dir / "flake.nix") - shutil.copyfile(project_root / "flake.lock", dir / "flake.lock") - shutil.copyfile(project_root / "treefmt.nix", dir / "treefmt.nix") + directory = Path(_dir) / "proj" + shutil.copytree(test_root / "testenv", directory) + shutil.copyfile(project_root / "flake.nix", directory / "flake.nix") + shutil.copyfile(project_root / "flake.lock", directory / "flake.lock") + shutil.copyfile(project_root / "treefmt.nix", directory / "treefmt.nix") nix_direnv = project_root / "direnvrc" - c = DirenvProject(Path(dir), nix_direnv) + c = DirenvProject(Path(directory), nix_direnv) try: yield c finally: diff --git a/tests/procs.py b/tests/procs.py index ea837d4e..f9d80bab 100644 --- a/tests/procs.py +++ b/tests/procs.py @@ -1,23 +1,27 @@ +import logging +import shlex import subprocess from pathlib import Path -from typing import IO, Any, List, Optional, Union +from typing import IO, Any -_FILE = Union[None, int, IO[Any]] -_DIR = Union[None, Path, str] +_FILE = None | int | IO[Any] +_DIR = None | Path | str + +log = logging.getLogger(__name__) def run( - cmd: List[str], + cmd: list[str], text: bool = True, check: bool = True, cwd: _DIR = None, stderr: _FILE = None, stdout: _FILE = None, - env: Optional[dict[str, str]] = None, + env: dict[str, str] | None = None, ) -> subprocess.CompletedProcess: if cwd is not None: - print(f"cd {cwd}") - print("$ " + " ".join(cmd)) + log.debug(f"cd {cwd}") + log.debug(f"$ {shlex.join(cmd)}") return subprocess.run( cmd, text=text, check=check, cwd=cwd, stderr=stderr, stdout=stdout, env=env ) diff --git a/tests/root.py b/tests/root.py index b3f0914d..a5bf3994 100644 --- a/tests/root.py +++ b/tests/root.py @@ -6,7 +6,7 @@ PROJECT_ROOT = TEST_ROOT.parent -@pytest.fixture +@pytest.fixture() def test_root() -> Path: """ Root directory of the tests @@ -14,7 +14,7 @@ def test_root() -> Path: return TEST_ROOT -@pytest.fixture +@pytest.fixture() def project_root() -> Path: """ Root directory of the tests diff --git a/tests/test_gc.py b/tests/test_gc.py index e46fcfd8..26f25663 100644 --- a/tests/test_gc.py +++ b/tests/test_gc.py @@ -1,22 +1,26 @@ +import logging import subprocess import sys import unittest import pytest -from direnv_project import DirenvProject -from procs import run + +from .direnv_project import DirenvProject +from .procs import run + +log = logging.getLogger(__name__) def common_test(direnv_project: DirenvProject) -> None: run(["nix-collect-garbage"]) - testenv = str(direnv_project.dir) + testenv = str(direnv_project.directory) out1 = run( ["direnv", "exec", testenv, "hello"], stderr=subprocess.PIPE, check=False, - cwd=direnv_project.dir, + cwd=direnv_project.directory, ) sys.stderr.write(out1.stderr) assert out1.returncode == 0 @@ -29,7 +33,7 @@ def common_test(direnv_project: DirenvProject) -> None: ["direnv", "exec", testenv, "hello"], stderr=subprocess.PIPE, check=False, - cwd=direnv_project.dir, + cwd=direnv_project.directory, ) sys.stderr.write(out2.stderr) assert out2.returncode == 0 @@ -38,23 +42,25 @@ def common_test(direnv_project: DirenvProject) -> None: def common_test_clean(direnv_project: DirenvProject) -> None: - testenv = str(direnv_project.dir) + testenv = str(direnv_project.directory) out3 = run( ["direnv", "exec", testenv, "hello"], stderr=subprocess.PIPE, check=False, - cwd=direnv_project.dir, + cwd=direnv_project.directory, ) sys.stderr.write(out3.stderr) files = [ - path for path in (direnv_project.dir / ".direnv").iterdir() if path.is_file() + path + for path in (direnv_project.directory / ".direnv").iterdir() + if path.is_file() ] rcs = [f for f in files if f.match("*.rc")] profiles = [f for f in files if not f.match("*.rc")] if len(rcs) != 1 or len(profiles) != 1: - print(files) + log.debug(files) assert len(rcs) == 1 assert len(profiles) == 1 @@ -75,11 +81,11 @@ def test_use_nix(direnv_project: DirenvProject, strict_env: bool) -> None: def test_use_flake(direnv_project: DirenvProject, strict_env: bool) -> None: direnv_project.setup_envrc("use flake", strict_env=strict_env) common_test(direnv_project) - inputs = list((direnv_project.dir / ".direnv/flake-inputs").iterdir()) + inputs = list((direnv_project.directory / ".direnv/flake-inputs").iterdir()) # should only contain our flake-utils flake if len(inputs) != 4: - run(["nix", "flake", "archive", "--json"], cwd=direnv_project.dir) - print(inputs) + run(["nix", "flake", "archive", "--json"], cwd=direnv_project.directory) + log.debug(inputs) assert len(inputs) == 4 for symlink in inputs: assert symlink.is_dir() diff --git a/tests/test_use_nix.py b/tests/test_use_nix.py index 0c79fa53..804079de 100644 --- a/tests/test_use_nix.py +++ b/tests/test_use_nix.py @@ -1,31 +1,35 @@ +import logging import os +import shlex import subprocess import sys import unittest -from typing import Optional import pytest -from direnv_project import DirenvProject -from procs import run + +from .direnv_project import DirenvProject +from .procs import run + +log = logging.getLogger(__name__) def direnv_exec( - direnv_project: DirenvProject, cmd: str, env: Optional[dict[str, str]] = None + direnv_project: DirenvProject, cmd: str, env: dict[str, str] | None = None ) -> None: - args = ["direnv", "exec", str(direnv_project.dir), "sh", "-c", cmd] - print("$ " + " ".join(args)) + args = ["direnv", "exec", str(direnv_project.directory), "sh", "-c", cmd] + log.debug(f"$ {shlex.join(args)}") out = run( args, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, - cwd=direnv_project.dir, + cwd=direnv_project.directory, env=env, ) sys.stdout.write(out.stdout) sys.stderr.write(out.stderr) assert out.returncode == 0 - assert "OK\n" == out.stdout + assert out.stdout == "OK\n" assert "renewed cache" in out.stderr @@ -57,7 +61,7 @@ def test_no_files(direnv_project: DirenvProject, strict_env: bool) -> None: stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=False, - cwd=direnv_project.dir, + cwd=direnv_project.directory, ) assert out.returncode == 0 assert 'Loaded watch: "."' not in out.stdout