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

Accept --id option multiple times for clean and status #2891

Merged
merged 5 commits into from
Aug 2, 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
12 changes: 3 additions & 9 deletions tmt/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3734,13 +3734,11 @@ def print_header(self) -> None:
def show(self) -> None:
""" Display the current status """
# Prepare absolute workdir path if --id was used
# FIXME: cast() - typeless "dispatcher" method
id_ = cast(str, self.opt('id'))
root_path = Path(self.opt('workdir-root'))
self.print_header()
assert self._cli_context_object is not None # narrow type
assert self._cli_context_object.tree is not None # narrow type
for abs_path in tmt.utils.generate_runs(root_path, id_):
for abs_path in tmt.utils.generate_runs(root_path, self.opt('id')):
run = Run(
logger=self._logger,
id_=abs_path,
Expand Down Expand Up @@ -3840,16 +3838,14 @@ def guests(self) -> bool:
""" Clean guests of runs """
self.info('guests', color='blue')
root_path = Path(self.opt('workdir-root'))
# FIXME: cast() - typeless "dispatcher" method
id_ = cast(str, self.opt('id_'))
if self.opt('last'):
# Pass the context containing --last to Run to choose
# the correct one.
return self._stop_running_guests(
Run(logger=self._logger, cli_invocation=self.cli_invocation))
successful = True
assert self._cli_context_object is not None # narrow type
for abs_path in tmt.utils.generate_runs(root_path, id_):
for abs_path in tmt.utils.generate_runs(root_path, self.opt('id_')):
run = Run(
logger=self._logger,
id_=abs_path,
Expand All @@ -3876,16 +3872,14 @@ def runs(self) -> bool:
""" Clean workdirs of runs """
self.info('runs', color='blue')
root_path = Path(self.opt('workdir-root'))
# FIXME: cast() - typeless "dispatcher" method
id_ = cast(str, self.opt('id_'))
if self.opt('last'):
# Pass the context containing --last to Run to choose
# the correct one.
last_run = Run(logger=self._logger, cli_invocation=self.cli_invocation)
last_run._workdir_load(last_run._workdir_path)
assert last_run.workdir is not None # narrow type
return self._clean_workdir(last_run.workdir)
all_workdirs = list(tmt.utils.generate_runs(root_path, id_))
all_workdirs = list(tmt.utils.generate_runs(root_path, self.opt('id_')))
keep = self.opt('keep')
if keep is not None:
# Sort by modify time of the workdirs and keep the newest workdirs
Expand Down
20 changes: 10 additions & 10 deletions tmt/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1718,8 +1718,8 @@ def try_command(context: Context, image_and_how: str, **kwargs: Any) -> None:
@pass_context
@workdir_root_options
@option(
'-i', '--id', metavar="ID",
help='Run id (name or directory path) to show status of.')
'-i', '--id', metavar="ID", multiple=True,
thrix marked this conversation as resolved.
Show resolved Hide resolved
help='Run id(name or directory path) to show status of. Can be specified multiple times.')
@option(
'--abandoned', is_flag=True, default=False,
help='List runs which have provision step completed but finish step not yet done.')
Expand Down Expand Up @@ -1855,8 +1855,8 @@ def perform_clean(
@option(
'-l', '--last', is_flag=True, help='Clean the workdir of the last run.')
@option(
'-i', '--id', 'id_', metavar="ID",
help='Run id (name or directory path) to clean workdir of.')
'-i', '--id', 'id_', metavar="ID", multiple=True,
help='Run id(name or directory path) to clean workdir of. Can be specified multiple times.')
@option(
'-k', '--keep', type=int, default=None,
help='The number of latest workdirs to keep, clean the rest.')
Expand All @@ -1866,15 +1866,15 @@ def clean_runs(
context: Context,
workdir_root: str,
last: bool,
id_: Optional[str],
id_: tuple[str, ...],
keep: Optional[int],
**kwargs: Any) -> None:
"""
Clean workdirs of past runs.

Remove all runs in '/var/tmp/tmt' by default.
"""
defined = [last is True, id_ is not None, keep is not None]
defined = [last is True, bool(id_), keep is not None]
if defined.count(True) > 1:
raise tmt.utils.GeneralError(
"Options --last, --id and --keep cannot be used together.")
Expand All @@ -1900,8 +1900,8 @@ def clean_runs(
@option(
'-l', '--last', is_flag=True, help='Stop the guest of the last run.')
@option(
'-i', '--id', 'id_', metavar="ID", default=None,
help='Run id (name or directory path) to stop the guest of.')
'-i', '--id', 'id_', metavar="ID", default=None, multiple=True,
help='Run id(name or directory path) to stop the guest of. Can be specified multiple times.')
@option(
'-h', '--how', metavar='METHOD',
help='Stop guests of the specified provision method.')
Expand All @@ -1911,14 +1911,14 @@ def clean_guests(
context: Context,
workdir_root: str,
last: bool,
id_: Optional[int],
id_: tuple[str, ...],
**kwargs: Any) -> None:
"""
Stop running guests of runs.

Stop guests of all runs in '/var/tmp/tmt' by default.
"""
if last and id_ is not None:
if last and bool(id_):
raise tmt.utils.GeneralError(
"Options --last and --id cannot be used together.")
if not Path(workdir_root).exists():
Expand Down
22 changes: 13 additions & 9 deletions tmt/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4656,17 +4656,21 @@ def validate_git_status(test: 'tmt.base.Test') -> tuple[bool, str]:

def generate_runs(
path: Path,
id_: Optional[str] = None) -> Iterator[Path]:
id_: tuple[str, ...]) -> Iterator[Path]:
""" Generate absolute paths to runs from path """
# Prepare absolute workdir path if --id was used
if id_:
run_path = Path(id_)
if '/' not in id_:
run_path = path / run_path
if run_path.is_absolute():
if run_path.exists():
run_path = None
for id_name in id_:
if id_name:
run_path = Path(id_name)
if '/' not in id_name:
run_path = path / run_path
if run_path.is_absolute() and run_path.exists():
yield run_path
return
else:
raise tmt.utils.GeneralError("Value of '--id' option cannot be an empty string.")
if run_path:
return
if not path.exists():
return
for childpath in path.iterdir():
Expand All @@ -4675,7 +4679,7 @@ def generate_runs(
# is being applied). If it is defined, it has been transformed
# to absolute path and must be equal to abs_path for the run
# in abs_path to be generated.
invalid_id = id_ and str(abs_child_path) != id_
invalid_id = id_ and str(abs_child_path) not in id_
invalid_run = not abs_child_path.joinpath('run.yaml').exists()
if not abs_child_path.is_dir() or invalid_id or invalid_run:
continue
Expand Down
Loading