Merge branch 'stable-2.14'

* stable-2.14:
  Fix documentation of branch regex filter
  Clarify limitations in project list filters
  RefFilter: Disallow using substring and regex filters together
  Clarify that branch and tag regex filters are case sensitive
  Add missing documentation of tag substring and regex filters
  Clarify that branch substring filter is case insensitive
  Fix documentation of branch substring option
  Clarify that group substring filter is case insensitive
  GroupsIT: Add test for listing groups by substring

Change-Id: Id479a1f868a75a6e8b117808b5a8418cded3fd00
This commit is contained in:
Paladox 2017-07-13 11:32:09 +01:00
commit 3928de5cb7
7 changed files with 145 additions and 4 deletions

View File

@ -227,6 +227,8 @@ error out.)
Substring(m)::
Limit the results to those groups that match the specified substring.
+
The match is case insensitive.
+
List all groups that match substring `test/`:
+
.Request

View File

@ -149,6 +149,8 @@ Prefix(p)::
Limit the results to those projects that start with the specified
prefix.
+
The match is case sensitive. May not be used together with `m` or `r`.
+
List all projects that start with `platform/`:
+
.Request
@ -182,6 +184,8 @@ Boundary matchers '^' and '$' are implicit. For example: the regex 'test.*' will
match any projects that start with 'test' and regex '.*test' will match any
project that end with 'test'.
+
The match is case sensitive. May not be used together with `m` or `p`.
+
List all projects that match regex `test.*project`:
+
.Request
@ -234,6 +238,8 @@ Query the second project in the project list:
Substring(m)::
Limit the results to those projects that match the specified substring.
+
The match is case insensitive. May not be used together with `r` or `p`.
+
List all projects that match substring `test/`:
+
.Request
@ -1201,9 +1207,11 @@ Skip the given number of branches from the beginning of the list.
----
Substring(m)::
Limit the results to those projects that match the specified substring.
Limit the results to those branches that match the specified substring.
+
List all projects that match substring `test`:
The match is case insensitive. May not be used together with `r`.
+
List all branches that match substring `test`:
+
.Request
----
@ -1229,8 +1237,10 @@ List all projects that match substring `test`:
Regex(r)::
Limit the results to those branches that match the specified regex.
Boundary matchers '^' and '$' are implicit. For example: the regex 't*' will
match any branches that start with 'test' and regex '*t' will match any
branches that end with 'test'.
match any branches that start with 't' and regex '*t' will match any
branches that end with 't'.
+
The match is case sensitive. May not be used together with `m`.
+
List all branches that match regex `t.*1`:
+
@ -1885,6 +1895,87 @@ Skip the given number of tags from the beginning of the list.
]
----
Substring(m)::
Limit the results to those tags that match the specified substring.
+
The match is case insensitive. May not be used together with `r`.
+
List all tags that match substring `v2`:
+
.Request
----
GET /projects/testproject/tags?m=v2 HTTP/1.0
----
+
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8
)]}'
[
{
"ref": "refs/tags/v2.0",
"revision": "1624f5af8ae89148d1a3730df8c290413e3dcf30"
},
]
----
Regex(r)::
Limit the results to those tags that match the specified regex.
Boundary matchers '^' and '$' are implicit. For example: the regex 't*' will
match any tags that start with 't' and regex '*t' will match any
tags that end with 't'.
+
The match is case sensitive. May not be used together with `m`.
+
List all tags that match regex `v.*0`:
+
.Request
----
GET /projects/testproject/tags?r=v.*0 HTTP/1.0
----
+
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8
)]}'
[
{
"ref": "refs/tags/v1.0",
"revision": "49ce77fdcfd3398dc0dedbe016d1a425fd52d666",
"object": "1624f5af8ae89148d1a3730df8c290413e3dcf30",
"message": "Annotated tag",
"tagger": {
"name": "David Pursehouse",
"email": "david.pursehouse@sonymobile.com",
"date": "2014-10-06 07:35:03.000000000",
"tz": 540
}
},
{
"ref": "refs/tags/v2.0",
"revision": "1624f5af8ae89148d1a3730df8c290413e3dcf30"
},
{
"ref": "refs/tags/v3.0",
"revision": "c628685b3c5a3614571ecb5c8fceb85db9112313",
"object": "1624f5af8ae89148d1a3730df8c290413e3dcf30",
"message": "Signed tag\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.11 (GNU/Linux)\n\niQEcBAABAgAGBQJUMlqYAAoJEPI2qVPgglptp7MH/j+KFcittFbxfSnZjUl8n5IZ\nveZo7wE+syjD9sUbMH4EGv0WYeVjphNTyViBof+stGTNkB0VQzLWI8+uWmOeiJ4a\nzj0LsbDOxodOEMI5tifo02L7r4Lzj++EbqtKv8IUq2kzYoQ2xjhKfFiGjeYOn008\n9PGnhNblEHZgCHguGR6GsfN8bfA2XNl9B5Ysl5ybX1kAVs/TuLZR4oDMZ/pW2S75\nhuyNnSgcgq7vl2gLGefuPs9lxkg5Fj3GZr7XPZk4pt/x1oiH7yXxV4UzrUwg2CC1\nfHrBlNbQ4uJNY8TFcwof52Z0cagM5Qb/ZSLglHbqEDGA68HPqbwf5z2hQyU2/U4\u003d\n\u003dZtUX\n-----END PGP SIGNATURE-----",
"tagger": {
"name": "David Pursehouse",
"email": "david.pursehouse@sonymobile.com",
"date": "2014-10-06 09:02:16.000000000",
"tz": 540
}
}
]
----
[[get-tag]]
=== Get Tag

View File

@ -506,6 +506,10 @@ public class GroupsIT extends AbstractDaemonTest {
assertThat(groups).containsKey("Administrators");
assertThat(groups).hasSize(1);
groups = gApi.groups().list().withSubstring("admin").getAsMap();
assertThat(groups).containsKey("Administrators");
assertThat(groups).hasSize(1);
String other = name("Administrators");
gApi.groups().create(other);
groups = gApi.groups().list().withSubstring("dmin").getAsMap();

View File

@ -16,6 +16,7 @@ package com.google.gerrit.acceptance.rest.project;
import static com.google.gerrit.acceptance.rest.project.RefAssert.assertRefNames;
import static com.google.gerrit.acceptance.rest.project.RefAssert.assertRefs;
import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@ -23,6 +24,7 @@ import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.TestProjectInput;
import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.ProjectApi.ListRefsRequest;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.reviewdb.client.RefNames;
import org.junit.Test;
@ -147,8 +149,17 @@ public class ListBranchesIT extends AbstractDaemonTest {
"refs/heads/someBranch1", "refs/heads/someBranch2", "refs/heads/someBranch3"),
list().withSubstring("Branch").get());
assertRefNames(
ImmutableList.of(
"refs/heads/someBranch1", "refs/heads/someBranch2", "refs/heads/someBranch3"),
list().withSubstring("somebranch").get());
// Using regex.
assertRefNames(ImmutableList.of("refs/heads/master"), list().withRegex(".*ast.*r").get());
assertRefNames(ImmutableList.of(), list().withRegex(".*AST.*R").get());
// Conflicting options
assertBadRequest(list().withSubstring("somebranch").withRegex(".*ast.*r"));
}
private ListRefsRequest<BranchInfo> list() throws Exception {
@ -162,4 +173,13 @@ public class ListBranchesIT extends AbstractDaemonTest {
info.canDelete = canDelete ? true : null;
return info;
}
private void assertBadRequest(ListRefsRequest<BranchInfo> req) throws Exception {
try {
req.get();
fail("Expected BadRequestException");
} catch (BadRequestException e) {
// Expected
}
}
}

View File

@ -112,6 +112,8 @@ public class ListProjectsIT extends AbstractDaemonTest {
assertThatNameList(filter(gApi.projects().list().withPrefix(p).get()))
.containsExactly(someOtherProject, someProject)
.inOrder();
p = name("SOME");
assertThatNameList(filter(gApi.projects().list().withPrefix(p).get())).isEmpty();
}
@Test
@ -161,6 +163,9 @@ public class ListProjectsIT extends AbstractDaemonTest {
assertThatNameList(filter(gApi.projects().list().withSubstring("some").get()))
.containsExactly(projectAwesome, someOtherProject, someProject)
.inOrder();
assertThatNameList(filter(gApi.projects().list().withSubstring("SOME").get()))
.containsExactly(projectAwesome, someOtherProject, someProject)
.inOrder();
}
@Test

View File

@ -17,6 +17,7 @@ package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import static org.junit.Assert.fail;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
@ -108,11 +109,17 @@ public class TagsIT extends AbstractDaemonTest {
result = getTags().withRegex("^tag-[C|D]$").get();
assertTagList(FluentIterable.from(ImmutableList.of("tag-C", "tag-D")), result);
result = getTags().withRegex("^tag-[c|d]$").get();
assertTagList(FluentIterable.from(ImmutableList.of()), result);
// With substring filter
result = getTags().withSubstring("tag-").get();
assertTagList(FluentIterable.from(testTags), result);
result = getTags().withSubstring("ag-B").get();
assertTagList(FluentIterable.from(ImmutableList.of("tag-B")), result);
// With conflicting options
assertBadRequest(getTags().withSubstring("ag-B").withRegex("^tag-[c|d]$"));
}
@Test
@ -344,4 +351,13 @@ public class TagsIT extends AbstractDaemonTest {
private TagApi tag(String tagname) throws Exception {
return gApi.projects().name(project.get()).tag(tagname);
}
private void assertBadRequest(ListRefsRequest<TagInfo> req) throws Exception {
try {
req.get();
fail("Expected BadRequestException");
} catch (BadRequestException e) {
// Expected
}
}
}

View File

@ -56,6 +56,9 @@ public class RefFilter<T extends RefInfo> {
}
public List<T> filter(List<T> refs) throws BadRequestException {
if (!Strings.isNullOrEmpty(matchSubstring) && !Strings.isNullOrEmpty(matchRegex)) {
throw new BadRequestException("specify exactly one of m/r");
}
FluentIterable<T> results = FluentIterable.from(refs);
if (!Strings.isNullOrEmpty(matchSubstring)) {
results = results.filter(new SubstringPredicate(matchSubstring));