Skip to content

Commit

Permalink
[Resolve #1291] Fix attribute error caused by a relative project path (
Browse files Browse the repository at this point in the history
…#1296)

Resolve [#1291](#1291)

Given a relative project path with a leading `.` and duplicate dependencies in multiple stack configurations, there is a chance of an AttributeError being raised. This is caused by dependencies failing to resolve into a valid Stack object due to an invalid path.

This PR fixes the issue by ensuring a given project path is resolved to the absolute path when initialising the Context.

An additional test of context with a relative path is included to ensure correct resolution.
  • Loading branch information
pjsmith404 committed May 3, 2023
1 parent 855a030 commit ef9dc21
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
2 changes: 1 addition & 1 deletion sceptre/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __init__(
):
# project_path: absolute path to the base sceptre project folder
# e.g. absolute_path/to/sceptre_directory
self.project_path = normalise_path(project_path)
self.project_path = path.abspath(normalise_path(project_path))

# config_path: holds the project stack_groups
# e.g {project_path}/config
Expand Down
44 changes: 38 additions & 6 deletions tests/test_context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from os import path
from os import getcwd, path
from unittest.mock import sentinel
from sceptre.context import SceptreContext

Expand All @@ -9,7 +9,7 @@ def setup_method(self, test_method):
self.config_path = "config"
self.config_file = "config.yaml"

def test_context_with_path(self):
def test_context_with_path_in_cwd(self):
self.context = SceptreContext(
project_path="project_path/to/sceptre",
command_path="command-path",
Expand All @@ -21,9 +21,39 @@ def test_context_with_path(self):
ignore_dependencies=sentinel.ignore_dependencies,
)

sentinel.project_path = "project_path/to/sceptre"
sentinel.project_path = f"{getcwd()}/project_path/to/sceptre"
assert self.context.project_path.replace(path.sep, "/") == sentinel.project_path

def test_context_with_relative_path(self):
self.context = SceptreContext(
project_path="./project_path/to/sceptre",
command_path="command-path",
command_params=sentinel.command_params,
user_variables=sentinel.user_variables,
options=sentinel.options,
output_format=sentinel.output_format,
no_colour=sentinel.no_colour,
ignore_dependencies=sentinel.ignore_dependencies,
)

expected = f"{getcwd()}/project_path/to/sceptre"
assert self.context.project_path.replace(path.sep, "/") == expected

def test_context_with_absolute_path(self):
self.context = SceptreContext(
project_path=f"{getcwd()}/project_path/to/sceptre",
command_path="command-path",
command_params=sentinel.command_params,
user_variables=sentinel.user_variables,
options=sentinel.options,
output_format=sentinel.output_format,
no_colour=sentinel.no_colour,
ignore_dependencies=sentinel.ignore_dependencies,
)

expected = f"{getcwd()}/project_path/to/sceptre"
assert self.context.project_path.replace(path.sep, "/") == expected

def test_full_config_path_returns_correct_path(self):
context = SceptreContext(
project_path="project_path",
Expand All @@ -36,7 +66,7 @@ def test_full_config_path_returns_correct_path(self):
ignore_dependencies=sentinel.ignore_dependencies,
)

full_config_path = path.join("project_path", self.config_path)
full_config_path = path.join(f"{getcwd()}/project_path", self.config_path)
assert context.full_config_path() == full_config_path

def test_full_command_path_returns_correct_path(self):
Expand All @@ -50,7 +80,9 @@ def test_full_command_path_returns_correct_path(self):
no_colour=sentinel.no_colour,
ignore_dependencies=sentinel.ignore_dependencies,
)
full_command_path = path.join("project_path", self.config_path, "command")
full_command_path = path.join(
f"{getcwd()}/project_path", self.config_path, "command"
)

assert context.full_command_path() == full_command_path

Expand All @@ -65,7 +97,7 @@ def test_full_templates_path_returns_correct_path(self):
no_colour=sentinel.no_colour,
ignore_dependencies=sentinel.ignore_dependencies,
)
full_templates_path = path.join("project_path", self.templates_path)
full_templates_path = path.join(f"{getcwd()}/project_path", self.templates_path)
assert context.full_templates_path() == full_templates_path

def test_clone__returns_full_clone_of_context(self):
Expand Down

0 comments on commit ef9dc21

Please sign in to comment.