From 7aa91bf8461eb9b006b23a28b1cf93a8b94bfd2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 4 Mar 2020 11:47:30 +0100 Subject: [PATCH] Implement simple implicit directories --- .../javahg/HgFileviewCommandResultReader.java | 35 +++++++++++ .../HgFileviewCommandResultReaderTest.java | 62 +++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReader.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReader.java index c8d03c7d8e..d62ab07f1c 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReader.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReader.java @@ -7,6 +7,8 @@ import sonia.scm.repository.FileObject; import sonia.scm.repository.SubRepository; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Deque; import java.util.LinkedList; @@ -34,6 +36,15 @@ class HgFileviewCommandResultReader { if (isParent(current, file)) { current.addChild(file); break; + } else if (isAncestor(current, file)) { + Collection missingParents = createMissingParents(current, file); + for (FileObject subDir : missingParents) { + current.addChild(subDir); + stack.push(subDir); + current = stack.peek(); + } + current.addChild(file); + break; } else { stack.pop(); } @@ -82,6 +93,30 @@ class HgFileviewCommandResultReader { return child.getParentPath().equals(parentPath); } + private boolean isAncestor(FileObject ancestor, FileObject child) { + String ancestorPath = ancestor.getPath(); + return child.getParentPath().startsWith(ancestorPath); + } + + private Collection createMissingParents(FileObject current, FileObject file) { + String missingPath = file.getPath().substring(current.getPath().length(), file.getPath().lastIndexOf('/')); + + FileObject directory = new FileObject(); + directory.setName(getNameFromPath(missingPath)); + directory.setDirectory(true); + directory.setPath(missingPath); + + Collection parents = new ArrayList<>(); + + if (!isParent(current, directory)) { + parents.addAll(createMissingParents(current, directory)); + } + + parents.add(directory); + + return parents; + } + private FileObject readDirectory(HgInputStream stream) throws IOException { FileObject directory = new FileObject(); String path = removeTrailingSlash(stream.textUpTo('\0')); diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReaderTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReaderTest.java index fa299877a8..9426cc4533 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReaderTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/javahg/HgFileviewCommandResultReaderTest.java @@ -118,6 +118,68 @@ class HgFileviewCommandResultReaderTest { .containsExactly(false); } + @Test + void shouldCreateDirectoriesImplicitly() throws IOException { + HgFileviewCommandResultReader reader = new MockInput() + .dir("") + .file("dir/a.txt") + .file("dir/b.txt") + .file("d.txt") + .build(); + + FileObject fileObject = reader.parseResult(); + + assertThat(fileObject.getChildren()) + .extracting("name") + .containsExactly("dir", "d.txt"); + assertThat(fileObject.getChildren()) + .extracting("directory") + .containsExactly(true, false); + + FileObject subDir = fileObject.getChildren().iterator().next(); + assertThat(subDir.getChildren()) + .extracting("name") + .containsExactly("a.txt", "b.txt"); + assertThat(subDir.getChildren()) + .extracting("directory") + .containsExactly(false, false); + } + + @Test + void shouldCreateSubSubDirectoriesImplicitly() throws IOException { + HgFileviewCommandResultReader reader = new MockInput() + .dir("") + .file("dir/more/a.txt") + .file("dir/b.txt") + .file("d.txt") + .build(); + + FileObject fileObject = reader.parseResult(); + + assertThat(fileObject.getChildren()) + .extracting("name") + .containsExactly("dir", "d.txt"); + assertThat(fileObject.getChildren()) + .extracting("directory") + .containsExactly(true, false); + + FileObject subDir = fileObject.getChildren().iterator().next(); + assertThat(subDir.getChildren()) + .extracting("name") + .containsExactly("more", "b.txt"); + assertThat(subDir.getChildren()) + .extracting("directory") + .containsExactly(true, false); + + FileObject subSubDir = subDir.getChildren().iterator().next(); + assertThat(subSubDir.getChildren()) + .extracting("name") + .containsExactly("a.txt"); + assertThat(subSubDir.getChildren()) + .extracting("directory") + .containsExactly(false); + } + @Test void shouldIgnoreTimeAndCommentWhenDisabled() throws IOException { HgFileviewCommandResultReader reader = new MockInput()