Skip to content

Commit 25ed6df

Browse files
Allow copy all files without timestamp checking by DirectoryArchiver
Implements forced options.
1 parent 991aa4c commit 25ed6df

File tree

4 files changed

+181
-50
lines changed

4 files changed

+181
-50
lines changed

src/main/java/org/codehaus/plexus/archiver/dir/DirectoryArchiver.java

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.io.File;
2121
import java.io.IOException;
22+
import java.io.InputStream;
2223
import java.nio.file.Files;
2324
import java.nio.file.attribute.FileTime;
2425
import java.util.ArrayList;
@@ -42,6 +43,15 @@
4243
public class DirectoryArchiver extends AbstractArchiver {
4344

4445
private final List<Runnable> directoryChmods = new ArrayList<>();
46+
private long filesCopied;
47+
48+
/**
49+
* Default constructor.
50+
*/
51+
public DirectoryArchiver() {
52+
// preserver default behavior
53+
setForced(false);
54+
}
4555

4656
public void resetArchiver() throws IOException {
4757
cleanUp();
@@ -67,7 +77,7 @@ public void execute() throws ArchiverException, IOException {
6777
throw new ArchiverException(destDirectory + " is not writable.");
6878
}
6979

70-
getLogger().info("Copying files to " + destDirectory.getAbsolutePath());
80+
getLogger().info("Copying files to {}", destDirectory.getAbsolutePath());
7181

7282
try {
7383
while (iter.hasNext()) {
@@ -93,6 +103,20 @@ public void execute() throws ArchiverException, IOException {
93103

94104
directoryChmods.forEach(Runnable::run);
95105
directoryChmods.clear();
106+
107+
if (filesCopied > 0) {
108+
getLogger()
109+
.info(
110+
"{} file{} copied to {}",
111+
filesCopied,
112+
filesCopied > 0 ? "s" : "",
113+
destDirectory.getAbsolutePath());
114+
} else {
115+
getLogger().info("All files are uptodate in {}", destDirectory.getAbsolutePath());
116+
}
117+
118+
filesCopied = 0;
119+
96120
} catch (final IOException ioe) {
97121
final String message = "Problem copying files : " + ioe.getMessage();
98122
throw new ArchiverException(message, ioe);
@@ -118,15 +142,20 @@ protected void copyFile(final ArchiveEntry entry, final String vPath) throws Arc
118142
final File outFile = new File(vPath);
119143

120144
final long inLastModified = in.getLastModified();
121-
final long outLastModified = outFile.lastModified();
122-
if (ResourceUtils.isUptodate(inLastModified, outLastModified)) {
123-
return;
145+
146+
if (!isForced()) {
147+
final long outLastModified = outFile.lastModified();
148+
if (ResourceUtils.isUptodate(inLastModified, outLastModified)) {
149+
return;
150+
}
124151
}
125152

126153
if (!in.isDirectory()) {
127154
makeParentDirectories(outFile);
128-
ResourceUtils.copyFile(entry.getInputStream(), outFile);
129-
155+
try (InputStream input = entry.getInputStream()) {
156+
ResourceUtils.copyFile(input, outFile);
157+
}
158+
filesCopied++;
130159
setFileModes(entry, outFile, inLastModified);
131160
} else { // file is a directory
132161
if (outFile.exists()) {
@@ -191,4 +220,9 @@ protected void close() throws IOException {}
191220
protected String getArchiveType() {
192221
return "directory";
193222
}
223+
224+
@Override
225+
public boolean isSupportingForced() {
226+
return true;
227+
}
194228
}

src/main/java/org/codehaus/plexus/archiver/util/ResourceUtils.java

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import java.io.File;
44
import java.io.IOException;
55
import java.io.InputStream;
6-
import java.io.OutputStream;
76
import java.nio.file.Files;
87

98
import org.codehaus.plexus.components.io.functions.FileSupplier;
109
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
11-
import org.codehaus.plexus.util.IOUtil;
10+
11+
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
1212

1313
/**
1414
* Utility class for work with {@link PlexusIoResource} instances.
@@ -35,16 +35,7 @@ public static boolean isUptodate(PlexusIoResource source, File destination) {
3535
* the given modification date.
3636
*/
3737
public static boolean isUptodate(PlexusIoResource source, long destinationDate) {
38-
final long s = source.getLastModified();
39-
if (s == PlexusIoResource.UNKNOWN_MODIFICATION_DATE) {
40-
return false;
41-
}
42-
43-
if (destinationDate == 0) {
44-
return false;
45-
}
46-
47-
return destinationDate > s;
38+
return isUptodate(source.getLastModified(), destinationDate);
4839
}
4940

5041
/**
@@ -60,35 +51,23 @@ public static boolean isUptodate(long sourceDate, long destinationDate) {
6051
return false;
6152
}
6253

63-
return destinationDate > sourceDate;
54+
return destinationDate >= sourceDate;
6455
}
6556

6657
/**
6758
* Copies the sources contents to the given destination file.
6859
*/
6960
public static void copyFile(PlexusIoResource in, File outFile) throws IOException {
70-
try (InputStream input = in.getContents();
71-
OutputStream output = Files.newOutputStream(outFile.toPath())) {
72-
IOUtil.copy(input, output);
61+
try (InputStream input = in.getContents()) {
62+
Files.copy(input, outFile.toPath(), REPLACE_EXISTING);
7363
}
7464
}
7565

7666
/**
7767
* Copies the sources contents to the given destination file.
7868
*/
7969
public static void copyFile(InputStream input, File outFile) throws IOException {
80-
OutputStream output = null;
81-
try {
82-
output = Files.newOutputStream(outFile.toPath());
83-
IOUtil.copy(input, output);
84-
output.close();
85-
output = null;
86-
input.close();
87-
input = null;
88-
} finally {
89-
IOUtil.close(input);
90-
IOUtil.close(output);
91-
}
70+
Files.copy(input, outFile.toPath(), REPLACE_EXISTING);
9271
}
9372

9473
/**

src/test/java/org/codehaus/plexus/archiver/jar/DirectoryArchiverUnpackJarTest.java

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
import javax.annotation.Nonnull;
44

5+
import java.io.BufferedWriter;
56
import java.io.File;
67
import java.io.IOException;
78
import java.io.InputStream;
8-
import java.nio.charset.Charset;
9+
import java.nio.charset.StandardCharsets;
10+
import java.nio.file.Files;
11+
import java.nio.file.Path;
12+
import java.nio.file.StandardOpenOption;
13+
import java.nio.file.attribute.FileTime;
914

15+
import org.apache.commons.io.FileUtils;
1016
import org.codehaus.plexus.archiver.Archiver;
1117
import org.codehaus.plexus.archiver.TestSupport;
1218
import org.codehaus.plexus.archiver.util.ArchiveEntryUtils;
@@ -15,7 +21,7 @@
1521
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
1622
import org.junit.jupiter.api.Test;
1723

18-
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
import static org.assertj.core.api.Assertions.assertThat;
1925

2026
class DirectoryArchiverUnpackJarTest extends TestSupport {
2127

@@ -36,25 +42,94 @@ public InputStream transform(@Nonnull PlexusIoResource resource, @Nonnull InputS
3642
@Test
3743
void test_dependency_sets_depSet_unpacked_rdonly() throws Exception {
3844
File src = new File("src/test/resources/unpack_issue.jar");
39-
assertTrue(src.exists());
45+
File dest = new File("target/depset_unpack");
46+
FileUtils.deleteDirectory(dest);
47+
assertThat(src).isFile();
48+
49+
Archiver archiver = createArchiver(src, dest);
50+
archiver.setDefaultDirectoryMode(0555);
51+
archiver.setDirectoryMode(0555); // causes permission denied if bug is not fixed.
52+
archiver.createArchive();
53+
assertThat(new File(dest, "child-1/META-INF/MANIFEST.MF")).isFile();
54+
55+
// make them writeable or mvn clean will fail
56+
ArchiveEntryUtils.chmod(new File(dest, "child-1/META-INF"), 0777);
57+
ArchiveEntryUtils.chmod(new File(dest, "child-1/META-INF/maven"), 0777);
58+
ArchiveEntryUtils.chmod(new File(dest, "child-1/META-INF/maven/test"), 0777);
59+
ArchiveEntryUtils.chmod(new File(dest, "child-1/META-INF/maven/test/child1"), 0777);
60+
ArchiveEntryUtils.chmod(new File(dest, "child-1/assembly-resources"), 0777);
61+
}
62+
63+
@Test
64+
void test_dependency_sets_depSet_unpacked_by_default_dont_override() throws Exception {
65+
66+
File src = new File("src/test/resources/unpack_issue.jar");
67+
File dest = new File("target/depset_unpack_dont_override");
68+
FileUtils.deleteDirectory(dest);
69+
70+
Archiver archiver = createArchiver(src, dest);
71+
archiver.createArchive();
72+
73+
File manifestFile = new File(dest, "child-1/META-INF/MANIFEST.MF");
74+
assertThat(manifestFile).content().hasLineCount(6);
75+
76+
// change content of one file
77+
overwriteFileContent(manifestFile.toPath());
78+
assertThat(manifestFile).content().hasLineCount(1);
79+
80+
archiver = createArchiver(src, dest);
81+
archiver.createArchive();
82+
83+
// content was not changed
84+
assertThat(manifestFile).content().hasLineCount(1);
85+
}
86+
87+
@Test
88+
void test_dependency_sets_depSet_force_unpacked() throws Exception {
89+
90+
File src = new File("src/test/resources/unpack_issue.jar");
91+
File dest = new File("target/depset_unpack_force");
92+
FileUtils.deleteDirectory(dest);
93+
94+
Archiver archiver = createArchiver(src, dest);
95+
archiver.createArchive();
96+
97+
File manifestFile = new File(dest, "child-1/META-INF/MANIFEST.MF");
98+
assertThat(manifestFile).content().hasLineCount(6);
99+
100+
// change content of one file
101+
overwriteFileContent(manifestFile.toPath());
102+
assertThat(manifestFile).content().hasLineCount(1);
103+
104+
archiver = createArchiver(src, dest);
105+
archiver.setForced(true);
106+
archiver.createArchive();
107+
108+
// content was changed
109+
assertThat(manifestFile).content().hasLineCount(6);
110+
}
111+
112+
private Archiver createArchiver(File src, File dest) {
113+
assertThat(src).isFile();
40114
DefaultArchivedFileSet afs = DefaultArchivedFileSet.archivedFileSet(src);
41115
afs.setIncludes(DEFAULT_INCLUDES_ARRAY);
42116
afs.setExcludes(null);
43117
afs.setPrefix("child-1/");
44118
afs.setStreamTransformer(new IdentityTransformer());
45-
Archiver archiver = (Archiver) lookup(Archiver.class, "dir");
46-
archiver.setDefaultDirectoryMode(0555);
47-
archiver.setDirectoryMode(0555); // causes permission denied if bug is not fixed.
48-
archiver.setDestFile(new File("target/depset_unpack"));
49-
archiver.addArchivedFileSet(afs, Charset.forName("UTF-8"));
50-
archiver.createArchive();
51-
assertTrue(new File("target/depset_unpack/child-1/META-INF/MANIFEST.MF").exists());
119+
Archiver archiver = lookup(Archiver.class, "dir");
120+
archiver.setDestFile(dest);
121+
archiver.addArchivedFileSet(afs, StandardCharsets.UTF_8);
122+
return archiver;
123+
}
52124

53-
// make them writeable or mvn clean will fail
54-
ArchiveEntryUtils.chmod(new File("target/depset_unpack/child-1/META-INF"), 0777);
55-
ArchiveEntryUtils.chmod(new File("target/depset_unpack/child-1/META-INF/maven"), 0777);
56-
ArchiveEntryUtils.chmod(new File("target/depset_unpack/child-1/META-INF/maven/test"), 0777);
57-
ArchiveEntryUtils.chmod(new File("target/depset_unpack/child-1/META-INF/maven/test/child1"), 0777);
58-
ArchiveEntryUtils.chmod(new File("target/depset_unpack/child-1/assembly-resources"), 0777);
125+
private void overwriteFileContent(Path path) throws IOException {
126+
FileTime lastModifiedTime = Files.getLastModifiedTime(path);
127+
128+
try (BufferedWriter writer =
129+
Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.TRUNCATE_EXISTING)) {
130+
writer.write("TEST123");
131+
}
132+
133+
Files.setLastModifiedTime(path, lastModifiedTime);
59134
}
60135
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright The Plexus developers.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.codehaus.plexus.archiver.util;
17+
18+
import java.util.stream.Stream;
19+
20+
import org.junit.jupiter.params.ParameterizedTest;
21+
import org.junit.jupiter.params.provider.Arguments;
22+
import org.junit.jupiter.params.provider.MethodSource;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
26+
class ResourceUtilsTest {
27+
28+
public static Stream<Arguments> testIsUpToDate() {
29+
return Stream.of(
30+
Arguments.of(0, 0, false), // dest and src 0
31+
Arguments.of(100, 0, false), // dest 0
32+
Arguments.of(0, 100, false), // src 0
33+
Arguments.of(100, 200, true),
34+
Arguments.of(200, 100, false),
35+
Arguments.of(100, 100, true));
36+
}
37+
38+
@ParameterizedTest
39+
@MethodSource
40+
void testIsUpToDate(long source, long destination, boolean expected) {
41+
assertThat(ResourceUtils.isUptodate(source, destination)).isEqualTo(expected);
42+
}
43+
}

0 commit comments

Comments
 (0)