Skip to content
Open
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
45 changes: 45 additions & 0 deletions src/poetry/console/commands/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import ClassVar

from cleo.helpers import option
from poetry.core.utils.helpers import module_name

from poetry.console.commands.command import Command

Expand Down Expand Up @@ -128,6 +129,46 @@ def _validate_dependencies_source(self, config: dict[str, Any]) -> list[str]:
for source in sorted(all_referenced_sources - sources)
]

def _validate_project_in_src(
self, toml_data: dict[str, Any], base_path: Path | None
) -> list[str]:
"""
Checks the validity of projects located under src/ subdirectory.
"""
result: list[str] = []

project_name = toml_data.get("project", {}).get("name") or toml_data.get(
"tool", {}
).get("poetry", {}).get("name")

if project_name is None or base_path is None:
return result

project_name = module_name(project_name)

project_dir = base_path / project_name
src_project_dir = base_path / "src" / project_name

project_dir_empty = (
project_dir.exists()
and project_dir.is_dir()
and not any(project_dir.iterdir())
)
src_dir_not_empty = (
src_project_dir.exists()
and src_project_dir.is_dir()
and any(src_project_dir.iterdir())
)

if project_dir_empty and src_dir_not_empty:
result.append(
f"Found empty directory '{project_name}' in project root while the actual package is in "
f"'src/{project_name}'. This may cause issues with package installation. "
"Consider removing the empty directory."
)

return result

def handle(self) -> int:
from poetry.core.pyproject.toml import PyProjectTOML

Expand All @@ -149,6 +190,10 @@ def handle(self) -> int:
check_result["errors"].extend(errors)
check_result["warnings"].extend(warnings)

project_root = poetry_file.parent
warnings = self._validate_project_in_src(toml_data, project_root)
check_result["warnings"].extend(warnings)

# Validate readme (files must exist)
# TODO: consider [project.readme] as well
if "readme" in poetry_config:
Expand Down
31 changes: 31 additions & 0 deletions tests/console/commands/test_check.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import os

from typing import TYPE_CHECKING

import pytest
Expand Down Expand Up @@ -59,6 +61,14 @@ def poetry_with_invalid_pyproject(
yield Factory().create_poetry(cwd)


@pytest.fixture
def poetry_with_src_folder(
set_project_context: SetProjectContext,
) -> Iterator[Poetry]:
with set_project_context("project_with_src_folder", in_place=False) as cwd:
yield Factory().create_poetry(cwd)


@pytest.fixture()
def tester(
command_tester_factory: CommandTesterFactory, poetry_simple_project: Poetry
Expand Down Expand Up @@ -309,3 +319,24 @@ def test_check_does_not_error_on_pypi_reference(

assert tester.io.fetch_output() == "All set!\n"
assert status_code == 0


def test_check_project_with_src_folder(
command_tester_factory: CommandTesterFactory,
poetry_with_src_folder: Poetry,
) -> None:
tester = command_tester_factory("check", poetry=poetry_with_src_folder)

poetry_file = poetry_with_src_folder.file.path
project_root = poetry_file.parent
project_dir = project_root / "project_with_src_folder"
os.makedirs(project_dir, exist_ok=True)
tester.execute("")

expected = """\
Warning: Found empty directory 'project_with_src_folder' in project root while the actual package is in\
'src/project_with_src_folder'. This may cause issues with package installation.\
Consider removing the empty directory.
"""

assert tester.io.fetch_error() == expected
12 changes: 12 additions & 0 deletions tests/fixtures/project_with_src_folder/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[project]
name = "project-with-src-folder"
version = "1.2.3"
description = "This is a description"
authors = []
license = "MIT"


[tool.poetry]
packages = []

[tool.poetry.group.dev.dependencies]
Loading