Skip to content

Commit

Permalink
Merge pull request #105 from RandomInEqualities/operations
Browse files Browse the repository at this point in the history
Allow copy and delete of ant default exclude files
jonesbusy authored Jul 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 886dac4 + b5c3e8f commit 9d4e1eb
Showing 8 changed files with 462 additions and 36 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -70,6 +70,12 @@
<version>1.87</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.20</version>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
31 changes: 27 additions & 4 deletions src/main/java/sp/sd/fileoperations/FileCopyOperation.java
Original file line number Diff line number Diff line change
@@ -11,8 +11,10 @@
import org.jenkinsci.Symbol;
import org.jenkinsci.remoting.RoleChecker;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import java.io.File;
import hudson.util.DirScanner;
import java.io.Serializable;

public class FileCopyOperation extends FileOperation implements Serializable {
@@ -23,6 +25,7 @@ public class FileCopyOperation extends FileOperation implements Serializable {
private final boolean renameFiles;
private final String sourceCaptureExpression;
private final String targetNameExpression;
private Boolean useDefaultExcludes;

@DataBoundConstructor
public FileCopyOperation(String includes,
@@ -39,6 +42,7 @@ public FileCopyOperation(String includes,
this.renameFiles = renameFiles;
this.sourceCaptureExpression = sourceCaptureExpression;
this.targetNameExpression = targetNameExpression;
this.useDefaultExcludes = true;
}

public String getIncludes() {
@@ -69,6 +73,10 @@ public String getTargetNameExpression() {
return targetNameExpression;
}

public boolean getUseDefaultExcludes() {
return useDefaultExcludes;
}

public boolean runOperation(Run<?, ?> run, FilePath buildWorkspace, Launcher launcher, TaskListener listener) {
boolean result = false;
try {
@@ -83,7 +91,8 @@ public boolean runOperation(Run<?, ?> run, FilePath buildWorkspace, Launcher lau
flattenFiles,
renameFiles,
sourceCaptureExpression,
targetNameExpression));
targetNameExpression,
useDefaultExcludes));
} catch (RuntimeException e) {
listener.getLogger().println(e.getMessage());
throw e;
@@ -108,6 +117,7 @@ private static final class TargetFileCallable implements FileCallable<Boolean> {
private final boolean renameFiles;
private final String sourceCaptureExpression;
private final String targetNameExpression;
private final boolean useDefaultExcludes;

public TargetFileCallable(TaskListener Listener,
String ResolvedIncludes,
@@ -116,7 +126,8 @@ public TargetFileCallable(TaskListener Listener,
boolean flattenFiles,
boolean renameFiles,
String sourceCaptureExpression,
String targetNameExpression) {
String targetNameExpression,
boolean UseDefaultExcludes) {
this.listener = Listener;
this.resolvedIncludes = ResolvedIncludes;
this.resolvedExcludes = ResolvedExcludes;
@@ -125,6 +136,7 @@ public TargetFileCallable(TaskListener Listener,
this.renameFiles = renameFiles;
this.sourceCaptureExpression = sourceCaptureExpression;
this.targetNameExpression = targetNameExpression;
this.useDefaultExcludes = UseDefaultExcludes;
}

@Override
@@ -133,7 +145,7 @@ public Boolean invoke(File ws, VirtualChannel channel) {
try {
FilePath fpWS = new FilePath(ws);
FilePath fpTL = new FilePath(fpWS, resolvedTargetLocation);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes, useDefaultExcludes);
if (resolvedFiles.length == 0) {
listener.getLogger().println("0 files found for include pattern '" + resolvedIncludes + "' and exclude pattern '" + resolvedExcludes + "'");
}
@@ -158,7 +170,7 @@ public Boolean invoke(File ws, VirtualChannel channel) {
for (FilePath item : resolvedFiles) {
listener.getLogger().println(item.getRemote());
}
fpWS.copyRecursiveTo(resolvedIncludes, resolvedExcludes, fpTL);
fpWS.copyRecursiveTo(new DirScanner.Glob(resolvedIncludes, resolvedExcludes, useDefaultExcludes), fpTL, resolvedIncludes);
result = true;
}
} catch (RuntimeException e) {
@@ -183,6 +195,17 @@ public static class DescriptorImpl extends FileOperationDescriptor {
public String getDisplayName() {
return "File Copy";
}
}

@DataBoundSetter
public void setUseDefaultExcludes(boolean useDefaultExcludes) {
this.useDefaultExcludes = useDefaultExcludes;
}

protected Object readResolve() {
if (useDefaultExcludes == null) {
useDefaultExcludes = true;
}
return this;
}
}
26 changes: 23 additions & 3 deletions src/main/java/sp/sd/fileoperations/FileDeleteOperation.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@

import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import java.io.File;

@@ -21,11 +22,13 @@
public class FileDeleteOperation extends FileOperation implements Serializable {
private final String includes;
private final String excludes;
private Boolean useDefaultExcludes;

@DataBoundConstructor
public FileDeleteOperation(String includes, String excludes) {
this.includes = includes;
this.excludes = excludes;
this.useDefaultExcludes = true;
}

public String getIncludes() {
@@ -36,14 +39,18 @@ public String getExcludes() {
return excludes;
}

public boolean getUseDefaultExcludes() {
return useDefaultExcludes;
}

public boolean runOperation(Run<?, ?> run, FilePath buildWorkspace, Launcher launcher, TaskListener listener) {
boolean result = false;
try {
listener.getLogger().println("File Delete Operation:");
EnvVars envVars = run.getEnvironment(listener);
try {
FilePath ws = new FilePath(buildWorkspace, ".");
result = ws.act(new TargetFileCallable(listener, envVars.expand(includes), envVars.expand(excludes)));
result = ws.act(new TargetFileCallable(listener, envVars.expand(includes), envVars.expand(excludes), useDefaultExcludes));
} catch (Exception e) {
listener.fatalError(e.getMessage());
return false;
@@ -60,19 +67,21 @@ private static final class TargetFileCallable implements FileCallable<Boolean> {
private final TaskListener listener;
private final String resolvedIncludes;
private final String resolvedExcludes;
private final boolean useDefaultExcludes;

public TargetFileCallable(TaskListener Listener, String ResolvedIncludes, String ResolvedExcludes) {
public TargetFileCallable(TaskListener Listener, String ResolvedIncludes, String ResolvedExcludes, boolean UseDefaultExcludes) {
this.listener = Listener;
this.resolvedIncludes = ResolvedIncludes;
this.resolvedExcludes = ResolvedExcludes;
this.useDefaultExcludes = UseDefaultExcludes;
}

@Override
public Boolean invoke(File ws, VirtualChannel channel) {
boolean result = false;
try {
FilePath fpWS = new FilePath(ws);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes, useDefaultExcludes);
if (resolvedFiles.length == 0) {
listener.getLogger().println("0 files found for include pattern '" + resolvedIncludes + "' and exclude pattern '" + resolvedExcludes + "'");
result = true;
@@ -127,6 +136,17 @@ public static class DescriptorImpl extends FileOperationDescriptor {
public String getDisplayName() {
return "File Delete";
}
}

@DataBoundSetter
public void setUseDefaultExcludes(boolean useDefaultExcludes) {
this.useDefaultExcludes = useDefaultExcludes;
}

protected Object readResolve() {
if (useDefaultExcludes == null) {
useDefaultExcludes = true;
}
return this;
}
}
26 changes: 23 additions & 3 deletions src/main/java/sp/sd/fileoperations/FileTransformOperation.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@

import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

import java.io.File;

@@ -21,11 +22,13 @@
public class FileTransformOperation extends FileOperation implements Serializable {
private final String includes;
private final String excludes;
private Boolean useDefaultExcludes;

@DataBoundConstructor
public FileTransformOperation(String includes, String excludes) {
this.includes = includes;
this.excludes = excludes;
this.useDefaultExcludes = true;
}

public String getIncludes() {
@@ -36,14 +39,18 @@ public String getExcludes() {
return excludes;
}

public boolean getUseDefaultExcludes() {
return useDefaultExcludes;
}

public boolean runOperation(Run<?, ?> run, FilePath buildWorkspace, Launcher launcher, TaskListener listener) {
boolean result = false;
try {
listener.getLogger().println("File Transform Operation:");
EnvVars envVars = run.getEnvironment(listener);
try {
FilePath ws = new FilePath(buildWorkspace, ".");
result = ws.act(new TargetFileCallable(listener, envVars.expand(includes), envVars.expand(excludes), envVars));
result = ws.act(new TargetFileCallable(listener, envVars.expand(includes), envVars.expand(excludes), useDefaultExcludes, envVars));
} catch (Exception e) {
listener.fatalError(e.getMessage());
return false;
@@ -61,11 +68,13 @@ private static final class TargetFileCallable implements FileCallable<Boolean> {
private final EnvVars environment;
private final String resolvedIncludes;
private final String resolvedExcludes;
private final boolean useDefaultExcludes;

public TargetFileCallable(TaskListener Listener, String ResolvedIncludes, String ResolvedExcludes, EnvVars environment) {
public TargetFileCallable(TaskListener Listener, String ResolvedIncludes, String ResolvedExcludes, boolean UseDefaultExcludes, EnvVars environment) {
this.listener = Listener;
this.resolvedIncludes = ResolvedIncludes;
this.resolvedExcludes = ResolvedExcludes;
this.useDefaultExcludes = UseDefaultExcludes;
this.environment = environment;
}

@@ -74,7 +83,7 @@ public Boolean invoke(File ws, VirtualChannel channel) {
boolean result = false;
try {
FilePath fpWS = new FilePath(ws);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes);
FilePath[] resolvedFiles = fpWS.list(resolvedIncludes, resolvedExcludes, useDefaultExcludes);
if (resolvedFiles.length == 0) {
listener.getLogger().println("0 files found for include pattern '" + resolvedIncludes + "' and exclude pattern '" + resolvedExcludes + "'");
result = true;
@@ -109,6 +118,17 @@ public static class DescriptorImpl extends FileOperationDescriptor {
public String getDisplayName() {
return "File Transform";
}
}

@DataBoundSetter
public void setUseDefaultExcludes(boolean useDefaultExcludes) {
this.useDefaultExcludes = useDefaultExcludes;
}

protected Object readResolve() {
if (useDefaultExcludes == null) {
useDefaultExcludes = true;
}
return this;
}
}
Original file line number Diff line number Diff line change
@@ -35,22 +35,46 @@ public void fileCopyOperation(String includes,
boolean flattenFiles,
boolean renameFiles,
String sourceCaptureExpression,
String targetNameExpression) {
String targetNameExpression,
boolean useDefaultExcludes) {
FileCopyOperation fileCopyOperation = new FileCopyOperation(includes,
excludes,
targetLocation,
flattenFiles,
renameFiles,
sourceCaptureExpression,
targetNameExpression);
excludes,
targetLocation,
flattenFiles,
renameFiles,
sourceCaptureExpression,
targetNameExpression);
fileCopyOperation.setUseDefaultExcludes(useDefaultExcludes);
fileOperations.add(fileCopyOperation);
}

public void fileDeleteOperation(String includes, String excludes) {
public void fileCopyOperation(String includes,
String excludes,
String targetLocation,
boolean flattenFiles,
boolean renameFiles,
String sourceCaptureExpression,
String targetNameExpression) {
fileCopyOperation(includes,
excludes,
targetLocation,
flattenFiles,
renameFiles,
sourceCaptureExpression,
targetNameExpression,
true);
}

public void fileDeleteOperation(String includes, String excludes, boolean useDefaultExcludes) {
FileDeleteOperation fileDeleteOperation = new FileDeleteOperation(includes, excludes);
fileDeleteOperation.setUseDefaultExcludes(useDefaultExcludes);
fileOperations.add(fileDeleteOperation);
}

public void fileDeleteOperation(String includes, String excludes) {
fileDeleteOperation(includes, excludes, true);
}

public void fileDownloadOperation(String url, String userName, String password, String targetLocation, String targetFileName, String proxyHost, String proxyPort) {
FileDownloadOperation fileDownloadOperation = new FileDownloadOperation(url, userName, password, targetLocation, targetFileName, proxyHost, proxyPort);
fileOperations.add(fileDownloadOperation);
@@ -66,11 +90,16 @@ public void filePropertiesToJsonOperation(String sourceFile, String targetFile)
fileOperations.add(filePropertiesToJsonOperation);
}

public void fileTransformOperation(String includes, String excludes) {
public void fileTransformOperation(String includes, String excludes, boolean useDefaultExcludes) {
FileTransformOperation fileTransformOperation = new FileTransformOperation(includes, excludes);
fileTransformOperation.setUseDefaultExcludes(useDefaultExcludes);
fileOperations.add(fileTransformOperation);
}

public void fileTransformOperation(String includes, String excludes) {
fileTransformOperation(includes, excludes, true);
}

Check warning on line 101 in src/main/java/sp/sd/fileoperations/dsl/FileOperationsJobDslContext.java

ci.jenkins.io / Code Coverage

Not covered lines

Lines 47-101 are not covered by tests

public void fileUnTarOperation(String filePath, String targetLocation, boolean isGZIP) {
FileUnTarOperation fileUnTarOperation = new FileUnTarOperation(filePath, targetLocation, isGZIP);
fileOperations.add(fileUnTarOperation);
139 changes: 125 additions & 14 deletions src/test/java/sp/sd/fileoperations/FileCopyOperationTest.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package sp.sd.fileoperations;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
@@ -30,19 +34,25 @@ public void testDefaults() {
assertEquals(false, fco.getRenameFiles());
assertEquals(null, fco.getSourceCaptureExpression());
assertEquals(null, fco.getTargetNameExpression());
assertEquals(true, fco.getUseDefaultExcludes());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepNoFlatten() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
// Given
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("test-results-xml/pod-0/classA/TestA.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-0/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classC/TestC.xml", ""));
fop.add(new FileCopyOperation("test-results-xml/**/*.xml", "", "test-results", false, false, null, null));

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("test-results/test-results-xml/pod-0/classA/TestA.xml").exists());
assertTrue(build.getWorkspace().child("test-results/test-results-xml/pod-0/classB/TestB.xml").exists());
@@ -53,15 +63,20 @@ public void testRunFileOperationWithFileOperationBuildStepNoFlatten() throws Exc

@Test
public void testRunFileOperationWithFileOperationBuildStepWithFlatten() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
// Given
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("test-results-xml/pod-0/classA/TestA.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-0/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classC/TestC.xml", ""));
fop.add(new FileCopyOperation("test-results-xml/**/*.xml", "", "test-results", true, false, null, null));

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("test-results/TestA.xml").exists());
assertTrue(build.getWorkspace().child("test-results/TestB.xml").exists());
@@ -70,16 +85,15 @@ public void testRunFileOperationWithFileOperationBuildStepWithFlatten() throws E

@Test
public void testRunFileOperationWithFileOperationBuildStepWithFlattenAndRename() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
// Required to handle test being run on either Windows or Unix systems
String dirSep = "(?:\\\\|/)";

// Given
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("test-results-xml/pod-0/classA/TestA.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-0/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classB/TestB.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classC/TestC.xml", ""));

// Required to handle test being run on either Windows or Unix systems
String dirSep = "(?:\\\\|/)";

fop.add(new FileCopyOperation(
"test-results-xml/**/*.xml",
"",
@@ -89,8 +103,13 @@ public void testRunFileOperationWithFileOperationBuildStepWithFlattenAndRename()
".*" + dirSep + "test-results-xml" + dirSep + ".*-([\\d]+)" +
dirSep + ".*" + dirSep + "([^" + dirSep + "]+)$",
"$1-$2"));

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("test-results/0-TestA.xml").exists());
assertTrue(build.getWorkspace().child("test-results/0-TestB.xml").exists());
@@ -103,14 +122,13 @@ public void testRunFileOperationWithFileOperationBuildStepWithFlattenAndRename()
*/
@Test
public void testFileCopyOperationForSourceCaptureExpressionExample() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("dir1/info-app.txt", ""));
fop.add(new FileCreateOperation("dir1/error-app.txt", ""));

// Required to handle test being run on either Windows or Unix systems
String dirSep = "(?:\\\\|/)";

// Given
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("dir1/info-app.txt", ""));
fop.add(new FileCreateOperation("dir1/error-app.txt", ""));
fop.add(new FileCopyOperation(
"**/dir1/*.txt",
"",
@@ -119,8 +137,13 @@ public void testFileCopyOperationForSourceCaptureExpressionExample() throws Exce
true,
"dir1" + dirSep + "(.*)-app\\.txt$",
"$1.log"));

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("logs/info.log").exists());
assertTrue(build.getWorkspace().child("logs/error.log").exists());
@@ -133,12 +156,11 @@ public void testFileCopyOperationForSourceCaptureExpressionExample() throws Exce
*/
@Test
public void testFileCopyOperationWithFlattenAndRenameFileWithoutMatchingRegex() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
// Given
List<FileOperation> fop = new ArrayList<>();
fop.add(new FileCreateOperation("test-results-xml/pod-0/classA/TestA.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-0/classA/Test-rename-A.xml", ""));
fop.add(new FileCreateOperation("test-results-xml/pod-1/classB/TestB.xml", ""));

fop.add(new FileCopyOperation(
"test-results-xml/**/*.xml",
"",
@@ -147,11 +169,100 @@ public void testFileCopyOperationWithFlattenAndRenameFileWithoutMatchingRegex()
true,
".*Test-rename-(.*)\\.xml$",
"Test$1.log"));

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("test-results/TestA.xml").exists());
assertTrue(build.getWorkspace().child("test-results/TestA.log").exists());
assertTrue(build.getWorkspace().child("test-results/TestB.xml").exists());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithDefaultExcludes() throws Exception {
// Given
FileCreateOperation fileCreateOperation = new FileCreateOperation(".gitignore", "");
FileCopyOperation fileCopyOperation = new FileCopyOperation(".gitignore", "", "output", false, false, null, null);
List<FileOperation> fop = Arrays.asList(fileCreateOperation, fileCopyOperation);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child(".gitignore").exists());
assertFalse(build.getWorkspace().child("output/.gitignore").exists());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithoutDefaultExcludes() throws Exception {
// Given
FileCreateOperation fileCreateOperation = new FileCreateOperation(".gitignore", "");
FileCopyOperation fileCopyOperation = new FileCopyOperation(".gitignore", "", "output", false, false, null, null);
fileCopyOperation.setUseDefaultExcludes(false);
List<FileOperation> fop = Arrays.asList(fileCreateOperation, fileCopyOperation);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child(".gitignore").exists());
assertTrue(build.getWorkspace().child("output/.gitignore").exists());
}

@Test
@WithoutJenkins
public void testSerializeWithXStream() {
// Given
FileCopyOperation originalObject = new FileCopyOperation("include", "exclude", "output", false, false, null, null);
originalObject.setUseDefaultExcludes(false);

// When
XStream xstream = new XStream();
xstream.addPermission(AnyTypePermission.ANY);
String serializedObjectXml = xstream.toXML(originalObject);
FileCopyOperation deserializedObject = (FileCopyOperation)xstream.fromXML(serializedObjectXml);

// Then
assertEquals(originalObject.getIncludes(), deserializedObject.getIncludes());
assertEquals(originalObject.getExcludes(), deserializedObject.getExcludes());
assertEquals(originalObject.getTargetLocation(), deserializedObject.getTargetLocation());
assertEquals(originalObject.getFlattenFiles(), deserializedObject.getFlattenFiles());
assertEquals(originalObject.getRenameFiles(), deserializedObject.getRenameFiles());
assertEquals(originalObject.getSourceCaptureExpression(), deserializedObject.getSourceCaptureExpression());
assertEquals(originalObject.getTargetNameExpression(), deserializedObject.getTargetNameExpression());
assertEquals(originalObject.getUseDefaultExcludes(), deserializedObject.getUseDefaultExcludes());
}

@Test
@WithoutJenkins
public void testSerializeWithXStreamBackwardsCompatibility() {
// Given
String serializedObjectXml =
"<FileCopyOperation>" +
" <includes>include</includes>" +
" <excludes>exclude</excludes>" +
" <targetLocation>output</targetLocation>" +
" <flattenFiles>false</flattenFiles>" +
" <renameFiles>false</renameFiles>" +
"</FileCopyOperation>";

// When
XStream xstream = new XStream();
xstream.alias("FileCopyOperation", FileCopyOperation.class);
xstream.addPermission(AnyTypePermission.ANY);
FileCopyOperation deserializedObject = (FileCopyOperation)xstream.fromXML(serializedObjectXml);

// Then
assertTrue(deserializedObject.getUseDefaultExcludes());
}
}
90 changes: 87 additions & 3 deletions src/test/java/sp/sd/fileoperations/FileDeleteOperationTest.java
Original file line number Diff line number Diff line change
@@ -2,14 +2,18 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import hudson.EnvVars;
import hudson.model.FreeStyleBuild;
import hudson.model.Result;
import hudson.model.FreeStyleProject;
import hudson.slaves.EnvironmentVariablesNodeProperty;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.Rule;
@@ -27,39 +31,119 @@ public void testDefaults() {
FileDeleteOperation fdo = new FileDeleteOperation("**/*.txt", "**/*.xml");
assertEquals("**/*.txt", fdo.getIncludes());
assertEquals("**/*.xml", fdo.getExcludes());
assertEquals(true, fdo.getUseDefaultExcludes());
}

@Test
public void testRunFileOperationWithFileOperationBuildStep() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
// Given
FileCreateOperation fco = new FileCreateOperation("NewFileName.txt", "This is File Content");
FileDeleteOperation fdo = new FileDeleteOperation("**/*.txt", "**/*.xml");
List<FileOperation> fop = new ArrayList<>();
fop.add(fco);
fop.add(fdo);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertFalse(build.getWorkspace().child("NewFileName.txt").exists());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithTokens() throws Exception {

// Given
EnvironmentVariablesNodeProperty prop = new EnvironmentVariablesNodeProperty();
EnvVars envVars = prop.getEnvVars();
envVars.put("TextFileName", "NewFileName.txt");
jenkins.jenkins.getGlobalNodeProperties().add(prop);

FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
FileCreateOperation fco = new FileCreateOperation("$TextFileName", "This is File Content");
FileDeleteOperation fdo = new FileDeleteOperation("**/*.txt", "**/*.xml");
List<FileOperation> fop = new ArrayList<>();
fop.add(fco);
fop.add(fdo);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertFalse(build.getWorkspace().child("NewFileName.txt").exists());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithDefaultExcludes() throws Exception {
// Given
FileCreateOperation fco = new FileCreateOperation(".gitignore", "This is File Content");
FileDeleteOperation fdo = new FileDeleteOperation(".gitignore", "");
List<FileOperation> fop = Arrays.asList(fco, fdo);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child(".gitignore").exists());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithoutDefaultExcludes() throws Exception {
// Given
FileCreateOperation fco = new FileCreateOperation(".gitignore", "This is File Content");
FileDeleteOperation fdo = new FileDeleteOperation(".gitignore", "");
fdo.setUseDefaultExcludes(false);
List<FileOperation> fop = Arrays.asList(fco, fdo);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertFalse(build.getWorkspace().child(".gitignore").exists());
}

@Test
@WithoutJenkins
public void testSerializeWithXStream() {
// Given
FileDeleteOperation originalObject = new FileDeleteOperation("include", "exclude");
originalObject.setUseDefaultExcludes(false);

// When
XStream xstream = new XStream();
xstream.addPermission(AnyTypePermission.ANY);
String serializedObjectXml = xstream.toXML(originalObject);
FileDeleteOperation deserializedObject = (FileDeleteOperation)xstream.fromXML(serializedObjectXml);

// Then
assertEquals(originalObject.getIncludes(), deserializedObject.getIncludes());
assertEquals(originalObject.getExcludes(), deserializedObject.getExcludes());
assertEquals(originalObject.getUseDefaultExcludes(), deserializedObject.getUseDefaultExcludes());
}

@Test
@WithoutJenkins
public void testSerializeWithXStreamBackwardsCompatibility() {
// Given
String serializedObjectXml = "<FileDeleteOperation><includes>include</includes><excludes>exclude</excludes></FileDeleteOperation>";

// When
XStream xstream = new XStream();
xstream.alias("FileDeleteOperation", FileDeleteOperation.class);
xstream.addPermission(AnyTypePermission.ANY);
FileDeleteOperation deserializedObject = (FileDeleteOperation)xstream.fromXML(serializedObjectXml);

// Then
assertTrue(deserializedObject.getUseDefaultExcludes());
}
}
133 changes: 133 additions & 0 deletions src/test/java/sp/sd/fileoperations/FileTransformOperationTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
package sp.sd.fileoperations;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.slaves.EnvironmentVariablesNodeProperty;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.WithoutJenkins;

import java.util.Arrays;
import java.util.List;

public class FileTransformOperationTest {

@Rule
public JenkinsRule jenkins = new JenkinsRule();

@@ -17,5 +34,121 @@ public void testDefaults() {
FileTransformOperation fto = new FileTransformOperation("NewFileName.config", "**/*.xml");
assertEquals("NewFileName.config", fto.getIncludes());
assertEquals("**/*.xml", fto.getExcludes());
assertEquals(true, fto.getUseDefaultExcludes());
}

static final class FileOperationPutEnvironment extends FileOperation {
public final transient JenkinsRule jenkins;
public final transient String key;
public final transient String value;

public FileOperationPutEnvironment(JenkinsRule jenkins, String key, String value) {
this.jenkins = jenkins;
this.key = key;
this.value = value;
}

public boolean runOperation(Run<?, ?> run, FilePath buildWorkspace, Launcher launcher, TaskListener listener) {
try {
EnvironmentVariablesNodeProperty prop = new EnvironmentVariablesNodeProperty();
EnvVars envVars = prop.getEnvVars();
envVars.put(key, value);
jenkins.jenkins.getGlobalNodeProperties().add(prop);
} catch (Exception e) {
fail("Unexpected exception during environment put.");
}
return true;
}
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithTokens() throws Exception {
// Given
FileCreateOperation fco = new FileCreateOperation("TestFile.txt", "$Content");
FileOperationPutEnvironment fpo = new FileOperationPutEnvironment(jenkins, "Content", "ReplacementContent");
FileTransformOperation fto = new FileTransformOperation("TestFile.txt", "");
List<FileOperation> fop = Arrays.asList(fco, fpo, fto);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertEquals("ReplacementContent", build.getWorkspace().child("TestFile.txt").readToString());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithDefaultExcludes() throws Exception {
// Given
FileCreateOperation fco = new FileCreateOperation(".gitignore", "$Content");
FileOperationPutEnvironment fpo = new FileOperationPutEnvironment(jenkins, "Content", "ReplacementContent");
FileTransformOperation fto = new FileTransformOperation(".gitignore", "");
List<FileOperation> fop = Arrays.asList(fco, fpo, fto);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child(".gitignore").exists());
assertEquals("$Content", build.getWorkspace().child(".gitignore").readToString());
}

@Test
public void testRunFileOperationWithFileOperationBuildStepWithoutDefaultExcludes() throws Exception {
// Given
FileCreateOperation fco = new FileCreateOperation(".gitignore", "$Content");
FileOperationPutEnvironment fpo = new FileOperationPutEnvironment(jenkins, "Content", "ReplacementContent");
FileTransformOperation fto = new FileTransformOperation(".gitignore", "");
fto.setUseDefaultExcludes(false);
List<FileOperation> fop = Arrays.asList(fco, fpo, fto);

// When
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();

// Then
assertEquals(Result.SUCCESS, build.getResult());
assertEquals("ReplacementContent", build.getWorkspace().child(".gitignore").readToString());
}

@Test
@WithoutJenkins
public void testSerializeWithXStream() {
// Given
FileTransformOperation originalObject = new FileTransformOperation("include", "exclude");
originalObject.setUseDefaultExcludes(false);

// When
XStream xstream = new XStream();
xstream.addPermission(AnyTypePermission.ANY);
String serializedObjectXml = xstream.toXML(originalObject);
FileTransformOperation deserializedObject = (FileTransformOperation)xstream.fromXML(serializedObjectXml);

// Then
assertEquals(originalObject.getIncludes(), deserializedObject.getIncludes());
assertEquals(originalObject.getExcludes(), deserializedObject.getExcludes());
assertEquals(originalObject.getUseDefaultExcludes(), deserializedObject.getUseDefaultExcludes());
}

@Test
@WithoutJenkins
public void testSerializeWithXStreamBackwardsCompatibility() {
// Given
String serializedObjectXml = "<FileTransformOperation><includes>include</includes><excludes>exclude</excludes></FileTransformOperation>";

// When
XStream xstream = new XStream();
xstream.alias("FileTransformOperation", FileTransformOperation.class);
xstream.addPermission(AnyTypePermission.ANY);
FileTransformOperation deserializedObject = (FileTransformOperation)xstream.fromXML(serializedObjectXml);

// Then
assertTrue(deserializedObject.getUseDefaultExcludes());
}
}

0 comments on commit 9d4e1eb

Please sign in to comment.