|
50 | 50 | max-line-length = 130 # Max line length for linting
|
51 | 51 | """
|
52 | 52 | import functools
|
| 53 | +import pkgutil |
53 | 54 | from pathlib import Path
|
54 | 55 | import re
|
55 | 56 | import sys
|
|
78 | 79 | from cylc.flow import LOG
|
79 | 80 | from cylc.flow.exceptions import CylcError
|
80 | 81 | import cylc.flow.flags
|
| 82 | +from cylc.flow import job_runner_handlers |
| 83 | +from cylc.flow.job_runner_mgr import JobRunnerManager |
81 | 84 | from cylc.flow.loggingutil import set_timestamps
|
82 | 85 | from cylc.flow.option_parsers import (
|
83 | 86 | CylcOptionParser as COP,
|
|
162 | 165 | }
|
163 | 166 |
|
164 | 167 |
|
| 168 | +def get_wallclock_directives(): |
| 169 | + """Get a set of directives equivalent to execution time limit""" |
| 170 | + job_runner_manager = JobRunnerManager() |
| 171 | + directives = {} |
| 172 | + for module in pkgutil.iter_modules(job_runner_handlers.__path__): |
| 173 | + directive = getattr( |
| 174 | + job_runner_manager._get_sys(module.name), |
| 175 | + 'TIME_LIMIT_DIRECTIVE', |
| 176 | + None |
| 177 | + ) |
| 178 | + if directive: |
| 179 | + directives[module.name] = directive |
| 180 | + return directives |
| 181 | + |
| 182 | + |
| 183 | +WALLCLOCK_DIRECTIVES = get_wallclock_directives() |
| 184 | + |
| 185 | + |
| 186 | +def check_wallclock_directives(line: str) -> Union[Dict[str, str], bool]: |
| 187 | + """Check for job runner specific directives |
| 188 | + equivelent to exection time limit. |
| 189 | + """ |
| 190 | + for directive in set(WALLCLOCK_DIRECTIVES.values()): |
| 191 | + if line.strip().startswith(directive): |
| 192 | + return {'directive': line.strip()} |
| 193 | + return False |
| 194 | + |
| 195 | + |
165 | 196 | def check_jinja2_no_shebang(
|
166 | 197 | line: str,
|
167 | 198 | file: Path,
|
@@ -533,6 +564,30 @@ def list_wrapper(line: str, check: Callable) -> Optional[Dict[str, str]]:
|
533 | 564 | 'S013': {
|
534 | 565 | 'short': 'Items should be indented in 4 space blocks.',
|
535 | 566 | FUNCTION: check_indentation
|
| 567 | + }, |
| 568 | + 'S014': { |
| 569 | + 'short': ( |
| 570 | + 'Use ``[runtime][TASK]execution time limit``' |
| 571 | + ' rather than job runner directive: ``{directive}``.' |
| 572 | + ), |
| 573 | + 'rst': ( |
| 574 | + 'Using ``[runtime][TASK]execution time limit`` is' |
| 575 | + ' recommended in preference to using job runner' |
| 576 | + ' directives because it allows Cylc to retain awareness' |
| 577 | + ' of whether the job should have finished, even if contact' |
| 578 | + ' with the target job runner\'s platform has been lost.' |
| 579 | + ' \n\nThe following directives are considered equivelent to' |
| 580 | + ' execution time limit:\n * ' |
| 581 | + ) |
| 582 | + + '\n * '.join(( |
| 583 | + f'``{directive}`` ({job_runner})' |
| 584 | + for job_runner, directive in WALLCLOCK_DIRECTIVES.items() |
| 585 | + )) + ( |
| 586 | + '\n\n.. note:: Using ``execution time limit`` which' |
| 587 | + ' is automatically translated to the job runner\'s timeout' |
| 588 | + ' directive can make your workflow more portable.' |
| 589 | + ), |
| 590 | + FUNCTION: check_wallclock_directives, |
536 | 591 | }
|
537 | 592 | }
|
538 | 593 | # Subset of deprecations which are tricky (impossible?) to scrape from the
|
|
0 commit comments