implement new browse api for git

This commit is contained in:
Sebastian Sdorra
2018-10-08 14:39:11 +02:00
parent e5a3cbb50e
commit ed9f5fc69e
2 changed files with 110 additions and 87 deletions

View File

@@ -35,6 +35,9 @@ package sonia.scm.repository.spi;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -61,6 +64,7 @@ import sonia.scm.repository.SubRepository;
import sonia.scm.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -107,6 +111,7 @@ public class GitBrowseCommand extends AbstractGitCommand
logger.debug("try to create browse result for {}", request);
BrowserResult result;
org.eclipse.jgit.lib.Repository repo = open();
ObjectId revId;
@@ -121,7 +126,7 @@ public class GitBrowseCommand extends AbstractGitCommand
if (revId != null)
{
result = getResult(repo, request, revId);
result = new BrowserResult(revId.getName(), getEntry(repo, request, revId));
}
else
{
@@ -134,8 +139,7 @@ public class GitBrowseCommand extends AbstractGitCommand
logger.warn("coul not find head of repository, empty?");
}
result = new BrowserResult(Constants.HEAD, null, null,
Collections.EMPTY_LIST);
result = new BrowserResult(Constants.HEAD, createEmtpyRoot());
}
return result;
@@ -143,6 +147,14 @@ public class GitBrowseCommand extends AbstractGitCommand
//~--- methods --------------------------------------------------------------
private FileObject createEmtpyRoot() {
FileObject fileObject = new FileObject();
fileObject.setName("");
fileObject.setPath("");
fileObject.setDirectory(true);
return fileObject;
}
/**
* Method description
*
@@ -193,7 +205,6 @@ public class GitBrowseCommand extends AbstractGitCommand
if (!file.isDirectory() &&!request.isDisableLastCommit())
{
logger.trace("fetch last commit for {} at {}", path, revId.getName());
RevCommit commit = getLatestCommit(repo, revId, path);
if (commit != null)
@@ -265,22 +276,19 @@ public class GitBrowseCommand extends AbstractGitCommand
return result;
}
private BrowserResult getResult(org.eclipse.jgit.lib.Repository repo,
BrowseCommandRequest request, ObjectId revId)
throws IOException, RevisionNotFoundException {
BrowserResult result = null;
private FileObject getEntry(org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId) throws IOException, RevisionNotFoundException {
RevWalk revWalk = null;
TreeWalk treeWalk = null;
try
{
if (logger.isDebugEnabled())
{
logger.debug("load repository browser for revision {}", revId.name());
}
FileObject result;
try {
logger.debug("load repository browser for revision {}", revId.name());
treeWalk = new TreeWalk(repo);
treeWalk.setRecursive(request.isRecursive());
if (!Strings.isNullOrEmpty(request.getPath())) {
treeWalk.setFilter(PathFilter.create(request.getPath()));
}
revWalk = new RevWalk(repo);
RevTree tree = revWalk.parseTree(revId);
@@ -291,65 +299,21 @@ public class GitBrowseCommand extends AbstractGitCommand
}
else
{
// TODO throw exception
logger.error("could not find tree for {}", revId.name());
}
result = new BrowserResult();
List<FileObject> files = Lists.newArrayList();
String path = request.getPath();
if (Util.isEmpty(path))
{
while (treeWalk.next())
{
FileObject fo = createFileObject(repo, request, revId, treeWalk);
if (fo != null)
{
files.add(fo);
}
}
}
else
{
String[] parts = path.split("/");
int current = 0;
int limit = parts.length;
while (treeWalk.next())
{
String name = treeWalk.getNameString();
if (current >= limit)
{
String p = treeWalk.getPathString();
if (p.split("/").length > limit)
{
FileObject fo = createFileObject(repo, request, revId, treeWalk);
if (fo != null)
{
files.add(fo);
}
}
}
else if (name.equalsIgnoreCase(parts[current]))
{
current++;
if (!request.isRecursive())
{
treeWalk.enterSubtree();
}
}
if (Strings.isNullOrEmpty(request.getPath())) {
result = createEmtpyRoot();
findChildren(result, repo, request, revId, treeWalk);
} else {
result = first(repo, request, revId, treeWalk);
if ( result.isDirectory() ) {
treeWalk.enterSubtree();
findChildren(result, repo, request, revId, treeWalk);
}
}
result.setFiles(files);
result.setRevision(revId.getName());
}
finally
{
@@ -360,6 +324,45 @@ public class GitBrowseCommand extends AbstractGitCommand
return result;
}
private FileObject findChildren(FileObject parent, org.eclipse.jgit.lib.Repository repo, BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, RevisionNotFoundException {
List<FileObject> files = Lists.newArrayList();
while (treeWalk.next())
{
FileObject fo = createFileObject(repo, request, revId, treeWalk);
if (!fo.getPath().startsWith(parent.getPath())) {
parent.setChildren(files);
return fo;
}
if (fo != null)
{
files.add(fo);
}
if (request.isRecursive() && fo.isDirectory()) {
treeWalk.enterSubtree();
FileObject rc = findChildren(fo, repo, request, revId, treeWalk);
if (rc != null) {
files.add(rc);
}
}
}
parent.setChildren(files);
return null;
}
private FileObject first(org.eclipse.jgit.lib.Repository repo,
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException, RevisionNotFoundException {
if (!treeWalk.next()) {
throw new IOException("tree seams to be empty");
}
return createFileObject(repo, request, revId, treeWalk);
}
@SuppressWarnings("unchecked")
private Map<String,
SubRepository> getSubRepositories(org.eclipse.jgit.lib.Repository repo,

View File

@@ -58,6 +58,15 @@ import static org.junit.Assert.assertTrue;
*/
public class GitBrowseCommandTest extends AbstractGitCommandTestBase
{
@Test
public void testGetFile() throws IOException, RevisionNotFoundException {
BrowseCommandRequest request = new BrowseCommandRequest();
request.setPath("a.txt");
BrowserResult result = createCommand().getBrowserResult(request);
FileObject fileObject = result.getFile();
assertEquals("a.txt", fileObject.getName());
}
/**
* Test browse command with default branch.
@@ -65,12 +74,13 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase
@Test
public void testDefaultBranch() throws IOException, RevisionNotFoundException {
// without default branch, the repository head should be used
BrowserResult result = createCommand().getBrowserResult(new BrowseCommandRequest());
assertNotNull(result);
FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
assertNotNull(root);
List<FileObject> foList = result.getFiles();
List<FileObject> foList = root.getChildren();
assertNotNull(foList);
assertFalse(foList.isEmpty());
assertEquals(4, foList.size());
assertEquals("a.txt", foList.get(0).getName());
@@ -80,10 +90,11 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase
// set default branch and fetch again
repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch");
result = createCommand().getBrowserResult(new BrowseCommandRequest());
assertNotNull(result);
foList = result.getFiles();
root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
assertNotNull(root);
foList = root.getChildren();
assertNotNull(foList);
assertFalse(foList.isEmpty());
assertEquals(2, foList.size());
@@ -94,12 +105,10 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase
@Test
public void testBrowse() throws IOException, RevisionNotFoundException {
BrowserResult result =
createCommand().getBrowserResult(new BrowseCommandRequest());
FileObject root = createCommand().getBrowserResult(new BrowseCommandRequest()).getFile();
assertNotNull(root);
assertNotNull(result);
List<FileObject> foList = result.getFiles();
List<FileObject> foList = root.getChildren();
assertNotNull(foList);
assertFalse(foList.isEmpty());
@@ -139,11 +148,11 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase
request.setPath("c");
BrowserResult result = createCommand().getBrowserResult(request);
FileObject root = createCommand().getBrowserResult(request).getFile();
assertNotNull(root);
assertNotNull(result);
List<FileObject> foList = result.getFiles();
List<FileObject> foList = root.getChildren();
assertNotNull(foList);
assertFalse(foList.isEmpty());
@@ -181,20 +190,31 @@ public class GitBrowseCommandTest extends AbstractGitCommandTestBase
}
@Test
public void testRecusive() throws IOException, RevisionNotFoundException {
public void testRecursive() throws IOException, RevisionNotFoundException {
BrowseCommandRequest request = new BrowseCommandRequest();
request.setRecursive(true);
BrowserResult result = createCommand().getBrowserResult(request);
FileObject root = createCommand().getBrowserResult(request).getFile();
assertNotNull(root);
assertNotNull(result);
List<FileObject> foList = result.getFiles();
List<FileObject> foList = root.getChildren();
assertNotNull(foList);
assertFalse(foList.isEmpty());
assertEquals(5, foList.size());
assertEquals(4, foList.size());
assertEquals("a.txt", foList.get(0).getName());
assertEquals("b.txt", foList.get(1).getName());
FileObject c = foList.get(2);
assertEquals("c", c.getName());
assertEquals("f.txt", foList.get(3).getName());
List<FileObject> cChilds = c.getChildren();
assertEquals("d.txt", cChilds.get(0).getName());
assertEquals("e.txt", cChilds.get(1).getName());
}
/**