Skip to content
Permalink
Browse files

Merge pull request #42 from ikedam/feature/JENKINS-14900_Excludes

[JENKINS-14900] [JENKINS-18662] [JENKINS-23444] Fixes for filter.
  • Loading branch information...
ikedam committed Jul 20, 2014
2 parents e894206 + 247eae8 commit 13282b4c62a11477ad6451030bd692560e858304
@@ -4,9 +4,10 @@
import hudson.FilePath;
import hudson.model.AbstractBuild;
import hudson.model.Run;
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Extension point for how files are copied.
@@ -22,6 +23,8 @@
*/
public abstract class Copier implements ExtensionPoint {

private static Logger LOG = Logger.getLogger(Copier.class.getName());

/**
* Called before copy-artifact operation.
* @param src
@@ -36,22 +39,49 @@

/**
* @deprecated
* call/override {@link #copyAll(FilePath srcDir, String filter, FilePath targetDir, boolean fingerprintArtifacts)} instead.
* call/override {@link #copyAll(FilePath srcDir, String filter, String excludes, FilePath targetDir, boolean fingerprintArtifacts)} instead.
*/
public int copyAll(FilePath srcDir, String filter, FilePath targetDir) throws IOException, InterruptedException {
return copyAll(srcDir, filter, targetDir, true);
return copyAll(srcDir, filter, null, targetDir, true);
}

/**
* @deprecated
* call/override {@link #copyAll(FilePath, String, String, FilePath, boolean)} instead.
*/
@Deprecated
public int copyAll(FilePath srcDir, String filter, FilePath targetDir, boolean fingerprintArtifacts) throws IOException, InterruptedException {
return copyAll(srcDir, filter, null, targetDir, fingerprintArtifacts);
}

/**
* Copy files matching the given file mask to the specified target.
*
* You must override this when deriving {@link Copier}.
*
* @param srcDir Source directory
* @param filter Ant GLOB pattern
* @param excludes Ant GLOB pattern. Can be null.
* @param targetDir Target directory
* @param fingerprintArtifacts boolean controlling if the copy should also fingerprint the artifacts
* @return Number of files that were copied
* @see FilePath#copyRecursiveTo(String,FilePath)
*/
public abstract int copyAll(FilePath srcDir, String filter, FilePath targetDir, boolean fingerprintArtifacts) throws IOException, InterruptedException;
public int copyAll(FilePath srcDir, String filter, String excludes, FilePath targetDir, boolean fingerprintArtifacts) throws IOException, InterruptedException {
try {
Class<?> classOfCopyAll = getClass().getMethod("copyAll", FilePath.class, String.class, FilePath.class, boolean.class).getDeclaringClass();
if (!Copier.class.equals(classOfCopyAll)) {
// For backward compatibility.
// avoid cyclic invocation.
return copyAll(srcDir, filter, targetDir, fingerprintArtifacts);
}
} catch(SecurityException e) {
LOG.log(Level.WARNING, "Unexpected exception in copyartifact-plugin", e);
} catch(NoSuchMethodException e) {
LOG.log(Level.WARNING, "Unexpected exception in copyartifact-plugin", e);
}
throw new AbstractMethodError("You need override Copier#copyAll(FilePath, String, String, FilePath, boolean)");
}

/**
* @deprecated
@@ -66,6 +66,7 @@
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
@@ -86,6 +87,7 @@
private String project;
private String parameters;
private final String filter, target;
private final String excludes;
private /*almost final*/ BuildSelector selector;
@Deprecated private transient Boolean stable;
private final Boolean flatten, optional;
@@ -97,8 +99,14 @@ public CopyArtifact(String projectName, String parameters, BuildSelector selecto
this(projectName, parameters, selector, filter, target, flatten, optional, true);
}

@DataBoundConstructor
@Deprecated
public CopyArtifact(String projectName, String parameters, BuildSelector selector, String filter, String target,
boolean flatten, boolean optional, boolean fingerprintArtifacts) {
this(projectName, parameters, selector, filter, null, target, flatten, optional, fingerprintArtifacts);
}

@DataBoundConstructor
public CopyArtifact(String projectName, String parameters, BuildSelector selector, String filter, String excludes, String target,
boolean flatten, boolean optional, boolean fingerprintArtifacts) {
// check the permissions only if we can
StaplerRequest req = Stapler.getCurrentRequest();
@@ -118,6 +126,7 @@ public CopyArtifact(String projectName, String parameters, BuildSelector selecto
this.parameters = Util.fixEmptyAndTrim(parameters);
this.selector = selector;
this.filter = Util.fixNull(filter).trim();
this.excludes = Util.fixNull(excludes).trim();
this.target = Util.fixNull(target).trim();
this.flatten = flatten ? Boolean.TRUE : null;
this.optional = optional ? Boolean.TRUE : null;
@@ -204,6 +213,10 @@ public String getFilter() {
return filter;
}

public String getExcludes() {
return excludes;
}

public String getTarget() {
return target;
}
@@ -249,6 +262,7 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListene
upgradeIfNecessary(build.getProject());
PrintStream console = listener.getLogger();
String expandedProject = project, expandedFilter = filter;
String expandedExcludes = getExcludes();
try {
EnvVars env = build.getEnvironment(listener);
env.overrideAll(build.getBuildVariables()); // Add in matrix axes..
@@ -281,19 +295,23 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListene
if (target.length() > 0) targetDir = new FilePath(targetDir, env.expand(target));
expandedFilter = env.expand(filter);
if (expandedFilter.trim().length() == 0) expandedFilter = "**";
expandedExcludes = env.expand(expandedExcludes);
if (StringUtils.isBlank(expandedExcludes)) {
expandedExcludes = null;
}

Copier copier = Jenkins.getInstance().getExtensionList(Copier.class).get(0).clone();

if (Hudson.getInstance().getPlugin("maven-plugin") != null && (src instanceof MavenModuleSetBuild) ) {
// use classes in the "maven-plugin" plugin as might not be installed
// Copy artifacts from the build (ArchiveArtifacts build step)
boolean ok = perform(src, build, expandedFilter, targetDir, baseTargetDir, copier, console);
boolean ok = perform(src, build, expandedFilter, expandedExcludes, targetDir, baseTargetDir, copier, console);
// Copy artifacts from all modules of this Maven build (automatic archiving)
for (Iterator<MavenBuild> it = ((MavenModuleSetBuild)src).getModuleLastBuilds().values().iterator(); it.hasNext(); ) {
// for(Run r: ....values()) causes upcasting and loading MavenBuild compiled with jdk 1.6.
// SEE https://wiki.jenkins-ci.org/display/JENKINS/Tips+for+optional+dependencies for details.
Run<?,?> r = it.next();
ok |= perform(r, build, expandedFilter, targetDir, baseTargetDir, copier, console);
ok |= perform(r, build, expandedFilter, expandedExcludes, targetDir, baseTargetDir, copier, console);
}
return ok;
} else if (src instanceof MatrixBuild) {
@@ -302,11 +320,11 @@ public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListene
// Use MatrixBuild.getExactRuns if available
for (Run r : ((MatrixBuild) src).getExactRuns())
// Use subdir of targetDir with configuration name (like "jdk=java6u20")
ok |= perform(r, build, expandedFilter, targetDir.child(r.getParent().getName()),
ok |= perform(r, build, expandedFilter, expandedExcludes, targetDir.child(r.getParent().getName()),
baseTargetDir, copier, console);
return ok;
} else {
return perform(src, build, expandedFilter, targetDir, baseTargetDir, copier, console);
return perform(src, build, expandedFilter, expandedExcludes, targetDir, baseTargetDir, copier, console);
}
}
catch (IOException ex) {
@@ -363,7 +381,7 @@ private ItemGroup getItemGroup(AbstractBuild<?, ?> build) {
}


private boolean perform(Run src, AbstractBuild<?,?> dst, String expandedFilter, FilePath targetDir,
private boolean perform(Run src, AbstractBuild<?,?> dst, String expandedFilter, String expandedExcludes, FilePath targetDir,
FilePath baseTargetDir, Copier copier, PrintStream console)
throws IOException, InterruptedException {
FilePath srcDir = selector.getSourceDirectory(src, console);
@@ -375,10 +393,10 @@ private boolean perform(Run src, AbstractBuild<?,?> dst, String expandedFilter,
try {
int cnt;
if (!isFlatten())
cnt = copier.copyAll(srcDir, expandedFilter, targetDir, isFingerprintArtifacts());
cnt = copier.copyAll(srcDir, expandedFilter, expandedExcludes, targetDir, isFingerprintArtifacts());
else {
targetDir.mkdirs(); // Create target if needed
FilePath[] list = srcDir.list(expandedFilter);
FilePath[] list = srcDir.list(expandedFilter, expandedExcludes, false);
for (FilePath file : list)
copier.copyOne(file, new FilePath(targetDir, file.getName()), isFingerprintArtifacts());
cnt = list.length;
@@ -40,9 +40,9 @@
public class FilePathCopyMethod extends Copier {
/** @see FilePath#recursiveCopyTo(String,FilePath) */
@Override
public int copyAll(FilePath srcDir, String filter, FilePath targetDir, boolean fingerprintArtifacts)
public int copyAll(FilePath srcDir, String filter, String excludes, FilePath targetDir, boolean fingerprintArtifacts)
throws IOException, InterruptedException {
return srcDir.copyRecursiveTo(filter, targetDir);
return srcDir.copyRecursiveTo(filter, excludes, targetDir);
}

/** @see FilePath#copyTo(FilePath) */
@@ -58,9 +58,9 @@ private MessageDigest newMD5() {
}

@Override
public int copyAll(FilePath srcDir, String filter, FilePath targetDir, boolean fingerprintArtifacts) throws IOException, InterruptedException {
public int copyAll(FilePath srcDir, String filter, String excludes, FilePath targetDir, boolean fingerprintArtifacts) throws IOException, InterruptedException {
targetDir.mkdirs(); // Create target if needed
FilePath[] list = srcDir.list(filter);
FilePath[] list = srcDir.list(filter, excludes, false);
for (FilePath file : list) {
String tail = file.getRemote().substring(srcDir.getRemote().length());
if (tail.startsWith("\\") || tail.startsWith("/"))
@@ -31,6 +31,9 @@ THE SOFTWARE.
<f:entry title="${%Artifacts to copy}" field="filter">
<f:textbox/>
</f:entry>
<f:entry title="${%Artifacts not to copy}" field="excludes">
<f:textbox/>
</f:entry>
<f:entry title="${%Target directory}" field="target">
<f:textbox/>
</f:entry>
@@ -1,6 +1,7 @@
Project\ name=\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8
Which\ build=\u30D3\u30EB\u30C9
Artifacts\ to\ copy=\u30B3\u30D4\u30FC\u3059\u308B\u6210\u679C\u7269
Artifacts\ not\ to\ copy=\u30b3\u30d4\u30fc\u3057\u306a\u3044\u6210\u679c\u7269
Target\ directory=\u30B3\u30D4\u30FC\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA
Flatten\ directories=\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u69CB\u9020\u3092\u7121\u8996
Optional=\u30AA\u30D7\u30B7\u30E7\u30F3
@@ -0,0 +1,4 @@
<div>
Specify paths or patterns of artifacts to exclude, even if specified in "Artifacts to copy".
Can be blank.
</div>
@@ -0,0 +1,4 @@
<div>
「コピーする成果物」で指定したパターンに含まれるけれども除外したい成果物のパスやパターンを指定します。
必要ない場合は空のままでよいです。
</div>
@@ -1,5 +1,6 @@
<div>
Relative paths to artifact(s) to copy or leave blank to copy all artifacts.
This works just as a filter, and doesn't care whether all specified artifacts really exists.
Check the <tt>/artifact/</tt> browser of a build to see the relative paths
to use here, as the build page typically hides intermediate directories.
Can use wildcards like <tt>module/dist/**/*.zip</tt>, and use comma (followed
@@ -1,5 +1,6 @@
<div>
Hier werden relative Pfade zu einzelnen Artefakten angegeben oder freigelassen um alle Artefakte zu kopieren.
This works just as a filter, and doesn't care whether all specified artifacts really exists (requires translation).
Der <tt>/artifact/</tt> Browser eines Builds kann benutzt werden um die relativen Pfade
zu &uuml;berpr&uuml;fen, die man hier benutzen kann (die Build-Seite versteckt typischerweise die
dazwischenliegenden Verzeichnisse).
@@ -1,5 +1,6 @@
<div>
コピーする成果物の相対パスを設定します。設定しないとすべての成果物をコピーします。
この項目はコピーする成果物を絞り込むために使用され、指定した成果物自体が本当にあるかどうかは確認しません。
ビルドページでは成果物のパスは分からないので、"最新成功ビルドの成果物"リンクで相対パスを確認してください。
<tt>module/dist/**/*.zip</tt>のように、ワイルドカードを使用できます。
また、カンマを使用して(カンマの後にスペースがあっても問題ありません)複数のエントリーを設定することもできます。
Oops, something went wrong.

0 comments on commit 13282b4

Please sign in to comment.
You can’t perform that action at this time.