From 115f346cd872bedd1478544fc85710bf1546fbc2 Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Wed, 23 Aug 2017 11:28:28 -0400 Subject: [PATCH] Bug 1392795 - [yamllint] Group paths to lint by their closest config and run each config group separately, r=dustin This makes configuration files for yamllint work a bit better. It's still not perfect, but it's an improvement on the current situation. MozReview-Commit-ID: IKxgQm1a7bP --HG-- extra : rebase_source : 051fafe21337f0557ee39ec71c90e74fd61d3da7 --- .yamllint | 5 ++++ taskcluster/.yamllint | 2 ++ tools/lint/yamllint_/__init__.py | 42 +++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 .yamllint diff --git a/.yamllint b/.yamllint new file mode 100644 index 000000000000..52f04cc937aa --- /dev/null +++ b/.yamllint @@ -0,0 +1,5 @@ +--- +ignore: | + *node_modules* + +extends: default diff --git a/taskcluster/.yamllint b/taskcluster/.yamllint index b37a7238cb13..980ebd7cf516 100644 --- a/taskcluster/.yamllint +++ b/taskcluster/.yamllint @@ -1,4 +1,6 @@ --- +ignore: | + *node_modules* extends: default diff --git a/tools/lint/yamllint_/__init__.py b/tools/lint/yamllint_/__init__.py index 16fe34a61320..2f6754963831 100644 --- a/tools/lint/yamllint_/__init__.py +++ b/tools/lint/yamllint_/__init__.py @@ -6,6 +6,7 @@ import re import os import signal import subprocess +from collections import defaultdict import which from mozprocess import ProcessHandlerMixin @@ -114,13 +115,35 @@ def gen_yamllint_args(cmdargs, paths=None, conf_file=None): args = cmdargs[:] if isinstance(paths, basestring): paths = [paths] - if conf_file: + if conf_file and conf_file != 'default': return args + ['-c', conf_file] + paths return args + paths -def lint(files, config, **lintargs): +def ancestors(path): + while path: + yield path + (path, child) = os.path.split(path) + if child == "": + break + +def get_relevant_configs(name, path, root): + """Returns a list of configuration files that exist in `path`'s ancestors, + sorted from closest->furthest. + """ + configs = [] + for path in ancestors(path): + if path == root: + break + + config = os.path.join(path, name) + if os.path.isfile(config): + configs.append(config) + return configs + + +def lint(files, config, **lintargs): if not reinstall_yamllint(): print(YAMLLINT_INSTALL_ERROR) return 1 @@ -138,17 +161,12 @@ def lint(files, config, **lintargs): # Run any paths with a .yamllint file in the directory separately so # it gets picked up. This means only .yamllint files that live in # directories that are explicitly included will be considered. - no_config = [] + paths_by_config = defaultdict(list) for f in files: - yamllint_config = os.path.join(f, '.yamllint') - if not os.path.isfile(yamllint_config): - no_config.append(f) - continue - run_process(config, - gen_yamllint_args(cmdargs, conf_file=yamllint_config, paths=f)) + conf_files = get_relevant_configs('.yamllint', f, config['root']) + paths_by_config[conf_files[0] if conf_files else 'default'].append(f) - if no_config: - run_process(config, - gen_yamllint_args(cmdargs, paths=no_config)) + for conf_file, paths in paths_by_config.items(): + run_process(config, gen_yamllint_args(cmdargs, conf_file=conf_file, paths=paths)) return results