Skip to content

Commit b19f083

Browse files
Cimon Lucas (LCM)Cimon Lucas (LCM)
authored andcommitted
Adding --mustache-remover-env
1 parent 54848e5 commit b19f083

File tree

3 files changed

+65
-36
lines changed

3 files changed

+65
-36
lines changed

pre_commit_hooks/validate_html.py

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def main(argv=None):
2626
help='run on larger files: sets Java stack size to 32768k')
2727
parser.add_argument('--remove-mustaches', action='store_true', default=False)
2828
parser.add_argument('--mustache-remover', choices=('pybar', 'jinja2'), default='pybar')
29+
parser.add_argument('--mustache-remover-env', action='append', nargs=2, help='Predefined KEY VALUE pair to substitute in the template')
2930
parser.add_argument('--mustache-remover-copy-ext', default='~~')
3031
parser.add_argument('--mustache-remover-default-value', default='DUMMY')
3132
parser.add_argument('--templates-include-dir', help='Required for Jinja2 templates that use the `include` directive'
@@ -40,9 +41,10 @@ def main(argv=None):
4041

4142
logging.basicConfig(level=getattr(logging, args.log))
4243

44+
placeholder = Placeholder(args.mustache_remover_default_value, args.mustache_remover_env)
4345
validator = CustomHTMLValidator(mustache_remover_name=args.mustache_remover,
4446
mustache_remover_copy_ext=args.mustache_remover_copy_ext,
45-
mustache_remover_default_value=args.mustache_remover_default_value,
47+
mustache_remover_placeholder=placeholder,
4648
templates_include_dir=args.templates_include_dir,
4749
directory=None, match=None, ignore=args.ignore, ignore_re=args.ignore_re)
4850
return validator.validate(
@@ -53,12 +55,19 @@ def main(argv=None):
5355
)
5456

5557

58+
class Placeholder:
59+
def __init__(self, default_value, env=None):
60+
self.default_value = default_value
61+
self.env = {k: eval(v) for k, v in env or ()}
62+
63+
64+
5665
class CustomHTMLValidator(Validator):
5766

58-
def __init__(self, mustache_remover_name, mustache_remover_copy_ext, mustache_remover_default_value, templates_include_dir, *args, **kwargs):
67+
def __init__(self, mustache_remover_name, mustache_remover_copy_ext, mustache_remover_placeholder, templates_include_dir, *args, **kwargs):
5968
Validator.__init__(self, *args, **kwargs)
6069
self.mustache_remover_copy_ext = mustache_remover_copy_ext
61-
self.mustache_remover_default_value = mustache_remover_default_value
70+
self.mustache_remover_placeholder = mustache_remover_placeholder
6271
self.mustache_remover = Jinja2MustacheRemover(templates_include_dir) if mustache_remover_name == 'jinja2' else PybarMustacheRemover()
6372

6473
def validate(self, files=None, remove_mustaches=False, **kwargs):
@@ -68,19 +77,19 @@ def validate(self, files=None, remove_mustaches=False, **kwargs):
6877
with generate_mustachefree_tmpfiles(files,
6978
self.mustache_remover,
7079
copy_ext=self.mustache_remover_copy_ext,
71-
default_value=self.mustache_remover_default_value) as tmpfiles:
80+
placeholder=self.mustache_remover_placeholder) as tmpfiles:
7281
return Validator.validate(self, tmpfiles, **kwargs)
7382
else:
7483
return Validator.validate(self, files, **kwargs)
7584

7685
@contextlib.contextmanager
77-
def generate_mustachefree_tmpfiles(filepaths, mustache_remover, copy_ext, default_value):
86+
def generate_mustachefree_tmpfiles(filepaths, mustache_remover, copy_ext, placeholder):
7887
mustachefree_tmpfiles = []
7988

8089
for filepath in filepaths:
8190
tmpfile = filepath + copy_ext
8291
shutil.copyfile(filepath, tmpfile)
83-
code_without_mustaches = mustache_remover.clean_template(filepath, default_value)
92+
code_without_mustaches = mustache_remover.clean_template(filepath, placeholder)
8493
with open(tmpfile, 'w+') as new_tmpfile:
8594
new_tmpfile.write(code_without_mustaches)
8695
mustachefree_tmpfiles.append(tmpfile)
@@ -95,54 +104,65 @@ def generate_mustachefree_tmpfiles(filepaths, mustache_remover, copy_ext, defaul
95104
class PybarMustacheRemover:
96105
def __init__(self):
97106
self.tmplt_compiler = PybarCompiler()
98-
def clean_template(self, filepath, default_value):
107+
def clean_template(self, filepath, placeholder):
99108
with open(filepath, 'r') as src_file:
100109
template_content = text_type(src_file.read())
101110
try:
102111
compiled_template = self.tmplt_compiler.compile(template_content)
103-
return compiled_template(RecursiveDefaultPlaceholder(default_value))
112+
return compiled_template(PybarPlaceholderContext(placeholder))
104113
except PybarsError as error:
105114
raise_from(MustacheSubstitutionFail('For HTML template file {}: {}'.format(filepath, error)), error)
106115

107-
class RecursiveDefaultPlaceholder:
108-
def __init__(self, default):
109-
self.default = default
110-
def __str__(self):
111-
return str(self.default)
112-
def __getattribute__(self, name):
113-
if name == 'default' or name.startswith('__'):
114-
return object.__getattribute__(self, name)
115-
return self
116-
def __iter__(self):
117-
return iter([self, self])
118-
def __getitem__(self, _):
119-
return self
116+
class PybarPlaceholderContext:
117+
def __init__(self, placeholder):
118+
self.placeholder = placeholder
119+
def get(self, segment):
120+
if segment in self.placeholder.env:
121+
return self.placeholder.env[segment]
122+
return RecursiveDefaultPlaceholder(self.placeholder.default_value)
120123

121124

122125
class Jinja2MustacheRemover:
123126
def __init__(self, templates_include_dir):
124127
self.template_loader_extra_paths = [templates_include_dir] if templates_include_dir else []
125-
def clean_template(self, filepath, default_value):
126-
env = Jinja2PlaceholderEnvironment(default_value, loader=FileSystemLoader([os.path.dirname(filepath)] + self.template_loader_extra_paths))
128+
def clean_template(self, filepath, placeholder):
129+
env = Jinja2PlaceholderEnvironment(placeholder, loader=FileSystemLoader([os.path.dirname(filepath)] + self.template_loader_extra_paths))
127130
template = env.get_template(os.path.basename(filepath))
128-
context = Jinja2PlaceholderContext(default_value, env, DEFAULT_NAMESPACE.copy(), template.name, template.blocks)
131+
context = Jinja2PlaceholderContext(placeholder, env, DEFAULT_NAMESPACE.copy(), template.name, template.blocks)
129132
return concat(template.root_render_func(context))
130133

131134
class Jinja2PlaceholderEnvironment(Environment):
132-
def __init__(self, default, *args, **kwargs):
135+
def __init__(self, placeholder, *args, **kwargs):
133136
Environment.__init__(self, *args, **kwargs)
134-
self.default = default
137+
self.placeholder = placeholder
135138
def getattr(self, *_, **__):
136-
return RecursiveDefaultPlaceholder(self.default)
139+
return RecursiveDefaultPlaceholder(self.placeholder.default_value)
137140

138141
class Jinja2PlaceholderContext(Context):
139-
def __init__(self, default, *args, **kwargs):
142+
def __init__(self, placeholder, *args, **kwargs):
140143
Context.__init__(self, *args, **kwargs)
141-
self.default = default
144+
self.placeholder = placeholder
142145
def call(self, *_, **__):
143-
return RecursiveDefaultPlaceholder(self.default)
144-
def resolve_or_missing(self, *_, **__):
145-
return RecursiveDefaultPlaceholder(self.default)
146+
return RecursiveDefaultPlaceholder(self.placeholder.default_value)
147+
def resolve_or_missing(self, key, missing=None):
148+
if key in self.placeholder.env:
149+
return self.placeholder.env[key]
150+
return RecursiveDefaultPlaceholder(self.placeholder.default_value)
151+
152+
153+
class RecursiveDefaultPlaceholder:
154+
def __init__(self, default):
155+
self.default = default
156+
def __str__(self):
157+
return str(self.default)
158+
def __getattribute__(self, name):
159+
if name == 'default' or name.startswith('__'):
160+
return object.__getattribute__(self, name)
161+
return self
162+
def __iter__(self):
163+
return iter([self, self])
164+
def __getitem__(self, _):
165+
return self
146166

147167

148168
class MustacheSubstitutionFail(Exception):

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
name='pre-commit-hooks',
66
description='A pre-commit hook to validate your HTML files / templates against the W3C v.Nu checker',
77
url='https://github.com/Lucas-C/pre-commit-hooks-html',
8-
version='1.3.4',
8+
version='1.3.5',
99

1010
author='Lucas Cimon',
1111
author_email='lucas.cimon@gmail.com',

tests/validate_html_test.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import absolute_import
22
from __future__ import unicode_literals
33

4-
from pre_commit_hooks.validate_html import Jinja2MustacheRemover, main as validate_html
4+
from pre_commit_hooks.validate_html import Jinja2MustacheRemover, Placeholder, PybarMustacheRemover, main as validate_html
55

66

77
HTML_WITH_HANDLEBAR_TITLE = '''<!DOCTYPE html>
@@ -16,8 +16,8 @@
1616
</html>'''
1717

1818

19-
def test_jinja2mustacheremover():
20-
assert Jinja2MustacheRemover('tests').clean_template('tests/jinja-template.html', 'DUMMY') == '''base.html content
19+
def test_Jinja2MustacheRemover():
20+
assert Jinja2MustacheRemover('tests').clean_template('tests/jinja-template.html', Placeholder('DUMMY')) == '''base.html content
2121
Jinja test
2222
2323
DUMMY
@@ -31,6 +31,15 @@ def test_jinja2mustacheremover():
3131
partial.html content
3232
'''
3333

34+
def test_Jinja2MustacheRemover_providedEnv(tmpdir):
35+
html_file = tmpdir.join('test.html')
36+
html_file.write('{{x}}')
37+
assert Jinja2MustacheRemover('tests').clean_template(html_file.strpath, Placeholder('DUMMY', (('x', '"42"'),))) == '42'
38+
39+
def test_PybarMustacheRemover_providedEnv(tmpdir):
40+
hbs_file = tmpdir.join('test.hbs')
41+
hbs_file.write('{{x}}')
42+
assert PybarMustacheRemover().clean_template(hbs_file.strpath, Placeholder('DUMMY', (('x', '42'),))) == '42'
3443

3544
def test_validate_pybar_ok(tmpdir, caplog):
3645
hbs_file = tmpdir.join('test.hbs')

0 commit comments

Comments
 (0)