Merge ~cjwatson/turnip:log-by-date into turnip:master

Proposed by Colin Watson
Status: Needs review
Proposed branch: ~cjwatson/turnip:log-by-date
Merge into: turnip:master
Diff against target: 118 lines (+29/-3)
4 files modified
requirements.txt (+1/-0)
setup.py (+1/-0)
turnip/api/store.py (+16/-2)
turnip/api/views.py (+11/-1)
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+295544@code.launchpad.net

Commit message

Add start_time and end_time parameters to log API

This is useful for bounding the set of commits returned in cases where
we may not have a reliable stop commit.

Description of the change

When I was integrating git commits into Launchpad's merge proposal conversations, I initially thought about filtering by date on the turnip side, but ended up doing that on the Launchpad side instead since it was simpler. However, it can apparently happen that our idea of the stop commit isn't in the source repository, in which case we need a different way to bound the set of commits returned by turnip's log API.

I think the OOPSes I've seen are mainly a bug in Launchpad: we need to be requesting cross-repository diffs in a better way, and I'll work on that separately. Still, it doesn't hurt to attack this from multiple fronts.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)
Revision history for this message
William Grant (wgrant) :

Unmerged commits

ee4cd2f... by Colin Watson

Add start_time and end_time parameters to log API

This is useful for bounding the set of commits returned in cases where
we may not have a reliable stop commit.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/requirements.txt b/requirements.txt
index eafd823..cc6dcf9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -27,6 +27,7 @@ python-mimeparse==0.1.4
27# See lp:~deryck/python-openid/python-openid-fix1034376 which27# See lp:~deryck/python-openid/python-openid-fix1034376 which
28# reapplied a patch from wgrant to get codehosting going again.28# reapplied a patch from wgrant to get codehosting going again.
29python-openid==2.2.5-fix103437629python-openid==2.2.5-fix1034376
30pytz==2014.10
30PyYAML==3.1131PyYAML==3.11
31repoze.lru==0.632repoze.lru==0.6
32simplejson==3.6.533simplejson==3.6.5
diff --git a/setup.py b/setup.py
index be53437..cbcfb1f 100755
--- a/setup.py
+++ b/setup.py
@@ -25,6 +25,7 @@ requires = [
25 'pygit2>=0.22.1,<0.23.0',25 'pygit2>=0.22.1,<0.23.0',
26 'python-openid',26 'python-openid',
27 'PyYAML',27 'PyYAML',
28 'pytz',
28 'Twisted',29 'Twisted',
29 'waitress',30 'waitress',
30 'zope.interface',31 'zope.interface',
diff --git a/turnip/api/store.py b/turnip/api/store.py
index 1291c13..0b08fa9 100644
--- a/turnip/api/store.py
+++ b/turnip/api/store.py
@@ -6,6 +6,7 @@ from contextlib2 import (
6 contextmanager,6 contextmanager,
7 ExitStack,7 ExitStack,
8 )8 )
9from datetime import datetime
9import itertools10import itertools
10import os11import os
11import re12import re
@@ -25,6 +26,7 @@ from pygit2 import (
25 Oid,26 Oid,
26 Repository,27 Repository,
27 )28 )
29import pytz
2830
29from turnip.pack.helpers import ensure_config31from turnip.pack.helpers import ensure_config
3032
@@ -397,12 +399,15 @@ def get_diff(repo_store, repo_name, sha1_from, sha1_to, context_lines=3):
397 return diff399 return diff
398400
399401
400def get_log(repo_store, repo_name, start=None, limit=None, stop=None):402def get_log(repo_store, repo_name, start=None, limit=None, stop=None,
403 start_time=None, end_time=None):
401 """Return a commit collection from HEAD or optionally a start oid.404 """Return a commit collection from HEAD or optionally a start oid.
402405
403 :param start: sha1 or branch to start listing commits from.406 :param start: sha1 or branch to start listing commits from.
404 :param limit: limit number of commits to return.407 :param limit: limit number of commits to return.
405 :param stop: ignore a commit (and its ancestors).408 :param stop: ignore a commit (and its ancestors).
409 :param start_time: ignore commits before this time (and their ancestors).
410 :param end_time: ignore commits after this time.
406 """411 """
407 with open_repo(repo_store, repo_name) as repo:412 with open_repo(repo_store, repo_name) as repo:
408 if not start:413 if not start:
@@ -412,7 +417,16 @@ def get_log(repo_store, repo_name, start=None, limit=None, stop=None):
412 walker.hide(stop) # filter stop sha1 and its ancestors417 walker.hide(stop) # filter stop sha1 and its ancestors
413 if limit > 0:418 if limit > 0:
414 walker = itertools.islice(walker, limit)419 walker = itertools.islice(walker, limit)
415 return [format_commit(commit) for commit in walker]420 for commit in walker:
421 if start_time is not None or end_time is not None:
422 commit_time = datetime.fromtimestamp(
423 commit.committer.time, tz=pytz.UTC)
424 if start_time is not None and commit_time < start_time:
425 walker.hide(commit)
426 continue
427 if end_time is not None and commit_time > end_time:
428 continue
429 yield format_commit(commit)
416430
417431
418def get_commit(repo_store, repo_name, revision, repo=None):432def get_commit(repo_store, repo_name, revision, repo=None):
diff --git a/turnip/api/views.py b/turnip/api/views.py
index abdfaca..6e6c413 100644
--- a/turnip/api/views.py
+++ b/turnip/api/views.py
@@ -1,6 +1,7 @@
1# Copyright 2015 Canonical Ltd. This software is licensed under the1# Copyright 2015 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4from datetime import datetime
4import os5import os
5import re6import re
6from subprocess import CalledProcessError7from subprocess import CalledProcessError
@@ -9,6 +10,7 @@ from cornice.resource import resource
9from cornice.util import extract_json_data10from cornice.util import extract_json_data
10from pygit2 import GitError11from pygit2 import GitError
11import pyramid.httpexceptions as exc12import pyramid.httpexceptions as exc
13import pytz
1214
13from turnip.config import TurnipConfig15from turnip.config import TurnipConfig
14from turnip.api import store16from turnip.api import store
@@ -285,9 +287,17 @@ class LogAPI(BaseAPI):
285 sha1 = self.request.matchdict['sha1']287 sha1 = self.request.matchdict['sha1']
286 limit = int(self.request.params.get('limit', -1))288 limit = int(self.request.params.get('limit', -1))
287 stop = self.request.params.get('stop')289 stop = self.request.params.get('stop')
290 start_time = self.request.params.get('start_time')
291 if start_time is not None:
292 start_time = datetime.fromtimestamp(start_time, tz=pytz.UTC)
293 end_time = self.request.params.get('end_time')
294 if end_time is not None:
295 end_time = datetime.fromtimestamp(end_time, tz=pytz.UTC)
288296
289 try:297 try:
290 log = store.get_log(repo_store, repo_name, sha1, limit, stop)298 log = list(store.get_log(
299 repo_store, repo_name, start=sha1, limit=limit, stop=stop,
300 start_time=start_time, end_time=end_time))
291 except GitError:301 except GitError:
292 return exc.HTTPNotFound()302 return exc.HTTPNotFound()
293 return log303 return log

Subscribers

People subscribed via source and target branches