mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-12-12 14:17:46 +00:00
Fix template name separator for Windows users
See: https://github.com/overhangio/tutor/issues/381
This commit is contained in:
parent
6848253b8e
commit
998dec7149
@ -4,6 +4,7 @@ Note: Breaking changes between versions are indicated by "💥".
|
||||
|
||||
## Unreleased
|
||||
|
||||
- [Bugfix] Fix template rendering for Windows users.
|
||||
- [Improvement] Switch to `bcrypt` for htpasswd password generation, for better portability on Windows.
|
||||
- [Improvement] In the openedx production docker image, add some jitter to the gunicorn worker restart process to prevent all workers from restarting at the same time.
|
||||
|
||||
|
@ -28,9 +28,9 @@ class EnvTests(unittest.TestCase):
|
||||
def test_is_binary_file(self):
|
||||
self.assertTrue(env.is_binary_file("/home/somefile.ico"))
|
||||
|
||||
def test_find_path(self):
|
||||
def test_find_os_path(self):
|
||||
renderer = env.Renderer({}, [env.TEMPLATES_ROOT])
|
||||
path = renderer.find_path("local/docker-compose.yml")
|
||||
path = renderer.find_os_path("local/docker-compose.yml")
|
||||
self.assertTrue(os.path.exists(path))
|
||||
|
||||
def test_pathjoin(self):
|
||||
|
@ -101,8 +101,10 @@ def printvalue(context, key):
|
||||
try:
|
||||
# Note that this will incorrectly print None values
|
||||
fmt.echo(config[key])
|
||||
except KeyError:
|
||||
raise exceptions.TutorError("Missing configuration value: {}".format(key))
|
||||
except KeyError as e:
|
||||
raise exceptions.TutorError(
|
||||
"Missing configuration value: {}".format(key)
|
||||
) from e
|
||||
|
||||
|
||||
config_command.add_command(save)
|
||||
|
49
tutor/env.py
49
tutor/env.py
@ -57,8 +57,11 @@ class Renderer:
|
||||
environment.globals["TUTOR_VERSION"] = __version__
|
||||
self.environment = environment
|
||||
|
||||
def iter_templates_in(self, *path):
|
||||
prefix = "/".join(path)
|
||||
def iter_templates_in(self, *prefix):
|
||||
"""
|
||||
The elements of `prefix` must contain only "/", and not os.sep.
|
||||
"""
|
||||
prefix = "/".join(prefix)
|
||||
for template in self.environment.loader.list_templates():
|
||||
if template.startswith(prefix) and self.is_part_of_env(template):
|
||||
yield template
|
||||
@ -88,7 +91,8 @@ class Renderer:
|
||||
is_excluded = is_excluded or ignore_folder in parts
|
||||
return not is_excluded
|
||||
|
||||
def find_path(self, path):
|
||||
def find_os_path(self, template_name):
|
||||
path = template_name.replace("/", os.sep)
|
||||
for templates_root in self.template_roots:
|
||||
full_path = os.path.join(templates_root, path)
|
||||
if os.path.exists(full_path):
|
||||
@ -119,35 +123,41 @@ class Renderer:
|
||||
template = self.environment.from_string(text)
|
||||
return self.__render(template)
|
||||
|
||||
def render_file(self, path):
|
||||
def render_template(self, template_name):
|
||||
"""
|
||||
Render a template file. Return the corresponding string. If it's a binary file
|
||||
(as indicated by its path), return bytes.
|
||||
|
||||
The template_name *always* uses "/" separators, and is not os-dependent. Do not pass the result of
|
||||
os.path.join(...) to this function.
|
||||
"""
|
||||
if is_binary_file(path):
|
||||
if is_binary_file(template_name):
|
||||
# Don't try to render binary files
|
||||
with open(self.find_path(path), "rb") as f:
|
||||
with open(self.find_os_path(template_name), "rb") as f:
|
||||
return f.read()
|
||||
|
||||
try:
|
||||
template = self.environment.get_template(path)
|
||||
template = self.environment.get_template(template_name)
|
||||
except Exception:
|
||||
fmt.echo_error("Error loading template " + path)
|
||||
fmt.echo_error("Error loading template " + template_name)
|
||||
raise
|
||||
|
||||
try:
|
||||
return self.__render(template)
|
||||
except (jinja2.exceptions.TemplateError, exceptions.TutorError):
|
||||
fmt.echo_error("Error rendering template " + path)
|
||||
fmt.echo_error("Error rendering template " + template_name)
|
||||
raise
|
||||
except Exception:
|
||||
fmt.echo_error("Unknown error rendering template " + path)
|
||||
fmt.echo_error("Unknown error rendering template " + template_name)
|
||||
raise
|
||||
|
||||
def render_all_to(self, root):
|
||||
for template in self.iter_templates_in():
|
||||
rendered = self.render_file(template)
|
||||
dst = os.path.join(root, template)
|
||||
def render_all_to(self, root, *prefix):
|
||||
"""
|
||||
`prefix` can be used to limit the templates to render.
|
||||
"""
|
||||
for template_name in self.iter_templates_in(*prefix):
|
||||
rendered = self.render_template(template_name)
|
||||
dst = os.path.join(root, template_name.replace("/", os.sep))
|
||||
write_to(rendered, dst)
|
||||
|
||||
def __render(self, template):
|
||||
@ -207,13 +217,10 @@ def save_plugin_templates(plugin, root, config):
|
||||
def save_all_from(prefix, root, config):
|
||||
"""
|
||||
Render the templates that start with `prefix` and store them with the same
|
||||
hierarchy at `root`.
|
||||
hierarchy at `root`. Here, `prefix` can be the result of os.path.join(...).
|
||||
"""
|
||||
renderer = Renderer.instance(config)
|
||||
for template in renderer.iter_templates_in(prefix):
|
||||
rendered = renderer.render_file(template)
|
||||
dst = os.path.join(root, template)
|
||||
write_to(rendered, dst)
|
||||
renderer.render_all_to(root, prefix.replace(os.sep, "/"))
|
||||
|
||||
|
||||
def write_to(content, path):
|
||||
@ -233,8 +240,8 @@ def render_file(config, *path):
|
||||
Return the rendered contents of a template.
|
||||
"""
|
||||
renderer = Renderer.instance(config)
|
||||
file_path = os.path.join(*path)
|
||||
return renderer.render_file(file_path)
|
||||
template_name = "/".join(path)
|
||||
return renderer.render_template(template_name)
|
||||
|
||||
|
||||
def render_dict(config):
|
||||
|
Loading…
Reference in New Issue
Block a user