Skip to content

Commit

Permalink
Merge pull request #4362 from wxtim/main
Browse files Browse the repository at this point in the history
Remove runN symlink when cleaning latest run
  • Loading branch information
wxtim authored Aug 19, 2021
1 parent 3fc995c commit 26cc709
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ Remove obsolete Cylc 7 `[scheduling]spawn to max active cycle points` config.
safer by preventing cleaning of dirs that contain more than one workflow
run dir (use `--force` to override this safeguard).

[#4362](https://github.com/cylc/cylc-flow/pull/4362) -
When using `cylc clean` on a sequential run directory, remove the `runN` symlink
if it points to the removed directory.

-------------------------------------------------------------------------------
## __cylc-8.0b2 (<span actions:bind='release-date'>Released 2021-07-28</span>)__

Expand Down
9 changes: 9 additions & 0 deletions cylc/flow/workflow_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,15 @@ def clean(reg: str, run_dir: Path, rm_dirs: Optional[Set[str]] = None) -> None:
# Remove empty parents of symlink target up to <symlink_dir>/cylc-run/
remove_empty_parents(target, Path(reg, symlink))

# Remove `runN` symlink if it's now broken
runN = run_dir.parent / WorkflowFiles.RUN_N
if (
runN.is_symlink() and
not run_dir.exists() and
os.readlink(str(runN)) == run_dir.name
):
runN.unlink()


def get_symlink_dirs(reg: str, run_dir: Union[Path, str]) -> Dict[str, Path]:
"""Return the standard symlink dirs and their targets if they exist in
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/test_workflow_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import os
from pathlib import Path
import pytest
import re
import shutil
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
from unittest import mock
Expand All @@ -40,6 +41,7 @@
_remote_clean_cmd,
check_flow_file,
check_nested_run_dirs,
clean,
get_rsync_rund_cmd,
get_symlink_dirs,
is_installed,
Expand Down Expand Up @@ -1523,3 +1525,32 @@ def test_get_rsync_rund_cmd(tmp_run_dir: Callable):
'--exclude=log', '--exclude=work', '--exclude=share',
'--exclude=_cylc-install', '--exclude=.service',
'blah/', f'{cylc_run_dir}/']


@pytest.mark.parametrize(
'expect, dirs',
[
(['run1'], ['run1', 'run2']),
(['run1', 'run11'], ['run1', 'run11', 'run2']),
(['run1200'], ['run1200', 'run1201']),
(['foo'], ['foo', 'bar']),
]
)
def test_delete_runN(tmp_path, expect, dirs):
"""It deletes the runN symlink.
"""
for dir_ in dirs:
(tmp_path / dir_).mkdir()
if re.findall('run\d*', dirs[-1]):
(Path(tmp_path / 'runN')).symlink_to(dirs[-1])
clean(str(tmp_path.name) + '/' + dirs[-1], tmp_path / dirs[-1])
assert sorted([i.stem for i in tmp_path.glob('*')]) == sorted(expect)


def test_delete_runN_skipif_cleanedrun_not_runN(tmp_path):
"""It doesn't delete the symlink dir to be cleaned is not runN"""
for folder in ['run1', 'run2']:
(tmp_path / folder).mkdir()
(tmp_path / 'runN').symlink_to(tmp_path / 'run2')
clean(str(tmp_path.name) + '/' + 'run1', tmp_path / 'run1')
assert sorted([i.stem for i in tmp_path.glob('*')]) == ['run2', 'runN']

0 comments on commit 26cc709

Please sign in to comment.