|
33 | 33 | import java.nio.file.Files; |
34 | 34 | import java.nio.file.Path; |
35 | 35 | import java.util.LinkedHashMap; |
| 36 | +import java.util.List; |
36 | 37 | import java.util.Map; |
37 | 38 | import java.util.stream.Stream; |
38 | 39 |
|
@@ -111,25 +112,44 @@ public void create(@NotNull final URL url) throws IOException, URISyntaxExceptio |
111 | 112 | * @throws IOException on error |
112 | 113 | */ |
113 | 114 | public void copyDirectory(Path src, Path dest) throws IOException { |
| 115 | + // Create a deterministic order of paths for creation time, so last modified time indexing is stable in tests |
| 116 | + // note we cannot use Files.copy(sourceFile, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES) |
| 117 | + // as the original creation time is the user checkout and not different accross files |
| 118 | + List<Path> allPaths; |
114 | 119 | try (Stream<Path> stream = Files.walk(src)) { |
115 | | - stream.forEach(sourceFile -> { |
116 | | - if (sourceFile.equals(src)) { |
117 | | - return; |
| 120 | + allPaths = stream.filter(p -> !p.equals(src)).sorted().toList(); |
| 121 | + } |
| 122 | + // Set base time to now, and go ahead in time for each subsequent path by 1 minute |
| 123 | + java.time.Instant baseTime = java.time.Instant.now(); |
| 124 | + for (int i = 0; i < allPaths.size(); i++) { |
| 125 | + Path sourcePath = allPaths.get(i); |
| 126 | + Path destRelativePath = getDestinationRelativePath(src, sourcePath); |
| 127 | + Path destPath = dest.resolve(destRelativePath); |
| 128 | + var fileTime = java.nio.file.attribute.FileTime.from(baseTime.plusSeconds(i * 60L)); |
| 129 | + if (Files.isDirectory(sourcePath)) { |
| 130 | + if (!Files.exists(destPath)) { |
| 131 | + Files.createDirectories(destPath); |
118 | 132 | } |
119 | 133 | try { |
120 | | - Path destRelativePath = getDestinationRelativePath(src, sourceFile); |
121 | | - Path destPath = dest.resolve(destRelativePath); |
122 | | - if (Files.isDirectory(sourceFile)) { |
123 | | - if (!Files.exists(destPath)) { |
124 | | - Files.createDirectory(destPath); |
125 | | - } |
126 | | - return; |
127 | | - } |
128 | | - Files.copy(sourceFile, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES); |
129 | | - } catch (Exception e) { |
130 | | - throw new RuntimeException(e); |
| 134 | + Files.setLastModifiedTime(destPath, fileTime); |
| 135 | + Files.setAttribute(destPath, "basic:creationTime", fileTime); |
| 136 | + } catch (Exception ignored) { |
| 137 | + // Not all filesystems support creationTime |
| 138 | + } |
| 139 | + } else { |
| 140 | + // Ensure parent directory exists before copying file |
| 141 | + Path parentDir = destPath.getParent(); |
| 142 | + if (parentDir != null && !Files.exists(parentDir)) { |
| 143 | + Files.createDirectories(parentDir); |
131 | 144 | } |
132 | | - }); |
| 145 | + Files.copy(sourcePath, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES); |
| 146 | + Files.setLastModifiedTime(destPath, fileTime); |
| 147 | + try { |
| 148 | + Files.setAttribute(destPath, "basic:creationTime", fileTime); |
| 149 | + } catch (Exception ignored) { |
| 150 | + // Not all filesystems support creationTime |
| 151 | + } |
| 152 | + } |
133 | 153 | } |
134 | 154 | } |
135 | 155 |
|
|
0 commit comments