Skip to content

Commit

Permalink
Tidy
Browse files Browse the repository at this point in the history
  • Loading branch information
MetRonnie committed Feb 1, 2024
1 parent 38a4e15 commit 7d56175
Showing 1 changed file with 63 additions and 57 deletions.
120 changes: 63 additions & 57 deletions cylc/flow/scripts/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
Checks code style, deprecated syntax and other issues.
"""
# NOTE: docstring needed for `cylc help all` output
# NOTE: docstring needed for `cylc help all` output and docs
# (if editing check this still comes out as expected)

COP_DOC = """cylc lint [OPTIONS] ARGS
Expand Down Expand Up @@ -88,6 +88,10 @@
from cylc.flow.terminal import cli_function

if TYPE_CHECKING:
# BACK COMPAT: typing_extensions.Literal
# FROM: Python 3.7
# TO: Python 3.8
from typing_extensions import Literal
from optparse import Values

LINT_TABLE = ['tool', 'cylc', 'lint']
Expand All @@ -104,6 +108,11 @@
# 8.4.0 ?
DEPR_LINT_SECTION = 'cylc-lint'

IGNORE = 'ignore'
EXCLUDE = 'exclude'
RULESETS = 'rulesets'
MAX_LINE_LENGTH = 'max-line-length'

DEPRECATED_ENV_VARS = {
'CYLC_SUITE_HOST': 'CYLC_WORKFLOW_HOST',
'CYLC_SUITE_OWNER': 'CYLC_WORKFLOW_OWNER',
Expand Down Expand Up @@ -602,7 +611,9 @@ def list_wrapper(line: str, check: Callable) -> Optional[Dict[str, str]]:
},
'U008': {
'short': 'Suicide triggers are not required at Cylc 8.',
'url': '',
'url': (
'https://cylc.github.io/cylc-doc/stable/html/7-to-8'
'/major-changes/suicide-triggers.html'),
'kwargs': True,
FUNCTION: functools.partial(
check_for_suicide_triggers,
Expand All @@ -616,9 +627,7 @@ def list_wrapper(line: str, check: Callable) -> Optional[Dict[str, str]]:
},
'U010': {
'short': 'rose suite-hook is deprecated at Rose 2,',
'url': (
'https://cylc.github.io/cylc-doc/stable/html/7-to-8'
'/major-changes/suicide-triggers.html'),
'url': '',
FUNCTION: lambda line: 'rose suite-hook' in line,
},
'U011': {
Expand Down Expand Up @@ -711,25 +720,25 @@ def list_wrapper(line: str, check: Callable) -> Optional[Dict[str, str]]:
list_wrapper, check=CHECK_FOR_OLD_VARS.findall),
},
}
RULESETS = ['728', 'style', 'all']
ALL_RULESETS = ['728', 'style', 'all']
EXTRA_TOML_VALIDATION = {
'ignore': {
IGNORE: {
lambda x: re.match(r'[A-Z]\d\d\d', x):
'{item} not valid: Ignore codes should be in the form X001',
lambda x: x in parse_checks(['728', 'style']):
'{item} is a not a known linter code.'
},
'rulesets': {
lambda item: item in RULESETS:
RULESETS: {
lambda item: item in ALL_RULESETS:
'{item} not valid: Rulesets can be '
'\'728\', \'style\' or \'all\'.'
},
'max-line-length': {
MAX_LINE_LENGTH: {
lambda x: isinstance(x, int):
'max-line-length must be an integer.'
},
# consider checking that item is file?
'exclude': {}
EXCLUDE: {}
}


Expand Down Expand Up @@ -774,7 +783,7 @@ def validate_toml_items(tomldata):
f'Only {[*EXTRA_TOML_VALIDATION.keys()]} '
f'allowed as toml sections but you used "{key}"'
)
if key != 'max-line-length':
if key != MAX_LINE_LENGTH:
# Item should be a list...
if not isinstance(items, list):
raise CylcError(
Expand All @@ -798,11 +807,11 @@ def get_pyproject_toml(dir_: Path) -> Dict[str, Any]:
"""if a pyproject.toml file is present open it and return settings.
"""
tomlfile = dir_ / 'pyproject.toml'
tomldata = {
'rulesets': [],
'ignore': [],
'exclude': [],
'max-line-length': None,
tomldata: Dict[str, Union[List[str], int, None]] = {
RULESETS: [],
IGNORE: [],
EXCLUDE: [],
MAX_LINE_LENGTH: None,
}
if tomlfile.is_file():
try:
Expand Down Expand Up @@ -849,9 +858,9 @@ def merge_cli_with_tomldata(target: Path, options: 'Values') -> Dict[str, Any]:
tomlopts = get_pyproject_toml(target)
return _merge_cli_with_tomldata(
{
'exclude': [],
'ignore': options.ignores,
'rulesets': options.linter
EXCLUDE: [],
IGNORE: options.ignores,
RULESETS: options.linter
},
tomlopts,
ruleset_default
Expand Down Expand Up @@ -886,30 +895,30 @@ def _merge_cli_with_tomldata(
>>> result['exclude']
['*.bk']
"""
if isinstance(clidata['rulesets'][0], list):
clidata['rulesets'] = clidata['rulesets'][0]
if isinstance(clidata[RULESETS][0], list):
clidata[RULESETS] = clidata[RULESETS][0]

output = {}

# Combine 'ignore' sections:
output['ignore'] = sorted(set(clidata['ignore'] + tomldata['ignore']))
output[IGNORE] = sorted(set(clidata[IGNORE] + tomldata[IGNORE]))

# Replace 'rulesets from toml with those from CLI if they exist:
# Replace 'rulesets' from toml with those from CLI if they exist:

if override_cli_default_rules:
output['rulesets'] = (
tomldata['rulesets'] if tomldata['rulesets']
else clidata['rulesets']
output[RULESETS] = (
tomldata[RULESETS] if tomldata[RULESETS]
else clidata[RULESETS]
)
else:
output['rulesets'] = (
clidata['rulesets'] if clidata['rulesets']
else tomldata['rulesets']
output[RULESETS] = (
clidata[RULESETS] if clidata[RULESETS]
else tomldata[RULESETS]
)

# Return 'exclude' and 'max-line-length' for the tomldata:
output['exclude'] = tomldata['exclude']
output['max-line-length'] = tomldata.get('max-line-length', None)
output[EXCLUDE] = tomldata[EXCLUDE]
output[MAX_LINE_LENGTH] = tomldata.get(MAX_LINE_LENGTH, None)

return output

Expand Down Expand Up @@ -1239,20 +1248,7 @@ def get_cylc_files(
yield path


REFERENCE_TEMPLATES = {
'section heading': '\n{title}\n{underline}\n',
'issue heading': {
'text': '\n{check}:\n {summary}\n {url}\n\n',
'rst': '\n{url}_\n{underline}\n{summary}\n\n',
},
'auto gen message': (
'U998 and U999 represent automatically generated'
' sets of deprecations and upgrades.'
),
}


def get_reference(linter, output_type):
def get_reference(linter: str, output_type: 'Literal["text", "rst"]') -> str:
"""Fill out a template with all the issues Cylc Lint looks for.
"""
if linter in {'all', ''}:
Expand All @@ -1261,7 +1257,10 @@ def get_reference(linter, output_type):
rulesets = [linter]
checks = parse_checks(rulesets, reference=True)

issue_heading_template = REFERENCE_TEMPLATES['issue heading'][output_type]
issue_heading_template = (
'\n{url}_\n{underline}\n{summary}\n\n' if output_type == 'rst' else
'\n{check}:\n {summary}\n {url}\n\n'
)
output = ''
current_checkset = ''
for index, meta in checks.items():
Expand All @@ -1270,11 +1269,15 @@ def get_reference(linter, output_type):
if meta['purpose'] != current_checkset:
current_checkset = meta['purpose']
title = CHECKS_DESC[meta["purpose"]]
output += REFERENCE_TEMPLATES['section heading'].format(
title=title, underline="-" * len(title))
output += '\n{title}\n{underline}\n'.format(
title=title, underline="-" * len(title)
)

if current_checkset == 'A':
output += REFERENCE_TEMPLATES['auto gen message']
output += (
'U998 and U999 represent automatically generated'
' sets of deprecations and upgrades.'
)

# Fill a template with info about the issue.
if output_type == 'rst':
Expand Down Expand Up @@ -1321,18 +1324,18 @@ def target_version_check(
disabled thatr with --exit-zero.
"""
cylc8 = (target / 'flow.cylc').exists()
if not cylc8 and mergedopts['rulesets'] == ['728']:
if not cylc8 and mergedopts[RULESETS] == ['728']:
LOG.error(
f'{target} not a Cylc 8 workflow: '
'Lint after renaming '
'"suite.rc" to "flow.cylc"'
)
sys.exit(not quiet)
elif not cylc8 and '728' in mergedopts['rulesets']:
check_names = mergedopts['rulesets']
elif not cylc8 and '728' in mergedopts[RULESETS]:
check_names = mergedopts[RULESETS]
check_names.remove('728')
else:
check_names = mergedopts['rulesets']
check_names = mergedopts[RULESETS]
return check_names


Expand Down Expand Up @@ -1399,6 +1402,9 @@ def get_option_parser() -> COP:

@cli_function(get_option_parser)
def main(parser: COP, options: 'Values', target=None) -> None:
if cylc.flow.flags.verbosity < 2:
set_timestamps(LOG, False)

if options.ref_mode:
print(get_reference(options.linter, 'text'))
sys.exit(0)
Expand Down Expand Up @@ -1426,13 +1432,13 @@ def main(parser: COP, options: 'Values', target=None) -> None:
# Get the checks object.
checks = parse_checks(
check_names,
ignores=mergedopts['ignore'],
max_line_len=mergedopts['max-line-length']
ignores=mergedopts[IGNORE],
max_line_len=mergedopts[MAX_LINE_LENGTH]
)

# Check each file matching a pattern:
counter: Dict[str, int] = {}
for file in get_cylc_files(target, mergedopts['exclude']):
for file in get_cylc_files(target, mergedopts[EXCLUDE]):
LOG.debug(f'Checking {file}')
check_cylc_file(
file,
Expand Down

0 comments on commit 7d56175

Please sign in to comment.