Scan all branches for cache generation
To date, both the 'reno cache' tool and related distutils command only scanned the current branch. This resulted in an incomplete cache for projects that used multiple branches. Resolve this by including info from all enabled branches. Change-Id: Ibe92a9fa5f42b5a7160201cd64ee6a93f9a78229 Signed-off-by: Stephen Finucane <sfinucan@redhat.com> Story: #1565544 Task: #14465
This commit is contained in:
parent
8d94d16714
commit
4b2de69354
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The ``reno cache`` command and ``build_reno`` setuptools command now
|
||||
default to scanning to all enabled branches. This ensures the cache is
|
||||
complete for projects that use multiple branches, such as stable branches.
|
@ -10,6 +10,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import os
|
||||
import sys
|
||||
|
||||
@ -21,7 +22,14 @@ from reno import scanner
|
||||
|
||||
def build_cache_db(conf, versions_to_include):
|
||||
s = scanner.Scanner(conf)
|
||||
notes = s.get_notes_by_version()
|
||||
|
||||
branches = [conf.branch]
|
||||
if not conf.branch: # if no branch requested, scan all
|
||||
branches += s.get_series_branches()
|
||||
|
||||
notes = collections.OrderedDict()
|
||||
for branch in branches:
|
||||
notes.update(s.get_notes_by_version(branch))
|
||||
|
||||
# Default to including all versions returned by the scanner.
|
||||
if not versions_to_include:
|
||||
|
@ -810,7 +810,7 @@ class Scanner(object):
|
||||
"Return true if the file exists at the given commit."
|
||||
return bool(self.get_file_at_commit(filename, sha))
|
||||
|
||||
def _get_series_branches(self):
|
||||
def get_series_branches(self):
|
||||
"Get branches matching the branch_name_re config option."
|
||||
refs = self._repo.get_refs()
|
||||
LOG.debug('refs %s', list(refs.keys()))
|
||||
@ -846,7 +846,7 @@ class Scanner(object):
|
||||
if branch.startswith('origin/'):
|
||||
branch = branch[7:]
|
||||
LOG.debug('looking for the branch before %s', branch)
|
||||
branch_names = self._get_series_branches()
|
||||
branch_names = self.get_series_branches()
|
||||
if branch not in branch_names:
|
||||
LOG.debug('Could not find branch %r among %s',
|
||||
branch, branch_names)
|
||||
@ -910,7 +910,7 @@ class Scanner(object):
|
||||
return candidate
|
||||
return None
|
||||
|
||||
def get_notes_by_version(self):
|
||||
def get_notes_by_version(self, branch=None):
|
||||
"""Return an OrderedDict mapping versions to lists of notes files.
|
||||
|
||||
The versions are presented in reverse chronological order.
|
||||
@ -918,13 +918,13 @@ class Scanner(object):
|
||||
Notes files are associated with the earliest version for which
|
||||
they were available, regardless of whether they changed later.
|
||||
|
||||
:param reporoot: Path to the root of the git repository.
|
||||
:type reporoot: str
|
||||
:param branch: The branch to scan. If not provided, using the branch
|
||||
configured in ``self.conf``.
|
||||
"""
|
||||
|
||||
reporoot = self.reporoot
|
||||
notesdir = self.conf.notespath
|
||||
branch = self.conf.branch
|
||||
branch = branch or self.conf.branch
|
||||
earliest_version = self.conf.earliest_version
|
||||
collapse_pre_releases = self.conf.collapse_pre_releases
|
||||
stop_at_branch_base = self.conf.stop_at_branch_base
|
||||
@ -967,7 +967,7 @@ class Scanner(object):
|
||||
# On the current branch, stop at the point where the most
|
||||
# recent branch was created, if we can find one.
|
||||
LOG.debug('working on current branch without earliest_version')
|
||||
branches = self._get_series_branches()
|
||||
branches = self.get_series_branches()
|
||||
if branches:
|
||||
for earlier_branch in reversed(branches):
|
||||
LOG.debug('checking if current branch is later than %s',
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import collections
|
||||
import fixtures
|
||||
import textwrap
|
||||
|
||||
@ -24,10 +25,15 @@ from reno.tests import base
|
||||
|
||||
class TestCache(base.TestCase):
|
||||
|
||||
scanner_output = {
|
||||
'0.0.0': [('note1', 'shaA')],
|
||||
'1.0.0': [('note2', 'shaB'), ('note3', 'shaC')],
|
||||
}
|
||||
scanner_output = [
|
||||
collections.OrderedDict([ # master
|
||||
('0.0.0', [('note1', 'shaA')]),
|
||||
('1.0.0', [('note2', 'shaB'), ('note3', 'shaC')]),
|
||||
]),
|
||||
collections.OrderedDict([ # stable/1.0
|
||||
('1.0.1', [('note4', 'shaD')]),
|
||||
]),
|
||||
]
|
||||
|
||||
note_bodies = {
|
||||
'note1': textwrap.dedent("""
|
||||
@ -42,7 +48,11 @@ class TestCache(base.TestCase):
|
||||
'note3': textwrap.dedent("""
|
||||
features:
|
||||
- We added a feature!
|
||||
""")
|
||||
"""),
|
||||
'note4': textwrap.dedent("""
|
||||
fixes:
|
||||
- We fixed all the bugs!
|
||||
"""),
|
||||
}
|
||||
|
||||
def _get_note_body(self, filename, sha):
|
||||
@ -57,12 +67,18 @@ class TestCache(base.TestCase):
|
||||
self.c = config.Config('.')
|
||||
|
||||
@mock.patch('reno.scanner.Scanner.get_notes_by_version')
|
||||
def test_build_cache_db(self, gnbv):
|
||||
gnbv.return_value = self.scanner_output
|
||||
@mock.patch('reno.scanner.Scanner.get_series_branches')
|
||||
def test_build_cache_db(self, mock_get_branches, mock_get_notes):
|
||||
mock_get_notes.side_effect = self.scanner_output
|
||||
mock_get_branches.return_value = ['stable/1.0']
|
||||
expected = {
|
||||
'notes': [
|
||||
{'version': k, 'files': v}
|
||||
for k, v in self.scanner_output.items()
|
||||
{'version': '0.0.0',
|
||||
'files': [('note1', 'shaA')]},
|
||||
{'version': '1.0.0',
|
||||
'files': [('note2', 'shaB'), ('note3', 'shaC')]},
|
||||
{'version': '1.0.1',
|
||||
'files': [('note4', 'shaD')]},
|
||||
],
|
||||
'file-contents': {
|
||||
'note1': {
|
||||
@ -77,6 +93,9 @@ class TestCache(base.TestCase):
|
||||
'note3': {
|
||||
'features': ['We added a feature!'],
|
||||
},
|
||||
'note4': {
|
||||
'fixes': ['We fixed all the bugs!'],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -85,4 +104,7 @@ class TestCache(base.TestCase):
|
||||
versions_to_include=[],
|
||||
)
|
||||
|
||||
mock_get_branches.assert_called_once()
|
||||
mock_get_notes.assert_has_calls([
|
||||
mock.call(None), mock.call('stable/1.0')])
|
||||
self.assertEqual(expected, db)
|
||||
|
@ -2432,7 +2432,7 @@ class GetSeriesBranchesTest(Base):
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
self.assertEqual(
|
||||
[],
|
||||
self.scanner._get_series_branches(),
|
||||
self.scanner.get_series_branches(),
|
||||
)
|
||||
|
||||
def test_real_branches_sorted_names(self):
|
||||
@ -2445,7 +2445,7 @@ class GetSeriesBranchesTest(Base):
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
self.assertEqual(
|
||||
['stable/a', 'stable/b'],
|
||||
self.scanner._get_series_branches(),
|
||||
self.scanner.get_series_branches(),
|
||||
)
|
||||
|
||||
def test_eol_tag(self):
|
||||
@ -2455,7 +2455,7 @@ class GetSeriesBranchesTest(Base):
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
self.assertEqual(
|
||||
['stable/a'],
|
||||
self.scanner._get_series_branches(),
|
||||
self.scanner.get_series_branches(),
|
||||
)
|
||||
|
||||
def test_mix_tag_and_branch(self):
|
||||
@ -2468,5 +2468,5 @@ class GetSeriesBranchesTest(Base):
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
self.assertEqual(
|
||||
['stable/a', 'stable/b'],
|
||||
self.scanner._get_series_branches(),
|
||||
self.scanner.get_series_branches(),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user