Skip to content

Commit

Permalink
[Resolve #1135] Fix path to templates (#1141)
Browse files Browse the repository at this point in the history
Currently the root file path for the template file handler points to a different
location than the existing template_path. This makes the migration process
confusing and arduous for users. Therefore when a user specifies a relative
path to the file we make both parameters point to the same location, the
`sceptre_project_dir/templates` directory.
  • Loading branch information
zaro0508 committed Oct 25, 2021
1 parent fbb5129 commit 5c0ab39
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 23 deletions.
14 changes: 6 additions & 8 deletions docs/_source/docs/template_handlers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ Template handlers can be used to resolve a ``template`` config block to a CloudF
fetch templates from S3, for example. Users can create their own template handlers to easily add support for other
template loading mechanisms. See `Custom Template Handlers`_ for more information.

When a ``template_path`` property is specified in the Stack config, it is wired into a ``file`` template handler by
default. This saves you from having to specify a full ``template`` block if you just want to load a file from disk.

.. warning::

The ``template_path`` key is deprecated in favor of the ``template`` key.
Expand All @@ -18,10 +15,11 @@ Available Template Handlers
file
~~~~~~~~~~~~~~~~~~~~

Loads a template from disk. Supports JSON, YAML, Jinja2 and Python files. Will be used if the ``template_path`` Stack
config property is set, for backwards compatibility reasons.
Loads a template from the local file system. This handler supports templates with .json, .yaml, .template, .j2
and .py extensions. This is the default template handler type, specifying the ``file`` type is optional.

This is the default template handler type, setting the ``file`` type is optional.
For backwards compatability, when a ``template_path`` key is specified in the Stack config, it is wired to
use the ``file`` template handler.

Syntax:

Expand All @@ -40,8 +38,8 @@ Example:
.. note::

The path for the ``template_path`` property is relative to the sceptre_dir/templates directory while the path for
this template ``path`` property is relative to the current working directory.
The ``path`` property can contain an absolute or relative path to the template file.
This handler assumes a relative path to be from sceptre_project_dir/templates


s3
Expand Down
1 change: 0 additions & 1 deletion sceptre/config/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,6 @@ def _parsed_stack_group_config(self, stack_group_config):
for key in
set(stack_group_config) - set(CONFIG_MERGE_STRATEGIES)
}
parsed_config.pop("project_path")
parsed_config.pop("stack_group_path")
return parsed_config

Expand Down
30 changes: 17 additions & 13 deletions sceptre/template_handlers/file.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import os
import sceptre.template_handlers.helper as helper

from pathlib import Path
from sceptre.exceptions import UnsupportedTemplateFileTypeError
from sceptre.template_handlers import TemplateHandler

Expand All @@ -12,7 +12,6 @@ class File(TemplateHandler):
"""

def __init__(self, *args, **kwargs):
self.logger = logging.getLogger(__name__)
super(File, self).__init__(*args, **kwargs)

def schema(self):
Expand All @@ -25,28 +24,33 @@ def schema(self):
}

def handle(self):
file_extension = os.path.splitext(self.arguments["path"])[1]
path = self.arguments["path"]
project_path = self.stack_group_config.get("project_path")
input_path = Path(self.arguments["path"])
if input_path.is_absolute():
path = str(input_path)
else:
path = str(Path(project_path) / 'templates' / input_path)

if input_path.suffix not in self.supported_template_extensions:
raise UnsupportedTemplateFileTypeError(
"Template has file extension %s. Only %s are supported.",
input_path.suffix, ",".join(self.supported_template_extensions)
)

try:
if file_extension in {".json", ".yaml", ".template"}:
if input_path.suffix in self.standard_template_extensions:
with open(path) as template_file:
return template_file.read()
elif file_extension == ".j2":
elif input_path.suffix in self.jinja_template_extensions:
return helper.render_jinja_template(
os.path.dirname(path),
os.path.basename(path),
{"sceptre_user_data": self.sceptre_user_data},
self.stack_group_config.get("j2_environment", {})
)
elif file_extension == ".py":
elif input_path.suffix in self.python_template_extensions:
return helper.call_sceptre_handler(path,
self.sceptre_user_data)
else:
raise UnsupportedTemplateFileTypeError(
"Template has file extension %s. Only .py, .yaml, "
".template, .json and .j2 are supported.",
os.path.splitext(path)[1]
)
except Exception as e:
helper.print_template_traceback(path)
raise e
1 change: 1 addition & 0 deletions tests/test_config_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ def test_construct_stacks_constructs_stack(
template_bucket_name='stack_group_template_bucket_name',
template_key_prefix=None,
stack_group_config={
"project_path": self.context.project_path,
"custom_key": "custom_value"
}
)
Expand Down
4 changes: 3 additions & 1 deletion tests/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def setup_method(self, test_method):
name="template_name",
handler_config={"type": "file", "path": "/folder/template.py"},
sceptre_user_data={},
stack_group_config={},
stack_group_config={
"project_path": "projects"
},
connection_manager=connection_manager,
)

Expand Down

0 comments on commit 5c0ab39

Please sign in to comment.