Add support for Gerrit as a hosting service
Review Request #8938 — Created May 10, 2017 and submitted
This patch adds support for Gerrit as a hosting service when the Gerrit
server has thegerrit-reviewboard
plugin installed (see: /r/8919/ et
al.). The Gerrit API does not provide sufficient information (e.g., it
cannot retrieve files by blob ID, cannot list commits, and cannot
retrieve diffs for arbitrary commits not related to changes), so we rely
on the plugin for this. This hosting service will check for the plugin's
presence via the Gerrit API and will not allow repositories without it
installed.
- Tested post-commit review request creation.
- Tested
rbt post
with a Gerrit-backed repository. - Ran unit tests.
Description | From | Last Updated |
---|---|---|
F401 'reviewboard.scmtools.errors.SCMError' imported but unused |
reviewbot | |
F401 'hashlib' imported but unused |
reviewbot | |
F401 'hmac' imported but unused |
reviewbot | |
F401 'json' imported but unused |
reviewbot | |
F401 'hashlib.md5' imported but unused |
reviewbot | |
F401 'textwrap.dedent' imported but unused |
reviewbot | |
F401 'django.core.exceptions.ObjectDoesNotExist' imported but unused |
reviewbot | |
F401 'django.utils.six' imported but unused |
reviewbot | |
F401 'django.utils.six.moves.cStringIO as StringIO' imported but unused |
reviewbot | |
F401 'django.utils.six.moves.urllib.error.HTTPError' imported but unused |
reviewbot | |
F401 'django.utils.six.moves.urllib.parse.urlparse' imported but unused |
reviewbot | |
F401 'djblets.testing.decorators.add_fixtures' imported but unused |
reviewbot | |
F401 'reviewboard.hostingsvcs.gerrit.Gerrit' imported but unused |
reviewbot | |
F401 'reviewboard.hostingsvcs.models.HostingServiceAccount' imported but unused |
reviewbot | |
E303 too many blank lines (2) |
reviewbot | |
E128 continuation line under-indented for visual indent |
reviewbot | |
E128 continuation line under-indented for visual indent |
reviewbot | |
E128 continuation line under-indented for visual indent |
reviewbot | |
E501 line too long (84 > 79 characters) |
reviewbot | |
E126 continuation line over-indented for hanging indent |
reviewbot | |
"subclasses" |
chipx86 | |
I think you meant "hosting account"? |
chipx86 | |
t comes after s. |
david | |
Wrap in parens instead of using the continuation character. |
david | |
The Meta class should come last in the form. |
chipx86 | |
The > can be inside the <tt>. In other words, one <tt> should be fine. |
chipx86 | |
Here too. |
chipx86 | |
Missing : after :py:meth. |
chipx86 | |
"hostingsvcs" |
chipx86 | |
"project form?" |
chipx86 | |
Seems like this should maybe be "Gerrit URL"? |
chipx86 | |
This is missing help text. |
chipx86 | |
This should be "Project name". It's also missing help text. |
chipx86 | |
Wrap this error in _()? |
david | |
The error should be less terse. Maybe "This is not a valid port. Ports must be in the range of … |
chipx86 | |
Might read better as "The only required part is the FQDN ... |
chipx86 | |
typo: ot |
david | |
Looks like this could be one line? |
chipx86 | |
This can be one statement. |
chipx86 | |
What happens if this changes in the future? Think we should code defensively here. If the data doesn't include this, … |
chipx86 | |
We only use this in one error message that's only called when configuring a repository, so let's do that there … |
chipx86 | |
Probably belongs up with form. |
chipx86 | |
This is the default. |
chipx86 | |
You don't have to provide this argument. It will be captured by kwargs. |
chipx86 | |
No need to provide this either. |
chipx86 | |
Missing , optional. |
chipx86 | |
Missing , optional. |
chipx86 | |
Needs the full class path. |
chipx86 | |
e should be passed in as another arg, since the logger functions do their own format operation. |
david | |
Ideally we should flesh this out. "Unable to authenticate with Gerrit. The username or password might be invalid." It's best … |
chipx86 | |
Missing docs. |
chipx86 | |
We should be using encrypt_password and decrypt_password for any credentials being stored. |
chipx86 | |
Typo: "reviewbaord" -> "reviewboard" |
chipx86 | |
This can only be done if we're shipping this with 3.0. We still support Python 2.6 for Review Board 2.5. |
chipx86 | |
I'd suggest following GitHub's model and defining an api_get that does the common stuff (passing credentials and only returning the … |
chipx86 | |
I am left in suspense. |
chipx86 | |
Historically, this function comes before the rest of the overriden functions (this, then authorize, then the rest). |
chipx86 | |
Typo: "reviewbaord" -> "reviewboard" |
chipx86 | |
You can do: parts = [ ... ] + rest_parts |
chipx86 | |
Better formatted as: url = ('%s/' % urljoin(...)) I believe that will fit on two lines. Maybe three, if you … |
chipx86 | |
Should be one statement. |
chipx86 | |
Can you add two blank lines between these? |
david | |
Undo this change. |
david | |
Undo this change. |
david | |
Undo this change. |
david | |
Undo this change. The .closest is part of the whole selector process. The .setVisible is the thing we're calling on … |
chipx86 | |
Can you add two blank lines between these? |
david | |
E999 SyntaxError: invalid syntax |
reviewbot | |
E501 line too long (80 > 79 characters) |
reviewbot | |
E303 too many blank lines (2) |
reviewbot | |
E303 too many blank lines (2) |
reviewbot | |
W391 blank line at end of file |
reviewbot | |
This should go after all the django.utils.six imports |
david | |
Use parens instead of \ |
david | |
Trailing comma isn't necessary since these are just args. ) can be on this line too. |
david | |
Should be marked for translation. |
david | |
Should be marked for translation. |
david | |
Should end in a period to match the others. |
david | |
Instead of implementing a custom clean method you should be able to just pass in min_value and max_value to the … |
david | |
Other implementations call this arg hosting_service |
david | |
typo: ot |
david | |
Comma after "Otherwise" |
david | |
The string included in the comment here doesn't match the code. |
david | |
The implementation of _parse_plugin_version could raise exceptions if we get something unexpected from the server. Can we try/catch and convert … |
david | |
Blank line after this. |
david | |
Add two blank lines after this. |
david | |
Undo this change. Maybe wrap the whole thing in parens too? |
david | |
Undo this change. |
david | |
Undo this change. |
david | |
Undo this change. |
david | |
Undo this change. |
david | |
Add two blank lines before this. |
david | |
F401 'django.core.exceptions.ValidationError' imported but unused |
reviewbot | |
E203 whitespace before ':' |
reviewbot | |
E231 missing whitespace after ':' |
reviewbot | |
E701 multiple statements on one line (colon) |
reviewbot | |
E999 SyntaxError: invalid syntax |
reviewbot | |
We should probably assert that gerrit_url is not None here. |
david | |
Leftover debug output? |
david | |
Leftover debug output? |
david | |
I think this would be more readable if we split it up a bit: url = urljoin(repository.extra_data['gerrit_url'], '/'.join(parts)) if query: … |
david | |
Why this change? |
david | |
Blank line after this. |
david | |
So in python 3, json.dumps requires that all the keys and values be str. I think instead of having a … |
david | |
Same here. |
david | |
And here. |
david | |
And here. |
david | |
And here. |
david | |
Blank line after this. |
david | |
And here. |
david | |
E131 continuation line unaligned for hanging indent |
reviewbot | |
Because we know the format, this would be a lot more readable as: 'required': '%d.%d.%d' % self.REQUIRED_PLUGIN_VERSION, |
david | |
Please pass in e as an arg to logging.error instead of pre-formatting it. |
david | |
This should fit on one line. |
david | |
This can just use + instead of extend |
david | |
F401 'django.utils.six' imported but unused |
reviewbot | |
Swap these. |
chipx86 | |
Should be in alphabetical order. |
chipx86 | |
I know the base implementation doesn't do anything, but it might in the future. Let's call the parent method here. |
chipx86 | |
"to the" |
chipx86 | |
We should specify the URL here (first argument in *args), since we otherwise don't have enough information to figure out … |
chipx86 | |
Can we have a module-level logger? |
chipx86 | |
"Source code" |
chipx86 | |
Mind linking to the URL here? |
chipx86 | |
No need for the backtick when using a reference without a space in the name. |
chipx86 | |
"Gerrit" |
chipx86 | |
The ] shouldn't be here. |
chipx86 | |
We should link to the URL for the repository in this message. We can then provide instructions in that repository's … |
chipx86 | |
This can fit on one line. |
chipx86 | |
We should specify the repository ID here, since we otherwise don't have enough information to debug problems. |
chipx86 | |
Keyword arguments should ideally be used in localized text when there's more than one variable being injected. Helps with translations … |
chipx86 | |
The dictionary should be expanded. |
chipx86 | |
Same here. |
chipx86 | |
We should specify the URL here, since we otherwise don't have enough information to debug problems. |
chipx86 | |
Missing gettext. |
chipx86 | |
Missing gettext. |
chipx86 | |
The dictionary should be expanded. |
chipx86 | |
Same here. |
chipx86 | |
Parens around the equality check. |
chipx86 | |
Missing gettext. |
chipx86 | |
Missing gettext. |
chipx86 | |
Same here. |
chipx86 | |
Same here. |
chipx86 | |
gettext |
chipx86 | |
Can we catch an exception here and handle it gracefully, in case something goes wonky with the response? |
chipx86 | |
Same here. |
chipx86 | |
We should specify the repository ID here, since we otherwise don't have enough information to debug problems. |
chipx86 | |
We should ideally use keywords for the format string here. |
chipx86 | |
Same here. |
chipx86 | |
Can you place arguments starting right after Commit(? These aren't long enough to require wrapping. |
chipx86 | |
Same here. |
chipx86 | |
Should use +=. It's faster. Or just + on the previous line. |
chipx86 | |
Alphabetical order. |
chipx86 | |
Alphabetical order. |
chipx86 | |
Private methods go last. |
chipx86 | |
You can start after Repository( |
chipx86 | |
This shouldn't be necessary on Gerrit. Same with other calls in this file. |
chipx86 | |
The parens aren't necessary in JavaScript. |
chipx86 | |
E501 line too long (82 > 79 characters) |
reviewbot | |
E501 line too long (92 > 79 characters) |
reviewbot | |
E501 line too long (81 > 79 characters) |
reviewbot | |
E127 continuation line over-indented for visual indent |
reviewbot | |
W391 blank line at end of file |
reviewbot | |
E501 line too long (92 > 79 characters) |
reviewbot | |
E501 line too long (92 > 79 characters) |
reviewbot | |
E501 line too long (92 > 79 characters) |
reviewbot | |
I just realized this isn't going to work. e.read() makes no sense for a b64decode. The error isn't really descriptive … |
chipx86 | |
This needs to be unfolded as well. |
chipx86 |
- Change Summary:
-
Unit tests.
- Summary:
-
WIP: Gerrit SupportAdd support for Gerrit as a hosting service
- Description:
-
~ WIP
~ This patch adds support for Gerrit as a hosting service when the Gerrit
+ server has the gerrit-reviewboard
plugin installed (see: /r/8919/ et+ al.). The Gerrit API does not provide sufficient information (e.g., it + cannot retrieve files by blob ID, cannot list commits, and cannot + retrieve diffs for arbitrary commits not related to changes), so we rely + on the plugin for this. This hosting service will check for the plugin's + presence via the Gerrit API and will not allow repositories without it + installed. - Testing Done:
-
+ - Tested post-commit review request creation.
+ - Tested
rbt post
with a Gerrit-backed repository.
+ - Ran unit tests.
Checks run (1 failed, 1 succeeded)
flake8
-
-
-
-
-
-
-
-
-
-
-
-
-
The error should be less terse. Maybe "This is not a valid port. Ports must be in the range of 0-65535."
-
-
-
-
What happens if this changes in the future? Think we should code defensively here. If the data doesn't include this, log it and return the data as-is. Might also want to make the
\n
optional, as that seems like an easy thing that can change. -
We only use this in one error message that's only called when configuring a repository, so let's do that there instead.
-
-
-
-
-
-
-
-
Ideally we should flesh this out. "Unable to authenticate with Gerrit. The username or password might be invalid."
It's best to avoid overly terse errors that look like they came from Posix libraries.
-
-
-
-
I'd suggest following GitHub's model and defining an
api_get
that does the common stuff (passing credentials and only returning the data). -
-
Historically, this function comes before the rest of the overriden functions (this, then
authorize
, then the rest). -
-
-
Better formatted as:
url = ('%s/' % urljoin(...))
I believe that will fit on two lines. Maybe three, if you need to put
'/'.join(parts)
on the next line. -
-
Undo this change. The
.closest
is part of the whole selector process. The.setVisible
is the thing we're calling on the resulting elements.
- Commit:
-
132ec30a34ede4c145c351ae1bb63c42eeafd408
Checks run (2 succeeded)
-
-
-
-
-
-
-
-
Instead of implementing a custom clean method you should be able to just pass in
min_value
andmax_value
to theforms.IntegerField
constructor. -
-
-
-
-
-
The implementation of
_parse_plugin_version
could raise exceptions if we get something unexpected from the server. Can we try/catch and convert to aRepositoryError
? -
-
-
-
-
-
-
-
-
-
- Change Summary:
-
Addressed David's feedback
- Commit:
-
132ec30a34ede4c145c351ae1bb63c42eeafd40894bd97fdcb38df77c798472722c37a0e661f712a
- Change Summary:
-
Fixed typo and test failures.
Fix branch retrieval.Manual testing.
- Commit:
-
94bd97fdcb38df77c798472722c37a0e661f712a195458a9e609e56847ec82e6d7f24550d866bea2
Checks run (2 succeeded)
- Change Summary:
-
Publish right changeset
- Commit:
-
195458a9e609e56847ec82e6d7f24550d866bea29b33de326d3e740febd6ec18cfb48e29a336a30d
Checks run (2 succeeded)
- Change Summary:
-
Addressed David's feedback
- Commit:
-
9b33de326d3e740febd6ec18cfb48e29a336a30d639c85ab2d5a1df87bfe49e9aa0814c90c1618d3
Checks run (2 succeeded)
- Change Summary:
-
Addressed David's feedback.
- Commit:
-
639c85ab2d5a1df87bfe49e9aa0814c90c1618d32049fb6d13a537310bd7fba1dc37c32d24bfba50
- Commit:
-
2049fb6d13a537310bd7fba1dc37c32d24bfba50281ec69a84c890149fe2c5f6562f5a9ce7cbc3d5
Checks run (2 succeeded)
- Change Summary:
-
Addressed David's feedback.
- Commit:
-
281ec69a84c890149fe2c5f6562f5a9ce7cbc3d5d7ca381374c4239518f524add0f7bfa44f9d2a80
- Change Summary:
-
Linting.
- Commit:
-
d7ca381374c4239518f524add0f7bfa44f9d2a801f0aa4dfbc6c40684fe348a89596a65d9eeb6ab2
Checks run (2 succeeded)
-
This looks like more feedback than it is. Primarily some small docs/error message stuff repeated for different instances.
-
-
-
I know the base implementation doesn't do anything, but it might in the future. Let's call the parent method here.
-
-
We should specify the URL here (first argument in
*args
), since we otherwise don't have enough information to figure out what went wrong. -
-
-
-
-
-
We should link to the URL for the repository in this message. We can then provide instructions in that repository's README for installation instructions.
-
We should specify the repository ID here, since we otherwise don't have enough information to debug problems.
-
Keyword arguments should ideally be used in localized text when there's more than one variable being injected. Helps with translations when the order ends up changing.
-
-
-
-
-
-
-
-
Can we catch an exception here and handle it gracefully, in case something goes wonky with the response?
-
We should specify the repository ID here, since we otherwise don't have enough information to debug problems.
-
-
-
-
-
-
-
-
- Change Summary:
-
post correct revision.
- Commit:
-
4404c4ee7df5a5ca36c3a62058727dcef72fbaf7602caaea3acf1909666239d5447cb1435be4dd58
Checks run (2 succeeded)
- Commit:
-
602caaea3acf1909666239d5447cb1435be4dd5886ed503416778e770e67577804cc1b692e2256d1