ListProjects: Allow to filter list by project state
Bug: Issue 7747 Change-Id: Ibf39b408fce8e76a61706ae45da433faaf0391f2
This commit is contained in:
@@ -325,7 +325,8 @@ GET /projects/?type=PERMISSIONS HTTP/1.0
|
|||||||
----
|
----
|
||||||
|
|
||||||
All::
|
All::
|
||||||
Get all projects, including those whose state is "HIDDEN".
|
Get all projects, including those whose state is "HIDDEN". May not be used
|
||||||
|
together with the `state` option.
|
||||||
+
|
+
|
||||||
.Request
|
.Request
|
||||||
----
|
----
|
||||||
@@ -351,6 +352,30 @@ GET /projects/?all HTTP/1.0
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
State(s)::
|
||||||
|
Get all projects with the given state. May not be used together with the
|
||||||
|
`all` option.
|
||||||
|
+
|
||||||
|
.Request
|
||||||
|
----
|
||||||
|
GET /projects/?state=HIDDEN HTTP/1.0
|
||||||
|
----
|
||||||
|
+
|
||||||
|
.Response
|
||||||
|
----
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Disposition: attachment
|
||||||
|
Content-Type: application/json; charset=UTF-8
|
||||||
|
|
||||||
|
)]}'
|
||||||
|
{
|
||||||
|
"some-other-project": {
|
||||||
|
"id": "some-other-project",
|
||||||
|
"state": "HIDDEN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
[[query-projects]]
|
[[query-projects]]
|
||||||
=== Query Projects
|
=== Query Projects
|
||||||
--
|
--
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.extensions.api.projects;
|
package com.google.gerrit.extensions.api.projects;
|
||||||
|
|
||||||
|
import com.google.gerrit.extensions.client.ProjectState;
|
||||||
import com.google.gerrit.extensions.common.ProjectInfo;
|
import com.google.gerrit.extensions.common.ProjectInfo;
|
||||||
import com.google.gerrit.extensions.restapi.NotImplementedException;
|
import com.google.gerrit.extensions.restapi.NotImplementedException;
|
||||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||||
@@ -94,6 +95,7 @@ public interface Projects {
|
|||||||
private boolean showTree;
|
private boolean showTree;
|
||||||
private boolean all;
|
private boolean all;
|
||||||
private FilterType type = FilterType.ALL;
|
private FilterType type = FilterType.ALL;
|
||||||
|
private ProjectState state = null;
|
||||||
|
|
||||||
public List<ProjectInfo> get() throws RestApiException {
|
public List<ProjectInfo> get() throws RestApiException {
|
||||||
Map<String, ProjectInfo> map = getAsMap();
|
Map<String, ProjectInfo> map = getAsMap();
|
||||||
@@ -158,6 +160,11 @@ public interface Projects {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListRequest withState(ProjectState state) {
|
||||||
|
this.state = state;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getDescription() {
|
public boolean getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
@@ -197,6 +204,10 @@ public interface Projects {
|
|||||||
public boolean isAll() {
|
public boolean isAll() {
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProjectState getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -131,6 +131,8 @@ class ProjectsImpl implements Projects {
|
|||||||
|
|
||||||
lp.setAll(request.isAll());
|
lp.setAll(request.isAll());
|
||||||
|
|
||||||
|
lp.setState(request.getState());
|
||||||
|
|
||||||
return lp.apply();
|
return lp.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -190,6 +190,15 @@ public class ListProjects implements RestReadView<TopLevelResource> {
|
|||||||
this.all = all;
|
this.all = all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Option(
|
||||||
|
name = "--state",
|
||||||
|
aliases = {"-s"},
|
||||||
|
usage = "filter by project state"
|
||||||
|
)
|
||||||
|
public void setState(com.google.gerrit.extensions.client.ProjectState state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
@Option(
|
@Option(
|
||||||
name = "--limit",
|
name = "--limit",
|
||||||
aliases = {"-n"},
|
aliases = {"-n"},
|
||||||
@@ -249,6 +258,7 @@ public class ListProjects implements RestReadView<TopLevelResource> {
|
|||||||
private FilterType type = FilterType.ALL;
|
private FilterType type = FilterType.ALL;
|
||||||
private boolean showDescription;
|
private boolean showDescription;
|
||||||
private boolean all;
|
private boolean all;
|
||||||
|
private com.google.gerrit.extensions.client.ProjectState state;
|
||||||
private int limit;
|
private int limit;
|
||||||
private int start;
|
private int start;
|
||||||
private String matchPrefix;
|
private String matchPrefix;
|
||||||
@@ -318,6 +328,9 @@ public class ListProjects implements RestReadView<TopLevelResource> {
|
|||||||
|
|
||||||
public SortedMap<String, ProjectInfo> display(@Nullable OutputStream displayOutputStream)
|
public SortedMap<String, ProjectInfo> display(@Nullable OutputStream displayOutputStream)
|
||||||
throws BadRequestException, PermissionBackendException {
|
throws BadRequestException, PermissionBackendException {
|
||||||
|
if (all && state != null) {
|
||||||
|
throw new BadRequestException("'all' and 'state' may not be used together");
|
||||||
|
}
|
||||||
if (groupUuid != null) {
|
if (groupUuid != null) {
|
||||||
try {
|
try {
|
||||||
if (!groupControlFactory.controlFor(groupUuid).isVisible()) {
|
if (!groupControlFactory.controlFor(groupUuid).isVisible()) {
|
||||||
@@ -349,9 +362,14 @@ public class ListProjects implements RestReadView<TopLevelResource> {
|
|||||||
try {
|
try {
|
||||||
for (Project.NameKey projectName : filter(perm)) {
|
for (Project.NameKey projectName : filter(perm)) {
|
||||||
final ProjectState e = projectCache.get(projectName);
|
final ProjectState e = projectCache.get(projectName);
|
||||||
if (e == null || (!all && e.getProject().getState() == HIDDEN)) {
|
if (e == null || (e.getProject().getState() == HIDDEN && !all && state != HIDDEN)) {
|
||||||
// If we can't get it from the cache, pretend its not present.
|
// If we can't get it from the cache, pretend it's not present.
|
||||||
// If all wasn't selected, and its HIDDEN, pretend its not present.
|
// If all wasn't selected, and it's HIDDEN, pretend it's not present.
|
||||||
|
// If state HIDDEN wasn't selected, and it's HIDDEN, pretend it's not present.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != null && e.getProject().getState() != state) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -191,37 +191,56 @@ public class ListProjectsIT extends AbstractDaemonTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void listWithHiddenProject() throws Exception {
|
public void listWithHiddenAndReadonlyProjects() throws Exception {
|
||||||
Project.NameKey hidden = createProject("project-to-hide");
|
Project.NameKey hidden = createProject("project-to-hide");
|
||||||
|
Project.NameKey readonly = createProject("project-to-read");
|
||||||
|
|
||||||
// The project is included because it was not hidden yet
|
// Set project read-only
|
||||||
|
ConfigInput input = new ConfigInput();
|
||||||
|
input.state = ProjectState.READ_ONLY;
|
||||||
|
ConfigInfo info = gApi.projects().name(readonly.get()).config(input);
|
||||||
|
assertThat(info.state).isEqualTo(input.state);
|
||||||
|
|
||||||
|
// The hidden project is included because it was not hidden yet.
|
||||||
|
// The read-only project is included.
|
||||||
assertThatNameList(gApi.projects().list().get())
|
assertThatNameList(gApi.projects().list().get())
|
||||||
.containsExactly(allProjects, allUsers, project, hidden)
|
.containsExactly(allProjects, allUsers, project, hidden, readonly)
|
||||||
.inOrder();
|
.inOrder();
|
||||||
|
|
||||||
// Hide the project
|
// Hide the project
|
||||||
ConfigInput input = new ConfigInput();
|
|
||||||
input.state = ProjectState.HIDDEN;
|
input.state = ProjectState.HIDDEN;
|
||||||
ConfigInfo info = gApi.projects().name(hidden.get()).config(input);
|
info = gApi.projects().name(hidden.get()).config(input);
|
||||||
assertThat(info.state).isEqualTo(input.state);
|
assertThat(info.state).isEqualTo(input.state);
|
||||||
|
|
||||||
// Project is still accessible directly
|
// Project is still accessible directly
|
||||||
gApi.projects().name(hidden.get()).get();
|
gApi.projects().name(hidden.get()).get();
|
||||||
|
|
||||||
// But is not included in the list
|
// Hidden project is not included in the list
|
||||||
assertThatNameList(gApi.projects().list().get())
|
assertThatNameList(gApi.projects().list().get())
|
||||||
.containsExactly(allProjects, allUsers, project)
|
.containsExactly(allProjects, allUsers, project, readonly)
|
||||||
.inOrder();
|
.inOrder();
|
||||||
|
|
||||||
// ALL filter applies to type, and doesn't include hidden state
|
// ALL filter applies to type, and doesn't include hidden state
|
||||||
assertThatNameList(gApi.projects().list().withType(FilterType.ALL).get())
|
assertThatNameList(gApi.projects().list().withType(FilterType.ALL).get())
|
||||||
.containsExactly(allProjects, allUsers, project)
|
.containsExactly(allProjects, allUsers, project, readonly)
|
||||||
.inOrder();
|
.inOrder();
|
||||||
|
|
||||||
// "All" boolean option causes hidden projects to be included
|
// "All" boolean option causes hidden projects to be included
|
||||||
assertThatNameList(gApi.projects().list().withAll(true).get())
|
assertThatNameList(gApi.projects().list().withAll(true).get())
|
||||||
.containsExactly(allProjects, allUsers, project, hidden)
|
.containsExactly(allProjects, allUsers, project, hidden, readonly)
|
||||||
.inOrder();
|
.inOrder();
|
||||||
|
|
||||||
|
// "State" option causes only the projects in that state to be included
|
||||||
|
assertThatNameList(gApi.projects().list().withState(ProjectState.HIDDEN).get())
|
||||||
|
.containsExactly(hidden);
|
||||||
|
assertThatNameList(gApi.projects().list().withState(ProjectState.READ_ONLY).get())
|
||||||
|
.containsExactly(readonly);
|
||||||
|
assertThatNameList(gApi.projects().list().withState(ProjectState.ACTIVE).get())
|
||||||
|
.containsExactly(allProjects, allUsers, project)
|
||||||
|
.inOrder();
|
||||||
|
|
||||||
|
// Cannot use "all" and "state" together
|
||||||
|
assertBadRequest(gApi.projects().list().withAll(true).withState(ProjectState.ACTIVE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertBadRequest(ListRequest req) throws Exception {
|
private void assertBadRequest(ListRequest req) throws Exception {
|
||||||
|
Reference in New Issue
Block a user