Skip to content

Commit

Permalink
Recreate deleted directories per #44.
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenh committed Jan 5, 2020
1 parent b468589 commit 9c8ab36
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 38 deletions.
68 changes: 30 additions & 38 deletions src/main/java/mirror/UpdateTree.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package mirror;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.google.protobuf.TextFormat;
import org.apache.commons.lang3.StringUtils;
import org.jooq.lambda.Seq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
Expand All @@ -11,17 +21,6 @@
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.apache.commons.lang3.StringUtils;
import org.jooq.lambda.Seq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.google.protobuf.TextFormat;

/**
* A tree of file+directory metadata ({@link Update}s).
*
Expand Down Expand Up @@ -71,8 +70,7 @@ public static String toDebugString(Update u) {
}
}

@VisibleForTesting
public static UpdateTree newRoot() {
@VisibleForTesting public static UpdateTree newRoot() {
return new UpdateTree(new MirrorPaths(null, null, new PathRules(), new PathRules(), false, new ArrayList<>()));
}

Expand Down Expand Up @@ -113,12 +111,12 @@ private void addUpdate(Update update, boolean local) {
}
}

/** Invokes {@link visitor} at each node in the tree, including the root, descending until {@code visitor} returns false. */
/** Invokes {@param visitor} at each node in the tree, including the root, descending until {@code visitor} returns false. */
public void visit(Predicate<Node> visitor) {
visit(root, visitor);
}

/** Invokes {@link visitor} at each node in the tree, including the root. */
/** Invokes {@param visitor} at each node in the tree, including the root. */
public void visitAll(Consumer<Node> visitor) {
visit(root, n -> {
visitor.accept(n);
Expand All @@ -127,7 +125,7 @@ public void visitAll(Consumer<Node> visitor) {
}

/**
* Invokes {@link visitor} at each dirty node in the tree, including the root.
* Invokes {@param visitor} at each dirty node in the tree, including the root.
*
* After this method completes, all nodes are reset to clean.
*/
Expand All @@ -143,23 +141,14 @@ public void visitDirty(Consumer<Node> visitor) {
});
}

@Override
public String toString() {
@Override public String toString() {
StringBuilder sb = new StringBuilder();
visitAll(
node -> sb
.append(
node.getPath() //
+ " local="
+ node.local.getModTime()
+ " remote="
+ node.remote.getModTime())
.append("\n"));
visitAll(node -> sb.append(node.getPath() //
+ " local=" + node.local.getModTime() + " remote=" + node.remote.getModTime()).append("\n"));
return sb.toString();
}

@VisibleForTesting
Node find(String path) {
@VisibleForTesting Node find(String path) {
if ("".equals(path)) {
return root;
}
Expand All @@ -173,14 +162,15 @@ Node find(String path) {
return current;
}

@VisibleForTesting
List<Node> getChildren() {
@VisibleForTesting List<Node> getChildren() {
return root.children;
}

public enum NodeType {
File, Directory, Symlink
};
}

;

/** Either a directory or file within the tree. */
public class Node {
Expand Down Expand Up @@ -265,10 +255,13 @@ boolean isLocalNewer() {
}

boolean isNewer(Update a, Update b) {
return a != null
&& (b == null || sanityCheckTimestamp(a.getModTime()) > sanityCheckTimestamp(b.getModTime()))
&& !(a.getDelete() && (b == null || b.getDelete())) // ignore no-op deletes
&& !(!a.getDelete() && UpdateTree.isDirectory(a) && b != null && UpdateTree.isDirectory(b)); // modtimes on existing dirs don't matter
if (a == null) {
return false;
}
boolean isNewer = b == null || (sanityCheckTimestamp(a.getModTime()) > sanityCheckTimestamp(b.getModTime()));
boolean isNoopDelete = a.getDelete() && (b == null || b.getDelete());
boolean isDirModtimeChange = !a.getDelete() && UpdateTree.isDirectory(a) && b != null && UpdateTree.isDirectory(b) && !b.getDelete();
return isNewer && !isNoopDelete && !isDirModtimeChange;
}

boolean isParentDeleted() {
Expand Down Expand Up @@ -384,8 +377,7 @@ void setIgnoreRules(String ignoreData) {
});
}

@Override
public String toString() {
@Override public String toString() {
return name;
}

Expand Down
8 changes: 8 additions & 0 deletions src/test/java/mirror/UpdateTreeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ public void isNewerForDirectoriesDoesNotCareAboutModTime() {
assertThat(root.getChildren().get(0).isRemoteNewer(), is(false));
}

@Test
public void isNewerForDeletedDirectoriesDoesCareAboutModTime() {
root.addLocal(Update.newBuilder().setPath("foo").setDirectory(true).setModTime(3).build());
root.addRemote(Update.newBuilder().setPath("foo").setDirectory(true).setDelete(true).setModTime(2).build());
assertThat(root.getChildren().get(0).isLocalNewer(), is(true));
assertThat(root.getChildren().get(0).isRemoteNewer(), is(false));
}

@Test
public void isNewerForDeletedDirectoryDoesCareAboutModTime() {
root.addLocal(Update.newBuilder().setPath("foo").setDirectory(true).setDelete(true).setModTime(2).build());
Expand Down

0 comments on commit 9c8ab36

Please sign in to comment.