Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions py/envoy.base.utils/envoy/base/utils/abstract/project/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,15 @@ def base_version(self) -> str:

@async_property(cache=True)
async def data(self) -> typing.ChangelogDict:
return self.project.changelogs.validate_sections(
await self.project.execute(self.get_data, self.path),
self.path)
changelogs = self.project.changelogs
if changelogs._entries_layout and self._is_current:
parsed = await self.project.execute(
self.get_data_from_entries,
self.path,
changelogs.current_dir_path)
else:
parsed = await self.project.execute(self.get_data, self.path)
return changelogs.validate_sections(parsed, self.path)

@property
@abstracts.interfacemethod
Expand All @@ -213,6 +219,10 @@ async def release_date(self) -> str:
def version(self) -> _version.Version:
return self._version

@property
def _is_current(self) -> bool:
return self.version == self.project.changelogs.current

async def entries(self, section: str) -> list[interface.IChangelogEntry]:
return sorted(
self.entry_class(section, entry)
Expand Down Expand Up @@ -264,6 +274,10 @@ def current(self) -> _version.Version:
def current_path(self) -> pathlib.Path:
return self.project.path.joinpath(self.rel_current_path)

@property
def current_dir_path(self) -> pathlib.Path:
return self.project.path.joinpath(self.rel_current_dir_path)

@cached_property
def current_tpl(self) -> jinja2.Template:
return jinja2.Template(CHANGELOG_CURRENT_TPL)
Expand Down Expand Up @@ -292,6 +306,10 @@ def paths(self) -> tuple[pathlib.Path, ...]:
def rel_current_path(self) -> pathlib.Path:
return pathlib.Path(CHANGELOG_CURRENT_PATH)

@property
def rel_current_dir_path(self) -> pathlib.Path:
return pathlib.Path(CHANGELOG_CURRENT_DIR_PATH)

@cached_property
def section_re(self) -> re.Pattern[str]:
return re.compile(r"\n[a-z_]*:")
Expand Down Expand Up @@ -474,6 +492,11 @@ def yaml_change_presenter(
def _yaml_changelogs_version(self) -> _version.Version:
return _version.Version(YAML_CHANGELOGS_VERSION)

@property
def _entries_layout(self) -> bool:
return (
self.project.path.joinpath(CHANGELOG_CURRENT_DIR_PATH).is_dir())

def _is_rst_changelog(self, version: _version.Version) -> bool:
return version < self._yaml_changelogs_version

Expand Down
94 changes: 89 additions & 5 deletions py/envoy.base.utils/tests/test_abstract_project_changelogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ def test_abstract_changelogs_current_path(patches):
assert "current_path" not in changelogs.__dict__


def test_abstract_changelogs_current_dir_path(patches):
project = MagicMock()
changelogs = DummyChangelogs(project)
patched = patches(
("AChangelogs.rel_current_dir_path",
dict(new_callable=PropertyMock)),
prefix="envoy.base.utils.abstract.project.changelog")

with patched as (m_rel, ):
assert (
changelogs.current_dir_path
== project.path.joinpath.return_value)
assert (
project.path.joinpath.call_args
== [(m_rel.return_value, ), {}])
assert "current_dir_path" not in changelogs.__dict__


def test_abstract_changelogs_current_tpl(patches):
changelogs = DummyChangelogs("PROJECT")
patched = patches(
Expand Down Expand Up @@ -295,6 +313,24 @@ def test_abstract_changelogs_rel_current_path(patches):
== [(m_path, ), {}])


def test_abstract_changelogs_rel_current_dir_path(patches):
changelogs = DummyChangelogs("PROJECT")
patched = patches(
"pathlib",
"CHANGELOG_CURRENT_DIR_PATH",
prefix="envoy.base.utils.abstract.project.changelog")

with patched as (m_plib, m_path):
assert (
changelogs.rel_current_dir_path
== m_plib.Path.return_value)

assert (
m_plib.Path.call_args
== [(m_path, ), {}])
assert "rel_current_dir_path" not in changelogs.__dict__


@pytest.mark.parametrize(
"raises",
[None, Exception, yaml.reader.ReaderError, exceptions.TypeCastingError])
Expand Down Expand Up @@ -1006,6 +1042,27 @@ def test_abstract_changelogs_changelogs_methods(patches, method):
== [(), {}])


@pytest.mark.parametrize("is_dir", [True, False])
def test_abstract_changelogs_entries_layout(patches, is_dir):
project = MagicMock()
changelogs = DummyChangelogs(project)
patched = patches(
"CHANGELOG_CURRENT_DIR_PATH",
prefix="envoy.base.utils.abstract.project.changelog")

with patched as (m_dir_path, ):
project.path.joinpath.return_value.is_dir.return_value = is_dir
assert changelogs._entries_layout == is_dir

assert (
project.path.joinpath.call_args
== [(m_dir_path, ), {}])
assert (
project.path.joinpath.return_value.is_dir.call_args
== [(), {}])
assert "_entries_layout" not in changelogs.__dict__


def test_abstract_changelogs__yaml_changelogs_version(patches):
changelogs = DummyChangelogs("PROJECT")
patched = patches(
Expand Down Expand Up @@ -1509,28 +1566,55 @@ def test_abstract_changelog_base_version(patches):
assert "base_version" not in changelog.__dict__


async def test_abstract_changelog_data(patches):
@pytest.mark.parametrize("match", [True, False])
def test_abstract_changelog__is_current(match):
project = MagicMock()
version = "VERSION"
changelog = DummyChangelog(project, version, "PATH")
project.changelogs.current = version if match else MagicMock()
assert changelog._is_current == match
assert "_is_current" not in changelog.__dict__


@pytest.mark.parametrize("entries_layout", [True, False])
@pytest.mark.parametrize("is_current", [True, False])
async def test_abstract_changelog_data(patches, entries_layout, is_current):
project = MagicMock()
project.execute = AsyncMock()
project.changelogs.validate_sections.return_value = "VALIDATED"
project.changelogs._entries_layout = entries_layout
changelog = DummyChangelog(project, "VERSION", "PATH")
patched = patches(
("AChangelog._is_current",
dict(new_callable=PropertyMock)),
"AChangelog.get_data",
"AChangelog.get_data_from_entries",
("AChangelog.path",
dict(new_callable=PropertyMock)),
prefix="envoy.base.utils.abstract.project.changelog")

with patched as (m_get, m_path):
with patched as (m_is_current, m_get, m_get_entries, m_path):
m_is_current.return_value = is_current
assert (
await changelog.data
== project.changelogs.validate_sections.return_value
== getattr(
changelog,
abstract.AChangelog.data.cache_name)["data"])

assert (
project.execute.call_args
== [(m_get, m_path.return_value), {}])
use_entries = is_current and entries_layout
if use_entries:
assert (
project.execute.call_args
== [(m_get_entries,
m_path.return_value,
project.changelogs.current_dir_path), {}])
assert not m_get.called
else:
assert (
project.execute.call_args
== [(m_get, m_path.return_value), {}])
assert not m_get_entries.called
assert (
project.changelogs.validate_sections.call_args
== [(project.execute.return_value, m_path.return_value), {}])
Expand Down