mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-05 07:09:48 +01:00
Detect missing paths in hg fileview command
If a not existing path is request in the fileview command, it will be treated as an empty directory. But such a thing does not exist in hg. Therefore we handle this result as what it is: a not existing path - and we throw a not found exception.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
@@ -17,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Overflow for too long branch names ([#1339](https://github.com/scm-manager/scm-manager/pull/1339))
|
||||
- Set default branch in branch selector if nothing is selected ([#1338](https://github.com/scm-manager/scm-manager/pull/1338))
|
||||
- Handling of branch with slashes in source view ([#1340](https://github.com/scm-manager/scm-manager/pull/1340))
|
||||
- Detect not existing paths correctly in Mercurial ([#1343](https://github.com/scm-manager/scm-manager/pull/1343))
|
||||
|
||||
## [2.5.0] - 2020-09-10
|
||||
### Added
|
||||
|
||||
@@ -36,6 +36,9 @@ import sonia.scm.repository.spi.javahg.HgFileviewCommand;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -93,7 +96,8 @@ public class HgBrowseCommand extends AbstractCommand implements BrowseCommand
|
||||
cmd.setLimit(request.getLimit());
|
||||
cmd.setOffset(request.getOffset());
|
||||
|
||||
FileObject file = cmd.execute();
|
||||
FileObject file = cmd.execute()
|
||||
.orElseThrow(() -> notFound(entity("File", request.getPath()).in("Revision", revision).in(getRepository())));
|
||||
return new BrowserResult(c == null? "tip": c.getNode(), revision, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.spi.javahg;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
@@ -29,12 +29,12 @@ package sonia.scm.repository.spi.javahg;
|
||||
import com.aragost.javahg.Repository;
|
||||
import com.aragost.javahg.internals.AbstractCommand;
|
||||
import com.aragost.javahg.internals.HgInputStream;
|
||||
|
||||
import sonia.scm.repository.FileObject;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Mercurial command to list files of a repository.
|
||||
@@ -161,7 +161,7 @@ public class HgFileviewCommand extends AbstractCommand
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public FileObject execute() throws IOException
|
||||
public Optional<FileObject> execute() throws IOException
|
||||
{
|
||||
cmdAppend("-t");
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.spi.javahg;
|
||||
|
||||
import com.aragost.javahg.DateTime;
|
||||
@@ -35,6 +35,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Optional;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
class HgFileviewCommandResultReader {
|
||||
|
||||
@@ -48,7 +52,7 @@ class HgFileviewCommandResultReader {
|
||||
this.disableLastCommit = disableLastCommit;
|
||||
}
|
||||
|
||||
FileObject parseResult() throws IOException {
|
||||
Optional<FileObject> parseResult() throws IOException {
|
||||
Deque<FileObject> stack = new LinkedList<>();
|
||||
|
||||
FileObject last = null;
|
||||
@@ -82,13 +86,17 @@ class HgFileviewCommandResultReader {
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
// if the stack is empty, the requested path is probably a file
|
||||
return last;
|
||||
return of(last);
|
||||
} else if (stack.size() == 1 && stack.getFirst().isDirectory() && stack.getFirst().getChildren().isEmpty()) {
|
||||
// There are no empty directories in hg. When we get this,
|
||||
// we just get the requested path as a directory, but it does not exist.
|
||||
return empty();
|
||||
} else {
|
||||
// if the stack is not empty, the requested path is a directory
|
||||
if (stream.read() == TRUNCATED_MARK) {
|
||||
stack.getLast().setTruncated(true);
|
||||
}
|
||||
return stack.getLast();
|
||||
return of(stack.getLast());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.spi.javahg;
|
||||
|
||||
import com.aragost.javahg.internals.HgInputStream;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sonia.scm.repository.FileObject;
|
||||
|
||||
@@ -34,6 +33,7 @@ import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
@@ -55,7 +55,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("b.txt", 100, time2.toEpochMilli(), "file b\nwith some\nmore text")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.isDirectory()).isTrue();
|
||||
assertThat(fileObject.getChildren())
|
||||
@@ -84,7 +84,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("a.txt")
|
||||
.truncated();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.isTruncated()).isTrue();
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("dir/a.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.isDirectory()).isTrue();
|
||||
assertThat(fileObject.getName()).isEqualTo("dir");
|
||||
@@ -117,7 +117,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("d.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.getChildren())
|
||||
.extracting("name")
|
||||
@@ -152,7 +152,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("d.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.getChildren())
|
||||
.extracting("name")
|
||||
@@ -179,7 +179,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("d.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.getChildren())
|
||||
.extracting("name")
|
||||
@@ -213,7 +213,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("directory/b.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.getChildren())
|
||||
.extracting("name")
|
||||
@@ -248,7 +248,7 @@ class HgFileviewCommandResultReaderTest {
|
||||
.file("a.txt")
|
||||
.build();
|
||||
|
||||
FileObject fileObject = reader.parseResult();
|
||||
FileObject fileObject = reader.parseResult().get();
|
||||
|
||||
assertThat(fileObject.getChildren())
|
||||
.extracting("description")
|
||||
@@ -258,6 +258,17 @@ class HgFileviewCommandResultReaderTest {
|
||||
.containsOnly(OptionalLong.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldIgnoreSingleEmptyDir() throws IOException {
|
||||
HgFileviewCommandResultReader reader = new MockInput()
|
||||
.dir("empty")
|
||||
.build();
|
||||
|
||||
Optional<FileObject> fileObject = reader.parseResult();
|
||||
|
||||
assertThat(fileObject).isEmpty();
|
||||
}
|
||||
|
||||
private HgInputStream createInputStream(String input) {
|
||||
return new HgInputStream(new ByteArrayInputStream(input.getBytes(UTF_8)), UTF_8.newDecoder());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user