Skip to content

Commit

Permalink
fix(run): simplify and fix run arg parsing
Browse files Browse the repository at this point in the history
Resolves: #10051
  • Loading branch information
abn committed Jan 17, 2025
1 parent 81f2935 commit 440adbf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 118 deletions.
67 changes: 32 additions & 35 deletions src/poetry/console/application.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from __future__ import annotations

import logging
import re

from contextlib import suppress
from importlib import import_module
from pathlib import Path
from typing import TYPE_CHECKING
Expand All @@ -13,8 +11,8 @@
from cleo.events.console_command_event import ConsoleCommandEvent
from cleo.events.console_events import COMMAND
from cleo.events.event_dispatcher import EventDispatcher
from cleo.exceptions import CleoError
from cleo.formatters.style import Style
from cleo.io.inputs.argv_input import ArgvInput

from poetry.__version__ import __version__
from poetry.console.command_loader import CommandLoader
Expand All @@ -28,7 +26,6 @@
from typing import Any

from cleo.events.event import Event
from cleo.io.inputs.argv_input import ArgvInput
from cleo.io.inputs.definition import Definition
from cleo.io.inputs.input import Input
from cleo.io.io import IO
Expand Down Expand Up @@ -277,40 +274,40 @@ def _configure_custom_application_options(self, io: IO) -> None:
is_directory=True,
)

def _configure_io(self, io: IO) -> None:
# We need to check if the command being run
# is the "run" command.
definition = self.definition
with suppress(CleoError):
io.input.bind(definition)

name = io.input.first_argument
if name == "run":
from poetry.console.io.inputs.run_argv_input import RunArgvInput

input = cast("ArgvInput", io.input)
run_input = RunArgvInput([self._name or "", *input._tokens])
# For the run command reset the definition
# with only the set options (i.e. the options given before the command)
for option_name, value in input.options.items():
if value:
option = definition.option(option_name)
run_input.add_parameter_option("--" + option.name)
if option.shortcut:
shortcuts = re.split(r"\|-?", option.shortcut.lstrip("-"))
shortcuts = [s for s in shortcuts if s]
for shortcut in shortcuts:
run_input.add_parameter_option("-" + shortcut.lstrip("-"))

with suppress(CleoError):
run_input.bind(definition)

for option_name, value in input.options.items():
if value:
run_input.set_option(option_name, value)
def _configure_run_command(self, io: IO) -> None:
command_name = io.input.first_argument
if command_name == "run":
current_input = cast(ArgvInput, io.input)
tokens: list[str] = current_input._tokens

if "--" in tokens:
return

command_index = tokens.index(command_name)
tokens_without_command = tokens[command_index + 1 :]
without_command = ArgvInput(
[self._name or "", *tokens_without_command], None
)

first_arg = without_command.first_argument
first_arg_index = (
tokens.index(first_arg) if first_arg else command_index + 1
)

run_input = ArgvInput(
[
self._name or "",
*tokens[:command_index],
*tokens[command_index + 1 : first_arg_index],
command_name,
"--",
*tokens[first_arg_index:],
]
)
io.set_input(run_input)

def _configure_io(self, io: IO) -> None:
self._configure_run_command(io)
super()._configure_io(io)

def register_command_loggers(
Expand Down
Empty file removed src/poetry/console/io/__init__.py
Empty file.
Empty file.
83 changes: 0 additions & 83 deletions src/poetry/console/io/inputs/run_argv_input.py

This file was deleted.

19 changes: 19 additions & 0 deletions tests/console/commands/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ def test_run_passes_all_args(app_tester: ApplicationTester, env: MockEnv) -> Non
assert env.executed == [["python", "-V"]]


def test_run_passes_args_after_run_before_command_(
app_tester: ApplicationTester, env: MockEnv
) -> None:
app_tester.execute("run -P. python -V", decorated=True)
assert env.executed == [["python", "-V"]]


def test_run_keeps_options_passed_before_command_args(
app_tester: ApplicationTester, env: MockEnv
) -> None:
app_tester.execute("run -V --no-ansi python", decorated=True)

assert not app_tester.io.is_decorated()
assert app_tester.io.fetch_output() == app_tester.io.remove_format(
app_tester.application.long_version + "\n"
)
assert env.executed == []


def test_run_keeps_options_passed_before_command(
app_tester: ApplicationTester, env: MockEnv
) -> None:
Expand Down

0 comments on commit 440adbf

Please sign in to comment.