Skip to content

Commit

Permalink
fix: Make task autocompletion work again in sub-directories (#258)
Browse files Browse the repository at this point in the history
Also:
- Tweak envfile caching logic
- Improve validation coverage for args config
- Fix rstcheck errors and upgrade sphinx
  • Loading branch information
nat-n authored Nov 23, 2024
1 parent c7b8b64 commit e5e7f60
Show file tree
Hide file tree
Showing 7 changed files with 267 additions and 227 deletions.
5 changes: 4 additions & 1 deletion docs/guides/args_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,14 @@ Named arguments support the following configuration options:

.. code-block:: toml
[tool.poe.tasks.deploy]
cmd = "..."
env.AWS_REGION.default = "eu-central-1"
[[tool.poe.tasks.deploy.args]]
name = "region"
help = "The region to deploy to"
default = "${AWS_REGION}"
env.AWS_REGION.default = "eu-central-1"
As in the above example, this can be combined with setting an :doc:`env value<../tasks/options>` on the task with the ``default`` specifier to get the following precedence of values for the arg:

Expand Down
11 changes: 7 additions & 4 deletions poethepoet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ def main():
from pathlib import Path

if len(sys.argv) > 1 and sys.argv[1].startswith("_"):
first_arg = sys.argv[1]
second_arg = next(iter(sys.argv[2:]), "")
third_arg = next(iter(sys.argv[3:]), "")
first_arg = sys.argv[1] # built in task name
second_arg = next(iter(sys.argv[2:]), "") # config path or poe alias
third_arg = next(iter(sys.argv[3:]), "") # path to alias config for bash

if first_arg in ("_list_tasks", "_describe_tasks"):
_list_tasks(target_path=str(Path(second_arg).expanduser().resolve()))
target_path = (
str(Path(second_arg).expanduser().resolve()) if second_arg else None
)
_list_tasks(target_path=target_path)
return

target_path = ""
Expand Down
8 changes: 6 additions & 2 deletions poethepoet/env/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ def __init__(self, project_dir: Path, ui: Optional["PoeUi"]):
self._ui = ui

def get(self, envfile: Union[str, Path]) -> Dict[str, str]:
"""
Parse, cache, and return the environment variables from the envfile at the
given path. The path is used as the cache key.
"""
from .parse import parse_env_file

envfile_path_str = str(envfile)
envfile_path = self._project_dir.joinpath(Path(envfile).expanduser()).absolute()
envfile_path_str = str(envfile_path)

if envfile_path_str in self._cache:
return self._cache[envfile_path_str]

result = {}

envfile_path = self._project_dir.joinpath(Path(envfile).expanduser())
if envfile_path.is_file():
try:
with envfile_path.open(encoding="utf-8") as envfile_file:
Expand Down
9 changes: 9 additions & 0 deletions poethepoet/options/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ def __getattr__(self, name: str):
f"{self.__class__.__name__} has no value for option {name!r}"
)

def __str__(self):
return (
f"{self.__class__.__name__}("
+ ", ".join(
f"{field}={getattr(self, field)!r}" for field in self.get_fields()
)
+ ")"
)

@classmethod
def parse(
cls,
Expand Down
22 changes: 17 additions & 5 deletions poethepoet/task/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ def parse(
def _get_arg_options_list(
arg: ArgParams, name: str | None = None, strict: bool = True
):
position = arg.get("positional", False)
positional = arg.get("positional", False)
name = name or arg.get("name")
if position:
if positional:
if strict and arg.get("options"):
raise ConfigValidationError(
f"Positional argument {name!r} may not declare options"
)
# Fill in the options param in a way that makes sesne for argparse
if isinstance(position, str):
return [position]
# Fill in the options param in a way that makes sense for argparse
if isinstance(positional, str):
return [positional]
return [name]
return tuple(arg.get("options", [f"--{name}"]))

Expand Down Expand Up @@ -152,6 +152,18 @@ def _validate(self):
"see the following documentation for details "
"https://docs.python.org/3/reference/lexical_analysis.html#identifiers"
)
else:
for option in self.options:
if not option.strip():
raise ConfigValidationError(
"Invalid empty value in CLI options list"
)
if option[0] != "-":
suggestion = f"-{option}" if len(option) == 1 else f"--{option}"
raise ConfigValidationError(
f"Invalid CLI option provided {option!r}, did you mean "
f"{suggestion!r}?"
)

if (
not isinstance(self.multiple, bool)
Expand Down
Loading

0 comments on commit e5e7f60

Please sign in to comment.