Merge lp:~maxiberta/launchpad/git-get-blob-unexport-api into lp:launchpad

Proposed by Maximiliano Bertacchini
Status: Merged
Approved by: Colin Watson
Approved revision: no longer in the source branch.
Merged at revision: 18018
Proposed branch: lp:~maxiberta/launchpad/git-get-blob-unexport-api
Merge into: lp:launchpad
Diff against target: 165 lines (+54/-30)
5 files modified
lib/lp/code/interfaces/githosting.py (+1/-1)
lib/lp/code/interfaces/gitrepository.py (+1/-9)
lib/lp/code/model/githosting.py (+7/-1)
lib/lp/code/model/tests/test_githosting.py (+41/-7)
lib/lp/code/model/tests/test_gitrepository.py (+4/-12)
To merge this branch: bzr merge lp:~maxiberta/launchpad/git-get-blob-unexport-api
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+293637@code.launchpad.net

Commit message

Unexport GitRepository.getBlob(); return a binary blob instead of dict.

Description of the change

Unexport GitRepository.getBlob(); return a binary blob instead of dict.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Needs Fixing
Revision history for this message
Colin Watson (cjwatson) wrote :

Looks better now, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/interfaces/githosting.py'
--- lib/lp/code/interfaces/githosting.py 2016-04-29 22:06:11 +0000
+++ lib/lp/code/interfaces/githosting.py 2016-05-03 18:43:05 +0000
@@ -96,5 +96,5 @@
96 :param filename: Relative path of a file in the repository.96 :param filename: Relative path of a file in the repository.
97 :param rev: An optional revision. Defaults to 'HEAD'.97 :param rev: An optional revision. Defaults to 'HEAD'.
98 :param logger: An optional logger.98 :param logger: An optional logger.
99 :return: A dict with keys 'data' and 'size'.99 :return: A binary string with the blob content.
100 """100 """
101101
=== modified file 'lib/lp/code/interfaces/gitrepository.py'
--- lib/lp/code/interfaces/gitrepository.py 2016-04-29 15:17:20 +0000
+++ lib/lp/code/interfaces/gitrepository.py 2016-05-03 18:43:05 +0000
@@ -533,20 +533,12 @@
533 :param logger: An optional logger.533 :param logger: An optional logger.
534 """534 """
535535
536 @operation_parameters(
537 filename=TextLine(
538 title=_("Relative path of file in the repository."),
539 required=True),
540 rev=TextLine(title=_("An optional revision. Defaults to 'HEAD'.")),
541 )
542 @export_read_operation()
543 @operation_for_version("devel")
544 def getBlob(filename, rev=None):536 def getBlob(filename, rev=None):
545 """Get a blob by file name from this repository.537 """Get a blob by file name from this repository.
546538
547 :param filename: Relative path of a file in the repository.539 :param filename: Relative path of a file in the repository.
548 :param rev: An optional revision. Defaults to 'HEAD'.540 :param rev: An optional revision. Defaults to 'HEAD'.
549 :return: A dict with keys 'data' and 'size'.541 :return: A binary string with the blob content.
550 """542 """
551543
552544
553545
=== modified file 'lib/lp/code/model/githosting.py'
--- lib/lp/code/model/githosting.py 2016-04-29 22:06:11 +0000
+++ lib/lp/code/model/githosting.py 2016-05-03 18:43:05 +0000
@@ -155,7 +155,13 @@
155 logger.info(155 logger.info(
156 "Fetching file %s from repository %s" % (filename, path))156 "Fetching file %s from repository %s" % (filename, path))
157 url = "/repo/%s/blob/%s" % (path, quote(filename))157 url = "/repo/%s/blob/%s" % (path, quote(filename))
158 return self._get(url, params={"rev": rev})158 response = self._get(url, params={"rev": rev})
159 blob = response["data"].decode("base64")
160 if len(blob) != response["size"]:
161 raise GitRepositoryScanFault(
162 "Unexpected size (%s vs %s)" % (
163 len(blob), response["size"]))
164 return blob
159 except Exception as e:165 except Exception as e:
160 raise GitRepositoryScanFault(166 raise GitRepositoryScanFault(
161 "Failed to get file from Git repository: %s" % unicode(e))167 "Failed to get file from Git repository: %s" % unicode(e))
162168
=== modified file 'lib/lp/code/model/tests/test_githosting.py'
--- lib/lp/code/model/tests/test_githosting.py 2016-04-29 22:06:11 +0000
+++ lib/lp/code/model/tests/test_githosting.py 2016-05-03 18:43:05 +0000
@@ -185,20 +185,20 @@
185 self.client.delete, "123")185 self.client.delete, "123")
186186
187 def test_getBlob(self):187 def test_getBlob(self):
188 blob = b''.join(chr(i) for i in range(256)).encode("base64")188 blob = b''.join(chr(i) for i in range(256))
189 content = {"data": blob, "size": len(blob)}189 content = {"data": blob.encode("base64"), "size": len(blob)}
190 with self.mockRequests(content=json.dumps(content)):190 with self.mockRequests(content=json.dumps(content)):
191 response = self.client.getBlob("123", "dir/path/file/name")191 response = self.client.getBlob("123", "dir/path/file/name")
192 self.assertEqual(content, response)192 self.assertEqual(blob, response)
193 self.assertRequest(193 self.assertRequest(
194 "repo/123/blob/dir/path/file/name", method="GET")194 "repo/123/blob/dir/path/file/name", method="GET")
195195
196 def test_getBlob_revision(self):196 def test_getBlob_revision(self):
197 blob = b''.join(chr(i) for i in range(256)).encode("base64")197 blob = b''.join(chr(i) for i in range(256))
198 content = {"data": blob, "size": len(blob)}198 content = {"data": blob.encode("base64"), "size": len(blob)}
199 with self.mockRequests(content=json.dumps(content)):199 with self.mockRequests(content=json.dumps(content)):
200 response = self.client.getBlob("123", "dir/path/file/name", "dev")200 response = self.client.getBlob("123", "dir/path/file/name", "dev")
201 self.assertEqual(content, response)201 self.assertEqual(blob, response)
202 self.assertRequest(202 self.assertRequest(
203 "repo/123/blob/dir/path/file/name?rev=dev", method="GET")203 "repo/123/blob/dir/path/file/name?rev=dev", method="GET")
204204
@@ -210,8 +210,42 @@
210 self.client.getBlob, "123", "dir/path/file/name")210 self.client.getBlob, "123", "dir/path/file/name")
211211
212 def test_getBlob_url_quoting(self):212 def test_getBlob_url_quoting(self):
213 with self.mockRequests():213 blob = b''.join(chr(i) for i in range(256))
214 content = {"data": blob.encode("base64"), "size": len(blob)}
215 with self.mockRequests(content=json.dumps(content)):
214 self.client.getBlob("123", "dir/+file name?.txt", "+rev/ no?")216 self.client.getBlob("123", "dir/+file name?.txt", "+rev/ no?")
215 self.assertRequest(217 self.assertRequest(
216 "repo/123/blob/dir/%2Bfile%20name%3F.txt?rev=%2Brev%2F+no%3F",218 "repo/123/blob/dir/%2Bfile%20name%3F.txt?rev=%2Brev%2F+no%3F",
217 method="GET")219 method="GET")
220
221 def test_getBlob_no_data(self):
222 with self.mockRequests(content=json.dumps({"size": 1})):
223 self.assertRaisesWithContent(
224 GitRepositoryScanFault,
225 "Failed to get file from Git repository: 'data'",
226 self.client.getBlob, "123", "dir/path/file/name")
227
228 def test_getBlob_no_size(self):
229 with self.mockRequests(content=json.dumps({"data": "data"})):
230 self.assertRaisesWithContent(
231 GitRepositoryScanFault,
232 "Failed to get file from Git repository: 'size'",
233 self.client.getBlob, "123", "dir/path/file/name")
234
235 def test_getBlob_bad_encoding(self):
236 content = {"data": "x", "size": 1}
237 with self.mockRequests(content=json.dumps(content)):
238 self.assertRaisesWithContent(
239 GitRepositoryScanFault,
240 "Failed to get file from Git repository: Incorrect padding",
241 self.client.getBlob, "123", "dir/path/file/name")
242
243 def test_getBlob_wrong_size(self):
244 blob = b''.join(chr(i) for i in range(256))
245 content = {"data": blob.encode("base64"), "size": 0}
246 with self.mockRequests(content=json.dumps(content)):
247 self.assertRaisesWithContent(
248 GitRepositoryScanFault,
249 "Failed to get file from Git repository: Unexpected size"
250 " (256 vs 0)",
251 self.client.getBlob, "123", "dir/path/file/name")
218252
=== modified file 'lib/lp/code/model/tests/test_gitrepository.py'
--- lib/lp/code/model/tests/test_gitrepository.py 2016-04-29 22:06:11 +0000
+++ lib/lp/code/model/tests/test_gitrepository.py 2016-05-03 18:43:05 +0000
@@ -2041,26 +2041,18 @@
2041 def test_getBlob_with_default_rev(self):2041 def test_getBlob_with_default_rev(self):
2042 repository = self.factory.makeGitRepository()2042 repository = self.factory.makeGitRepository()
2043 hosting_client = FakeMethod()2043 hosting_client = FakeMethod()
2044 expected_result = {2044 hosting_client.getBlob = FakeMethod(result='Some text')
2045 'data': u'Some text'.encode('base64'),
2046 'size': len(u'Some Text'),
2047 }
2048 hosting_client.getBlob = FakeMethod(result=expected_result)
2049 self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient))2045 self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient))
2050 ret = repository.getBlob('src/README.txt')2046 ret = repository.getBlob('src/README.txt')
2051 self.assertEqual(expected_result, ret)2047 self.assertEqual('Some text', ret)
20522048
2053 def test_getBlob_with_rev(self):2049 def test_getBlob_with_rev(self):
2054 repository = self.factory.makeGitRepository()2050 repository = self.factory.makeGitRepository()
2055 hosting_client = FakeMethod()2051 hosting_client = FakeMethod()
2056 expected_result = {2052 hosting_client.getBlob = FakeMethod(result='Some text')
2057 'data': u'Some text'.encode('base64'),
2058 'size': len(u'Some Text'),
2059 }
2060 hosting_client.getBlob = FakeMethod(result=expected_result)
2061 self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient))2053 self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient))
2062 ret = repository.getBlob('src/README.txt', 'some-rev')2054 ret = repository.getBlob('src/README.txt', 'some-rev')
2063 self.assertEqual(expected_result, ret)2055 self.assertEqual('Some text', ret)
20642056
20652057
2066class TestGitRepositorySet(TestCaseWithFactory):2058class TestGitRepositorySet(TestCaseWithFactory):