mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
from __future__ import absolute_import
 | 
						|
from __future__ import print_function
 | 
						|
from lib.template_parser import validate
 | 
						|
from lib.html_branches import build_id_dict
 | 
						|
from lib.pretty_print import validate_indent_html
 | 
						|
import argparse
 | 
						|
import sys
 | 
						|
import logging
 | 
						|
 | 
						|
from six.moves import filter
 | 
						|
 | 
						|
# check for the venv
 | 
						|
from lib import sanity_check
 | 
						|
sanity_check.check_venv(__file__)
 | 
						|
 | 
						|
import lister
 | 
						|
from typing import cast, Callable, Dict, Iterable, List
 | 
						|
 | 
						|
EXCLUDED_FILES = [
 | 
						|
    ## Test data Files for testing modules in tests
 | 
						|
    "tools/tests/test_template_data",
 | 
						|
]
 | 
						|
 | 
						|
def check_our_files(modified_only, all_dups, targets):
 | 
						|
    # type: (bool, bool, List[str]) -> None
 | 
						|
    by_lang = cast(
 | 
						|
        Dict[str, List[str]],
 | 
						|
        lister.list_files(
 | 
						|
            targets=targets,
 | 
						|
            modified_only=args.modified,
 | 
						|
            ftypes=['handlebars', 'html'],
 | 
						|
            group_by_ftype=True, exclude=EXCLUDED_FILES))
 | 
						|
 | 
						|
    check_handlebar_templates(by_lang['handlebars'])
 | 
						|
    check_html_templates(by_lang['html'], args.all_dups)
 | 
						|
 | 
						|
def check_html_templates(templates, all_dups):
 | 
						|
    # type: (Iterable[str], bool) -> None
 | 
						|
    # Our files with .html extensions are usually for Django, but we also
 | 
						|
    # have a few static .html files.
 | 
						|
    #
 | 
						|
    # 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.
 | 
						|
    logging.basicConfig(format='%(levelname)s:%(message)s')
 | 
						|
    templates = filter(
 | 
						|
        lambda fn: ('casperjs' not in fn),
 | 
						|
        templates)
 | 
						|
    templates = sorted(list(templates))
 | 
						|
 | 
						|
    template_id_dict = build_id_dict(templates)
 | 
						|
    # TODO: Clean up these cases of duplicate ids in the code
 | 
						|
    IGNORE_IDS = [
 | 
						|
        'api-example-tabs',
 | 
						|
        'errors',
 | 
						|
        'email',
 | 
						|
        'messages',
 | 
						|
        'registration',
 | 
						|
        'pw_strength',
 | 
						|
        'id_password',
 | 
						|
        'top_navbar',
 | 
						|
        'id_email',
 | 
						|
        'id_terms',
 | 
						|
        'send_confirm',
 | 
						|
        'register',
 | 
						|
    ]
 | 
						|
    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 '" + ids +
 | 
						|
                            "' present at following files:")
 | 
						|
            for fn in fns:
 | 
						|
                print(fn)
 | 
						|
 | 
						|
    for ids, fns in bad_ids_dict.items():
 | 
						|
        logging.error("Duplicate ID(s) detected :Id '" + ids +
 | 
						|
                      "' present at following files:")
 | 
						|
        for fn in fns:
 | 
						|
            print(fn)
 | 
						|
 | 
						|
    if list(bad_ids_dict.keys()):
 | 
						|
        print('Exiting--please clean up all duplicates before running this again.')
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    for fn in templates:
 | 
						|
        # 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/corporate/zephyr-mirror.html',
 | 
						|
            'templates/zerver/api.html',
 | 
						|
            'templates/zerver/api_endpoints.html',
 | 
						|
            'templates/zerver/apps.html',
 | 
						|
            'templates/zerver/features.html',
 | 
						|
            'templates/zerver/hello.html',
 | 
						|
            'templates/zerver/home.html',
 | 
						|
            'templates/zerver/integrations/index.html',
 | 
						|
            'templates/zerver/login.html',
 | 
						|
            'templates/zerver/markdown_help.html',
 | 
						|
            'templates/zerver/register.html',
 | 
						|
            'templates/zerver/search_operators.html',
 | 
						|
            'zerver/webhooks/taiga/doc.html',
 | 
						|
            'zerver/webhooks/zendesk/doc.html',
 | 
						|
        ]
 | 
						|
        validate(fn=fn, check_indent=(fn not in bad_files))
 | 
						|
 | 
						|
    # Ignore these files since these have not been cleaned yet :/
 | 
						|
    IGNORE_FILES = [
 | 
						|
        'puppet/zulip_ops/files/sparkle/mac/sparkle-changelog.html',
 | 
						|
        'puppet/zulip_ops/files/sparkle/sso/mac/sparkle-changelog.html',
 | 
						|
        'puppet/zulip_ops/files/sparkle/sso/win/sparkle-changelog.html',
 | 
						|
        'puppet/zulip_ops/files/sparkle/win/sparkle-changelog.html',
 | 
						|
        'static/html/5xx.html',
 | 
						|
        'templates/analytics/activity.html',
 | 
						|
        'templates/analytics/stats.html',
 | 
						|
        'templates/corporate/zephyr-mirror.html',
 | 
						|
        'templates/zerver/api.html',
 | 
						|
        'templates/zerver/apps.html',
 | 
						|
        'templates/zerver/compose.html',
 | 
						|
        'templates/zerver/hello.html',
 | 
						|
        'templates/zerver/home.html',
 | 
						|
        'templates/zerver/index.html',
 | 
						|
        'templates/zerver/keyboard_shortcuts.html',
 | 
						|
        'templates/zerver/login.html',
 | 
						|
        'templates/zerver/markdown_help.html',
 | 
						|
        'templates/zerver/navbar.html',
 | 
						|
        'zerver/webhooks/stripe/doc.html',
 | 
						|
        'zerver/webhooks/wordpress/doc.html',
 | 
						|
    ]
 | 
						|
    # TODO: Clean these files
 | 
						|
    for fn in templates:
 | 
						|
        if fn not in IGNORE_FILES:
 | 
						|
            if not validate_indent_html(fn):
 | 
						|
                sys.exit(1)
 | 
						|
 | 
						|
def check_handlebar_templates(templates):
 | 
						|
    # type: (Iterable[str]) -> None
 | 
						|
    # Check all our handlebars templates.
 | 
						|
    templates = [fn for fn in templates if fn.endswith('.handlebars')]
 | 
						|
    for fn in templates:
 | 
						|
        validate(fn=fn, check_indent=True)
 | 
						|
 | 
						|
    for fn in templates:
 | 
						|
        if not validate_indent_html(fn):
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    parser = argparse.ArgumentParser()
 | 
						|
    parser.add_argument('-m', '--modified',
 | 
						|
                        action='store_true', default=False,
 | 
						|
                        help='only check modified files')
 | 
						|
    parser.add_argument('--all-dups',
 | 
						|
                        action="store_true", default=False,
 | 
						|
                        help='Run lint tool to detect duplicate ids on ignored files as well')
 | 
						|
    parser.add_argument('targets', nargs=argparse.REMAINDER)
 | 
						|
    args = parser.parse_args()
 | 
						|
    check_our_files(args.modified, args.all_dups, args.targets)
 |