Skip to content
Draft
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
22 changes: 19 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 @@ -254,6 +254,16 @@ def changelog_class(self) -> type[interface.IChangelog]:

@cached_property
def changelog_paths(self) -> typing.ChangelogPathsDict:
if self._entries_layout:
historical_paths = self.project.path.glob(CHANGELOG_PATH_GLOB)
current_version = _version.Version(
self.project.version.base_version)
return {
**{
self._version_from_path(path): path
for path
in historical_paths},
current_version: self.current_dir_path}
return {
self._version_from_path(path): path
for path
Expand All @@ -263,7 +273,11 @@ def changelog_paths(self) -> typing.ChangelogPathsDict:
def changelogs(self) -> typing.ChangelogsDict:
return {
k: self.changelog_class(
self.project, k, self.changelog_paths[k],)
self.project,
k,
(self.current_path
if self._entries_layout and self.project.is_current(k)
else self.changelog_paths[k]),)
for k
in reversed(sorted(self.changelog_paths.keys()))}

Expand Down Expand Up @@ -299,9 +313,11 @@ async def is_pending(self) -> bool:

@property
def paths(self) -> tuple[pathlib.Path, ...]:
paths = self.project.path.glob(CHANGELOG_PATH_GLOB)
return (
*self.project.path.glob(CHANGELOG_PATH_GLOB),
self.current_path)
(*paths, self.current_dir_path)
if self._entries_layout
else (*paths, self.current_path))

@property
def rel_current_path(self) -> pathlib.Path:
Expand Down
114 changes: 102 additions & 12 deletions py/envoy.base.utils/tests/test_abstract_project_changelogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,48 @@ def test_abstract_changelogs_dunder_iter(iters, patches):
== clogs)


def test_abstract_changelogs_changelog_paths(iters, patches):
changelogs = DummyChangelogs("PROJECT")
@pytest.mark.parametrize("entries_layout", [True, False])
def test_abstract_changelogs_changelog_paths(iters, patches, entries_layout):
project = MagicMock()
project.version.base_version = "1.2.3"
changelogs = DummyChangelogs(project)
patched = patches(
("AChangelogs._entries_layout",
dict(new_callable=PropertyMock)),
("AChangelogs.current_dir_path",
dict(new_callable=PropertyMock)),
("AChangelogs.paths",
dict(new_callable=PropertyMock)),
"AChangelogs._version_from_path",
prefix="envoy.base.utils.abstract.project.changelog")
paths = iters(cb=lambda x: f"P{x}")

with patched as (m_paths, m_version):
m_paths.return_value = paths
with patched as (m_entries, m_current_dir_path, m_paths, m_version):
m_entries.return_value = entries_layout
m_version.side_effect = lambda x: f"P{x}"
assert (
changelogs.changelog_paths
== {f"P{p}": p
for p in paths})
if entries_layout:
project.path.glob.return_value = paths
assert (
changelogs.changelog_paths
== {
**{
f"P{p}": p
for p
in paths},
abstract.project.changelog._version.Version(
project.version.base_version):
m_current_dir_path.return_value})
assert not m_paths.called
assert (
project.path.glob.call_args
== [(abstract.project.changelog.CHANGELOG_PATH_GLOB, ), {}])
else:
m_paths.return_value = paths
assert (
changelogs.changelog_paths
== {f"P{p}": p
for p in paths})
assert not project.path.glob.called

assert (
m_version.call_args_list
Expand All @@ -116,15 +142,18 @@ def test_abstract_changelogs_changelogs(iters, patches):
patched = patches(
"reversed",
"sorted",
("AChangelogs._entries_layout",
dict(new_callable=PropertyMock)),
("AChangelogs.changelog_class",
dict(new_callable=PropertyMock)),
("AChangelogs.changelog_paths",
dict(new_callable=PropertyMock)),
prefix="envoy.base.utils.abstract.project.changelog")
paths = iters(cb=lambda x: f"P{x}")

with patched as (m_rev, m_sort, m_class, m_paths):
with patched as (m_rev, m_sort, m_entries, m_class, m_paths):
m_rev.return_value = paths
m_entries.return_value = False
assert (
changelogs.changelogs
== {p: m_class.return_value.return_value
Expand All @@ -150,6 +179,58 @@ def test_abstract_changelogs_changelogs(iters, patches):
assert "changelogs" in changelogs.__dict__


def test_abstract_changelogs_changelogs_entries_layout_current_path(patches):
project = MagicMock()
changelogs = DummyChangelogs(project)
current_version = abstract.project.changelog._version.Version("1.2.3")
historical_version = abstract.project.changelog._version.Version("1.2.2")
patched = patches(
"reversed",
"sorted",
("AChangelogs._entries_layout",
dict(new_callable=PropertyMock)),
("AChangelogs.changelog_class",
dict(new_callable=PropertyMock)),
("AChangelogs.changelog_paths",
dict(new_callable=PropertyMock)),
("AChangelogs.current_path",
dict(new_callable=PropertyMock)),
prefix="envoy.base.utils.abstract.project.changelog")

with patched as (
m_reversed, m_sorted, m_entries, m_class, m_paths,
m_current_path):
m_entries.return_value = True
project.is_current.side_effect = (
lambda version: version == current_version)
m_paths.return_value = {
current_version: MagicMock(name="CURRENT_DIR_PATH"),
historical_version: MagicMock(name="HISTORICAL_PATH")}
m_reversed.return_value = [current_version, historical_version]
assert (
changelogs.changelogs
== {
current_version: m_class.return_value.return_value,
historical_version: m_class.return_value.return_value})

assert (
m_class.return_value.call_args_list
== [[(project, current_version, m_current_path.return_value), {}],
[(project,
historical_version,
m_paths.return_value[historical_version]), {}]])
assert (
project.is_current.call_args_list
== [[(current_version, ), {}],
[(historical_version, ), {}]])
assert (
m_sorted.call_args
== [(m_paths.return_value.keys(), ), {}])
assert (
m_reversed.call_args
== [(m_sorted.return_value, ), {}])


def test_abstract_changelogs_current(patches):
changelogs = DummyChangelogs("PROJECT")
patched = patches(
Expand Down Expand Up @@ -276,20 +357,29 @@ async def test_abstract_changelogs_is_pending(patches, pending):
assert "is_pending" not in changelogs.__dict__


def test_abstract_changelogs_paths(iters, patches):
@pytest.mark.parametrize("entries_layout", [True, False])
def test_abstract_changelogs_paths(iters, patches, entries_layout):
project = MagicMock()
changelogs = DummyChangelogs(project)
patched = patches(
("AChangelogs._entries_layout",
dict(new_callable=PropertyMock)),
("AChangelogs.current_dir_path",
dict(new_callable=PropertyMock)),
("AChangelogs.current_path",
dict(new_callable=PropertyMock)),
prefix="envoy.base.utils.abstract.project.changelog")
paths = iters()
project.path.glob.return_value = paths

with patched as (m_path, ):
with patched as (m_entries, m_dir_path, m_path):
m_entries.return_value = entries_layout
assert (
changelogs.paths
== (*paths, m_path.return_value))
== (*paths, (
m_dir_path.return_value
if entries_layout
else m_path.return_value)))
assert (
project.path.glob.call_args
== [(abstract.project.changelog.CHANGELOG_PATH_GLOB, ), {}])
Expand Down
4 changes: 3 additions & 1 deletion py/envoy.code.check/envoy/code/check/abstract/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,9 @@ def check_version(self) -> tuple[str, ...]:
if self.duplicate_current:
errors.append(
"Duplicate current version file. "
"Only `current.yaml` should exist for the current version "
"A `changelogs/"
f"{self.project.version.base_version}.yaml` exists alongside "
"`changelogs/current/` for the in-flight changelog "
f"({self.project.version.base_version})")
elif self.version_higher_than_current:
errors.append(
Expand Down
5 changes: 4 additions & 1 deletion py/envoy.code.check/tests/test_abstract_changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,10 @@ def test_changelogstatus_check_version(
if duplicate_current:
expected.append(
"Duplicate current version file. "
"Only `current.yaml` should exist for the current version "
"A `changelogs/"
f"{m_project.return_value.version.base_version}.yaml` exists "
"alongside "
"`changelogs/current/` for the in-flight changelog "
f"({m_project.return_value.version.base_version})")
elif version_higher_than_current:
expected.append(
Expand Down