Skip to content

Commit

Permalink
rename requirements-txt and requirements-txt-dev (#609)
Browse files Browse the repository at this point in the history
* rename requirements-txt and requirements-txt-dev to requirements-files and requirements-files-dev

Co-authored-by: Mathieu Kniewallner <mathieu.kniewallner@gmail.com>
  • Loading branch information
fpgmaas and mkniewallner committed Mar 24, 2024
1 parent e5ca1a7 commit 4f697a1
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 76 deletions.
22 changes: 11 additions & 11 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ To determine the project's dependencies, _deptry_ will scan the directory it is
- development dependencies from `dev-dependencies.txt` and `dependencies-dev.txt`, if any exist

_deptry_ can be configured to look for `pip` requirements files with other names or in other directories.
See [Requirements txt](#requirements-txt) and [Requirements txt dev](#requirements-txt-dev).
See [Requirements files](#requirements-files) and [Requirements files dev](#requirements-files-dev).

## Excluding files and directories

Expand Down Expand Up @@ -228,40 +228,40 @@ ignore_notebooks = true
deptry . --ignore-notebooks
```

#### Requirements txt
#### Requirements files

List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source dependencies.

- Type: `list[str]`
- Default: `["requirements.txt"]`
- `pyproject.toml` option name: `requirements_txt`
- CLI option name: `--requirements-txt` (short: `-rt`)
- `pyproject.toml` option name: `requirements_files`
- CLI option name: `--requirements-files` (short: `-rt`)
- `pyproject.toml` example:
```toml
[tool.deptry]
requirements_txt = ["requirements.txt", "requirements-private.txt"]
requirements_files = ["requirements.txt", "requirements-private.txt"]
```
- CLI example:
```shell
deptry . --requirements-txt requirements.txt,requirements-private.txt
deptry . --requirements-files requirements.txt,requirements-private.txt
```

#### Requirements txt dev
#### Requirements files dev

List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source development dependencies.

- Type: `list[str]`
- Default: `["dev-requirements.txt", "requirements-dev.txt"]`
- `pyproject.toml` option name: `requirements_txt_dev`
- CLI option name: `--requirements-txt-dev` (short: `-rtd`)
- `pyproject.toml` option name: `requirements_files_dev`
- CLI option name: `--requirements-files-dev` (short: `-rtd`)
- `pyproject.toml` example:
```toml
[tool.deptry]
requirements_txt_dev = ["requirements-dev.txt", "requirements-tests.txt"]
requirements_files_dev = ["requirements-dev.txt", "requirements-tests.txt"]
```
- CLI example:
```shell
deptry . --requirements-txt-dev requirements-dev.txt,requirements-tests.txt
deptry . --requirements-files-dev requirements-dev.txt,requirements-tests.txt
```

#### Known first party
Expand Down
34 changes: 26 additions & 8 deletions python/deptry/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

from deptry.config import read_configuration_from_pyproject_toml
from deptry.core import Core
from deptry.deprecate.requirements_txt import (
REQUIREMENTS_TXT_DEPRECATION_MESSAGE,
REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE,
)

if TYPE_CHECKING:
from collections.abc import Mapping, MutableMapping, Sequence
Expand Down Expand Up @@ -183,19 +187,25 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b
help="Display the current version and exit.",
)
@click.option(
"--requirements-txt",
"-rt",
"--requirements-txt", "-rt", type=COMMA_SEPARATED_TUPLE, help="To be deprecated.", hidden=True, default=()
)
@click.option(
"--requirements-txt-dev", "-rtd", type=COMMA_SEPARATED_TUPLE, help="To be deprecated.", hidden=True, default=()
)
@click.option(
"--requirements-files",
"-rf",
type=COMMA_SEPARATED_TUPLE,
help=""".txt files to scan for dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] section is found, this argument is ignored
help=""".txt files to scan for dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored
and the dependencies are extracted from the pyproject.toml file instead. Can be multiple e.g. `deptry . --requirements-txt req/prod.txt,req/extra.txt`""",
default=("requirements.txt",),
show_default=True,
)
@click.option(
"--requirements-txt-dev",
"-rtd",
"--requirements-files-dev",
"-rfd",
type=COMMA_SEPARATED_TUPLE,
help=""".txt files to scan for additional development dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] section is found, this argument is ignored
help=""".txt files to scan for additional development dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored
and the dependencies are extracted from the pyproject.toml file instead. Can be multiple e.g. `deptry . --requirements-txt-dev req/dev.txt,req/test.txt`""",
default=("dev-requirements.txt", "requirements-dev.txt"),
show_default=True,
Expand Down Expand Up @@ -246,6 +256,8 @@ def deptry(
ignore_notebooks: bool,
requirements_txt: tuple[str, ...],
requirements_txt_dev: tuple[str, ...],
requirements_files: tuple[str, ...],
requirements_files_dev: tuple[str, ...],
known_first_party: tuple[str, ...],
json_output: str,
package_module_name_map: MutableMapping[str, tuple[str, ...]],
Expand All @@ -264,6 +276,12 @@ def deptry(
deptry src worker
"""

if requirements_txt:
logging.warning(REQUIREMENTS_TXT_DEPRECATION_MESSAGE)

if requirements_txt_dev:
logging.warning(REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE)
Core(
root=root,
config=config,
Expand All @@ -274,8 +292,8 @@ def deptry(
ignore_notebooks=ignore_notebooks,
ignore=ignore,
per_rule_ignores=per_rule_ignores,
requirements_txt=requirements_txt,
requirements_txt_dev=requirements_txt_dev,
requirements_files=requirements_txt or requirements_files,
requirements_files_dev=requirements_txt_dev or requirements_files_dev,
known_first_party=known_first_party,
json_output=json_output,
package_module_name_map=package_module_name_map,
Expand Down
12 changes: 6 additions & 6 deletions python/deptry/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from deptry.dependency_getter.pdm import PDMDependencyGetter
from deptry.dependency_getter.pep_621 import PEP621DependencyGetter
from deptry.dependency_getter.poetry import PoetryDependencyGetter
from deptry.dependency_getter.requirements_txt import RequirementsTxtDependencyGetter
from deptry.dependency_getter.requirements_files import RequirementsTxtDependencyGetter
from deptry.dependency_specification_detector import DependencyManagementFormat, DependencySpecificationDetector
from deptry.exceptions import IncorrectDependencyFormatError, UnsupportedPythonVersionError
from deptry.imports.extract import get_imported_modules_from_list_of_files
Expand Down Expand Up @@ -48,8 +48,8 @@ class Core:
extend_exclude: tuple[str, ...]
using_default_exclude: bool
ignore_notebooks: bool
requirements_txt: tuple[str, ...]
requirements_txt_dev: tuple[str, ...]
requirements_files: tuple[str, ...]
requirements_files_dev: tuple[str, ...]
known_first_party: tuple[str, ...]
json_output: str
package_module_name_map: Mapping[str, tuple[str, ...]]
Expand All @@ -59,7 +59,7 @@ def run(self) -> None:
self._log_config()

dependency_management_format = DependencySpecificationDetector(
self.config, requirements_txt=self.requirements_txt
self.config, requirements_files=self.requirements_files
).detect()
dependencies_extract = self._get_dependencies(dependency_management_format)

Expand Down Expand Up @@ -151,9 +151,9 @@ def _get_dependencies(self, dependency_management_format: DependencyManagementFo
return PEP621DependencyGetter(
self.config, self.package_module_name_map, self.pep621_dev_dependency_groups
).get()
if dependency_management_format is DependencyManagementFormat.REQUIREMENTS_TXT:
if dependency_management_format is DependencyManagementFormat.REQUIREMENTS_FILE:
return RequirementsTxtDependencyGetter(
self.config, self.package_module_name_map, self.requirements_txt, self.requirements_txt_dev
self.config, self.package_module_name_map, self.requirements_files, self.requirements_files_dev
).get()
raise IncorrectDependencyFormatError

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@
class RequirementsTxtDependencyGetter(DependencyGetter):
"""Extract dependencies from requirements.txt files."""

requirements_txt: tuple[str, ...] = ("requirements.txt",)
requirements_txt_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt")
requirements_files: tuple[str, ...] = ("requirements.txt",)
requirements_files_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt")

def get(self) -> DependenciesExtract:
dependencies = list(
itertools.chain(
*(self._get_dependencies_from_requirements_file(file_name) for file_name in self.requirements_txt)
*(self._get_dependencies_from_requirements_files(file_name) for file_name in self.requirements_files)
)
)

dev_dependencies = list(
itertools.chain(
*(
self._get_dependencies_from_requirements_file(file_name)
self._get_dependencies_from_requirements_files(file_name)
for file_name in self._scan_for_dev_requirements_files()
)
)
Expand All @@ -39,14 +39,14 @@ def get(self) -> DependenciesExtract:

def _scan_for_dev_requirements_files(self) -> list[str]:
"""
Check if any of the files passed as requirements_txt_dev exist, and if so; return them.
Check if any of the files passed as requirements_files_dev exist, and if so; return them.
"""
dev_requirements_files = [file_name for file_name in self.requirements_txt_dev if file_name in os.listdir()]
dev_requirements_files = [file_name for file_name in self.requirements_files_dev if file_name in os.listdir()]
if dev_requirements_files:
logging.debug("Found files with development requirements! %s", dev_requirements_files)
return dev_requirements_files

def _get_dependencies_from_requirements_file(self, file_name: str, is_dev: bool = False) -> list[Dependency]:
def _get_dependencies_from_requirements_files(self, file_name: str, is_dev: bool = False) -> list[Dependency]:
logging.debug("Scanning %s for %s", file_name, "dev dependencies" if is_dev else "dependencies")
dependencies = []

Expand Down
18 changes: 9 additions & 9 deletions python/deptry/dependency_specification_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class DependencyManagementFormat(Enum):
PDM = "pdm"
PEP_621 = "pep_621"
POETRY = "poetry"
REQUIREMENTS_TXT = "requirements_txt"
REQUIREMENTS_FILE = "requirements_files"


class DependencySpecificationDetector:
Expand All @@ -25,9 +25,9 @@ class DependencySpecificationDetector:
"""

def __init__(self, config: Path, requirements_txt: tuple[str, ...] = ("requirements.txt",)) -> None:
def __init__(self, config: Path, requirements_files: tuple[str, ...] = ("requirements.txt",)) -> None:
self.config = config
self.requirements_txt = requirements_txt
self.requirements_files = requirements_files

def detect(self) -> DependencyManagementFormat:
pyproject_toml_found = self._project_contains_pyproject_toml()
Expand All @@ -37,10 +37,10 @@ def detect(self) -> DependencyManagementFormat:
return DependencyManagementFormat.PDM
if pyproject_toml_found and self._project_uses_pep_621():
return DependencyManagementFormat.PEP_621
if self._project_uses_requirements_txt():
return DependencyManagementFormat.REQUIREMENTS_TXT
if self._project_uses_requirements_files():
return DependencyManagementFormat.REQUIREMENTS_FILE

raise DependencySpecificationNotFoundError(self.requirements_txt)
raise DependencySpecificationNotFoundError(self.requirements_files)

def _project_contains_pyproject_toml(self) -> bool:
if self.config.exists():
Expand Down Expand Up @@ -100,11 +100,11 @@ def _project_uses_pep_621(self) -> bool:
else:
return True

def _project_uses_requirements_txt(self) -> bool:
check = any(Path(requirements_txt).is_file() for requirements_txt in self.requirements_txt)
def _project_uses_requirements_files(self) -> bool:
check = any(Path(requirements_files).is_file() for requirements_files in self.requirements_files)
if check:
logging.debug(
"Dependency specification found in '%s'. Will use this to determine the project's dependencies.\n",
", ".join(self.requirements_txt),
", ".join(self.requirements_files),
)
return check
15 changes: 15 additions & 0 deletions python/deptry/deprecate/requirements_txt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from __future__ import annotations

REQUIREMENTS_TXT_DEPRECATION_MESSAGE = (
"Warning: In an upcoming release, support for the `--requirements-txt` command-line "
"option and the `requirements_txt` configuration parameter will be discontinued. "
"Instead, use `--requirements-files` or `requirements_files` under the `[tool.deptry]` "
"section in pyproject.toml."
)

REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE = (
"Warning: In an upcoming release, support for the `--requirements-txt-dev` command-line "
"option and the `requirements_txt_dev` configuration parameter will be discontinued. "
"Instead, use `--requirements-files-dev` or `requirements_files_dev` under the `[tool.deptry]` "
"section in pyproject.toml."
)
4 changes: 2 additions & 2 deletions python/deptry/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@


class DependencySpecificationNotFoundError(FileNotFoundError):
def __init__(self, requirements_txt: tuple[str, ...]) -> None:
def __init__(self, requirements_files: tuple[str, ...]) -> None:
super().__init__(
"No file called 'pyproject.toml' with a [tool.poetry.dependencies], [tool.pdm] or [project] section or"
f" file(s) called '{', '.join(requirements_txt)}' found. Exiting."
f" file(s) called '{', '.join(requirements_files)}' found. Exiting."
)


Expand Down
8 changes: 4 additions & 4 deletions tests/functional/cli/test_cli_requirements_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


@pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT)
def test_cli_single_requirements_txt(pip_venv_factory: PipVenvFactory) -> None:
def test_cli_single_requirements_files(pip_venv_factory: PipVenvFactory) -> None:
with pip_venv_factory(
Project.REQUIREMENTS_TXT,
install_command=(
Expand All @@ -23,7 +23,7 @@ def test_cli_single_requirements_txt(pip_venv_factory: PipVenvFactory) -> None:
) as virtual_env:
issue_report = f"{uuid.uuid4()}.json"
result = virtual_env.run(
"deptry . --requirements-txt requirements.txt --requirements-txt-dev requirements-dev.txt -o"
"deptry . --requirements-files requirements.txt --requirements-files-dev requirements-dev.txt -o"
f" {issue_report}"
)

Expand Down Expand Up @@ -105,7 +105,7 @@ def test_cli_single_requirements_txt(pip_venv_factory: PipVenvFactory) -> None:


@pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT)
def test_cli_multiple_requirements_txt(pip_venv_factory: PipVenvFactory) -> None:
def test_cli_multiple_requirements_files(pip_venv_factory: PipVenvFactory) -> None:
with pip_venv_factory(
Project.REQUIREMENTS_TXT,
install_command=(
Expand All @@ -114,7 +114,7 @@ def test_cli_multiple_requirements_txt(pip_venv_factory: PipVenvFactory) -> None
) as virtual_env:
issue_report = f"{uuid.uuid4()}.json"
result = virtual_env.run(
"deptry . --requirements-txt requirements.txt,requirements-2.txt --requirements-txt-dev"
"deptry . --requirements-files requirements.txt,requirements-2.txt --requirements-files-dev"
f" requirements-dev.txt -o {issue_report}"
)

Expand Down
Loading

0 comments on commit 4f697a1

Please sign in to comment.