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

cylc clean: rename --force to --yes #4675

Merged
merged 3 commits into from
Feb 11, 2022
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
17 changes: 13 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,24 @@ First Release Candidate for Cylc 8.

(See note on cylc-8 backward-incompatible changes, above)

Also note: you will not be able to restart workflows run with previous
Cylc 8 pre-releases due to changes in the workflow database structure
([#4581](https://github.com/cylc/cylc-flow/pull/4581))

### Enhancements

[#4581](https://github.com/cylc/cylc-flow/pull/4581) - Job and task history
is now loaded into the window about active tasks. Reflow future tasks now set
to waiting.
[#4581](https://github.com/cylc/cylc-flow/pull/4581) - Improvements allowing
the UI & TUI to remember more info about past tasks and jobs:
- Job and task history is now loaded into the window about active tasks.
- Reflow future tasks now set to waiting.

[#3931](https://github.com/cylc/cylc-flow/pull/3931) - Convert Cylc to
use the new "Universal Identifier".

[#3931](https://github.com/cylc/cylc-flow/pull/3931),
[#4675](https://github.com/cylc/cylc-flow/pull/4675) - `cylc clean` now
interactively prompts if trying to clean multiple run dirs.

[#4506](https://github.com/cylc/cylc-flow/pull/4506) - Cylc no longer
creates a `flow.cylc` symlink to a `suite.rc` file.
This only affects you if you have used a prior Cylc 8 pre-release.
Expand All @@ -72,7 +81,7 @@ now configurable in `global.cylc[install]max depth`, and `cylc install` will
fail if the workflow ID would exceed this depth.

[#4534](https://github.com/cylc/cylc-flow/pull/4534) - Permit jobs
to be run on platforms with no $HOME directory.
to be run on platforms with no `$HOME` directory.

[#4536](https://github.com/cylc/cylc-flow/pull/4536) - `cylc extract-resources`
renamed `cylc get-resources` and small changes made:
Expand Down
25 changes: 14 additions & 11 deletions cylc/flow/scripts/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# Remove the workflow at ~/cylc-run/foo/bar
$ cylc clean foo/bar

# Remove multiple workflows
# Remove multiple workflows
$ cylc clean one two three

# Remove the workflow's log directory
Expand Down Expand Up @@ -86,7 +86,7 @@ def get_option_parser():
'--rm', metavar='DIR[:DIR:...]',
help=("Only clean the specified subdirectories (or files) in the "
"run directory, rather than the whole run directory. "
"Accepts quoted globs. Implies --verbose."),
"Accepts quoted globs."),
action='append', dest='rm_dirs', default=[]
)

Expand All @@ -103,12 +103,12 @@ def get_option_parser():
)

parser.add_option(
'--force',
help=("Allow cleaning of directories that contain workflow run dirs "
"(e.g. 'cylc clean foo' when foo contains run1, run2 etc.). "
"Warning: this might lead to remote installations and "
"symlink dir targets not getting removed."),
action='store_true', dest='force'
'--yes', '-y',
help=(
"Skip interactive prompt if trying to clean multiple "
"run directories at once."
),
action='store_true', dest='skip_interactive'
)

parser.add_option(
Expand All @@ -125,7 +125,7 @@ def get_option_parser():


def prompt(workflows):
print('Would remove the following workflows:')
print("Would clean the following workflows:")
for workflow in workflows:
print(f' {workflow}')

Expand All @@ -137,7 +137,10 @@ def prompt(workflows):
if ret.lower() == 'n':
sys.exit(1)
else:
print('Use --force to remove multiple workflows.', file=sys.stderr)
print(
"Use --yes to remove multiple workflows in non-interactive mode.",
file=sys.stderr
)
sys.exit(1)


Expand Down Expand Up @@ -173,7 +176,7 @@ async def run(*ids, opts=None):
workflows, multi_mode = await scan(workflows, multi_mode)

workflows.sort()
if multi_mode and not opts.force:
if multi_mode and not opts.skip_interactive:
prompt(workflows) # prompt for approval or exit

for workflow in sorted(workflows):
Expand Down
19 changes: 9 additions & 10 deletions tests/unit/scripts/test_clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from types import SimpleNamespace
from typing import Callable, List

import pytest

from cylc.flow.scripts.clean import scan, run
from cylc.flow.scripts.clean import CleanOptions, scan, run


async def test_scan(tmp_run_dir):
Expand All @@ -44,7 +44,7 @@ async def test_scan(tmp_run_dir):


@pytest.fixture
def mute(monkeypatch):
def mute(monkeypatch: pytest.MonkeyPatch) -> List[str]:
"""Stop cylc clean from doing anything and log all init_clean calls."""
items = []

Expand All @@ -58,34 +58,33 @@ def _clean(id_, *_):
return items


async def test_multi(tmp_run_dir, mute):
async def test_multi(tmp_run_dir: Callable, mute: List[str]):
"""It supports cleaning multiple workflows."""
# cli opts
opts = SimpleNamespace()
opts.force = False
opts = CleanOptions()

# create three dummy workflows
tmp_run_dir('bar/pub/beer')
tmp_run_dir('baz/run1')
tmp_run_dir('foo')

# an explicit workflow ID goes straight through
mute[:] = []
mute.clear()
await run('foo', opts=opts)
assert mute == ['foo']

# a partial hierarchical ID gets expanded to all workflows contained
# in the hierarchy (note runs are a special case of hierarchical ID)
mute[:] = []
mute.clear()
await run('bar', opts=opts)
assert mute == ['bar/pub/beer']

# test a mixture of explicit and partial IDs
mute[:] = []
mute.clear()
await run('bar', 'baz', 'foo', opts=opts)
assert mute == ['bar/pub/beer', 'baz/run1', 'foo']

# test a glob
mute[:] = []
mute.clear()
await run('*', opts=opts)
assert mute == ['bar/pub/beer', 'baz/run1', 'foo']