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

Allow poetry plugin with empty command prefix to run tasks included from another file #216

Merged
merged 2 commits into from
Apr 26, 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
9 changes: 4 additions & 5 deletions poethepoet/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from typing import (
Any,
Dict,
Iterator,
List,
Mapping,
Expand Down Expand Up @@ -280,9 +281,7 @@ def __init__(
Path().resolve() if cwd is None else Path(cwd)
)
self._project_config = ProjectConfig(
{"tool.poe": table or {}},
path=self._project_dir.joinpath(config_name),
strict=False,
{"tool.poe": table or {}}, path=self._project_dir, strict=False
)
self._included_config = []

Expand Down Expand Up @@ -322,7 +321,7 @@ def task_names(self) -> Iterator[str]:
yield from result

@property
def tasks(self) -> Mapping[str, Any]:
def tasks(self) -> Dict[str, Any]:
result = dict(self._project_config.get("tasks", {}))
for config in self._included_config:
for task_name, task_def in config.get("tasks", {}).items():
Expand Down Expand Up @@ -356,7 +355,7 @@ def verbosity(self) -> int:

@property
def is_poetry_project(self) -> bool:
return "poetry" in self._project_config.full_config
return "poetry" in self._project_config.full_config.get("tool", {})

@property
def project_dir(self) -> Path:
Expand Down
44 changes: 18 additions & 26 deletions poethepoet/plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import Any, Dict, List
from typing import TYPE_CHECKING, Any, Dict, List

from cleo.commands.command import Command
from cleo.events.console_command_event import ConsoleCommandEvent
Expand All @@ -11,6 +11,9 @@

from .exceptions import PoePluginException

if TYPE_CHECKING:
from .config import PoeConfig


class PoeCommand(Command):
prefix: str
Expand Down Expand Up @@ -87,7 +90,7 @@ def activate(self, application: Application) -> None:

debug = bool(int(os.environ.get("DEBUG_POE_PLUGIN", "0")))
print(
"error: poethepoet plugin failed to activate."
"error: poethepoet plugin encountered an error."
+ ("" if debug else " Set DEBUG_POE_PLUGIN=1 for details."),
file=sys.stderr,
)
Expand All @@ -104,10 +107,10 @@ def _activate(self, application: Application) -> None:
# If there's no pyproject.toml then probably that's OK, don't freak out
return

command_prefix = poe_config.get("poetry_command", "poe").strip()
command_prefix = poe_config._project_config.get("poetry_command").strip()
PoeCommand.command_prefix = command_prefix

poe_tasks = poe_config.get("tasks", {})
poe_tasks = poe_config.tasks
self._validate_command_prefix(command_prefix)

if command_prefix in COMMANDS:
Expand Down Expand Up @@ -141,33 +144,22 @@ def _activate(self, application: Application) -> None:
self._monkey_patch_cleo(command_prefix, list(poe_tasks.keys()))

self._register_command_event_handler(
application, poe_config.get("poetry_hooks", {})
application, poe_config._project_config.get("poetry_hooks", {})
)

@classmethod
def _get_config(cls, application: Application) -> Dict[str, Any]:
def _get_config(cls, application: Application) -> "PoeConfig":
from .config import PoeConfig

# Try respect poetry's '--directory' if set
try:
pyproject = application.poetry.pyproject.data
except: # noqa: E722
# Fallback to loading the config again in case of future failure of the
# above undocumented API
import tomlkit

from .config import PoeConfig

# Try respect poetry's '--directory' if set
try:
pyproject_path = Path(application.poetry.pyproject_path)
except AttributeError:
pyproject_path = None

pyproject = tomlkit.loads(
Path(
PoeConfig().find_config_file(target_path=pyproject_path)
).read_text()
)
pyproject_dir = application.poetry.pyproject_path.parent
except AttributeError:
pyproject_dir = None

return pyproject.get("tool", {}).get("poe", {})
poe_config = PoeConfig(cwd=pyproject_dir)
poe_config.load(strict=False)
return poe_config

def _validate_command_prefix(self, command_prefix: str):
if command_prefix and not command_prefix.isalnum():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ poe_test_helpers = { path = "../../packages/poe_test_helpers" }

[tool.poe]
poetry_command = ""
include = "tasks.toml"

[tool.poe.tasks]
echo = { cmd = "poe_test_echo", help = "It's like echo"}
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/poetry_plugin_project/empty_prefix/tasks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tool.poe.tasks]
included-greeting = "echo 'Greetings from another file!'"
11 changes: 11 additions & 0 deletions tests/test_poetry_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,17 @@ def test_running_tasks_without_poe_command_prefix(run_poetry, projects):
# assert result.stderr == ""


@pytest.mark.slow()
@pytest.mark.usefixtures("_setup_poetry_project_empty_prefix")
def test_poetry_command_from_included_file_with_empty_prefix(run_poetry, projects):
result = run_poetry(
["included-greeting"],
cwd=projects["poetry_plugin/empty_prefix"].parent,
)
assert result.stdout.startswith("Poe => echo 'Greetings from another file!'")
# assert result.stderr == ""


@pytest.mark.slow()
@pytest.mark.usefixtures("_setup_poetry_project_empty_prefix")
def test_poetry_help_with_poe_command_prefix(run_poetry, projects):
Expand Down
Loading