Page Menu
Home
Software Heritage
Search
Configure Global Search
Log In
Files
F7122991
D66.id220.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
31 KB
Subscribers
None
D66.id220.diff
View Options
diff --git a/swh/web/ui/service.py b/swh/web/ui/service.py
--- a/swh/web/ui/service.py
+++ b/swh/web/ui/service.py
@@ -253,9 +253,9 @@
'Only sha1_git is supported.')
return sha1_git_bin
- sha1_bin_list = map(to_sha1_bin, sha1_git_list)
+ sha1_bin_list = (to_sha1_bin(x) for x in sha1_git_list)
revisions = backend.revision_get_multiple(sha1_bin_list)
- return map(converters.from_revision, revisions)
+ return (converters.from_revision(x) for x in revisions)
def lookup_revision_message(rev_sha1_git):
diff --git a/swh/web/ui/templates/revision-log.html b/swh/web/ui/templates/revision-log.html
--- a/swh/web/ui/templates/revision-log.html
+++ b/swh/web/ui/templates/revision-log.html
@@ -39,6 +39,13 @@
</div>
{% endif %}
+ {% if revision['history_context_url'] is not none %}
+ <div class="row">
+ <div class="col-md-2">Contextual Revision Log</div>
+ <div class="col-md-6"><p><a href="{{ revision['history_context_url'] }}">{{ revision['history_context_url'] }}</a></p></div>
+ </div>
+ {% endif %}
+
{% if revision['directory_url'] is not none %}
<div class="row">
<div class="col-md-2">directory</div>
diff --git a/swh/web/ui/templates/revision.html b/swh/web/ui/templates/revision.html
--- a/swh/web/ui/templates/revision.html
+++ b/swh/web/ui/templates/revision.html
@@ -22,6 +22,13 @@
</div>
{% endif %}
+ {% if revision['history_context_url'] is not none %}
+ <div class="row">
+ <div class="col-md-2">Contextual Revision Log</div>
+ <div class="col-md-6"><p><a href="{{ revision['history_context_url'] }}">{{ revision['history_context_url'] }}</a></p></div>
+ </div>
+ {% endif %}
+
{% if revision['directory_url'] is not none %}
<div class="row">
<div class="col-md-2">directory</div>
diff --git a/swh/web/ui/tests/test_utils.py b/swh/web/ui/tests/test_utils.py
--- a/swh/web/ui/tests/test_utils.py
+++ b/swh/web/ui/tests/test_utils.py
@@ -476,6 +476,19 @@
call('api_entity_by_uuid',
uuid='uuid-parent')])
+ @nottest
+ def _url_for_context_test(self, fn, **data):
+ if fn == 'api_revision':
+ if 'context' in data and data['context'] is not None:
+ return '/api/revision/%s/prev/%s/' % (data['sha1_git'], data['context']) # noqa
+ else:
+ return '/api/revision/%s/' % data['sha1_git']
+ elif fn == 'api_revision_log':
+ if 'prev_sha1s' in data:
+ return '/api/revision/%s/prev/%s/log/' % (data['sha1_git'], data['prev_sha1s']) # noqa
+ else:
+ return '/api/revision/%s/log/' % data['sha1_git']
+
@patch('swh.web.ui.utils.flask')
@istest
def enrich_revision_without_children_or_parent(self, mock_flask):
@@ -500,8 +513,7 @@
'committer': {'id': '2'},
})
- # then
- self.assertEqual(actual_revision, {
+ expected_revision = {
'id': 'rev-id',
'directory': '123',
'url': '/api/revision/rev-id/',
@@ -511,18 +523,22 @@
'author_url': '/api/person/1/',
'committer': {'id': '2'},
'committer_url': '/api/person/2/'
- })
+ }
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
- mock_flask.url_for.assert_has_calls([call('api_revision',
- sha1_git='rev-id'),
- call('api_revision_log',
- sha1_git='rev-id'),
- call('api_person',
- person_id='1'),
- call('api_person',
- person_id='2'),
- call('api_directory',
- sha1_git='123')])
+ mock_flask.url_for.assert_has_calls(
+ [call('api_revision',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id'),
+ call('api_person',
+ person_id='1'),
+ call('api_person',
+ person_id='2'),
+ call('api_directory',
+ sha1_git='123')])
@patch('swh.web.ui.utils.flask')
@istest
@@ -530,12 +546,7 @@
mock_flask):
# given
def url_for_test(fn, **data):
- if fn == 'api_revision':
- return '/api/revision/' + data['sha1_git'] + '/'
- elif fn == 'api_revision_log':
- return '/api/revision/' + data['sha1_git'] + '/log/'
- else:
- return '/api/revision/' + data['sha1_git_root'] + '/history/' + data['sha1_git'] + '/' # noqa
+ return self._url_for_context_test(fn, **data)
mock_flask.url_for.side_effect = url_for_test
@@ -544,37 +555,179 @@
'id': 'rev-id',
'parents': ['123'],
'children': ['456'],
- }, context='sha1_git_root')
+ }, context='prev-rev')
- # then
- self.assertEqual(actual_revision, {
+ expected_revision = {
'id': 'rev-id',
'url': '/api/revision/rev-id/',
'history_url': '/api/revision/rev-id/log/',
+ 'history_context_url': '/api/revision/rev-id/prev/prev-rev/log/',
+ 'parents': ['123'],
+ 'parent_urls': ['/api/revision/123/prev/prev-rev/rev-id/'],
+ 'children': ['456'],
+ 'children_urls': ['/api/revision/456/',
+ '/api/revision/prev-rev/'],
+ }
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
+
+ mock_flask.url_for.assert_has_calls(
+ [call('api_revision',
+ sha1_git='prev-rev'),
+ call('api_revision',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id',
+ prev_sha1s='prev-rev'),
+ call('api_revision',
+ sha1_git='123',
+ context='prev-rev/rev-id'),
+ call('api_revision',
+ sha1_git='456')])
+
+ @patch('swh.web.ui.utils.flask')
+ @istest
+ def enrich_revision_no_context(self, mock_flask):
+ # given
+ def url_for_test(fn, **data):
+ return self._url_for_context_test(fn, **data)
+
+ mock_flask.url_for.side_effect = url_for_test
+
+ # when
+ actual_revision = utils.enrich_revision({
+ 'id': 'rev-id',
'parents': ['123'],
- 'parent_urls': ['/api/revision/sha1_git_root/history/123/'],
'children': ['456'],
- 'children_urls': ['/api/revision/sha1_git_root/history/456/'],
})
+ expected_revision = {
+ 'id': 'rev-id',
+ 'url': '/api/revision/rev-id/',
+ 'history_url': '/api/revision/rev-id/log/',
+ 'parents': ['123'],
+ 'parent_urls': ['/api/revision/123/prev/rev-id/'],
+ 'children': ['456'],
+ 'children_urls': ['/api/revision/456/']
+ }
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
+
+ mock_flask.url_for.assert_has_calls(
+ [call('api_revision',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id'),
+ call('api_revision',
+ sha1_git='123',
+ context='rev-id'),
+ call('api_revision',
+ sha1_git='456')])
+
+ @patch('swh.web.ui.utils.flask')
+ @istest
+ def enrich_revision_context_empty_prev_list(self, mock_flask):
+ # given
+ mock_flask.url_for.side_effect = self._url_for_context_test
+
+ # when
+ expected_revision = {
+ 'id': 'rev-id',
+ 'url': '/api/revision/rev-id/',
+ 'history_url': '/api/revision/rev-id/log/',
+ 'history_context_url': ('/api/revision/rev-id/'
+ 'prev/prev-rev/log/'),
+ 'parents': ['123'],
+ 'parent_urls': ['/api/revision/123/prev/prev-rev/rev-id/'],
+ 'children': ['456'],
+ 'children_urls': ['/api/revision/456/', '/api/revision/prev-rev/'],
+ }
+
+ actual_revision = utils.enrich_revision({
+ 'id': 'rev-id',
+ 'url': '/api/revision/rev-id/',
+ 'parents': ['123'],
+ 'children': ['456']}, context='prev-rev')
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
+ mock_flask.url_for.assert_has_calls(
+ [call('api_revision',
+ sha1_git='prev-rev'),
+ call('api_revision',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id'),
+ call('api_revision_log',
+ sha1_git='rev-id',
+ prev_sha1s='prev-rev'),
+ call('api_revision',
+ sha1_git='123',
+ context='prev-rev/rev-id'),
+ call('api_revision',
+ sha1_git='456')])
+
+ @patch('swh.web.ui.utils.flask')
+ @istest
+ def enrich_revision_context_some_prev_list(self, mock_flask):
+ # given
+ mock_flask.url_for.side_effect = self._url_for_context_test
+
+ # when
+ expected_revision = {
+ 'id': 'rev-id',
+ 'url': '/api/revision/rev-id/',
+ 'history_url': '/api/revision/rev-id/log/',
+ 'history_context_url': ('/api/revision/rev-id/'
+ 'prev/prev1-rev/prev0-rev/log/'),
+ 'parents': ['123'],
+ 'parent_urls': ['/api/revision/123/prev/'
+ 'prev1-rev/prev0-rev/rev-id/'],
+ 'children': ['456'],
+ 'children_urls': ['/api/revision/456/',
+ '/api/revision/prev0-rev/prev/prev1-rev/'],
+ }
+
+ actual_revision = utils.enrich_revision({
+ 'id': 'rev-id',
+ 'parents': ['123'],
+ 'children': ['456']}, context='prev1-rev/prev0-rev')
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
mock_flask.url_for.assert_has_calls(
[call('api_revision',
+ sha1_git='prev0-rev',
+ context='prev1-rev'),
+ call('api_revision',
sha1_git='rev-id'),
call('api_revision_log',
sha1_git='rev-id'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
- sha1_git='123'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
+ call('api_revision_log',
+ sha1_git='rev-id',
+ prev_sha1s='prev1-rev/prev0-rev'),
+ call('api_revision',
+ sha1_git='123',
+ context='prev1-rev/prev0-rev/rev-id'),
+ call('api_revision',
sha1_git='456')])
@nottest
def _url_for_rev_message_test(self, fn, **data):
if fn == 'api_revision':
- return '/api/revision/' + data['sha1_git'] + '/'
+ if 'context' in data and data['context'] is not None:
+ return '/api/revision/%s/prev/%s/' % (data['sha1_git'], data['context']) # noqa
+ else:
+ return '/api/revision/%s/' % data['sha1_git']
elif fn == 'api_revision_log':
- return '/api/revision/' + data['sha1_git'] + '/log/'
+ if 'prev_sha1s' in data and data['prev_sha1s'] is not None:
+ return '/api/revision/%s/prev/%s/log/' % (data['sha1_git'], data['prev_sha1s']) # noqa
+ else:
+ return '/api/revision/%s/log/' % data['sha1_git']
elif fn == 'api_revision_raw_message':
return '/api/revision/' + data['sha1_git'] + '/raw/'
else:
@@ -587,35 +740,43 @@
mock_flask.url_for.side_effect = self._url_for_rev_message_test
# when
- actual_revision = utils.enrich_revision({
+ expected_revision = {
'id': 'rev-id',
+ 'url': '/api/revision/rev-id/',
+ 'history_url': '/api/revision/rev-id/log/',
+ 'history_context_url': ('/api/revision/rev-id/'
+ 'prev/prev-rev/log/'),
'message': None,
'parents': ['123'],
+ 'parent_urls': ['/api/revision/123/prev/prev-rev/rev-id/'],
'children': ['456'],
- }, context='sha1_git_root')
+ 'children_urls': ['/api/revision/456/', '/api/revision/prev-rev/'],
+ }
- # then
- self.assertEqual(actual_revision, {
+ actual_revision = utils.enrich_revision({
'id': 'rev-id',
- 'url': '/api/revision/rev-id/',
'message': None,
- 'history_url': '/api/revision/rev-id/log/',
'parents': ['123'],
- 'parent_urls': ['/api/revision/sha1_git_root/history/123/'],
'children': ['456'],
- 'children_urls': ['/api/revision/sha1_git_root/history/456/'],
- })
+ }, context='prev-rev')
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
mock_flask.url_for.assert_has_calls(
[call('api_revision',
+ sha1_git='prev-rev'),
+ call('api_revision',
sha1_git='rev-id'),
call('api_revision_log',
sha1_git='rev-id'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
- sha1_git='123'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
+ call('api_revision_log',
+ sha1_git='rev-id',
+ prev_sha1s='prev-rev'),
+ call('api_revision',
+ sha1_git='123',
+ context='prev-rev/rev-id'),
+ call('api_revision',
sha1_git='456')])
@patch('swh.web.ui.utils.flask')
@@ -631,30 +792,38 @@
'message_decoding_failed': True,
'parents': ['123'],
'children': ['456'],
- }, context='sha1_git_root')
+ }, context='prev-rev')
- # then
- self.assertEqual(actual_revision, {
+ expected_revision = {
'id': 'rev-id',
'url': '/api/revision/rev-id/',
+ 'history_url': '/api/revision/rev-id/log/',
+ 'history_context_url': ('/api/revision/rev-id/'
+ 'prev/prev-rev/log/'),
'message': None,
'message_decoding_failed': True,
'message_url': '/api/revision/rev-id/raw/',
- 'history_url': '/api/revision/rev-id/log/',
'parents': ['123'],
- 'parent_urls': ['/api/revision/sha1_git_root/history/123/'],
+ 'parent_urls': ['/api/revision/123/prev/prev-rev/rev-id/'],
'children': ['456'],
- 'children_urls': ['/api/revision/sha1_git_root/history/456/'],
- })
+ 'children_urls': ['/api/revision/456/', '/api/revision/prev-rev/'],
+ }
+
+ # then
+ self.assertEqual(actual_revision, expected_revision)
mock_flask.url_for.assert_has_calls(
[call('api_revision',
+ sha1_git='prev-rev'),
+ call('api_revision',
sha1_git='rev-id'),
call('api_revision_log',
sha1_git='rev-id'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
- sha1_git='123'),
- call('api_revision_history',
- sha1_git_root='sha1_git_root',
+ call('api_revision_log',
+ sha1_git='rev-id',
+ prev_sha1s='prev-rev'),
+ call('api_revision',
+ sha1_git='123',
+ context='prev-rev/rev-id'),
+ call('api_revision',
sha1_git='456')])
diff --git a/swh/web/ui/tests/views/test_api.py b/swh/web/ui/tests/views/test_api.py
--- a/swh/web/ui/tests/views/test_api.py
+++ b/swh/web/ui/tests/views/test_api.py
@@ -679,8 +679,8 @@
'8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'
],
'parent_urls': [
- '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5'
- '/history/8734ef7e7c357ce2af928115c6c6a42b7e2a44e7/'
+ '/api/1/revision/8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'
+ '/prev/18d8be353ed3480476f032475e7c233eff7371d5/'
],
'type': 'tar',
'synthetic': True,
@@ -1416,8 +1416,8 @@
'7834ef7e7c357ce2af928115c6c6a42b7e2a4345'
],
'parent_urls': [
- '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5'
- '/history/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/'
+ '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345'
+ '/prev/18d8be353ed3480476f032475e7c233eff7371d5/'
],
'type': 'tar',
'synthetic': True,
@@ -1521,8 +1521,8 @@
'committer_date_offset': 0,
'parents': ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'],
'parent_urls': [
- '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'
- '/history/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc/'
+ '/api/1/revision/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'
+ '/prev/7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/'
],
'type': 'tar',
'synthetic': True,
@@ -1545,8 +1545,8 @@
'committer_date_offset': 0,
'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'],
'parent_urls': [
- '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5'
- '/history/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/'
+ '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345'
+ '/prev/18d8be353ed3480476f032475e7c233eff7371d5/'
],
'type': 'tar',
'synthetic': True,
@@ -1596,8 +1596,8 @@
'7834ef7e7c357ce2af928115c6c6a42b7e2a4345'
],
'parent_urls': [
- '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5'
- '/history/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/'
+ '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345'
+ '/prev/18d8be353ed3480476f032475e7c233eff7371d5/'
],
'type': 'tar',
'synthetic': True,
@@ -1680,10 +1680,10 @@
'directory': '272'
}
- mock_service.lookup_revision_with_context.return_value = stub_revision
+ mock_service.lookup_revision.return_value = stub_revision
# then
- rv = self.app.get('/api/1/revision/666/history/883/')
+ rv = self.app.get('/api/1/revision/883/prev/999/')
self.assertEquals(rv.status_code, 200)
self.assertEquals(rv.mimetype, 'application/json')
@@ -1693,17 +1693,17 @@
'id': '883',
'url': '/api/1/revision/883/',
'history_url': '/api/1/revision/883/log/',
+ 'history_context_url': '/api/1/revision/883/prev/999/log/',
'children': ['777', '999'],
- 'children_urls': ['/api/1/revision/666/history/777/',
- '/api/1/revision/666/history/999/'],
+ 'children_urls': ['/api/1/revision/777/',
+ '/api/1/revision/999/'],
'parents': [],
'parent_urls': [],
'directory': '272',
'directory_url': '/api/1/directory/272/'
})
- mock_service.lookup_revision_with_context.assert_called_once_with(
- '666', '883', 100)
+ mock_service.lookup_revision.assert_called_once_with('883')
@patch('swh.web.ui.views.api._revision_directory_by')
@istest
diff --git a/swh/web/ui/tests/views/test_browse.py b/swh/web/ui/tests/views/test_browse.py
--- a/swh/web/ui/tests/views/test_browse.py
+++ b/swh/web/ui/tests/views/test_browse.py
@@ -760,7 +760,7 @@
'Not found!')
self.assertIsNone(self.get_context_variable('revision'))
- mock_api.api_revision.assert_called_once_with('1')
+ mock_api.api_revision.assert_called_once_with('1', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -780,7 +780,7 @@
'wrong input!')
self.assertIsNone(self.get_context_variable('revision'))
- mock_api.api_revision.assert_called_once_with('426')
+ mock_api.api_revision.assert_called_once_with('426', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -842,7 +842,7 @@
expected_revision)
self.assertIsNone(self.get_context_variable('message'))
- mock_api.api_revision.assert_called_once_with('426')
+ mock_api.api_revision.assert_called_once_with('426', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -875,7 +875,7 @@
'Not found!')
self.assertEqual(self.get_context_variable('revisions'), [])
- mock_api.api_revision_log.assert_called_once_with('sha1')
+ mock_api.api_revision_log.assert_called_once_with('sha1', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -895,7 +895,7 @@
'wrong input!')
self.assertEqual(self.get_context_variable('revisions'), [])
- mock_api.api_revision_log.assert_called_once_with('426')
+ mock_api.api_revision_log.assert_called_once_with('426', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -935,7 +935,7 @@
isinstance(self.get_context_variable('revisions'), map))
self.assertIsNone(self.get_context_variable('message'))
- mock_api.api_revision_log.assert_called_once_with('426')
+ mock_api.api_revision_log.assert_called_once_with('426', None)
@patch('swh.web.ui.views.browse.api')
@istest
@@ -976,7 +976,7 @@
'wrong input!')
self.assertEqual(self.get_context_variable('revisions'), [])
- mock_api.api_revision_log.assert_called_once_with('abcd')
+ mock_api.api_revision_log.assert_called_once_with('abcd', None)
@patch('swh.web.ui.views.browse.api')
@istest
diff --git a/swh/web/ui/utils.py b/swh/web/ui/utils.py
--- a/swh/web/ui/utils.py
+++ b/swh/web/ui/utils.py
@@ -200,14 +200,45 @@
def enrich_revision(revision, context=None):
"""Enrich revision with links where it makes sense (directory, parents).
+ Keep track of the navigation breadcrumbs if they are specified.
+ Args:
+ revision: the revision as a dict
+ context: the navigation breadcrumbs as a /-separated string of revision
+ sha1_git
"""
+
+ context_for_parents = None
+ context_for_children = None
+ url_immediate_child = None
+
if not context:
- context = revision['id']
+ context_for_parents = revision['id']
+ else:
+ context_for_parents = '%s/%s' % (context, revision['id'])
+ prev_for_children = context.split('/')[:-1]
+ if len(prev_for_children) > 0:
+ context_for_children = '/'.join(prev_for_children)
+ # This commit is not the first commit in the path
+ if context_for_children:
+ url_immediate_child = flask.url_for(
+ 'api_revision',
+ sha1_git=context.split('/')[-1],
+ context=context_for_children)
+ # This commit is the first commit in the path
+ else:
+ url_immediate_child = flask.url_for(
+ 'api_revision',
+ sha1_git=context.split('/')[-1])
revision['url'] = flask.url_for('api_revision', sha1_git=revision['id'])
revision['history_url'] = flask.url_for('api_revision_log',
sha1_git=revision['id'])
+ if context is not None:
+ revision['history_context_url'] = flask.url_for(
+ 'api_revision_log',
+ sha1_git=revision['id'],
+ prev_sha1s=context)
if 'author' in revision:
author = revision['author']
@@ -227,21 +258,30 @@
if 'parents' in revision:
parents = []
for parent in revision['parents']:
- parents.append(flask.url_for('api_revision_history',
- sha1_git_root=context,
- sha1_git=parent))
-
+ parents.append(flask.url_for('api_revision',
+ sha1_git=parent,
+ context=context_for_parents))
revision['parent_urls'] = parents
if 'children' in revision:
children = []
for child in revision['children']:
- children.append(flask.url_for('api_revision_history',
- sha1_git_root=context,
- sha1_git=child))
-
+ # child not the breadcrumb-indicated child > new breadcrumb start
+ if context:
+ if child != context.split('/')[-1]:
+ children.append(flask.url_for('api_revision',
+ sha1_git=child))
+ else:
+ children.append(flask.url_for('api_revision', sha1_git=child))
+
+ if url_immediate_child:
+ children.append(url_immediate_child)
revision['children_urls'] = children
+ else:
+ if url_immediate_child:
+ revision['children_urls'] = [url_immediate_child]
+
if 'message_decoding_failed' in revision:
revision['message_url'] = flask.url_for(
'api_revision_raw_message',
diff --git a/swh/web/ui/views/api.py b/swh/web/ui/views/api.py
--- a/swh/web/ui/views/api.py
+++ b/swh/web/ui/views/api.py
@@ -507,7 +507,8 @@
@app.route('/api/1/revision/')
@app.route('/api/1/revision/<string:sha1_git>/')
-def api_revision(sha1_git):
+@app.route('/api/1/revision/<string:sha1_git>/prev/<path:context>/')
+def api_revision(sha1_git, context=None):
"""Return information about revision with id sha1_git.
Args:
@@ -522,14 +523,13 @@
Example:
GET /api/1/revision/baf18f9fc50a0b6fef50460a76c33b2ddc57486e
-
"""
- return _api_lookup(
- sha1_git,
- lookup_fn=service.lookup_revision,
- error_msg_if_not_found='Revision with sha1_git %s not'
- ' found.' % sha1_git,
- enrich_fn=utils.enrich_revision)
+
+ revision = service.lookup_revision(sha1_git)
+ if not revision:
+ error_msg = 'Revision with sha1_git %s not found.' % sha1_git
+ raise NotFoundExc(error_msg)
+ return utils.enrich_revision(revision, context=context)
@app.route('/api/1/revision/<string:sha1_git>/raw/')
diff --git a/swh/web/ui/views/browse.py b/swh/web/ui/views/browse.py
--- a/swh/web/ui/views/browse.py
+++ b/swh/web/ui/views/browse.py
@@ -298,17 +298,32 @@
@app.route('/browse/revision/')
@app.route('/browse/revision/<string:sha1_git>/')
+@app.route('/browse/revision/<string:sha1_git>/prev/<path:prev_sha1s>/')
@set_renderers(HTMLRenderer)
-def browse_revision(sha1_git):
- """Browse revision with sha1_git.
+def browse_revision(sha1_git, prev_sha1s=None):
+ """Browse the revision with git SHA1 sha1_git_cur, while optionally keeping
+ the context from which we came as a list of previous (i.e. later)
+ revisions' sha1s.
+ Args:
+ sha1_git: the requested revision's sha1_git.
+ prev_sha1s: an optional string of /-separated sha1s representing our
+ context, ordered by descending revision date.
+
+ Returns:
+ Information about revision of git SHA1 sha1_git_cur, with relevant URLS
+ pointing to the context augmented with sha1_git_cur.
+
+ Example:
+ GET /browse/revision/
"""
+
env = {'sha1_git': sha1_git,
'message': None,
'revision': None}
try:
- rev = api.api_revision(sha1_git)
+ rev = api.api_revision(sha1_git, prev_sha1s)
env['revision'] = utils.prepare_data_for_view(rev)
except (NotFoundExc, BadInputExc) as e:
env['message'] = str(e)
@@ -325,10 +340,16 @@
@app.route('/browse/revision/<string:sha1_git>/log/')
+@app.route('/browse/revision/<string:sha1_git>/prev/<path:prev_sha1s>/log/')
@set_renderers(HTMLRenderer)
-def browse_revision_log(sha1_git):
- """Browse revision with sha1_git's log.
+def browse_revision_log(sha1_git, prev_sha1s=None):
+ """Browse revision with sha1_git's log. If the navigation path throught the
+ commit tree is specified, we intersect the earliest revision's log with the
+ revisions the user browsed through (ie his path) to the specified revision.
+ Args:
+ sha1_git: the current revision's SHA1_git checksum
+ prev_sha1s: optionally, the path through which we want log information
"""
env = {'sha1_git': sha1_git,
'sha1_url': '/browse/revision/%s/' % sha1_git,
@@ -336,7 +357,7 @@
'revisions': []}
try:
- revisions = api.api_revision_log(sha1_git)
+ revisions = api.api_revision_log(sha1_git, prev_sha1s)
env['revisions'] = map(utils.prepare_data_for_view, revisions)
except (NotFoundExc, BadInputExc) as e:
env['message'] = str(e)
@@ -392,6 +413,40 @@
return render_template('revision-log.html', **env)
+@app.route('/browse/revision/<string:sha1_git_cur>/prev/<path:sha1s>/')
+@set_renderers(HTMLRenderer)
+def browse_with_rev_context(sha1_git_cur, sha1s):
+ """Browse the revision with git SHA1 sha1_git_cur, while keeping the context
+ from which we came as a list of previous (i.e. later) revisions' sha1s.
+
+ Args:
+ sha1_git_cur: the requested revision's sha1_git.
+ sha1s: a string of /-separated sha1s representing our context, ordered
+ by descending revision date.
+
+ Returns:
+ Information about revision of git SHA1 sha1_git_cur, with relevant URLS
+ pointing to the context augmented with sha1_git_cur.
+
+ Example:
+ GET /browse/revision/
+ """
+ # in service: change enrichment function to prepare data with context
+
+ env = {'sha1_git': sha1_git_cur,
+ 'message': None,
+ 'revision': None}
+
+ try:
+ revision = api.api_revision(
+ sha1_git_cur, '%s' % sha1s)
+ env['revision'] = utils.prepare_data_for_view(revision)
+ except (BadInputExc, NotFoundExc) as e:
+ env['message'] = str(e)
+
+ return render_template('revision.html', **env)
+
+
@app.route('/browse/revision/<string:sha1_git_root>/history/<sha1_git>/')
@set_renderers(HTMLRenderer)
def browse_revision_history(sha1_git_root, sha1_git):
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Dec 17, 2:54 PM (2 d, 21 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3227234
Attached To
D66: Add navigation breadcrumbs for contextual revision browsing
Event Timeline
Log In to Comment