Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve usage of targetLocation if renameFiles and flattenFiles is used #106

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/main/java/sp/sd/fileoperations/FileCopyOperation.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package sp.sd.fileoperations;

import hudson.EnvVars;
import hudson.Launcher;
import hudson.Extension;
import hudson.FilePath;
import hudson.model.TaskListener;
import hudson.FilePath.FileCallable;
import hudson.Launcher;
import hudson.model.Run;

import hudson.model.TaskListener;
import hudson.remoting.VirtualChannel;
import org.jenkinsci.Symbol;
import org.jenkinsci.remoting.RoleChecker;
import org.kohsuke.stapler.DataBoundConstructor;

import java.io.File;

import hudson.FilePath.FileCallable;
import hudson.remoting.VirtualChannel;
import org.jenkinsci.remoting.RoleChecker;

import java.io.Serializable;

public class FileCopyOperation extends FileOperation implements Serializable {
Expand Down Expand Up @@ -143,7 +140,11 @@ public Boolean invoke(File ws, VirtualChannel channel) {
if (flattenFiles) {
for (FilePath item : resolvedFiles) {
if (renameFiles) {
String targetFileName = item.getRemote().replaceAll(sourceCaptureExpression, targetNameExpression);
final String relativePath = item.getRemote()
.replace(fpWS.getRemote(), ".");
final String relativeTargetFileName = relativePath
.replaceAll(sourceCaptureExpression, targetNameExpression);
final String targetFileName = relativePath.equals(relativeTargetFileName) ? item.getName() : relativeTargetFileName;
FilePath fpTF = new FilePath(fpTL, targetFileName);
listener.getLogger().println("Copy from " + item.getRemote() + " to " + fpTF);
item.copyTo(fpTF);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
By default, the file name of the source file is preserved. When flattening
files, this can cause problems if files of the same name exist in multiple
source sub-directories. Selecting this option allows the output file name
to be manipulated to avoid file name clashes.
to be manipulated to avoid file name clashes. Only used for setting flattenFiles: true.
</div>
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
<div>
Java-style regular expression that is run against the full path of each
Java-style regular expression that is run against the workspace relative path of each
matching source file. This should be used to capture parts of the path that
will be used in the target name expression to make each file name unique
across all subdirectories.
If path not match the regex the file is copied directly to the target location.
If the includes path is not handled within the regex the sub-directory structure will be preserved.
<p>
<strong>Example:</strong><br/>
<code>
<pre>
// folllowing structure:
// dir1/info-app.txt
// dir1/error-app.txt
fileOperations([fileCopyOperation(
includes: '**/dir1/*.txt',
targetLocation: 'logs/',
flattenFiles: true,
renameFiles: true,
sourceCaptureExpression: 'dir1/(.*)-app\\.txt$',
targetNameExpression: '$1.log')
])
</pre>
</code>
will result in:
<code>
<pre>
logs/info.log
logs/error.log
</pre>
</code>
</p>
</div>
58 changes: 57 additions & 1 deletion src/test/java/sp/sd/fileoperations/FileCopyOperationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.WithoutJenkins;

import hudson.FilePath;
import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Result;
Expand Down Expand Up @@ -98,4 +97,61 @@ public void testRunFileOperationWithFileOperationBuildStepWithFlattenAndRename()
assertTrue(build.getWorkspace().child("test-results/1-TestB.xml").exists());
assertTrue(build.getWorkspace().child("test-results/1-TestC.xml").exists());
}

/**
* @see "help-sourceCaptureExpression.html"
*/
@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 = "(?:\\\\|/)";

fop.add(new FileCopyOperation(
"**/dir1/*.txt",
"",
"logs",
true,
true,
"dir1" + dirSep + "(.*)-app\\.txt$",
"$1.log"));
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();
assertEquals(Result.SUCCESS, build.getResult());
assertTrue(build.getWorkspace().child("logs/info.log").exists());
assertTrue(build.getWorkspace().child("logs/error.log").exists());
}

/**
* Files will not be flatten because includes path is not included in sourceCaptureExpression.
*
* @see "https://github.com/jenkinsci/file-operations-plugin/issues/101"
*/
@Test
public void testFileCopyOperationWithFlattenAndRenameFileWithoutMatchingRegex() throws Exception {
FreeStyleProject p1 = jenkins.createFreeStyleProject("build1");
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",
"",
"test-results",
true,
true,
".*Test-rename-(.*)\\.xml$",
"Test$1.log"));
p1.getBuildersList().add(new FileOperationsBuilder(fop));
FreeStyleBuild build = p1.scheduleBuild2(0).get();
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());
}
}