mirror of https://github.com/zulip/zulip.git
lint: Use --groups to specify specific groups to run.
This helps generalize the use of groups inside zulint. Introduce list_files to return `by_lang` files dict. Add feature to create custom groups. Make custom groups for backend and frontend files.
This commit is contained in:
parent
b5b3d9bd5f
commit
e9ff9e34b3
|
@ -6,7 +6,7 @@ echo "Test suite is running under $(python --version)."
|
||||||
set -e
|
set -e
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
./tools/lint --backend --skip=gitlint,mypy # gitlint disabled because flaky
|
./tools/lint --groups=backend --skip=gitlint,mypy # gitlint disabled because flaky
|
||||||
./tools/test-tools
|
./tools/test-tools
|
||||||
# We need to pass a parallel level to test-backend because CircleCI's
|
# We need to pass a parallel level to test-backend because CircleCI's
|
||||||
# docker setup means the auto-detection logic sees the ~36 processes
|
# docker setup means the auto-detection logic sees the ~36 processes
|
||||||
|
|
|
@ -5,7 +5,7 @@ source tools/ci/activate-venv
|
||||||
set -e
|
set -e
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
./tools/lint --frontend --skip=gitlint # gitlint disabled because flaky
|
./tools/lint --groups=frontend --skip=gitlint # gitlint disabled because flaky
|
||||||
|
|
||||||
# Run the node tests first, since they're fast and deterministic
|
# Run the node tests first, since they're fast and deterministic
|
||||||
./tools/test-js-with-node --coverage
|
./tools/test-js-with-node --coverage
|
||||||
|
|
30
tools/lint
30
tools/lint
|
@ -10,9 +10,7 @@ from lib import sanity_check
|
||||||
sanity_check.check_venv(__file__)
|
sanity_check.check_venv(__file__)
|
||||||
|
|
||||||
from linter_lib.custom_check import python_rules, non_py_rules
|
from linter_lib.custom_check import python_rules, non_py_rules
|
||||||
from zulint import lister
|
|
||||||
from zulint.command import add_default_linter_arguments, LinterConfig
|
from zulint.command import add_default_linter_arguments, LinterConfig
|
||||||
from typing import cast, Dict, List
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
|
@ -24,13 +22,6 @@ def run():
|
||||||
parser.add_argument('--full',
|
parser.add_argument('--full',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Check some things we typically ignore')
|
help='Check some things we typically ignore')
|
||||||
limited_tests_group = parser.add_mutually_exclusive_group()
|
|
||||||
limited_tests_group.add_argument('--frontend',
|
|
||||||
action='store_true',
|
|
||||||
help='Only check files relevant to frontend')
|
|
||||||
limited_tests_group.add_argument('--backend',
|
|
||||||
action='store_true',
|
|
||||||
help='Only check files relevant to backend')
|
|
||||||
add_default_linter_arguments(parser)
|
add_default_linter_arguments(parser)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -50,23 +41,16 @@ def run():
|
||||||
|
|
||||||
assert_provisioning_status_ok(args.force)
|
assert_provisioning_status_ok(args.force)
|
||||||
|
|
||||||
backend_file_types = ['py', 'sh', 'pp', 'json', 'md', 'txt', 'text', 'yaml', 'rst']
|
|
||||||
frontend_file_types = ['js', 'ts', 'css', 'scss', 'handlebars', 'html']
|
|
||||||
file_types = backend_file_types + frontend_file_types
|
|
||||||
if args.backend:
|
|
||||||
file_types = backend_file_types
|
|
||||||
if args.frontend:
|
|
||||||
file_types = frontend_file_types
|
|
||||||
|
|
||||||
by_lang = cast(Dict[str, List[str]],
|
|
||||||
lister.list_files(args.targets, modified_only=args.modified,
|
|
||||||
ftypes=file_types,
|
|
||||||
use_shebang=True, group_by_ftype=True, exclude=EXCLUDED_FILES))
|
|
||||||
|
|
||||||
# Invoke the appropriate lint checker for each language,
|
# Invoke the appropriate lint checker for each language,
|
||||||
# and also check files for extra whitespace.
|
# and also check files for extra whitespace.
|
||||||
|
|
||||||
linter_config = LinterConfig(args, by_lang)
|
linter_config = LinterConfig(args)
|
||||||
|
|
||||||
|
by_lang = linter_config.list_files(groups={
|
||||||
|
'backend': ['py', 'sh', 'pp', 'json', 'md', 'txt', 'text', 'yaml', 'rst'],
|
||||||
|
'frontend': ['js', 'ts', 'css', 'scss', 'handlebars', 'html'],
|
||||||
|
}, exclude=EXCLUDED_FILES)
|
||||||
|
|
||||||
linter_config.external_linter('add_class', ['tools/find-add-class'], ['js'])
|
linter_config.external_linter('add_class', ['tools/find-add-class'], ['js'])
|
||||||
linter_config.external_linter('css', ['node', 'node_modules/.bin/stylelint'], ['css', 'scss'])
|
linter_config.external_linter('css', ['node', 'node_modules/.bin/stylelint'], ['css', 'scss'])
|
||||||
linter_config.external_linter('eslint', ['node', 'node_modules/.bin/eslint',
|
linter_config.external_linter('eslint', ['node', 'node_modules/.bin/eslint',
|
||||||
|
|
|
@ -39,7 +39,7 @@ run ./tools/check-provision $FORCEARG
|
||||||
run ./tools/clean-repo
|
run ./tools/clean-repo
|
||||||
|
|
||||||
# ci/backend
|
# ci/backend
|
||||||
run ./tools/lint --backend $FORCEARG
|
run ./tools/lint --groups=backend $FORCEARG
|
||||||
run ./tools/test-tools
|
run ./tools/test-tools
|
||||||
run ./tools/test-backend --include-webhooks $FORCEARG
|
run ./tools/test-backend --include-webhooks $FORCEARG
|
||||||
run ./tools/test-migrations
|
run ./tools/test-migrations
|
||||||
|
@ -57,7 +57,7 @@ run ./tools/test-api
|
||||||
# run ./tools/test-queue-worker-reload
|
# run ./tools/test-queue-worker-reload
|
||||||
|
|
||||||
# ci/frontend
|
# ci/frontend
|
||||||
run ./tools/lint --frontend $FORCEARG
|
run ./tools/lint --groups=frontend $FORCEARG
|
||||||
run ./tools/test-js-with-node
|
run ./tools/test-js-with-node
|
||||||
run ./manage.py makemessages --locale en
|
run ./manage.py makemessages --locale en
|
||||||
run env PYTHONWARNINGS=ignore ./tools/check-capitalization --no-generate
|
run env PYTHONWARNINGS=ignore ./tools/check-capitalization --no-generate
|
||||||
|
|
|
@ -60,8 +60,8 @@ script with at least the following options:
|
||||||
|
|
||||||
```
|
```
|
||||||
(zulip-py3-venv) tabbott@coset:~/zulip$ ./tools/lint --help
|
(zulip-py3-venv) tabbott@coset:~/zulip$ ./tools/lint --help
|
||||||
usage: lint [-h] [--force] [--full] [--frontend | --backend] [--modified]
|
usage: lint [-h] [--force] [--full] [--modified] [--verbose-timing]
|
||||||
[--verbose-timing] [--skip SKIP] [--only ONLY] [--list]
|
[--skip SKIP] [--only ONLY] [--list] [--groups GROUPS]
|
||||||
[targets [targets ...]]
|
[targets [targets ...]]
|
||||||
|
|
||||||
positional arguments:
|
positional arguments:
|
||||||
|
@ -76,6 +76,9 @@ optional arguments:
|
||||||
--skip SKIP Specify linters to skip, eg: --skip=mypy,gitlint
|
--skip SKIP Specify linters to skip, eg: --skip=mypy,gitlint
|
||||||
--only ONLY Specify linters to run, eg: --only=mypy,gitlint
|
--only ONLY Specify linters to run, eg: --only=mypy,gitlint
|
||||||
--list, -l List all the registered linters
|
--list, -l List all the registered linters
|
||||||
|
--groups GROUPS, -g GROUPS
|
||||||
|
Only run linter for languages in the group(s), e.g.:
|
||||||
|
--groups=backend,other_group
|
||||||
```
|
```
|
||||||
|
|
||||||
### pre-commit hook mode
|
### pre-commit hook mode
|
||||||
|
|
|
@ -11,9 +11,10 @@ import sys
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
# See https://zulip.readthedocs.io/en/latest/testing/mypy.html#mypy-in-production-scripts
|
# See https://zulip.readthedocs.io/en/latest/testing/mypy.html#mypy-in-production-scripts
|
||||||
from typing import Any, Callable, Dict, List
|
from typing import Callable, Dict, List
|
||||||
|
|
||||||
from zulint.printer import print_err, colors
|
from zulint.printer import print_err, colors
|
||||||
|
from zulint import lister
|
||||||
|
|
||||||
def add_default_linter_arguments(parser):
|
def add_default_linter_arguments(parser):
|
||||||
# type: (argparse.ArgumentParser) -> None
|
# type: (argparse.ArgumentParser) -> None
|
||||||
|
@ -37,6 +38,11 @@ def add_default_linter_arguments(parser):
|
||||||
parser.add_argument('--list', '-l',
|
parser.add_argument('--list', '-l',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='List all the registered linters')
|
help='List all the registered linters')
|
||||||
|
parser.add_argument('--groups', '-g',
|
||||||
|
default=[],
|
||||||
|
type=split_arg_into_list,
|
||||||
|
help='Only run linter for languages in the group(s), e.g.: '
|
||||||
|
'--groups=backend,frontend')
|
||||||
|
|
||||||
def split_arg_into_list(arg):
|
def split_arg_into_list(arg):
|
||||||
# type: (str) -> List[str]
|
# type: (str) -> List[str]
|
||||||
|
@ -66,10 +72,24 @@ def run_parallel(lint_functions):
|
||||||
class LinterConfig:
|
class LinterConfig:
|
||||||
lint_functions = {} # type: Dict[str, Callable[[], int]]
|
lint_functions = {} # type: Dict[str, Callable[[], int]]
|
||||||
|
|
||||||
def __init__(self, args, by_lang):
|
def __init__(self, args):
|
||||||
# type: (argparse.Namespace, Any) -> None
|
# type: (argparse.Namespace) -> None
|
||||||
self.args = args
|
self.args = args
|
||||||
self.by_lang = by_lang # type: Dict[str, List[str]]
|
self.by_lang = {} # type: Dict[str, List[str]]
|
||||||
|
|
||||||
|
def list_files(self, file_types=[], groups={}, use_shebang=True, group_by_ftype=True, exclude=[]):
|
||||||
|
# type: (List[str], Dict[str, List[str]], bool, bool, List[str]) -> Dict[str, List[str]]
|
||||||
|
assert file_types or groups, "Atleast one of `file_types` or `groups` must be specified."
|
||||||
|
|
||||||
|
if self.args.groups:
|
||||||
|
file_types = [ft for group in self.args.groups for ft in groups[group]]
|
||||||
|
else:
|
||||||
|
file_types.extend({ft for group in groups.values() for ft in group})
|
||||||
|
|
||||||
|
self.by_lang = lister.list_files(self.args.targets, modified_only=self.args.modified,
|
||||||
|
ftypes=file_types, use_shebang=use_shebang,
|
||||||
|
group_by_ftype=group_by_ftype, exclude=exclude)
|
||||||
|
return self.by_lang
|
||||||
|
|
||||||
def lint(self, func):
|
def lint(self, func):
|
||||||
# type: (Callable[[], int]) -> Callable[[], int]
|
# type: (Callable[[], int]) -> Callable[[], int]
|
||||||
|
|
Loading…
Reference in New Issue