checkupdates: sort tags by date in one go

This greatly speeds up checkupdates when UCM:Tags is used on git
repositories, especially on ones with lots of tags. The old method ran a
command per tag. The new method runs a single command and doesn't
require any sorting.

Test runs show that `fdroid checkupdates org.adaway` is down from ~13s
to ~10s on my laptop.
This commit is contained in:
Daniel Martí 2016-03-02 11:30:40 +00:00
parent 261cbcd3ee
commit 2a73b74603
2 changed files with 23 additions and 25 deletions

View file

@ -121,6 +121,10 @@ def check_tags(app, pattern):
hver = None hver = None
hcode = "0" hcode = "0"
tags = []
if repotype == 'git':
tags = vcs.latesttags()
else:
tags = vcs.gettags() tags = vcs.gettags()
if not tags: if not tags:
return (None, "No tags found", None) return (None, "No tags found", None)
@ -133,8 +137,8 @@ def check_tags(app, pattern):
return (None, "No matching tags found", None) return (None, "No matching tags found", None)
logging.debug("Matching tags: " + ','.join(tags)) logging.debug("Matching tags: " + ','.join(tags))
if len(tags) > 5 and repotype in ('git',): if len(tags) > 5 and repotype == 'git':
tags = vcs.latesttags(tags, 5) tags = tags[:5]
logging.debug("Latest tags: " + ','.join(tags)) logging.debug("Latest tags: " + ','.join(tags))
for tag in tags: for tag in tags:

View file

@ -588,14 +588,8 @@ class vcs:
rtags.append(tag) rtags.append(tag)
return rtags return rtags
def latesttags(self, tags, number): # Get a list of all the known tags, sorted from newest to oldest
"""Get the most recent tags in a given list. def latesttags(self):
:param tags: a list of tags
:param number: the number to return
:returns: A list containing the most recent tags in the provided
list, up to the maximum number given.
"""
raise VCSException('latesttags not supported for this vcs type') raise VCSException('latesttags not supported for this vcs type')
# Get current commit reference (hash, revision, etc) # Get current commit reference (hash, revision, etc)
@ -703,21 +697,21 @@ class vcs_git(vcs):
p = FDroidPopen(['git', 'tag'], cwd=self.local, output=False) p = FDroidPopen(['git', 'tag'], cwd=self.local, output=False)
return p.output.splitlines() return p.output.splitlines()
def latesttags(self, tags, number): tag_format = re.compile(r'.*tag: ([^),]*).*')
def latesttags(self):
self.checkrepo() self.checkrepo()
tl = [] p = FDroidPopen(['git', 'log', '--tags',
for tag in tags: '--simplify-by-decoration', '--pretty=format:%d'],
p = FDroidPopen(
['git', 'show', '--format=format:%ct', '-s', tag],
cwd=self.local, output=False) cwd=self.local, output=False)
# Timestamp is on the last line. For a normal tag, it's the only tags = []
# line, but for annotated tags, the rest of the info precedes it. for line in p.output.splitlines():
ts = int(p.output.splitlines()[-1]) m = self.tag_format.match(line)
tl.append((ts, tag)) if not m:
latest = [] continue
for _, t in sorted(tl)[-number:]: tag = m.group(1)
latest.append(t) tags.append(tag)
return latest return tags
class vcs_gitsvn(vcs): class vcs_gitsvn(vcs):