make list-changes smarter about the "previous" version
The old implementation of list-changes assumed that the deliverable file included all releases and that they were in order. That assumption does not hold for independent projects, where the history might not be there and new entries might be from different branches than the previous entries, all in the same file. This change uses git to determine the previous tag for each repository, then shows the right diffs based on that instead of the assumed tag from the deliverable file. Change-Id: I122a6ec1792a07cdb23f09a880110dff2446555e Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
parent
c3e818cab7
commit
83c16a48fe
@ -63,8 +63,9 @@ def git_branch_contains(workdir, repo, title, commit):
|
|||||||
header('%s %s' % (title, commit))
|
header('%s %s' % (title, commit))
|
||||||
cmd = ['git', 'branch', '-r', '--contains', commit]
|
cmd = ['git', 'branch', '-r', '--contains', commit]
|
||||||
print('\n' + ' '.join(cmd) + '\n')
|
print('\n' + ' '.join(cmd) + '\n')
|
||||||
subprocess.check_call(cmd, cwd=os.path.join(workdir, repo))
|
out = subprocess.check_output(cmd, cwd=os.path.join(workdir, repo))
|
||||||
print()
|
print(out + '\n')
|
||||||
|
return [o.strip() for o in out.splitlines()]
|
||||||
|
|
||||||
|
|
||||||
def git_diff(workdir, repo, git_range, file_pattern):
|
def git_diff(workdir, repo, git_range, file_pattern):
|
||||||
@ -166,13 +167,17 @@ def main():
|
|||||||
else:
|
else:
|
||||||
branch = 'stable/' + series
|
branch = 'stable/' + series
|
||||||
|
|
||||||
# assume the releases are in order and take the last two
|
# assume the releases are in order and take the last one
|
||||||
new_release = deliverable_info['releases'][-1]
|
new_release = deliverable_info['releases'][-1]
|
||||||
if len(deliverable_info['releases']) >= 2:
|
|
||||||
previous_release = deliverable_info['releases'][-2]
|
# build a map between version numbers and the release details
|
||||||
else:
|
by_version = {
|
||||||
previous_release = None
|
str(r['version']): r
|
||||||
|
for r in deliverable_info['releases']
|
||||||
|
}
|
||||||
|
|
||||||
for project in new_release['projects']:
|
for project in new_release['projects']:
|
||||||
|
|
||||||
tag_exists = gitutils.commit_exists(
|
tag_exists = gitutils.commit_exists(
|
||||||
project['repo'],
|
project['repo'],
|
||||||
new_release['version'],
|
new_release['version'],
|
||||||
@ -182,7 +187,7 @@ def main():
|
|||||||
(project['repo'], new_release['version']))
|
(project['repo'], new_release['version']))
|
||||||
|
|
||||||
# Check out the code.
|
# Check out the code.
|
||||||
print('\nChecking out repository')
|
print('\nChecking out repository {}'.format(project['repo']))
|
||||||
subprocess.check_call(
|
subprocess.check_call(
|
||||||
['zuul-cloner',
|
['zuul-cloner',
|
||||||
'--branch', branch,
|
'--branch', branch,
|
||||||
@ -192,18 +197,23 @@ def main():
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
start_range = None
|
# look at the previous tag for the parent of the commit
|
||||||
|
# getting the new release
|
||||||
|
previous_tag = gitutils.get_latest_tag(
|
||||||
|
workdir,
|
||||||
|
project['repo'],
|
||||||
|
'{}^'.format(project['hash'])
|
||||||
|
)
|
||||||
|
previous_release = by_version.get(previous_tag)
|
||||||
|
|
||||||
|
start_range = previous_tag
|
||||||
if previous_release:
|
if previous_release:
|
||||||
previous_project = {
|
previous_project = {
|
||||||
x['repo']: x
|
x['repo']: x
|
||||||
for x in previous_release['projects']
|
for x in previous_release['projects']
|
||||||
}.get(project['repo'])
|
}.get(project['repo'])
|
||||||
if previous_project is not None:
|
if previous_project is not None:
|
||||||
start_range = previous_project['hash']
|
start_range = previous_tag
|
||||||
if not start_range:
|
|
||||||
start_range = (
|
|
||||||
gitutils.get_latest_tag(workdir, project['repo']) or None
|
|
||||||
)
|
|
||||||
|
|
||||||
if start_range:
|
if start_range:
|
||||||
git_range = '%s..%s' % (start_range, project['hash'])
|
git_range = '%s..%s' % (start_range, project['hash'])
|
||||||
@ -229,14 +239,32 @@ def main():
|
|||||||
ref=project['hash'],
|
ref=project['hash'],
|
||||||
)
|
)
|
||||||
|
|
||||||
git_branch_contains(
|
branches = git_branch_contains(
|
||||||
workdir=workdir,
|
workdir=workdir,
|
||||||
repo=project['repo'],
|
repo=project['repo'],
|
||||||
title='Branches containing commit',
|
title='Branches containing commit',
|
||||||
commit=project['hash'],
|
commit=project['hash'],
|
||||||
)
|
)
|
||||||
|
|
||||||
head_sha = gitutils.sha_for_tag(workdir, project['repo'], 'HEAD')
|
header('Relationship to HEAD')
|
||||||
|
if series == '_independent':
|
||||||
|
interesting_branches = sorted(
|
||||||
|
b for b in branches
|
||||||
|
if '->' not in b
|
||||||
|
)
|
||||||
|
head_sha = gitutils.sha_for_tag(
|
||||||
|
workdir,
|
||||||
|
project['repo'],
|
||||||
|
interesting_branches[0],
|
||||||
|
)
|
||||||
|
print('HEAD of {} is {}'.format(interesting_branches[0], head_sha))
|
||||||
|
else:
|
||||||
|
head_sha = gitutils.sha_for_tag(
|
||||||
|
workdir,
|
||||||
|
project['repo'],
|
||||||
|
'HEAD',
|
||||||
|
)
|
||||||
|
print('HEAD of {} is {}'.format(branch, head_sha))
|
||||||
requested_sha = gitutils.sha_for_tag(
|
requested_sha = gitutils.sha_for_tag(
|
||||||
workdir,
|
workdir,
|
||||||
project['repo'],
|
project['repo'],
|
||||||
@ -247,12 +275,11 @@ def main():
|
|||||||
# git to give us the real SHA for the requested release in
|
# git to give us the real SHA for the requested release in
|
||||||
# case the deliverables file has the short version of the
|
# case the deliverables file has the short version of the
|
||||||
# hash.
|
# hash.
|
||||||
header('Relationship to HEAD')
|
|
||||||
if head_sha == requested_sha:
|
if head_sha == requested_sha:
|
||||||
print('\nRequest releases from HEAD on %s' % branch)
|
print('\nRequest releases from HEAD on %s' % branch)
|
||||||
else:
|
else:
|
||||||
git_log(workdir, project['repo'], 'Release will NOT include',
|
git_log(workdir, project['repo'], 'Release will NOT include',
|
||||||
'%s..%s~1' % (requested_sha, head_sha),
|
'%s..%s' % (requested_sha, head_sha),
|
||||||
extra_args=['--format=%h %ci %s'])
|
extra_args=['--format=%h %ci %s'])
|
||||||
|
|
||||||
# Show any requirements changes in the upcoming release.
|
# Show any requirements changes in the upcoming release.
|
||||||
|
@ -112,10 +112,13 @@ def check_ancestry(workdir, repo, old_version, sha):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_latest_tag(workdir, repo):
|
def get_latest_tag(workdir, repo, sha=None):
|
||||||
|
cmd = ['git', 'describe', '--abbrev=0']
|
||||||
|
if sha is not None:
|
||||||
|
cmd.append(sha)
|
||||||
try:
|
try:
|
||||||
return subprocess.check_output(
|
return subprocess.check_output(
|
||||||
['git', 'describe', '--abbrev=0'],
|
cmd,
|
||||||
cwd=os.path.join(workdir, repo),
|
cwd=os.path.join(workdir, repo),
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
).strip()
|
).strip()
|
||||||
|
Loading…
Reference in New Issue
Block a user