mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-11 16:05:44 +01:00
Clean up git cat command
This commit is contained in:
@@ -32,8 +32,6 @@
|
|||||||
|
|
||||||
package sonia.scm.repository.spi;
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.Constants;
|
import org.eclipse.jgit.lib.Constants;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.ObjectLoader;
|
import org.eclipse.jgit.lib.ObjectLoader;
|
||||||
@@ -51,135 +49,72 @@ import sonia.scm.repository.RepositoryException;
|
|||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
import java.io.FilterInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||||
*
|
|
||||||
* @author Sebastian Sdorra
|
|
||||||
*/
|
|
||||||
public class GitCatCommand extends AbstractGitCommand implements CatCommand
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
private static final Logger logger = LoggerFactory.getLogger(GitCatCommand.class);
|
||||||
* the logger for GitCatCommand
|
|
||||||
*/
|
|
||||||
private static final Logger logger =
|
|
||||||
LoggerFactory.getLogger(GitCatCommand.class);
|
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
public GitCatCommand(GitContext context, sonia.scm.repository.Repository repository) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param repository
|
|
||||||
*/
|
|
||||||
public GitCatCommand(GitContext context,
|
|
||||||
sonia.scm.repository.Repository repository)
|
|
||||||
{
|
|
||||||
super(context, repository);
|
super(context, repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param output
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void getCatResult(CatCommandRequest request, OutputStream output)
|
public void getCatResult(CatCommandRequest request, OutputStream output) throws IOException, RepositoryException {
|
||||||
throws IOException, RepositoryException
|
|
||||||
{
|
|
||||||
logger.debug("try to read content for {}", request);
|
logger.debug("try to read content for {}", request);
|
||||||
|
try (ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(request)) {
|
||||||
org.eclipse.jgit.lib.Repository repo = open();
|
closableObjectLoaderContainer.objectLoader.copyTo(output);
|
||||||
|
}
|
||||||
ObjectId revId = getCommitOrDefault(repo, request.getRevision());
|
|
||||||
getContent(repo, revId, request.getPath(), output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getCatResultStream(CatCommandRequest request) throws IOException, RepositoryException {
|
public InputStream getCatResultStream(CatCommandRequest request) throws IOException, RepositoryException {
|
||||||
logger.debug("try to read content for {}", request);
|
logger.debug("try to read content for {}", request);
|
||||||
|
return new InputStreamWrapper(getLoader(request));
|
||||||
org.eclipse.jgit.lib.Repository repo = open();
|
|
||||||
|
|
||||||
ObjectId revId = getCommitOrDefault(repo, request.getRevision());
|
|
||||||
ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(repo, revId, request.getPath());
|
|
||||||
return new InputStreamWrapper(closableObjectLoaderContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId,
|
void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId, String path, OutputStream output) throws IOException, RepositoryException {
|
||||||
String path, OutputStream output)
|
try (ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(repo, revId, path)) {
|
||||||
throws IOException, RepositoryException
|
|
||||||
{
|
|
||||||
ClosableObjectLoaderContainer closableObjectLoaderContainer = getLoader(repo, revId, path);
|
|
||||||
try {
|
|
||||||
closableObjectLoaderContainer.objectLoader.copyTo(output);
|
closableObjectLoaderContainer.objectLoader.copyTo(output);
|
||||||
} finally {
|
|
||||||
closableObjectLoaderContainer.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClosableObjectLoaderContainer getLoader(Repository repo, ObjectId revId,
|
private ClosableObjectLoaderContainer getLoader(CatCommandRequest request) throws IOException, RepositoryException {
|
||||||
String path)
|
org.eclipse.jgit.lib.Repository repo = open();
|
||||||
throws IOException, RepositoryException
|
ObjectId revId = getCommitOrDefault(repo, request.getRevision());
|
||||||
{
|
return getLoader(repo, revId, request.getPath());
|
||||||
TreeWalk treeWalk = null;
|
}
|
||||||
RevWalk revWalk = null;
|
|
||||||
|
|
||||||
try
|
private ClosableObjectLoaderContainer getLoader(Repository repo, ObjectId revId, String path) throws IOException, RepositoryException {
|
||||||
{
|
TreeWalk treeWalk = new TreeWalk(repo);
|
||||||
treeWalk = new TreeWalk(repo);
|
treeWalk.setRecursive(Util.nonNull(path).contains("/"));
|
||||||
treeWalk.setRecursive(Util.nonNull(path).contains("/"));
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
logger.debug("load content for {} at {}", path, revId.name());
|
||||||
{
|
|
||||||
logger.debug("load content for {} at {}", path, revId.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
revWalk = new RevWalk(repo);
|
RevWalk revWalk = new RevWalk(repo);
|
||||||
|
|
||||||
RevCommit entry = revWalk.parseCommit(revId);
|
RevCommit entry = revWalk.parseCommit(revId);
|
||||||
RevTree revTree = entry.getTree();
|
RevTree revTree = entry.getTree();
|
||||||
|
|
||||||
if (revTree != null)
|
if (revTree != null) {
|
||||||
{
|
treeWalk.addTree(revTree);
|
||||||
treeWalk.addTree(revTree);
|
} else {
|
||||||
}
|
logger.error("could not find tree for {}", revId.name());
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.error("could not find tree for {}", revId.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
treeWalk.setFilter(PathFilter.create(path));
|
|
||||||
|
|
||||||
if (treeWalk.next() && treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB)
|
|
||||||
{
|
|
||||||
ObjectId blobId = treeWalk.getObjectId(0);
|
|
||||||
ObjectLoader loader = repo.open(blobId);
|
|
||||||
|
|
||||||
return new ClosableObjectLoaderContainer(loader, treeWalk, revWalk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new PathNotFoundException(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
treeWalk.setFilter(PathFilter.create(path));
|
||||||
|
|
||||||
|
if (treeWalk.next() && treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) {
|
||||||
|
ObjectId blobId = treeWalk.getObjectId(0);
|
||||||
|
ObjectLoader loader = repo.open(blobId);
|
||||||
|
|
||||||
|
return new ClosableObjectLoaderContainer(loader, treeWalk, revWalk);
|
||||||
|
} else {
|
||||||
|
throw new PathNotFoundException(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,37 +130,28 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() {
|
||||||
GitUtil.release(revWalk);
|
GitUtil.release(revWalk);
|
||||||
GitUtil.release(treeWalk);
|
GitUtil.release(treeWalk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InputStreamWrapper extends InputStream {
|
private static class InputStreamWrapper extends FilterInputStream {
|
||||||
|
|
||||||
private final InputStream delegate;
|
private final ClosableObjectLoaderContainer container;
|
||||||
private final TreeWalk treeWalk;
|
|
||||||
private final RevWalk revWalk;
|
|
||||||
|
|
||||||
private InputStreamWrapper(ClosableObjectLoaderContainer container) throws IOException {
|
private InputStreamWrapper(ClosableObjectLoaderContainer container) throws IOException {
|
||||||
this(container.objectLoader.openStream(), container.treeWalk, container.revWalk);
|
super(container.objectLoader.openStream());
|
||||||
|
this.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStreamWrapper(InputStream delegate, TreeWalk treeWalk, RevWalk revWalk) {
|
@Override
|
||||||
this.delegate = delegate;
|
public void close() throws IOException {
|
||||||
this.treeWalk = treeWalk;
|
try {
|
||||||
this.revWalk = revWalk;
|
super.close();
|
||||||
}
|
} finally {
|
||||||
|
container.close();
|
||||||
@Override
|
|
||||||
public int read () throws IOException {
|
|
||||||
return delegate.read();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close () throws IOException {
|
|
||||||
GitUtil.release(revWalk);
|
|
||||||
GitUtil.release(treeWalk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,19 +32,16 @@
|
|||||||
|
|
||||||
package sonia.scm.repository.spi;
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import sonia.scm.repository.GitConstants;
|
||||||
|
import sonia.scm.repository.PathNotFoundException;
|
||||||
import sonia.scm.repository.RepositoryException;
|
import sonia.scm.repository.RepositoryException;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import sonia.scm.repository.GitConstants;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GitCatCommand}.
|
* Unit tests for {@link GitCatCommand}.
|
||||||
@@ -53,15 +50,8 @@ import sonia.scm.repository.GitConstants;
|
|||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public class GitCatCommandTest extends AbstractGitCommandTestBase
|
public class GitCatCommandTest extends AbstractGitCommandTestBase {
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests cat command with default branch.
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultBranch() throws IOException, RepositoryException {
|
public void testDefaultBranch() throws IOException, RepositoryException {
|
||||||
// without default branch, the repository head should be used
|
// without default branch, the repository head should be used
|
||||||
@@ -75,16 +65,8 @@ public class GitCatCommandTest extends AbstractGitCommandTestBase
|
|||||||
assertEquals("a and b", execute(request));
|
assertEquals("a and b", execute(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCat() throws IOException, RepositoryException
|
public void testCat() throws IOException, RepositoryException {
|
||||||
{
|
|
||||||
CatCommandRequest request = new CatCommandRequest();
|
CatCommandRequest request = new CatCommandRequest();
|
||||||
|
|
||||||
request.setPath("a.txt");
|
request.setPath("a.txt");
|
||||||
@@ -92,36 +74,37 @@ public class GitCatCommandTest extends AbstractGitCommandTestBase
|
|||||||
assertEquals("a and b", execute(request));
|
assertEquals("a and b", execute(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleCat() throws IOException, RepositoryException
|
public void testSimpleCat() throws IOException, RepositoryException {
|
||||||
{
|
|
||||||
CatCommandRequest request = new CatCommandRequest();
|
CatCommandRequest request = new CatCommandRequest();
|
||||||
|
|
||||||
request.setPath("b.txt");
|
request.setPath("b.txt");
|
||||||
assertEquals("b", execute(request));
|
assertEquals("b", execute(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Test(expected = PathNotFoundException.class)
|
||||||
* Method description
|
public void testUnknownFile() throws IOException, RepositoryException {
|
||||||
*
|
CatCommandRequest request = new CatCommandRequest();
|
||||||
*
|
|
||||||
* @param request
|
request.setPath("unknown");
|
||||||
*
|
assertEquals("b", execute(request));
|
||||||
* @return
|
}
|
||||||
*
|
|
||||||
* @throws IOException
|
@Test
|
||||||
* @throws RepositoryException
|
public void testSimpleStream() throws IOException, RepositoryException {
|
||||||
*/
|
CatCommandRequest request = new CatCommandRequest();
|
||||||
private String execute(CatCommandRequest request)
|
request.setPath("b.txt");
|
||||||
throws IOException, RepositoryException
|
|
||||||
{
|
InputStream catResultStream = new GitCatCommand(createContext(), repository).getCatResultStream(request);
|
||||||
|
|
||||||
|
assertEquals('b', catResultStream.read());
|
||||||
|
assertEquals('\n', catResultStream.read());
|
||||||
|
assertEquals(-1, catResultStream.read());
|
||||||
|
|
||||||
|
catResultStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String execute(CatCommandRequest request) throws IOException, RepositoryException {
|
||||||
String content = null;
|
String content = null;
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user