2016-05-25 15:53:13 +02:00
|
|
|
#!/usr/bin/env python
|
2016-03-10 18:22:27 +01:00
|
|
|
from __future__ import absolute_import
|
2016-07-08 22:25:20 +02:00
|
|
|
from __future__ import print_function
|
2016-08-02 00:14:01 +02:00
|
|
|
from lib.template_parser import validate
|
2016-07-08 22:40:24 +02:00
|
|
|
import optparse
|
2013-10-25 23:46:02 +02:00
|
|
|
import sys
|
2016-08-02 00:14:01 +02:00
|
|
|
|
2016-03-10 18:22:27 +01:00
|
|
|
from six.moves import filter
|
2016-07-08 22:25:20 +02:00
|
|
|
try:
|
|
|
|
import lister
|
2016-07-24 15:24:48 +02:00
|
|
|
from typing import cast, Callable, Dict, Iterable, List
|
2016-07-08 22:25:20 +02:00
|
|
|
except ImportError as e:
|
|
|
|
print("ImportError: {}".format(e))
|
|
|
|
print("You need to run the Zulip linters inside a Zulip dev environment.")
|
|
|
|
print("If you are using Vagrant, you can `vagrant ssh` to enter the Vagrant guest.")
|
|
|
|
sys.exit(1)
|
2013-10-25 23:46:02 +02:00
|
|
|
|
2014-02-27 16:41:47 +01:00
|
|
|
def check_our_files():
|
2016-07-24 15:24:48 +02:00
|
|
|
# type: () -> None
|
2016-07-08 22:40:24 +02:00
|
|
|
parser = optparse.OptionParser()
|
|
|
|
parser.add_option('--modified', '-m',
|
2016-07-24 15:43:28 +02:00
|
|
|
action='store_true', default=False,
|
2016-07-08 22:40:24 +02:00
|
|
|
help='Only check modified files')
|
|
|
|
(options, _) = parser.parse_args()
|
|
|
|
|
2016-07-24 15:24:48 +02:00
|
|
|
by_lang = cast(
|
|
|
|
Dict[str, List[str]],
|
|
|
|
lister.list_files(
|
|
|
|
modified_only=options.modified,
|
|
|
|
ftypes=['handlebars', 'html'],
|
|
|
|
group_by_ftype=True))
|
2013-10-25 20:47:03 +02:00
|
|
|
|
2016-07-08 22:40:24 +02:00
|
|
|
check_handlebar_templates(by_lang['handlebars'], options.modified)
|
2016-07-09 02:43:32 +02:00
|
|
|
check_html_templates(by_lang['html'], options.modified)
|
2013-11-18 22:57:55 +01:00
|
|
|
|
2016-07-09 02:43:32 +02:00
|
|
|
def check_html_templates(templates, modified_only):
|
2016-07-24 15:24:48 +02:00
|
|
|
# type: (Iterable[str], bool) -> None
|
2016-07-09 02:43:32 +02:00
|
|
|
# Our files with .html extensions are usually for Django, but we also
|
2016-07-12 21:28:08 +02:00
|
|
|
# have a few static .html files.
|
2016-07-09 02:43:32 +02:00
|
|
|
# The file base.html has a bit of funny HTML that we can't parse here yet.
|
2016-07-12 21:28:08 +02:00
|
|
|
#
|
|
|
|
# We also have .html files that we vendored from Casper.
|
|
|
|
# The casperjs files use HTML5 (whereas Zulip prefers XHTML), and
|
|
|
|
# there are also cases where Casper deliberately uses invalid HTML,
|
|
|
|
# so we exclude them from our linter.
|
|
|
|
templates = filter(
|
|
|
|
lambda fn: ('base.html' not in fn) and ('casperjs' not in fn),
|
|
|
|
templates)
|
2016-07-09 02:43:32 +02:00
|
|
|
templates = sorted(list(templates))
|
2013-10-25 20:47:03 +02:00
|
|
|
|
2016-07-08 22:40:24 +02:00
|
|
|
if not modified_only:
|
|
|
|
assert len(templates) >= 10 # sanity check that we are actually doing work
|
2014-02-27 16:41:47 +01:00
|
|
|
for fn in templates:
|
2016-07-12 22:32:36 +02:00
|
|
|
# Many of our Django templates have strange indentation. The
|
|
|
|
# indentation errors are often harmless, even stylistically
|
|
|
|
# harmless, but they tend to be in files that might be old
|
|
|
|
# and might eventually require more scrutiny for things like
|
|
|
|
# localization. See github #1236.
|
|
|
|
bad_files = [
|
|
|
|
'static/html/5xx.html',
|
|
|
|
'templates/500.html',
|
|
|
|
'templates/confirmation/confirm.html',
|
|
|
|
'templates/corporate/mit.html',
|
|
|
|
'templates/corporate/privacy.html',
|
|
|
|
'templates/corporate/terms-enterprise.html',
|
|
|
|
'templates/corporate/zephyr-mirror.html',
|
|
|
|
'templates/corporate/zephyr.html',
|
|
|
|
'templates/zerver/accounts_home.html',
|
|
|
|
'templates/zerver/accounts_send_confirm.html',
|
|
|
|
'templates/zerver/api.html',
|
|
|
|
'templates/zerver/api_endpoints.html',
|
|
|
|
'templates/zerver/apps.html',
|
|
|
|
'templates/zerver/create_realm.html',
|
|
|
|
'templates/zerver/emails/followup/day1.html',
|
|
|
|
'templates/zerver/emails/followup/day2.html',
|
|
|
|
'templates/zerver/features.html',
|
|
|
|
'templates/zerver/hello.html',
|
|
|
|
'templates/zerver/home.html',
|
|
|
|
'templates/zerver/integrations.html',
|
|
|
|
'templates/zerver/invite_user.html',
|
|
|
|
'templates/zerver/left-sidebar.html',
|
|
|
|
'templates/zerver/login.html',
|
|
|
|
'templates/zerver/markdown_help.html',
|
|
|
|
'templates/zerver/register.html',
|
|
|
|
'templates/zerver/right-sidebar.html',
|
|
|
|
'templates/zerver/search_operators.html',
|
|
|
|
]
|
|
|
|
validate(fn, check_indent=(fn not in bad_files))
|
2014-02-27 16:41:47 +01:00
|
|
|
|
2016-08-02 00:14:01 +02:00
|
|
|
def check_handlebar_templates(templates, modified_only):
|
|
|
|
# type: (Iterable[str], bool) -> None
|
|
|
|
# Check all our handlebars templates.
|
|
|
|
templates = [fn for fn in templates if fn.endswith('.handlebars')]
|
|
|
|
if not modified_only:
|
|
|
|
assert len(templates) >= 10 # sanity check that we are actually doing work
|
|
|
|
for fn in templates:
|
|
|
|
validate(fn, check_indent=True)
|
|
|
|
|
2014-02-27 16:41:47 +01:00
|
|
|
if __name__ == '__main__':
|
|
|
|
check_our_files()
|