Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename requirements-txt and requirements-txt-dev #609

Merged
merged 22 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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