@@ -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+
5665class 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
95104class 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
122125class 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
131134class 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
138141class 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
148168class MustacheSubstitutionFail (Exception ):
0 commit comments