zulip/tools/lint
Shubham Padia 259ef423ad icons: Let the system using the icons specify the fill color.
The fill color is ignored when we generate webfonts in our main app.
For our help center beta project using Astro, we would have needed to
come up with a way to change fill colors for all the icons. Since, there
was no reason for us to keep the fill colors in the SVGs, we decided to
remove it instead and add a lint rule to keep that in check.
See
https://chat.zulip.org/#narrow/channel/6-frontend/topic/fill.20in.20our.20current.20svg.20icons
for more details.
2025-05-22 16:00:21 -07:00

227 lines
6.8 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import os
import sys
tools_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = os.path.join(tools_dir, "..")
sys.path.insert(0, root_dir)
# check for the venv
from tools.lib import sanity_check
sanity_check.check_venv(__file__)
from zulint.command import LinterConfig, add_default_linter_arguments
from tools.linter_lib.custom_check import non_py_rules, python_rules
def run() -> None:
from tools.lib.test_script import (
add_provision_check_override_param,
assert_provisioning_status_ok,
)
from tools.linter_lib.exclude import EXCLUDED_FILES, PUPPET_CHECK_RULES_TO_EXCLUDE
parser = argparse.ArgumentParser()
add_provision_check_override_param(parser)
parser.add_argument("--full", action="store_true", help="Check some things we typically ignore")
parser.add_argument("--use-mypy-daemon", action="store_true", help="Run mypy daemon instead")
add_default_linter_arguments(parser)
args = parser.parse_args()
os.chdir(root_dir)
assert_provisioning_status_ok(args.skip_provision_check)
# Invoke the appropriate lint checker for each language,
# and also check files for extra whitespace.
linter_config = LinterConfig(args)
by_lang = linter_config.list_files(
groups={
"backend": [
"bash",
"json",
"md",
"pp",
"py",
"pyi",
"sh",
"text",
"txt",
"yaml",
"yml",
],
"frontend": [
"cjs",
"css",
"cts",
"flow",
"hbs",
"html",
"js",
"mjs",
"mts",
"svg",
"ts",
],
},
exclude=EXCLUDED_FILES,
)
linter_config.external_linter(
"css",
["node_modules/.bin/stylelint"],
["css"],
fix_arg="--fix",
description="Standard CSS style and formatting linter (config: stylelint.config.js)",
)
linter_config.external_linter(
"eslint",
["node_modules/.bin/eslint", "--max-warnings=0", "--cache"],
["cjs", "cts", "js", "mjs", "mts", "ts"],
fix_arg="--fix",
description="Standard JavaScript style and formatting linter (config: eslint.config.js).",
)
linter_config.external_linter(
"puppet",
["env", "RUBYOPT=-W0", "puppet", "parser", "validate"],
["pp"],
description="Runs the puppet parser validator, checking for syntax errors.",
)
linter_config.external_linter(
"puppet-lint",
["puppet-lint", "--fail-on-warnings", *PUPPET_CHECK_RULES_TO_EXCLUDE],
["pp"],
fix_arg="--fix",
description="Standard puppet linter (config: tools/linter_lib/exclude.py)",
)
linter_config.external_linter(
"templates",
["tools/check-templates"],
["hbs", "html"],
description="Custom linter checks whitespace formatting of HTML templates",
fix_arg="--fix",
)
linter_config.external_linter(
"openapi",
["node", "tools/check-openapi"],
["yaml"],
description="Validates our OpenAPI/Swagger API documentation (zerver/openapi/zulip.yaml) ",
fix_arg="--fix",
)
linter_config.external_linter(
"shellcheck",
["shellcheck", "-x", "-P", "SCRIPTDIR"],
["bash", "sh"],
description="Standard shell script linter",
)
linter_config.external_linter(
"shfmt",
["shfmt"],
["bash", "sh"],
check_arg="-d",
fix_arg="-w",
description="Formats shell scripts",
)
command = ["tools/run-mypy", "--quiet"]
if args.skip_provision_check:
command.append("--skip-provision-check")
if args.use_mypy_daemon:
command.append("--use-daemon")
linter_config.external_linter(
"mypy",
command,
["py", "pyi"],
pass_targets=False,
description="Static type checker for Python (config: pyproject.toml)",
suppress_line=(
(lambda line: line.startswith("Daemon") or line == "Restarting: configuration changed")
if args.use_mypy_daemon
else lambda _: False
),
)
linter_config.external_linter(
"ruff",
["ruff", "check", "--quiet"],
["py", "pyi"],
fix_arg="--fix",
description="Python linter",
)
linter_config.external_linter(
"tsc",
["tools/run-tsc"],
["ts"],
pass_targets=False,
description="TypeScript compiler (config: tsconfig.json)",
)
linter_config.external_linter(
"gitlint",
["tools/commit-message-lint"],
description="Checks commit messages for common formatting errors (config: .gitlint)",
)
linter_config.external_linter(
"prettier",
["node_modules/.bin/prettier", "--cache", "--check", "--log-level=warn"],
["cjs", "css", "cts", "flow", "js", "json", "md", "mjs", "mts", "ts", "yaml", "yml"],
fix_arg=["--write"],
description="Formats CSS, JavaScript, YAML",
)
linter_config.external_linter(
"ruff-format",
["ruff", "format", "--quiet"],
["py", "pyi"],
description="Reformats Python code",
check_arg=["--check"],
)
semgrep_command = [
"semgrep",
"scan",
"--scan-unknown-extensions",
"--error",
"--disable-version-check",
"--quiet",
]
linter_config.external_linter(
"semgrep-py",
[*semgrep_command, "--config=./tools/semgrep-py.yml"],
["py"],
fix_arg="--autofix",
description="Syntactic grep (semgrep) code search tool (config: ./tools/semgrep-py.yml)",
)
linter_config.external_linter(
"mailmap",
["sh", "-c", "grep '^[^#]' .mailmap | LC_ALL=C.UTF-8 sort -cf"],
description="Check that .mailmap is sorted",
)
linter_config.external_linter(
"thirdparty",
["tools/check-thirdparty"],
description="Check docs/THIRDPARTY copyright file syntax",
)
@linter_config.lint
def custom_py() -> int:
"""Runs custom checks for python files (config: tools/linter_lib/custom_check.py)"""
failed = python_rules.check(by_lang, verbose=args.verbose)
return 1 if failed else 0
@linter_config.lint
def custom_nonpy() -> int:
"""Runs custom checks for non-python files (config: tools/linter_lib/custom_check.py)"""
failed = False
for rule in non_py_rules:
failed = failed or rule.check(by_lang, verbose=args.verbose)
return 1 if failed else 0
linter_config.do_lint()
if __name__ == "__main__":
run()