refactor existing implementation into a class
As part of the re-implementation work using dulwich I want to create a Scanner class, to replace some of the module-level functions in the scanner module now. This patch moves existing code around into something like what I would expect that API to look like, without changing the implementation details. The class API is still subject to change in the future, but this should make it a little easier to review those implementation changes. Change-Id: If92f6ff5bce955bbdcb748cee52ad71210ae313b Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
17a248dc84
commit
db4e3647e2
|
@ -20,7 +20,8 @@ from reno import scanner
|
|||
|
||||
|
||||
def build_cache_db(conf, versions_to_include):
|
||||
notes = scanner.get_notes_by_version(conf)
|
||||
s = scanner.Scanner(conf)
|
||||
notes = s.get_notes_by_version()
|
||||
|
||||
# Default to including all versions returned by the scanner.
|
||||
if not versions_to_include:
|
||||
|
@ -31,11 +32,7 @@ def build_cache_db(conf, versions_to_include):
|
|||
file_contents = {}
|
||||
for version in versions_to_include:
|
||||
for filename, sha in notes[version]:
|
||||
body = scanner.get_file_at_commit(
|
||||
conf.reporoot,
|
||||
filename,
|
||||
sha,
|
||||
)
|
||||
body = s.get_file_at_commit(filename, sha)
|
||||
# We want to save the contents of the file, which is YAML,
|
||||
# inside another YAML file. That looks terribly ugly with
|
||||
# all of the escapes needed to format it properly as
|
||||
|
|
|
@ -52,6 +52,7 @@ class Loader(object):
|
|||
self._earliest_version = conf.earliest_version
|
||||
|
||||
self._cache = None
|
||||
self._scanner = scanner.Scanner(self._config)
|
||||
self._scanner_output = None
|
||||
self._cache_filename = get_cache_filename(self._reporoot,
|
||||
self._notespath)
|
||||
|
@ -75,7 +76,7 @@ class Loader(object):
|
|||
for n in self._cache['notes']
|
||||
}
|
||||
else:
|
||||
self._scanner_output = scanner.get_notes_by_version(self._config)
|
||||
self._scanner_output = self._scanner.get_notes_by_version()
|
||||
|
||||
@property
|
||||
def versions(self):
|
||||
|
@ -96,7 +97,7 @@ class Loader(object):
|
|||
if self._cache:
|
||||
content = self._cache['file-contents'][filename]
|
||||
else:
|
||||
body = scanner.get_file_at_commit(self._reporoot, filename, sha)
|
||||
body = self._scanner.get_file_at_commit(filename, sha)
|
||||
content = yaml.safe_load(body)
|
||||
|
||||
for section_name, section_content in content.items():
|
||||
|
|
667
reno/scanner.py
667
reno/scanner.py
|
@ -25,48 +25,6 @@ from reno import utils
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_current_version(reporoot, branch=None):
|
||||
"""Return the current version of the repository.
|
||||
|
||||
If the repo appears to contain a python project, use setup.py to
|
||||
get the version so pbr (if used) can do its thing. Otherwise, use
|
||||
git describe.
|
||||
|
||||
"""
|
||||
cmd = ['git', 'describe', '--tags']
|
||||
if branch is not None:
|
||||
cmd.append(branch)
|
||||
try:
|
||||
result = utils.check_output(cmd, cwd=reporoot).strip()
|
||||
if '-' in result:
|
||||
# Descriptions that come after a commit look like
|
||||
# 2.0.0-1-abcde, and we want to remove the SHA value from
|
||||
# the end since we only care about the version number
|
||||
# itself, but we need to recognize that the change is
|
||||
# unreleased so keep the -1 part.
|
||||
result, dash, ignore = result.rpartition('-')
|
||||
except subprocess.CalledProcessError:
|
||||
# This probably means there are no tags.
|
||||
result = '0.0.0'
|
||||
return result
|
||||
|
||||
|
||||
def get_file_at_commit(reporoot, filename, sha):
|
||||
"Return the contents of the file if it exists at the commit, or None."
|
||||
try:
|
||||
return utils.check_output(
|
||||
['git', 'show', '%s:%s' % (sha, filename)],
|
||||
cwd=reporoot,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
|
||||
def _file_exists_at_commit(reporoot, filename, sha):
|
||||
"Return true if the file exists at the given commit."
|
||||
return bool(get_file_at_commit(reporoot, filename, sha))
|
||||
|
||||
|
||||
def _get_unique_id(filename):
|
||||
base = os.path.basename(filename)
|
||||
root, ext = os.path.splitext(base)
|
||||
|
@ -78,64 +36,6 @@ def _get_unique_id(filename):
|
|||
return uniqueid
|
||||
|
||||
|
||||
def _get_branch_base(reporoot, branch):
|
||||
"Return the tag at base of the branch."
|
||||
# Based on
|
||||
# http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git
|
||||
# git rev-list $(git rev-list --first-parent \
|
||||
# ^origin/stable/newton master | tail -n1)^^!
|
||||
#
|
||||
# Determine the list of commits accessible from the branch we are
|
||||
# supposed to be scanning, but not on master.
|
||||
cmd = [
|
||||
'git',
|
||||
'rev-list',
|
||||
'--first-parent',
|
||||
branch, # on the branch
|
||||
'^master', # not on master
|
||||
]
|
||||
try:
|
||||
LOG.debug(' '.join(cmd))
|
||||
parents = utils.check_output(cmd, cwd=reporoot).strip()
|
||||
if not parents:
|
||||
# There are no commits on the branch, yet, so we can use
|
||||
# our current-version logic.
|
||||
return _get_current_version(reporoot, branch)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
parent = parents.splitlines()[-1]
|
||||
LOG.debug('parent = %r', parent)
|
||||
# Now get the previous commit, which should be the one we tagged
|
||||
# to create the branch.
|
||||
cmd = [
|
||||
'git',
|
||||
'rev-list',
|
||||
'{}^^!'.format(parent),
|
||||
]
|
||||
try:
|
||||
sha = utils.check_output(cmd, cwd=reporoot).strip()
|
||||
LOG.debug('sha = %r', sha)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
# Now get the tag for that commit.
|
||||
cmd = [
|
||||
'git',
|
||||
'describe',
|
||||
'--abbrev=0',
|
||||
sha,
|
||||
]
|
||||
try:
|
||||
return utils.check_output(cmd, cwd=reporoot).strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
|
||||
|
||||
# The git log output from _get_tags_on_branch() looks like this sample
|
||||
# from the openstack/nova repository for git 1.9.1:
|
||||
#
|
||||
|
@ -207,244 +107,349 @@ def _get_version_tags_on_branch(reporoot, branch):
|
|||
return tags
|
||||
|
||||
|
||||
def get_notes_by_version(conf):
|
||||
"""Return an OrderedDict mapping versions to lists of notes files.
|
||||
class Scanner(object):
|
||||
|
||||
The versions are presented in reverse chronological order.
|
||||
def __init__(self, conf):
|
||||
self.conf = conf
|
||||
self.reporoot = self.conf.reporoot
|
||||
|
||||
Notes files are associated with the earliest version for which
|
||||
they were available, regardless of whether they changed later.
|
||||
def _get_current_version(self, branch=None):
|
||||
"""Return the current version of the repository.
|
||||
|
||||
:param reporoot: Path to the root of the git repository.
|
||||
:type reporoot: str
|
||||
"""
|
||||
If the repo appears to contain a python project, use setup.py to
|
||||
get the version so pbr (if used) can do its thing. Otherwise, use
|
||||
git describe.
|
||||
|
||||
reporoot = conf.reporoot
|
||||
notesdir = conf.notespath
|
||||
branch = conf.branch
|
||||
earliest_version = conf.earliest_version
|
||||
collapse_pre_releases = conf.collapse_pre_releases
|
||||
stop_at_branch_base = conf.stop_at_branch_base
|
||||
|
||||
LOG.debug('scanning %s/%s (branch=%s)' % (reporoot, notesdir, branch))
|
||||
|
||||
# If the user has not told us where to stop, try to work it out
|
||||
# for ourselves. If branch is set and is not "master", then we
|
||||
# want to stop at the base of the branch.
|
||||
if (stop_at_branch_base and
|
||||
(not earliest_version) and branch and (branch != 'master')):
|
||||
LOG.debug('determining earliest_version from branch')
|
||||
earliest_version = _get_branch_base(reporoot, branch)
|
||||
if earliest_version and collapse_pre_releases:
|
||||
if PRE_RELEASE_RE.search(earliest_version):
|
||||
# The earliest version won't actually be the pre-release
|
||||
# that might have been tagged when the branch was created,
|
||||
# but the final version. Strip the pre-release portion of
|
||||
# the version number.
|
||||
earliest_version = '.'.join(earliest_version.split('.')[:-1])
|
||||
LOG.debug('using earliest_version = %r', earliest_version)
|
||||
|
||||
# Determine all of the tags known on the branch, in their date
|
||||
# order. We scan the commit history in topological order to ensure
|
||||
# we have the commits in the right version, so we might encounter
|
||||
# the tags in a different order during that phase.
|
||||
versions_by_date = _get_version_tags_on_branch(reporoot, branch)
|
||||
LOG.debug('versions by date %r' % (versions_by_date,))
|
||||
versions = []
|
||||
earliest_seen = collections.OrderedDict()
|
||||
|
||||
# Determine the current version, which might be an unreleased or
|
||||
# dev version if there are unreleased commits at the head of the
|
||||
# branch in question. Since the version may not already be known,
|
||||
# make sure it is in the list of versions by date. And since it is
|
||||
# the most recent version, go ahead and insert it at the front of
|
||||
# the list.
|
||||
current_version = _get_current_version(reporoot, branch)
|
||||
LOG.debug('current repository version: %s' % current_version)
|
||||
if current_version not in versions_by_date:
|
||||
LOG.debug('adding %s to versions by date' % current_version)
|
||||
versions_by_date.insert(0, current_version)
|
||||
|
||||
# Remember the most current filename for each id, to allow for
|
||||
# renames.
|
||||
last_name_by_id = {}
|
||||
|
||||
# Remember uniqueids that have had files deleted.
|
||||
uniqueids_deleted = collections.defaultdict(set)
|
||||
|
||||
# FIXME(dhellmann): This might need to be more line-oriented for
|
||||
# longer histories.
|
||||
log_cmd = [
|
||||
'git', 'log',
|
||||
'--topo-order', # force traversal order rather than date order
|
||||
'--pretty=%x00%H %d', # output contents in parsable format
|
||||
'--name-only' # only include the names of the files in the patch
|
||||
]
|
||||
if branch is not None:
|
||||
log_cmd.append(branch)
|
||||
LOG.debug('running %s' % ' '.join(log_cmd))
|
||||
history_results = utils.check_output(log_cmd, cwd=reporoot)
|
||||
history = history_results.split('\x00')
|
||||
current_version = current_version
|
||||
for h in history:
|
||||
h = h.strip()
|
||||
if not h:
|
||||
continue
|
||||
# print(h)
|
||||
|
||||
hlines = h.splitlines()
|
||||
|
||||
# The first line of the block will include the SHA and may
|
||||
# include tags, the other lines are filenames.
|
||||
sha = hlines[0].split(' ')[0]
|
||||
tags = TAG_RE.findall(hlines[0])
|
||||
# Filter the files based on the notes directory we were
|
||||
# given. We cannot do this in the git log command directly
|
||||
# because it means we end up skipping some of the tags if the
|
||||
# commits being tagged don't include any release note
|
||||
# files. Even if this list ends up empty, we continue doing
|
||||
# the other processing so that we record all of the known
|
||||
# versions.
|
||||
filenames = []
|
||||
for f in hlines[2:]:
|
||||
if fnmatch.fnmatch(f, notesdir + '/*.yaml'):
|
||||
filenames.append(f)
|
||||
elif fnmatch.fnmatch(f, notesdir + '/*'):
|
||||
LOG.warning('found and ignored extra file %s', f)
|
||||
|
||||
# If there are no tags in this block, assume the most recently
|
||||
# seen version.
|
||||
if not tags:
|
||||
tags = [current_version]
|
||||
else:
|
||||
current_version = tags[0]
|
||||
LOG.debug('%s has tags %s (%r), updating current version to %s' %
|
||||
(sha, tags, hlines[0], current_version))
|
||||
|
||||
# Remember each version we have seen.
|
||||
if current_version not in versions:
|
||||
LOG.debug('%s is a new version' % current_version)
|
||||
versions.append(current_version)
|
||||
|
||||
LOG.debug('%s contains files %s' % (sha, filenames))
|
||||
|
||||
# Remember the files seen, using their UUID suffix as a unique id.
|
||||
for f in filenames:
|
||||
# Updated as older tags are found, handling edits to release
|
||||
# notes.
|
||||
uniqueid = _get_unique_id(f)
|
||||
LOG.debug('%s: found file %s',
|
||||
uniqueid, f)
|
||||
LOG.debug('%s: setting earliest reference to %s' %
|
||||
(uniqueid, tags[0]))
|
||||
earliest_seen[uniqueid] = tags[0]
|
||||
if uniqueid in last_name_by_id:
|
||||
# We already have a filename for this id from a
|
||||
# new commit, so use that one in case the name has
|
||||
# changed.
|
||||
LOG.debug('%s: was seen before in %s',
|
||||
uniqueid, last_name_by_id[uniqueid])
|
||||
continue
|
||||
elif _file_exists_at_commit(reporoot, f, sha):
|
||||
LOG.debug('%s: looking for %s in deleted files %s',
|
||||
uniqueid, f, uniqueids_deleted[uniqueid])
|
||||
if f in uniqueids_deleted[uniqueid]:
|
||||
# The file exists in the commit, but was deleted
|
||||
# later in the history.
|
||||
LOG.debug('%s: skipping deleted file %s',
|
||||
uniqueid, f)
|
||||
else:
|
||||
# Remember this filename as the most recent version of
|
||||
# the unique id we have seen, in case the name
|
||||
# changed from an older commit.
|
||||
last_name_by_id[uniqueid] = (f, sha)
|
||||
LOG.debug('%s: remembering %s as filename',
|
||||
uniqueid, f)
|
||||
else:
|
||||
# Track files that have been deleted. The rename logic
|
||||
# above checks for repeated references to files that
|
||||
# are deleted later, and the inversion logic below
|
||||
# checks for any remaining values and skips those
|
||||
# entries.
|
||||
LOG.debug('%s: saw a file that no longer exists',
|
||||
uniqueid)
|
||||
uniqueids_deleted[uniqueid].add(f)
|
||||
LOG.debug('%s: deleted files %s',
|
||||
uniqueid, uniqueids_deleted[uniqueid])
|
||||
|
||||
# Invert earliest_seen to make a list of notes files for each
|
||||
# version.
|
||||
files_and_tags = collections.OrderedDict()
|
||||
for v in versions:
|
||||
files_and_tags[v] = []
|
||||
# Produce a list of the actual files present in the repository. If
|
||||
# a note is removed, this step should let us ignore it.
|
||||
for uniqueid, version in earliest_seen.items():
|
||||
"""
|
||||
cmd = ['git', 'describe', '--tags']
|
||||
if branch is not None:
|
||||
cmd.append(branch)
|
||||
try:
|
||||
base, sha = last_name_by_id[uniqueid]
|
||||
if base in uniqueids_deleted.get(uniqueid, set()):
|
||||
LOG.debug('skipping deleted note %s' % uniqueid)
|
||||
continue
|
||||
files_and_tags[version].append((base, sha))
|
||||
except KeyError:
|
||||
# Unable to find the file again, skip it to avoid breaking
|
||||
# the build.
|
||||
msg = ('[reno] unable to find file associated '
|
||||
'with unique id %r, skipping') % uniqueid
|
||||
LOG.debug(msg)
|
||||
print(msg, file=sys.stderr)
|
||||
result = utils.check_output(cmd, cwd=self.reporoot).strip()
|
||||
if '-' in result:
|
||||
# Descriptions that come after a commit look like
|
||||
# 2.0.0-1-abcde, and we want to remove the SHA value from
|
||||
# the end since we only care about the version number
|
||||
# itself, but we need to recognize that the change is
|
||||
# unreleased so keep the -1 part.
|
||||
result, dash, ignore = result.rpartition('-')
|
||||
except subprocess.CalledProcessError:
|
||||
# This probably means there are no tags.
|
||||
result = '0.0.0'
|
||||
return result
|
||||
|
||||
# Combine pre-releases into the final release, if we are told to
|
||||
# and the final release exists.
|
||||
if collapse_pre_releases:
|
||||
collapsing = files_and_tags
|
||||
files_and_tags = collections.OrderedDict()
|
||||
for ov in versions_by_date:
|
||||
if ov not in collapsing:
|
||||
# We don't need to collapse this one because there are
|
||||
# no notes attached to it.
|
||||
def _get_branch_base(self, branch):
|
||||
"Return the tag at base of the branch."
|
||||
# Based on
|
||||
# http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git
|
||||
# git rev-list $(git rev-list --first-parent \
|
||||
# ^origin/stable/newton master | tail -n1)^^!
|
||||
#
|
||||
# Determine the list of commits accessible from the branch we are
|
||||
# supposed to be scanning, but not on master.
|
||||
cmd = [
|
||||
'git',
|
||||
'rev-list',
|
||||
'--first-parent',
|
||||
branch, # on the branch
|
||||
'^master', # not on master
|
||||
]
|
||||
try:
|
||||
LOG.debug(' '.join(cmd))
|
||||
parents = utils.check_output(cmd, cwd=self.reporoot).strip()
|
||||
if not parents:
|
||||
# There are no commits on the branch, yet, so we can use
|
||||
# our current-version logic.
|
||||
return self._get_current_version(branch)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
parent = parents.splitlines()[-1]
|
||||
LOG.debug('parent = %r', parent)
|
||||
# Now get the previous commit, which should be the one we tagged
|
||||
# to create the branch.
|
||||
cmd = [
|
||||
'git',
|
||||
'rev-list',
|
||||
'{}^^!'.format(parent),
|
||||
]
|
||||
try:
|
||||
sha = utils.check_output(cmd, cwd=self.reporoot).strip()
|
||||
LOG.debug('sha = %r', sha)
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
# Now get the tag for that commit.
|
||||
cmd = [
|
||||
'git',
|
||||
'describe',
|
||||
'--abbrev=0',
|
||||
sha,
|
||||
]
|
||||
try:
|
||||
return utils.check_output(cmd, cwd=self.reporoot).strip()
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOG.warning('failed to retrieve branch base: %s [%s]',
|
||||
e, e.output.strip())
|
||||
return None
|
||||
|
||||
def get_file_at_commit(self, filename, sha):
|
||||
"Return the contents of the file if it exists at the commit, or None."
|
||||
try:
|
||||
return utils.check_output(
|
||||
['git', 'show', '%s:%s' % (sha, filename)],
|
||||
cwd=self.reporoot,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
def _file_exists_at_commit(self, filename, sha):
|
||||
"Return true if the file exists at the given commit."
|
||||
return bool(self.get_file_at_commit(filename, sha))
|
||||
|
||||
def get_notes_by_version(self):
|
||||
"""Return an OrderedDict mapping versions to lists of notes files.
|
||||
|
||||
The versions are presented in reverse chronological order.
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
reporoot = self.reporoot
|
||||
notesdir = self.conf.notespath
|
||||
branch = 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
|
||||
|
||||
LOG.debug('scanning %s/%s (branch=%s)' % (reporoot, notesdir, branch))
|
||||
|
||||
# If the user has not told us where to stop, try to work it out
|
||||
# for ourselves. If branch is set and is not "master", then we
|
||||
# want to stop at the base of the branch.
|
||||
if (stop_at_branch_base and
|
||||
(not earliest_version) and branch and (branch != 'master')):
|
||||
LOG.debug('determining earliest_version from branch')
|
||||
earliest_version = self._get_branch_base(branch)
|
||||
if earliest_version and collapse_pre_releases:
|
||||
if PRE_RELEASE_RE.search(earliest_version):
|
||||
# The earliest version won't actually be the pre-release
|
||||
# that might have been tagged when the branch was created,
|
||||
# but the final version. Strip the pre-release portion of
|
||||
# the version number.
|
||||
earliest_version = '.'.join(
|
||||
earliest_version.split('.')[:-1]
|
||||
)
|
||||
LOG.debug('using earliest_version = %r', earliest_version)
|
||||
|
||||
# Determine all of the tags known on the branch, in their date
|
||||
# order. We scan the commit history in topological order to ensure
|
||||
# we have the commits in the right version, so we might encounter
|
||||
# the tags in a different order during that phase.
|
||||
versions_by_date = _get_version_tags_on_branch(reporoot, branch)
|
||||
LOG.debug('versions by date %r' % (versions_by_date,))
|
||||
versions = []
|
||||
earliest_seen = collections.OrderedDict()
|
||||
|
||||
# Determine the current version, which might be an unreleased or
|
||||
# dev version if there are unreleased commits at the head of the
|
||||
# branch in question. Since the version may not already be known,
|
||||
# make sure it is in the list of versions by date. And since it is
|
||||
# the most recent version, go ahead and insert it at the front of
|
||||
# the list.
|
||||
current_version = self._get_current_version(branch)
|
||||
LOG.debug('current repository version: %s' % current_version)
|
||||
if current_version not in versions_by_date:
|
||||
LOG.debug('adding %s to versions by date' % current_version)
|
||||
versions_by_date.insert(0, current_version)
|
||||
|
||||
# Remember the most current filename for each id, to allow for
|
||||
# renames.
|
||||
last_name_by_id = {}
|
||||
|
||||
# Remember uniqueids that have had files deleted.
|
||||
uniqueids_deleted = collections.defaultdict(set)
|
||||
|
||||
# FIXME(dhellmann): This might need to be more line-oriented for
|
||||
# longer histories.
|
||||
log_cmd = [
|
||||
'git', 'log',
|
||||
'--topo-order', # force traversal order rather than date order
|
||||
'--pretty=%x00%H %d', # output contents in parsable format
|
||||
'--name-only' # only include the names of the files in the patch
|
||||
]
|
||||
if branch is not None:
|
||||
log_cmd.append(branch)
|
||||
LOG.debug('running %s' % ' '.join(log_cmd))
|
||||
history_results = utils.check_output(log_cmd, cwd=reporoot)
|
||||
history = history_results.split('\x00')
|
||||
current_version = current_version
|
||||
for h in history:
|
||||
h = h.strip()
|
||||
if not h:
|
||||
continue
|
||||
pre_release_match = PRE_RELEASE_RE.search(ov)
|
||||
LOG.debug('checking %r', ov)
|
||||
if pre_release_match:
|
||||
# Remove the trailing pre-release part of the version
|
||||
# from the string.
|
||||
pre_rel_str = pre_release_match.groups()[0]
|
||||
canonical_ver = ov[:-len(pre_rel_str)].rstrip('.')
|
||||
if canonical_ver not in versions_by_date:
|
||||
# This canonical version was never tagged, so we
|
||||
# do not want to collapse the pre-releases. Reset
|
||||
# to the original version.
|
||||
canonical_ver = ov
|
||||
else:
|
||||
LOG.debug('combining into %r', canonical_ver)
|
||||
# print(h)
|
||||
|
||||
hlines = h.splitlines()
|
||||
|
||||
# The first line of the block will include the SHA and may
|
||||
# include tags, the other lines are filenames.
|
||||
sha = hlines[0].split(' ')[0]
|
||||
tags = TAG_RE.findall(hlines[0])
|
||||
# Filter the files based on the notes directory we were
|
||||
# given. We cannot do this in the git log command directly
|
||||
# because it means we end up skipping some of the tags if the
|
||||
# commits being tagged don't include any release note
|
||||
# files. Even if this list ends up empty, we continue doing
|
||||
# the other processing so that we record all of the known
|
||||
# versions.
|
||||
filenames = []
|
||||
for f in hlines[2:]:
|
||||
if fnmatch.fnmatch(f, notesdir + '/*.yaml'):
|
||||
filenames.append(f)
|
||||
elif fnmatch.fnmatch(f, notesdir + '/*'):
|
||||
LOG.warning('found and ignored extra file %s', f)
|
||||
|
||||
# If there are no tags in this block, assume the most recently
|
||||
# seen version.
|
||||
if not tags:
|
||||
tags = [current_version]
|
||||
else:
|
||||
canonical_ver = ov
|
||||
if canonical_ver not in files_and_tags:
|
||||
files_and_tags[canonical_ver] = []
|
||||
files_and_tags[canonical_ver].extend(collapsing[ov])
|
||||
current_version = tags[0]
|
||||
LOG.debug('%s has tags %s (%r), '
|
||||
'updating current version to %s' %
|
||||
(sha, tags, hlines[0], current_version))
|
||||
|
||||
# Only return the parts of files_and_tags that actually have
|
||||
# filenames associated with the versions.
|
||||
trimmed = collections.OrderedDict()
|
||||
for ov in versions_by_date:
|
||||
if not files_and_tags.get(ov):
|
||||
continue
|
||||
# Sort the notes associated with the version so they are in a
|
||||
# deterministic order, to avoid having the same data result in
|
||||
# different output depending on random factors. Earlier
|
||||
# versions of the scanner assumed the notes were recorded in
|
||||
# chronological order based on the commit date, but with the
|
||||
# change to use topological sorting that is no longer
|
||||
# necessarily true. We want the notes to always show up in the
|
||||
# same order, but it doesn't really matter what order that is,
|
||||
# so just sort based on the unique id.
|
||||
trimmed[ov] = sorted(files_and_tags[ov])
|
||||
# If we have been told to stop at a version, we can do that
|
||||
# now.
|
||||
if earliest_version and ov == earliest_version:
|
||||
break
|
||||
# Remember each version we have seen.
|
||||
if current_version not in versions:
|
||||
LOG.debug('%s is a new version' % current_version)
|
||||
versions.append(current_version)
|
||||
|
||||
LOG.debug('[reno] found %d versions and %d files',
|
||||
len(trimmed.keys()), sum(len(ov) for ov in trimmed.values()))
|
||||
return trimmed
|
||||
LOG.debug('%s contains files %s' % (sha, filenames))
|
||||
|
||||
# Remember the files seen, using their UUID suffix as a unique id.
|
||||
for f in filenames:
|
||||
# Updated as older tags are found, handling edits to release
|
||||
# notes.
|
||||
uniqueid = _get_unique_id(f)
|
||||
LOG.debug('%s: found file %s',
|
||||
uniqueid, f)
|
||||
LOG.debug('%s: setting earliest reference to %s' %
|
||||
(uniqueid, tags[0]))
|
||||
earliest_seen[uniqueid] = tags[0]
|
||||
if uniqueid in last_name_by_id:
|
||||
# We already have a filename for this id from a
|
||||
# new commit, so use that one in case the name has
|
||||
# changed.
|
||||
LOG.debug('%s: was seen before in %s',
|
||||
uniqueid, last_name_by_id[uniqueid])
|
||||
continue
|
||||
elif self._file_exists_at_commit(f, sha):
|
||||
LOG.debug('%s: looking for %s in deleted files %s',
|
||||
uniqueid, f, uniqueids_deleted[uniqueid])
|
||||
if f in uniqueids_deleted[uniqueid]:
|
||||
# The file exists in the commit, but was deleted
|
||||
# later in the history.
|
||||
LOG.debug('%s: skipping deleted file %s',
|
||||
uniqueid, f)
|
||||
else:
|
||||
# Remember this filename as the most recent version of
|
||||
# the unique id we have seen, in case the name
|
||||
# changed from an older commit.
|
||||
last_name_by_id[uniqueid] = (f, sha)
|
||||
LOG.debug('%s: remembering %s as filename',
|
||||
uniqueid, f)
|
||||
else:
|
||||
# Track files that have been deleted. The rename logic
|
||||
# above checks for repeated references to files that
|
||||
# are deleted later, and the inversion logic below
|
||||
# checks for any remaining values and skips those
|
||||
# entries.
|
||||
LOG.debug('%s: saw a file that no longer exists',
|
||||
uniqueid)
|
||||
uniqueids_deleted[uniqueid].add(f)
|
||||
LOG.debug('%s: deleted files %s',
|
||||
uniqueid, uniqueids_deleted[uniqueid])
|
||||
|
||||
# Invert earliest_seen to make a list of notes files for each
|
||||
# version.
|
||||
files_and_tags = collections.OrderedDict()
|
||||
for v in versions:
|
||||
files_and_tags[v] = []
|
||||
# Produce a list of the actual files present in the repository. If
|
||||
# a note is removed, this step should let us ignore it.
|
||||
for uniqueid, version in earliest_seen.items():
|
||||
try:
|
||||
base, sha = last_name_by_id[uniqueid]
|
||||
if base in uniqueids_deleted.get(uniqueid, set()):
|
||||
LOG.debug('skipping deleted note %s' % uniqueid)
|
||||
continue
|
||||
files_and_tags[version].append((base, sha))
|
||||
except KeyError:
|
||||
# Unable to find the file again, skip it to avoid breaking
|
||||
# the build.
|
||||
msg = ('[reno] unable to find file associated '
|
||||
'with unique id %r, skipping') % uniqueid
|
||||
LOG.debug(msg)
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
# Combine pre-releases into the final release, if we are told to
|
||||
# and the final release exists.
|
||||
if collapse_pre_releases:
|
||||
collapsing = files_and_tags
|
||||
files_and_tags = collections.OrderedDict()
|
||||
for ov in versions_by_date:
|
||||
if ov not in collapsing:
|
||||
# We don't need to collapse this one because there are
|
||||
# no notes attached to it.
|
||||
continue
|
||||
pre_release_match = PRE_RELEASE_RE.search(ov)
|
||||
LOG.debug('checking %r', ov)
|
||||
if pre_release_match:
|
||||
# Remove the trailing pre-release part of the version
|
||||
# from the string.
|
||||
pre_rel_str = pre_release_match.groups()[0]
|
||||
canonical_ver = ov[:-len(pre_rel_str)].rstrip('.')
|
||||
if canonical_ver not in versions_by_date:
|
||||
# This canonical version was never tagged, so we
|
||||
# do not want to collapse the pre-releases. Reset
|
||||
# to the original version.
|
||||
canonical_ver = ov
|
||||
else:
|
||||
LOG.debug('combining into %r', canonical_ver)
|
||||
else:
|
||||
canonical_ver = ov
|
||||
if canonical_ver not in files_and_tags:
|
||||
files_and_tags[canonical_ver] = []
|
||||
files_and_tags[canonical_ver].extend(collapsing[ov])
|
||||
|
||||
# Only return the parts of files_and_tags that actually have
|
||||
# filenames associated with the versions.
|
||||
trimmed = collections.OrderedDict()
|
||||
for ov in versions_by_date:
|
||||
if not files_and_tags.get(ov):
|
||||
continue
|
||||
# Sort the notes associated with the version so they are in a
|
||||
# deterministic order, to avoid having the same data result in
|
||||
# different output depending on random factors. Earlier
|
||||
# versions of the scanner assumed the notes were recorded in
|
||||
# chronological order based on the commit date, but with the
|
||||
# change to use topological sorting that is no longer
|
||||
# necessarily true. We want the notes to always show up in the
|
||||
# same order, but it doesn't really matter what order that is,
|
||||
# so just sort based on the unique id.
|
||||
trimmed[ov] = sorted(files_and_tags[ov])
|
||||
# If we have been told to stop at a version, we can do that
|
||||
# now.
|
||||
if earliest_version and ov == earliest_version:
|
||||
break
|
||||
|
||||
LOG.debug('[reno] found %d versions and %d files',
|
||||
len(trimmed.keys()), sum(len(ov) for ov in trimmed.values()))
|
||||
return trimmed
|
||||
|
|
|
@ -45,19 +45,19 @@ class TestCache(base.TestCase):
|
|||
""")
|
||||
}
|
||||
|
||||
def _get_note_body(self, reporoot, filename, sha):
|
||||
def _get_note_body(self, filename, sha):
|
||||
return self.note_bodies.get(filename, '')
|
||||
|
||||
def setUp(self):
|
||||
super(TestCache, self).setUp()
|
||||
self.useFixture(
|
||||
mockpatch.Patch('reno.scanner.get_file_at_commit',
|
||||
mockpatch.Patch('reno.scanner.Scanner.get_file_at_commit',
|
||||
new=self._get_note_body)
|
||||
)
|
||||
self.c = config.Config('.')
|
||||
|
||||
def test_build_cache_db(self):
|
||||
with mock.patch('reno.scanner.get_notes_by_version') as gnbv:
|
||||
with mock.patch('reno.scanner.Scanner.get_notes_by_version') as gnbv:
|
||||
gnbv.return_value = self.scanner_output
|
||||
db = cache.build_cache_db(
|
||||
self.c,
|
||||
|
|
|
@ -197,6 +197,7 @@ class Base(base.TestCase):
|
|||
self.temp_dir = self.useFixture(fixtures.TempDir()).path
|
||||
self.reporoot = os.path.join(self.temp_dir, 'reporoot')
|
||||
self.c = config.Config(self.reporoot)
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
self._git_setup()
|
||||
self._counter = itertools.count(1)
|
||||
self.get_note_num = lambda: next(self._counter)
|
||||
|
@ -206,7 +207,7 @@ class BasicTest(Base):
|
|||
|
||||
def test_non_python_no_tags(self):
|
||||
filename = self._add_notes_file()
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -219,7 +220,7 @@ class BasicTest(Base):
|
|||
def test_python_no_tags(self):
|
||||
self._make_python_package()
|
||||
filename = self._add_notes_file()
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -233,7 +234,7 @@ class BasicTest(Base):
|
|||
filename = self._add_notes_file()
|
||||
self._add_other_file('not-a-release-note.txt')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -246,7 +247,7 @@ class BasicTest(Base):
|
|||
def test_note_commit_tagged(self):
|
||||
filename = self._add_notes_file()
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -260,7 +261,7 @@ class BasicTest(Base):
|
|||
self._make_python_package()
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
filename = self._add_notes_file()
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -275,7 +276,7 @@ class BasicTest(Base):
|
|||
self._add_other_file('ignore-1.txt')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
self._add_other_file('ignore-2.txt')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -290,7 +291,7 @@ class BasicTest(Base):
|
|||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
f1 = self._add_notes_file()
|
||||
f2 = self._add_notes_file()
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -305,7 +306,7 @@ class BasicTest(Base):
|
|||
f1 = self._add_notes_file(commit=False)
|
||||
f2 = self._add_notes_file()
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -321,7 +322,7 @@ class BasicTest(Base):
|
|||
f1 = self._add_notes_file()
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '2.0.0')
|
||||
f2 = self._add_notes_file()
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -341,7 +342,7 @@ class BasicTest(Base):
|
|||
f2 = f1.replace('slug1', 'slug2')
|
||||
self._run_git('mv', f1, f2)
|
||||
self._git_commit('rename note file')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -360,7 +361,7 @@ class BasicTest(Base):
|
|||
f2 = f1.replace('slug1', 'slug0')
|
||||
self._run_git('mv', f1, f2)
|
||||
self._git_commit('rename note file')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -379,7 +380,7 @@ class BasicTest(Base):
|
|||
with open(os.path.join(self.reporoot, f1), 'w') as f:
|
||||
f.write('---\npreamble: new contents for file')
|
||||
self._git_commit('edit note file')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -398,7 +399,7 @@ class BasicTest(Base):
|
|||
f2 = f1.replace('slug1', 'slug2')
|
||||
self._run_git('mv', f1, f2)
|
||||
self._git_commit('rename note file')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -420,7 +421,7 @@ class BasicTest(Base):
|
|||
'slug1-0000000000000001')
|
||||
self._run_git('mv', f1, f2)
|
||||
self._git_commit('rename note file')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -442,7 +443,7 @@ class BasicTest(Base):
|
|||
self.c.override(
|
||||
earliest_version='2.0.0',
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -462,7 +463,7 @@ class BasicTest(Base):
|
|||
self._run_git('rm', f1)
|
||||
self._git_commit('remove note file')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '2.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -492,7 +493,7 @@ class BasicTest(Base):
|
|||
'--pretty=%H %d',
|
||||
'--name-only')
|
||||
self.addDetail('git log', text_content(log_results))
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -511,7 +512,7 @@ class PreReleaseTest(Base):
|
|||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0a1')
|
||||
f1 = self._add_notes_file('slug1')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0a2')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -527,7 +528,7 @@ class PreReleaseTest(Base):
|
|||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0b1')
|
||||
f1 = self._add_notes_file('slug1')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0b2')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -543,7 +544,7 @@ class PreReleaseTest(Base):
|
|||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0rc1')
|
||||
f1 = self._add_notes_file('slug1')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0.0rc2')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -568,7 +569,7 @@ class PreReleaseTest(Base):
|
|||
self.c.override(
|
||||
collapse_pre_releases=True,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -590,7 +591,7 @@ class PreReleaseTest(Base):
|
|||
self.c.override(
|
||||
collapse_pre_releases=True,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -615,7 +616,7 @@ class PreReleaseTest(Base):
|
|||
self.c.override(
|
||||
collapse_pre_releases=True,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -643,7 +644,7 @@ class MergeCommitTest(Base):
|
|||
self._run_git('merge', '--no-ff', 'test_merge_commit')
|
||||
self._add_other_file('ignore-2.txt')
|
||||
self._run_git('tag', '-s', '-m', 'second tag', '2.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -671,7 +672,7 @@ class MergeCommitTest(Base):
|
|||
self._run_git('merge', '--no-ff', 'test_merge_commit')
|
||||
self._add_other_file('ignore-2.txt')
|
||||
self._run_git('tag', '-s', '-m', 'second tag', '2.0.0')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -703,7 +704,7 @@ class MergeCommitTest(Base):
|
|||
self._add_other_file('ignore-2.txt')
|
||||
self._run_git('tag', '-s', '-m', 'third tag', '2.0.0')
|
||||
self._add_other_file('ignore-3.txt')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -739,7 +740,7 @@ class MergeCommitTest(Base):
|
|||
self._add_other_file('ignore-2.txt')
|
||||
self._run_git('tag', '-s', '-m', 'third tag', '2.0.0')
|
||||
self._add_other_file('ignore-3.txt')
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -789,7 +790,7 @@ class BranchTest(Base):
|
|||
f21 = self._add_notes_file('slug21')
|
||||
log_text = self._run_git('log')
|
||||
self.addDetail('git log', text_content(log_text))
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -814,7 +815,7 @@ class BranchTest(Base):
|
|||
self.c.override(
|
||||
branch='stable/2',
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -841,7 +842,7 @@ class BranchTest(Base):
|
|||
self.c.override(
|
||||
stop_at_branch_base=False,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -877,7 +878,7 @@ class BranchTest(Base):
|
|||
branch='stable/4',
|
||||
collapse_pre_releases=False,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -913,7 +914,7 @@ class BranchTest(Base):
|
|||
branch='stable/4',
|
||||
collapse_pre_releases=True,
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -946,7 +947,7 @@ class BranchTest(Base):
|
|||
self.c.override(
|
||||
branch='stable/4',
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -979,7 +980,7 @@ class BranchTest(Base):
|
|||
self.c.override(
|
||||
branch='stable/4',
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -1010,7 +1011,7 @@ class BranchTest(Base):
|
|||
self.c.override(
|
||||
branch='stable/4',
|
||||
)
|
||||
raw_results = scanner.get_notes_by_version(self.c)
|
||||
raw_results = self.scanner.get_notes_by_version()
|
||||
results = {
|
||||
k: [f for (f, n) in v]
|
||||
for (k, v) in raw_results.items()
|
||||
|
@ -1183,3 +1184,33 @@ class GetTagsParseTest(base.TestCase):
|
|||
actual = scanner._get_version_tags_on_branch('reporoot',
|
||||
branch=None)
|
||||
self.assertEqual(self.EXPECTED, actual)
|
||||
|
||||
|
||||
class VersionTest(Base):
|
||||
|
||||
def setUp(self):
|
||||
super(VersionTest, self).setUp()
|
||||
self._make_python_package()
|
||||
self.f1 = self._add_notes_file('slug1')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '1.0.0')
|
||||
self.f2 = self._add_notes_file('slug2')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '2.0.0')
|
||||
self._add_notes_file('slug3')
|
||||
self._run_git('tag', '-s', '-m', 'first tag', '3.0.0')
|
||||
|
||||
def test_tagged_head(self):
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
results = self.scanner._get_current_version(None)
|
||||
self.assertEqual(
|
||||
'3.0.0',
|
||||
results,
|
||||
)
|
||||
|
||||
def test_head_after_tag(self):
|
||||
self._add_notes_file('slug4')
|
||||
self.scanner = scanner.Scanner(self.c)
|
||||
results = self.scanner._get_current_version(None)
|
||||
self.assertEqual(
|
||||
'3.0.0-1',
|
||||
results,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue