Files
upstream-zulip/tools/check-templates
upstream-mirror 64898b2c79
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

133 lines
4.3 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import logging
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
# check for the venv
from tools.lib import sanity_check
sanity_check.check_venv(__file__)
from collections.abc import Iterable
from zulint import lister
from tools.lib.html_branches import build_id_dict
from tools.lib.pretty_print import validate_indent_html
from tools.lib.template_parser import validate
EXCLUDED_FILES = [
## Test data Files for testing modules in tests
"tools/tests/test_template_data",
# Our parser doesn't handle the way its conditionals are layered
"templates/zerver/emails/missed_message.html",
# Previously unchecked and our parser doesn't like its indentation
"web/icons/template.hbs",
# Template checker recommends very hard to read indentation.
"web/templates/bookend.hbs",
]
def check_our_files(modified_only: bool, all_dups: bool, fix: bool, targets: list[str]) -> None:
by_lang = lister.list_files(
targets=targets,
modified_only=modified_only,
ftypes=["hbs", "html"],
group_by_ftype=True,
exclude=EXCLUDED_FILES,
)
check_handlebars_templates(by_lang["hbs"], fix)
check_html_templates(by_lang["html"], all_dups, fix)
def check_html_templates(templates: Iterable[str], all_dups: bool, fix: bool) -> None:
# Our files with .html extensions are usually for Django, but we also
# have a few static .html files.
logging.basicConfig(format="%(levelname)s:%(message)s")
templates = sorted(fn for fn in templates)
# Use of lodash templates <%= %>.
if "templates/corporate/team.html" in templates:
templates.remove("templates/corporate/team.html")
def check_for_duplicate_ids(templates: list[str]) -> dict[str, list[str]]:
template_id_dict = build_id_dict(templates)
# TODO: Clean up these cases of duplicate ids in the code
IGNORE_IDS = [
"errors",
"email",
"registration",
"pw_strength",
"id_password",
"top_navbar",
"id_email",
"id_terms",
"logout_form",
"send_confirm",
"charged_amount",
"change-plan-status",
]
bad_ids_dict = {
ids: fns
for ids, fns in template_id_dict.items()
if (ids not in IGNORE_IDS) and len(fns) > 1
}
if all_dups:
ignorable_ids_dict = {
ids: fns
for ids, fns in template_id_dict.items()
if ids in IGNORE_IDS and len(fns) > 1
}
for ids, fns in ignorable_ids_dict.items():
logging.warning("Duplicate ID(s) detected: ID %r present at following files:", ids)
for fn in fns:
print(fn)
for ids, fns in bad_ids_dict.items():
logging.error("Duplicate ID(s) detected: ID %r present at following files:", ids)
for fn in fns:
print(fn)
return bad_ids_dict
bad_ids_list = list(check_for_duplicate_ids(templates).keys())
if bad_ids_list:
print("Exiting--please clean up all duplicates before running this again.")
sys.exit(1)
for fn in templates:
tokens = validate(fn, template_format="django")
if not validate_indent_html(fn, tokens, fix):
sys.exit(1)
def check_handlebars_templates(templates: Iterable[str], fix: bool) -> None:
# Check all our Handlebars templates.
templates = [fn for fn in templates if fn.endswith(".hbs")]
for fn in templates:
tokens = validate(fn, template_format="handlebars")
if not validate_indent_html(fn, tokens, fix):
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--modified", action="store_true", help="only check modified files")
parser.add_argument(
"--all-dups",
action="store_true",
help="Run lint tool to detect duplicate ids on ignored files as well",
)
parser.add_argument(
"--fix", action="store_true", help="Automatically fix indentation problems."
)
parser.add_argument("targets", nargs=argparse.REMAINDER)
args = parser.parse_args()
check_our_files(args.modified, args.all_dups, args.fix, args.targets)