Revision API: Implement methods to access files and diff info
Change-Id: Ib9c01304ea40392812c07fcedd5816c5bf12e202
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
index f896692..14dca0b 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
@@ -57,7 +57,7 @@
public class PushOneCommit {
public static final String SUBJECT = "test commit";
public static final String FILE_NAME = "a.txt";
- private static final String FILE_CONTENT = "some content";
+ public static final String FILE_CONTENT = "some content";
public interface Factory {
PushOneCommit create(
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 11ed309..3f72c28 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -15,9 +15,12 @@
package com.google.gerrit.acceptance.api.revision;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.PushOneCommit.FILE_CONTENT;
+import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.junit.Assert.fail;
+import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -29,10 +32,13 @@
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.common.SubmitType;
import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.reviewdb.client.Patch;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
@@ -40,7 +46,9 @@
import org.junit.Before;
import org.junit.Test;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
@NoHttpd
public class RevisionIT extends AbstractDaemonTest {
@@ -280,6 +288,48 @@
// TODO(dborowitz): Test for other-branches.
}
+ @Test
+ public void files() throws Exception {
+ PushOneCommit.Result r = createChange();
+ assertThat(Iterables.all(gApi.changes()
+ .id(r.getChangeId())
+ .revision(r.getCommit().name())
+ .files()
+ .keySet(), new Predicate<String>() {
+ @Override
+ public boolean apply(String file) {
+ return file.matches(FILE_NAME + '|' + Patch.COMMIT_MSG);
+ }
+ }))
+ .isTrue();
+ }
+
+ @Test
+ public void diff() throws Exception {
+ PushOneCommit.Result r = createChange();
+ DiffInfo diff = gApi.changes()
+ .id(r.getChangeId())
+ .revision(r.getCommit().name())
+ .file(FILE_NAME)
+ .diff();
+ assertThat(diff.metaA).isNull();
+ assertThat(diff.metaB.lines).isEqualTo(1);
+ }
+
+ @Test
+ public void content() throws Exception {
+ PushOneCommit.Result r = createChange();
+ BinaryResult bin = gApi.changes()
+ .id(r.getChangeId())
+ .revision(r.getCommit().name())
+ .file(FILE_NAME)
+ .content();
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ bin.writeTo(os);
+ String res = new String(os.toByteArray(), StandardCharsets.UTF_8);
+ assertThat(res).isEqualTo(FILE_CONTENT);
+ }
+
private void assertMergeable(String id, boolean expected) throws Exception {
MergeableInfo m = gApi.changes().id(id).current().mergeable();
assertThat(m.mergeable).isEqualTo(expected);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/FileApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/FileApiImpl.java
new file mode 100644
index 0000000..42c1e23
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/FileApiImpl.java
@@ -0,0 +1,77 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.api.changes;
+
+import com.google.gerrit.extensions.api.changes.FileApi;
+import com.google.gerrit.extensions.common.DiffInfo;
+import com.google.gerrit.extensions.restapi.BinaryResult;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.server.change.FileResource;
+import com.google.gerrit.server.change.GetContent;
+import com.google.gerrit.server.change.GetDiff;
+import com.google.gerrit.server.project.InvalidChangeOperationException;
+import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.assistedinject.Assisted;
+
+import java.io.IOException;
+
+class FileApiImpl extends FileApi.NotImplemented implements FileApi {
+ interface Factory {
+ FileApiImpl create(FileResource r);
+ }
+
+ private final GetContent getContent;
+ private final Provider<GetDiff> getDiff;
+ private final FileResource file;
+
+ @Inject
+ FileApiImpl(GetContent getContent,
+ Provider<GetDiff> getDiff,
+ @Assisted FileResource file) {
+ this.getContent = getContent;
+ this.getDiff = getDiff;
+ this.file = file;
+ }
+
+ @Override
+ public BinaryResult content() throws RestApiException {
+ try {
+ return getContent.apply(file);
+ } catch (NoSuchChangeException | IOException | OrmException e) {
+ throw new RestApiException("Cannot retrieve file content", e);
+ }
+ }
+
+ @Override
+ public DiffInfo diff() throws RestApiException {
+ try {
+ return getDiff.get().apply(file).value();
+ } catch (IOException | InvalidChangeOperationException | OrmException e) {
+ throw new RestApiException("Cannot retrieve diff", e);
+ }
+ }
+
+ @Override
+ public DiffInfo diff(String base) throws RestApiException {
+ try {
+ return getDiff.get().setBase(base).apply(file).value();
+ } catch (IOException | InvalidChangeOperationException | OrmException e) {
+ throw new RestApiException("Cannot retrieve diff", e);
+ }
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/Module.java
index dbf5f27..aa63996 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/Module.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/Module.java
@@ -24,5 +24,6 @@
factory(ChangeApiImpl.Factory.class);
factory(RevisionApiImpl.Factory.class);
+ factory(FileApiImpl.Factory.class);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
index ab788c9..65b4f05 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
@@ -19,9 +19,11 @@
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
+import com.google.gerrit.extensions.api.changes.FileApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.api.changes.SubmitInput;
+import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.common.MergeableInfo;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -44,6 +46,7 @@
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
+import java.util.Map;
import java.util.Set;
class RevisionApiImpl extends RevisionApi.NotImplemented implements RevisionApi {
@@ -65,6 +68,7 @@
private final Provider<Files.ListFiles> listFiles;
private final Provider<PostReview> review;
private final Provider<Mergeable> mergeable;
+ private final FileApiImpl.Factory fileApi;
@Inject
RevisionApiImpl(Changes changes,
@@ -80,6 +84,7 @@
Provider<Files.ListFiles> listFiles,
Provider<PostReview> review,
Provider<Mergeable> mergeable,
+ FileApiImpl.Factory fileApi,
@Assisted RevisionResource r) {
this.changes = changes;
this.cherryPick = cherryPick;
@@ -94,6 +99,7 @@
this.deleteReviewed = deleteReviewed;
this.listFiles = listFiles;
this.mergeable = mergeable;
+ this.fileApi = fileApi;
this.revision = r;
}
@@ -211,4 +217,31 @@
throw new RestApiException("Cannot check mergeability", e);
}
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, FileInfo> files() throws RestApiException {
+ try {
+ return (Map<String, FileInfo>)listFiles.get().apply(revision).value();
+ } catch (OrmException | IOException e) {
+ throw new RestApiException("Cannot retrieve files", e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<String, FileInfo> files(String base) throws RestApiException {
+ try {
+ return (Map<String, FileInfo>) listFiles.get().setBase(base)
+ .apply(revision).value();
+ } catch (OrmException | IOException e) {
+ throw new RestApiException("Cannot retrieve files", e);
+ }
+ }
+
+ @Override
+ public FileApi file(String path) {
+ return fileApi.create(files.get().parse(revision,
+ IdString.fromDecoded(path)));
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Files.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Files.java
index 4a3082c..1c0b0a4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Files.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Files.java
@@ -86,8 +86,7 @@
}
@Override
- public FileResource parse(RevisionResource rev, IdString id)
- throws ResourceNotFoundException, OrmException, AuthException {
+ public FileResource parse(RevisionResource rev, IdString id) {
return new FileResource(rev, id.get());
}
@@ -334,5 +333,10 @@
git.close();
}
}
+
+ public ListFiles setBase(String base) {
+ this.base = base;
+ return this;
+ }
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
index 7c7bcdae..f731b5f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
@@ -251,6 +251,11 @@
return links.isEmpty() ? null : links.toList();
}
+ public GetDiff setBase(String base) {
+ this.base = base;
+ return this;
+ }
+
private static class Content {
final List<ContentEntry> lines;
final SparseFileContent fileA;