diff --git a/bin/gen_release_notes.py b/bin/gen_release_notes.py index 90dae365109..7f62228d59a 100755 --- a/bin/gen_release_notes.py +++ b/bin/gen_release_notes.py @@ -182,9 +182,7 @@ async def gather_commits(version: str) -> str: return out.decode().strip() -async def gather_bugs(version: str) -> typing.List[str]: - commits = await gather_commits(version) - +async def parse_issues(commits: str) -> typing.List[str]: issues: typing.List[str] = [] for commit in commits.split('\n'): sha, message = commit.split(maxsplit=1) @@ -193,6 +191,7 @@ async def gather_bugs(version: str) -> typing.List[str]: stdout=asyncio.subprocess.PIPE) _out, _ = await p.communicate() out = _out.decode().split('\n') + for line in reversed(out): if line.startswith('Closes:'): bug = line.lstrip('Closes:').strip() @@ -205,6 +204,13 @@ async def gather_bugs(version: str) -> typing.List[str]: else: issues.append(bug.lstrip('#')) + return issues + + +async def gather_bugs(version: str) -> typing.List[str]: + commits = await gather_commits(version) + issues = await parse_issues(commits) + loop = asyncio.get_event_loop() async with aiohttp.ClientSession(loop=loop) as session: results = await asyncio.gather(*[get_bug(session, i) for i in issues]) diff --git a/bin/gen_release_notes_test.py b/bin/gen_release_notes_test.py index 2f114ce144c..eca0c4b8af4 100644 --- a/bin/gen_release_notes_test.py +++ b/bin/gen_release_notes_test.py @@ -1,4 +1,4 @@ -# Copyright © 2019 Intel Corporation +# Copyright © 2019,2021 Intel Corporation # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -18,8 +18,19 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import sys +import textwrap +import typing + import pytest +# AsyncMock is new in 3.8, so if we're using an older version we need the +# backported version of mock +if sys.version_info >= (3, 8): + from unittest import mock +else: + import mock + from .gen_release_notes import * @@ -58,3 +69,40 @@ async def test_gather_commits(): version = '19.2.0' out = await gather_commits(version) assert out + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + 'content, bugs', + [ + # It is important to have the title on a new line, as + # textwrap.dedent wont work otherwise. + ( + '''\ + A commit + + It has a message in it + + Closes: #1 + ''', + ['1'], + ), + ( + '''\ + A commit with no body + + Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3456 + ''', + ['3456'], + ), + ]) +async def test_parse_issues(content: str, bugs: typing.List[str]) -> None: + mock_com = mock.AsyncMock(return_value=(textwrap.dedent(content).encode(), '')) + mock_p = mock.Mock() + mock_p.communicate = mock_com + mock_exec = mock.AsyncMock(return_value=mock_p) + + with mock.patch('bin.gen_release_notes.asyncio.create_subprocess_exec', mock_exec), \ + mock.patch('bin.gen_release_notes.gather_commits', mock.AsyncMock(return_value='sha\n')): + ids = await parse_issues('1234 not used') + assert ids == bugs