diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a280266e..177ba28f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -7,12 +7,18 @@ Look for contribution areas in the
## Background
-Plugin source code is hosted on https://github.com/jenkinsci/parameterized-trigger-plugin[GitHub].
-New feature proposals and bug fix proposals should be submitted as https://help.github.com/articles/creating-a-pull-request[GitHub pull requests].
-Your pull request will be evaluated by the https://ci.jenkins.io/job/Plugins/job/parameterized-trigger-plugin/[Jenkins job].
+Plugin source code is hosted on [GitHub](https://github.com/jenkinsci/parameterized-trigger-plugin).
+New feature proposals and bug fix proposals should be submitted as [GitHub pull requests](https://help.github.com/articles/creating-a-pull-request).
+Your pull request will be evaluated by the [Jenkins job](https://ci.jenkins.io/job/Plugins/job/parameterized-trigger-plugin/).
-Before submitting your change, please assure that you've added tests to verify your change.
-Tests help us assure that we're delivering a reliable plugin, and that we've communicated our intent to other developers as executable descriptions of plugin behavior.
+Before submitting your change, please assure that you've added tests which verify your change.
+
+## Code formatting
+
+Source code and pom file formatting is maintained by the `spotless` maven plugin.
+Before submitting a pull request, confirm the formatting is correct with:
+
+* `mvn spotless:apply`
## Building and Testing
@@ -24,11 +30,29 @@ Compile the plugin without running tests using the command:
* `mvn clean -DskipTests verify`
+### Reviewing code coverage
+
Code coverage reporting is available as a maven target.
Please try to improve code coverage with tests when you submit.
* `mvn -P enable-jacoco clean install jacoco:report` to report code coverage
+The code coverage report is a set of HTML files that show methods and lines executed.
+The following commands will open the `index.html` file in the browser.
+
+* Windows - `start target\site\jacoco\index.html`
+* Linux - `xdg-open target/site/jacoco/index.html`
+* Gitpod - `cd target/site/jacoco && python -m http.server 8000`
+
+The file will have a list of package names.
+Click on them to find a list of class names.
+
+The lines of the code will be covered in three different colors, red, green, and orange.
+Red lines are not covered in the tests.
+Green lines are covered with tests.
+
+### Spotbugs static analysis
+
Please don't introduce new spotbugs output.
* `mvn spotbugs:check` to analyze project using https://spotbugs.github.io/[Spotbugs].
diff --git a/pom.xml b/pom.xml
index 7c6116b4..a1ab6f61 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,3 +1,4 @@
+
4.0.0
@@ -8,6 +9,12 @@
+ parameterized-trigger
+ ${changelist}
+ hpi
+ Jenkins Parameterized Trigger plugin
+ https://github.com/jenkinsci/parameterized-trigger-plugin
+
The MIT License (MIT)
@@ -16,16 +23,38 @@
- parameterized-trigger
- hpi
- ${changelist}
- Jenkins Parameterized Trigger plugin
- https://github.com/jenkinsci/parameterized-trigger-plugin
+
+ scm:git:https://github.com/${gitHubRepo}.git
+ scm:git:git@github.com:${gitHubRepo}.git
+ ${scmTag}
+ https://github.com/${gitHubRepo}
+
+
+
+ 999999-SNAPSHOT
+ jenkinsci/parameterized-trigger-plugin
+ 2.387.3
+ Max
+ Low
+ false
+
+
+
+
+
+ io.jenkins.tools.bom
+ bom-2.387.x
+ 2543.vfb_1a_5fb_9496d
+ pom
+ import
+
+
+
org.jenkins-ci.plugins
- subversion
+ conditional-buildstep
true
@@ -50,24 +79,33 @@
org.jenkins-ci.plugins
- conditional-buildstep
+ script-security
+
+
+ org.jenkins-ci.plugins
+ subversion
true
+
+ org.awaitility
+ awaitility
+ 4.2.0
+ test
+
org.jenkins-ci.plugins
apache-httpcomponents-client-4-api
test
-
- org.jenkins-ci.plugins.workflow
- workflow-job
+ org.jenkins-ci.plugins
+ matrix-auth
test
- org.jenkins-ci.plugins.workflow
- workflow-cps
+ org.jenkins-ci.plugins
+ token-macro
test
@@ -75,14 +113,20 @@
workflow-basic-steps
test
+
+ org.jenkins-ci.plugins.workflow
+ workflow-cps
+ test
+
org.jenkins-ci.plugins.workflow
workflow-durable-task-step
test
+
org.jenkins-ci.plugins.workflow
- workflow-support
+ workflow-job
test
@@ -91,8 +135,8 @@
test
- org.jenkins-ci.plugins
- matrix-auth
+ org.jenkins-ci.plugins.workflow
+ workflow-support
test
@@ -100,42 +144,8 @@
mockito-core
test
-
- org.jenkins-ci.plugins
- script-security
-
-
- org.jenkins-ci.plugins
- token-macro
- test
-
-
- org.awaitility
- awaitility
- 4.2.0
- test
-
-
-
-
- io.jenkins.tools.bom
- bom-2.387.x
- 2543.vfb_1a_5fb_9496d
- import
- pom
-
-
-
-
-
- scm:git:https://github.com/${gitHubRepo}.git
- scm:git:git@github.com:${gitHubRepo}.git
- https://github.com/${gitHubRepo}
- ${scmTag}
-
-
repo.jenkins-ci.org
@@ -149,12 +159,4 @@
https://repo.jenkins-ci.org/public/
-
-
- 999999-SNAPSHOT
- jenkinsci/parameterized-trigger-plugin
- 2.387.3
- Max
- Low
-
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactory.java b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactory.java
index 8ddc6b77..e99e2d60 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactory.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactory.java
@@ -4,7 +4,6 @@
import hudson.model.AbstractBuild;
import hudson.model.AbstractDescribableImpl;
import hudson.model.TaskListener;
-
import java.io.IOException;
import java.util.List;
@@ -12,7 +11,8 @@
* Generates Build Parameters. These will can be used in the TriggerBuilder to trigger the same projects with many different
* parameters.
*/
-public abstract class AbstractBuildParameterFactory extends AbstractDescribableImpl implements ExtensionPoint {
+public abstract class AbstractBuildParameterFactory extends AbstractDescribableImpl
+ implements ExtensionPoint {
/**
* Let N be the length of the list returned by this method, and each item in this list X1, X2, X3, ... XN.
*
@@ -24,14 +24,14 @@ public abstract class AbstractBuildParameterFactory extends AbstractDescribableI
* The build which the parameterized trigger is configured and executing.
* @param listener
* Connected to the build output.
- *
+ *
* @return can be empty but never null.
*/
- public abstract List getParameters(AbstractBuild,?> build, TaskListener listener)
+ public abstract List getParameters(AbstractBuild, ?> build, TaskListener listener)
throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException;
@Override
public AbstractBuildParameterFactoryDescriptor getDescriptor() {
- return (AbstractBuildParameterFactoryDescriptor)super.getDescriptor();
+ return (AbstractBuildParameterFactoryDescriptor) super.getDescriptor();
}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactoryDescriptor.java b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactoryDescriptor.java
index a36f8583..1b9ba966 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactoryDescriptor.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameterFactoryDescriptor.java
@@ -15,6 +15,5 @@ public AbstractBuildParameterFactoryDescriptor(Class extends AbstractBuildPara
super(clazz);
}
- public AbstractBuildParameterFactoryDescriptor() {
- }
+ public AbstractBuildParameterFactoryDescriptor() {}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameters.java b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameters.java
index 07e202ba..8a5a72be 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameters.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/AbstractBuildParameters.java
@@ -9,7 +9,6 @@
import hudson.model.Queue;
import hudson.model.Queue.Task;
import hudson.model.TaskListener;
-
import java.io.IOException;
/**
@@ -20,7 +19,8 @@
*
* @see Queue#schedule(Task, int, Action...)
*/
-public abstract class AbstractBuildParameters extends AbstractDescribableImpl implements ExtensionPoint {
+public abstract class AbstractBuildParameters extends AbstractDescribableImpl
+ implements ExtensionPoint {
/**
*
@@ -29,13 +29,13 @@ public abstract class AbstractBuildParameters extends AbstractDescribableImpl build, TaskListener listener)
+ public abstract Action getAction(AbstractBuild, ?> build, TaskListener listener)
throws IOException, InterruptedException, DontTriggerException;
/**
* Retrieve the build environment from the upstream build
*/
- public EnvVars getEnvironment(AbstractBuild,?> build, TaskListener listener)
+ public EnvVars getEnvironment(AbstractBuild, ?> build, TaskListener listener)
throws IOException, InterruptedException {
CapturedEnvironmentAction capture = build.getAction(CapturedEnvironmentAction.class);
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BinaryFileParameterFactory.java b/src/main/java/hudson/plugins/parameterizedtrigger/BinaryFileParameterFactory.java
index 7a05a480..8d88e3fb 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BinaryFileParameterFactory.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BinaryFileParameterFactory.java
@@ -8,8 +8,6 @@
import hudson.model.ParametersAction;
import hudson.model.TaskListener;
import hudson.plugins.parameterizedtrigger.FileBuildParameterFactory.NoFilesFoundEnum;
-import org.kohsuke.stapler.DataBoundConstructor;
-
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -17,6 +15,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
+import org.kohsuke.stapler.DataBoundConstructor;
/**
* Creates a {@link FileParameterValue} for each matching file.
@@ -36,7 +35,7 @@ public BinaryFileParameterFactory(String parameterName, String filePattern, NoFi
}
public BinaryFileParameterFactory(String parameterName, String filePattern) {
- this(parameterName,filePattern, NoFilesFoundEnum.SKIP);
+ this(parameterName, filePattern, NoFilesFoundEnum.SKIP);
}
public String getParameterName() {
@@ -52,32 +51,37 @@ public NoFilesFoundEnum getNoFilesFoundAction() {
}
@Override
- public List getParameters(AbstractBuild, ?> build, TaskListener listener) throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
+ public List getParameters(AbstractBuild, ?> build, TaskListener listener)
+ throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
List result = new ArrayList<>();
FilePath workspace = build.getWorkspace();
if (workspace == null) {
throw new IOException("Failed to get workspace");
}
try {
- // save them into the master because FileParameterValue might need files after the agent workspace have disappeared/reused
+ // save them into the master because FileParameterValue might need files after the agent workspace have
+ // disappeared/reused
FilePath target = new FilePath(build.getRootDir()).child("parameter-files");
int n = workspace.copyRecursiveTo(getFilePattern(), target);
- if (n==0) {
+ if (n == 0) {
noFilesFoundAction.failCheck(listener);
} else {
- for(final FilePath f: target.list(getFilePattern())) {
+ for (final FilePath f : target.list(getFilePattern())) {
LOGGER.fine("Triggering build with " + f.getName());
result.add(new AbstractBuildParameters() {
@Override
- public Action getAction(AbstractBuild,?> build, TaskListener listener) throws IOException, InterruptedException, DontTriggerException {
- assert f.getChannel()==null; // we copied files locally. This file must be local to the master
- FileParameterValue fv = new FileParameterValue(parameterName, new File(f.getRemote()), f.getName());
-
- if ($setLocation!=null) {
+ public Action getAction(AbstractBuild, ?> build, TaskListener listener)
+ throws IOException, InterruptedException, DontTriggerException {
+ assert f.getChannel()
+ == null; // we copied files locally. This file must be local to the master
+ FileParameterValue fv =
+ new FileParameterValue(parameterName, new File(f.getRemote()), f.getName());
+
+ if ($setLocation != null) {
try {
- $setLocation.invoke(fv,parameterName);
+ $setLocation.invoke(fv, parameterName);
} catch (IllegalAccessException | InvocationTargetException e) {
// be defensive as the core might change
}
@@ -94,7 +98,6 @@ public Action getAction(AbstractBuild,?> build, TaskListener listener) throws
return result;
}
-
@Extension
public static class DescriptorImpl extends AbstractBuildParameterFactoryDescriptor {
@Override
@@ -108,11 +111,12 @@ public String getDisplayName() {
static {
// work around NPE fixed in the core at 4a95cc6f9269108e607077dc9fd57f06e4c9af26
try {
- $setLocation = FileParameterValue.class.getDeclaredMethod("setLocation",String.class);
+ $setLocation = FileParameterValue.class.getDeclaredMethod("setLocation", String.class);
$setLocation.setAccessible(true);
} catch (NoSuchMethodException e) {
// ignore
}
}
+
private static final Logger LOGGER = Logger.getLogger(BinaryFileParameterFactory.class.getName());
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java b/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java
index d49d5284..b22f045b 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BlockableBuildTriggerConfig.java
@@ -1,7 +1,8 @@
package hudson.plugins.parameterizedtrigger;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
@@ -9,21 +10,16 @@
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.Job;
-import hudson.model.Node;
-import jenkins.model.Jenkins;
-import org.kohsuke.stapler.DataBoundConstructor;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ListMultimap;
import hudson.model.Label;
+import hudson.model.Node;
import hudson.model.TaskListener;
import hudson.model.queue.QueueTaskFuture;
-
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import jenkins.model.Jenkins;
+import org.kohsuke.stapler.DataBoundConstructor;
/**
* {@link BuildTriggerConfig} that supports blocking of the execution.
@@ -35,13 +31,18 @@ public class BlockableBuildTriggerConfig extends BuildTriggerConfig {
@SuppressFBWarnings(value = "UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD", justification = "Part of the public API")
public boolean buildAllNodesWithLabel;
- public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, List configs) {
+ public BlockableBuildTriggerConfig(
+ String projects, BlockingBehaviour block, List configs) {
super(projects, ResultCondition.ALWAYS, false, configs);
this.block = block;
}
@DataBoundConstructor
- public BlockableBuildTriggerConfig(String projects, BlockingBehaviour block, List configFactories,List configs) {
+ public BlockableBuildTriggerConfig(
+ String projects,
+ BlockingBehaviour block,
+ List configFactories,
+ List configs) {
super(projects, ResultCondition.ALWAYS, false, configFactories, configs, false);
this.block = block;
}
@@ -51,56 +52,63 @@ public BlockingBehaviour getBlock() {
}
@Override
- public List> perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ public List> perform(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
List> r = super.perform(build, launcher, listener);
- if (block==null) return Collections.emptyList();
+ if (block == null) return Collections.emptyList();
return r;
}
@Override
- public ListMultimap> perform2(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
- ListMultimap> futures = super.perform2(build, launcher, listener);
- if(block==null) return ArrayListMultimap.create();
+ public ListMultimap> perform2(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
+ ListMultimap> futures =
+ super.perform2(build, launcher, listener);
+ if (block == null) return ArrayListMultimap.create();
return futures;
}
@Override
- public ListMultimap> perform3(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ public ListMultimap> perform3(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
ListMultimap> futures = super.perform3(build, launcher, listener);
- if(block==null) return ArrayListMultimap.create();
+ if (block == null) return ArrayListMultimap.create();
return futures;
}
@Override
- protected QueueTaskFuture schedule(AbstractBuild, ?> build, Job project, List list, TaskListener listener) throws InterruptedException, IOException {
- if (block!=null) {
+ protected QueueTaskFuture schedule(AbstractBuild, ?> build, Job project, List list, TaskListener listener)
+ throws InterruptedException, IOException {
+ if (block != null) {
while (true) {
// add DifferentiatingAction to make sure this doesn't get merged with something else,
// which is most likely unintended. Might make sense to do it at BuildTriggerConfig for all.
list = CollectionUtils.immutableList(list, new DifferentiatingAction());
-
// if we fail to add the item to the queue, wait and retry.
// it also means we have to force quiet period = 0, or else it'll never leave the queue
QueueTaskFuture f = schedule(build, project, 0, list, listener);
- // When a project is disabled or the configuration is not yet saved f will always be null and we're caught in a loop, therefore we need to check for it
- if (f != null || !canBeScheduled(project)){
+ // When a project is disabled or the configuration is not yet saved f will always be null and we're
+ // caught in a loop, therefore we need to check for it
+ if (f != null || !canBeScheduled(project)) {
return f;
}
Thread.sleep(1000);
}
} else {
- return super.schedule(build,project,list,listener);
+ return super.schedule(build, project, list, listener);
}
}
public Collection getNodes() {
Label label = Jenkins.get().getLabel("asrt");
- if (label==null) return Collections.emptyList();
+ if (label == null) return Collections.emptyList();
return label.getNodes();
}
@Extension
- public static class DescriptorImpl extends BuildTriggerConfig.DescriptorImpl {
- }
+ public static class DescriptorImpl extends BuildTriggerConfig.DescriptorImpl {}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BlockingBehaviour.java b/src/main/java/hudson/plugins/parameterizedtrigger/BlockingBehaviour.java
index 90f5974b..65d71f0f 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BlockingBehaviour.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BlockingBehaviour.java
@@ -25,18 +25,17 @@
package hudson.plugins.parameterizedtrigger;
-import hudson.model.AbstractDescribableImpl;
-import org.apache.commons.lang.StringUtils;
+import static hudson.model.Result.*;
+
+import edu.umd.cs.findbugs.annotations.CheckForNull;
import hudson.Extension;
+import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import hudson.model.Result;
-import org.kohsuke.stapler.DataBoundConstructor;
-
-import edu.umd.cs.findbugs.annotations.CheckForNull;
import java.util.Arrays;
import java.util.List;
-
-import static hudson.model.Result.*;
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
/**
* Determines how to handle the status of the triggered builds in {@link TriggerBuilder}.
@@ -56,7 +55,7 @@ public BlockingBehaviour(String buildStepFailureThreshold, String unstableThresh
}
private Result parse(String t) {
- if(StringUtils.isBlank(t) || "never".equals(t)) {
+ if (StringUtils.isBlank(t) || "never".equals(t)) {
return null;
}
return Result.fromString(t);
@@ -67,10 +66,10 @@ public BlockingBehaviour(Result buildStepFailureThreshold, Result unstableThresh
this.unstableThreshold = unstableThreshold;
this.failureThreshold = failureThreshold;
}
-
+
/**
* Maps the result of a triggered build to the result of the triggering build step.
- *
+ *
* @param r the {@link Result} of the triggered build to map
* @return {@code false} if the triggering build step has to fail, {@code true} otherwise
*/
@@ -80,14 +79,14 @@ public boolean mapBuildStepResult(Result r) {
/**
* Maps the result of a triggered build to the result of the triggering build.
- *
+ *
* @param r the {@link Result} of the triggered build to map
* @return the result of the triggering build
*/
@CheckForNull
public Result mapBuildResult(Result r) {
- if (failureThreshold!=null && r.isWorseOrEqualTo(failureThreshold)) return FAILURE;
- if (unstableThreshold!=null && r.isWorseOrEqualTo(unstableThreshold)) return UNSTABLE;
+ if (failureThreshold != null && r.isWorseOrEqualTo(failureThreshold)) return FAILURE;
+ if (unstableThreshold != null && r.isWorseOrEqualTo(unstableThreshold)) return UNSTABLE;
return null;
}
@@ -99,7 +98,7 @@ public String getDisplayName() {
}
public List getAllResults() {
- return Arrays.asList(SUCCESS,UNSTABLE,FAILURE);
+ return Arrays.asList(SUCCESS, UNSTABLE, FAILURE);
}
}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameterConfig.java b/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameterConfig.java
index 5486936e..f0a18aed 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameterConfig.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameterConfig.java
@@ -33,34 +33,34 @@
*
* @author Chris Johnson
*/
-public class BooleanParameterConfig implements Describable{
+public class BooleanParameterConfig implements Describable {
- private final String name;
- private final boolean value;
+ private final String name;
+ private final boolean value;
- @DataBoundConstructor
- public BooleanParameterConfig(String name, boolean value) {
- this.name = name;
- this.value = value;
- }
- public boolean getValue() {
- return value;
- }
+ @DataBoundConstructor
+ public BooleanParameterConfig(String name, boolean value) {
+ this.name = name;
+ this.value = value;
+ }
- public String getName() {
- return name;
- }
+ public boolean getValue() {
+ return value;
+ }
- public Descriptor getDescriptor() {
- return Jenkins.get().getDescriptorOrDie(getClass());
- }
-
-
- @Extension
- public static class DescriptorImpl extends Descriptor {
- @Override
- public String getDisplayName() {
- return ""; // unused
- }
- }
+ public String getName() {
+ return name;
+ }
+
+ public Descriptor getDescriptor() {
+ return Jenkins.get().getDescriptorOrDie(getClass());
+ }
+
+ @Extension
+ public static class DescriptorImpl extends Descriptor {
+ @Override
+ public String getDisplayName() {
+ return ""; // unused
+ }
+ }
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameters.java b/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameters.java
index 6ef0ee22..5859e2ed 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameters.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BooleanParameters.java
@@ -32,10 +32,8 @@
import hudson.model.ParametersAction;
import hudson.model.TaskListener;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
-
import org.kohsuke.stapler.DataBoundConstructor;
/**
@@ -44,34 +42,33 @@
*/
public class BooleanParameters extends AbstractBuildParameters {
- private final List configs;
+ private final List configs;
- @DataBoundConstructor
- public BooleanParameters(List configs ){
- this.configs = configs;
- }
+ @DataBoundConstructor
+ public BooleanParameters(List configs) {
+ this.configs = configs;
+ }
- @Override
- public Action getAction(AbstractBuild, ?> build, TaskListener listener) throws IOException, InterruptedException, DontTriggerException {
+ @Override
+ public Action getAction(AbstractBuild, ?> build, TaskListener listener)
+ throws IOException, InterruptedException, DontTriggerException {
- List values = configs
- .stream()
- .map( config -> new BooleanParameterValue(config.getName(), config.getValue()) )
- .collect( Collectors.toList() );
+ List values = configs.stream()
+ .map(config -> new BooleanParameterValue(config.getName(), config.getValue()))
+ .collect(Collectors.toList());
- return new ParametersAction(values);
- }
+ return new ParametersAction(values);
+ }
- public List getConfigs() {
- return configs;
- }
+ public List getConfigs() {
+ return configs;
+ }
- @Extension
- public static class DescriptorImpl extends Descriptor {
- @Override
- public String getDisplayName() {
- return "Boolean parameters";
- }
-
- }
+ @Extension
+ public static class DescriptorImpl extends Descriptor {
+ @Override
+ public String getDisplayName() {
+ return "Boolean parameters";
+ }
+ }
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BuildInfoExporterAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/BuildInfoExporterAction.java
index 1898ec4a..3c1764e3 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BuildInfoExporterAction.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BuildInfoExporterAction.java
@@ -30,16 +30,14 @@
import hudson.model.AbstractProject;
import hudson.model.EnvironmentContributingAction;
import hudson.model.Result;
-import jenkins.model.Jenkins;
-import org.kohsuke.stapler.export.Exported;
-import org.kohsuke.stapler.export.ExportedBean;
-
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
+import jenkins.model.Jenkins;
+import org.kohsuke.stapler.export.Exported;
+import org.kohsuke.stapler.export.ExportedBean;
@ExportedBean
public class BuildInfoExporterAction implements EnvironmentContributingAction {
@@ -51,7 +49,7 @@ public class BuildInfoExporterAction implements EnvironmentContributingAction {
public static final String BUILD_RESULT_VARIABLE_PREFIX = "TRIGGERED_BUILD_RESULT_";
public static final String BUILD_RUN_COUNT_PREFIX = "TRIGGERED_BUILD_RUN_COUNT_";
public static final String RUN = "_RUN_";
- //now unused as part of map
+ // now unused as part of map
private transient String buildName;
private transient int buildNumber;
@@ -70,11 +68,13 @@ public BuildInfoExporterAction(BuildReference buildRef) {
lastReference = buildRef;
}
- public BuildInfoExporterAction(String buildName, int buildNumber, AbstractBuild, ?> parentBuild, Result buildResult) {
+ public BuildInfoExporterAction(
+ String buildName, int buildNumber, AbstractBuild, ?> parentBuild, Result buildResult) {
this(new BuildReference(buildName, buildNumber, buildResult));
}
- static BuildInfoExporterAction addBuildInfoExporterAction(AbstractBuild, ?> parentBuild, String triggeredProject, int buildNumber, Result buildResult) {
+ static BuildInfoExporterAction addBuildInfoExporterAction(
+ AbstractBuild, ?> parentBuild, String triggeredProject, int buildNumber, Result buildResult) {
BuildInfoExporterAction action = parentBuild.getAction(BuildInfoExporterAction.class);
if (action == null) {
action = new BuildInfoExporterAction(triggeredProject, buildNumber, parentBuild, buildResult);
@@ -85,7 +85,8 @@ static BuildInfoExporterAction addBuildInfoExporterAction(AbstractBuild, ?> pa
return action;
}
- static BuildInfoExporterAction addBuildInfoExporterAction(AbstractBuild, ?> parentBuild, String triggeredProject) {
+ static BuildInfoExporterAction addBuildInfoExporterAction(
+ AbstractBuild, ?> parentBuild, String triggeredProject) {
BuildInfoExporterAction action = parentBuild.getAction(BuildInfoExporterAction.class);
if (action == null) {
action = new BuildInfoExporterAction(new BuildReference(triggeredProject));
@@ -133,60 +134,58 @@ public BuildReference(final String projectName) {
}
@Override
- public String getIconFileName()
- {
- return null;
+ public String getIconFileName() {
+ return null;
}
@Override
- public String getDisplayName()
- {
- return null;
+ public String getDisplayName() {
+ return null;
}
@Override
- public String getUrlName()
- {
- return null;
+ public String getUrlName() {
+ return null;
}
@Override
public void buildEnvVars(AbstractBuild, ?> build, EnvVars env) {
- // Note: this will only indicate the last project in the list that is ran
- env.put(JOB_NAME_VARIABLE, lastReference.projectName.replaceAll("[^a-zA-Z0-9]+", "_"));
- //all projects triggered.
- // this should not include projects that don't have a build item.
- String sanitizedProjectList = getProjectListString(",");
- env.put(ALL_JOBS_NAME_VARIABLE, sanitizedProjectList);
-
- for (String project : getProjectsWithBuilds()) {
- // for each project add the following variables once
- // all buildnumbers, lastbuildnumber
- // all Run results, last build result
- String sanitizedBuildName = project.replaceAll("[^a-zA-Z0-9]+", "_");
- List refs = getBuildRefs(project);
-
- env.put(ALL_BUILD_NUMBER_VARIABLE_PREFIX + sanitizedBuildName, getBuildNumbersString(refs, ","));
- env.put(BUILD_RUN_COUNT_PREFIX + sanitizedBuildName, Integer.toString(refs.size()));
- for (BuildReference br : refs) {
- if (br.buildNumber != 0) {
- String triggeredBuildRunResultKey = BUILD_RESULT_VARIABLE_PREFIX + sanitizedBuildName + RUN + Integer.toString(br.buildNumber);
- env.put(triggeredBuildRunResultKey, br.buildResult.toString());
- }
- }
- BuildReference lastBuild = null;
- for (int i = (refs.size()); i > 0; i--) {
- if (refs.get(i - 1).buildNumber != 0) {
- lastBuild = refs.get(i - 1);
- }
- break;
+ // Note: this will only indicate the last project in the list that is ran
+ env.put(JOB_NAME_VARIABLE, lastReference.projectName.replaceAll("[^a-zA-Z0-9]+", "_"));
+ // all projects triggered.
+ // this should not include projects that don't have a build item.
+ String sanitizedProjectList = getProjectListString(",");
+ env.put(ALL_JOBS_NAME_VARIABLE, sanitizedProjectList);
+
+ for (String project : getProjectsWithBuilds()) {
+ // for each project add the following variables once
+ // all buildnumbers, lastbuildnumber
+ // all Run results, last build result
+ String sanitizedBuildName = project.replaceAll("[^a-zA-Z0-9]+", "_");
+ List refs = getBuildRefs(project);
+
+ env.put(ALL_BUILD_NUMBER_VARIABLE_PREFIX + sanitizedBuildName, getBuildNumbersString(refs, ","));
+ env.put(BUILD_RUN_COUNT_PREFIX + sanitizedBuildName, Integer.toString(refs.size()));
+ for (BuildReference br : refs) {
+ if (br.buildNumber != 0) {
+ String triggeredBuildRunResultKey =
+ BUILD_RESULT_VARIABLE_PREFIX + sanitizedBuildName + RUN + Integer.toString(br.buildNumber);
+ env.put(triggeredBuildRunResultKey, br.buildResult.toString());
+ }
+ }
+ BuildReference lastBuild = null;
+ for (int i = (refs.size()); i > 0; i--) {
+ if (refs.get(i - 1).buildNumber != 0) {
+ lastBuild = refs.get(i - 1);
+ }
+ break;
+ }
+ if (lastBuild != null) {
+ env.put(BUILD_NUMBER_VARIABLE_PREFIX + sanitizedBuildName, Integer.toString(lastBuild.buildNumber));
+ env.put(BUILD_RESULT_VARIABLE_PREFIX + sanitizedBuildName, lastBuild.buildResult.toString());
+ }
}
- if (lastBuild != null) {
- env.put(BUILD_NUMBER_VARIABLE_PREFIX + sanitizedBuildName, Integer.toString(lastBuild.buildNumber));
- env.put(BUILD_RESULT_VARIABLE_PREFIX + sanitizedBuildName, lastBuild.buildResult.toString());
- }
- }
}
private List getBuildRefs(String project) {
@@ -207,120 +206,120 @@ private List getBuildRefs(String project) {
@Exported(visibility = 1)
public List> getTriggeredBuilds() {
- List> builds = new ArrayList<>();
-
- for (BuildReference br : this.builds) {
- AbstractProject, ? extends AbstractBuild, ?>> project =
- Jenkins.get().getItemByFullName(br.projectName, AbstractProject.class);
- if (br.buildNumber != 0) {
- builds.add((project != null)?project.getBuildByNumber(br.buildNumber):null);
- }
- }
- return builds;
- }
+ List> builds = new ArrayList<>();
- /**
- * Gets all the projects that triggered from this one which were non blocking,
- * which we don't have a builds for. Does not include builds that are returned
- * in #link{getTriggeredBuilds} Used in the UI for see Summary.groovy
- *
- * @return List of Projects that are triggered by this build. May contains null if a project is deleted.
- */
- @Exported(visibility = 1)
- public List> getTriggeredProjects() {
- List> projects = new ArrayList<>();
-
- for (BuildReference br : this.builds) {
- if (br.buildNumber == 0) {
+ for (BuildReference br : this.builds) {
AbstractProject, ? extends AbstractBuild, ?>> project =
Jenkins.get().getItemByFullName(br.projectName, AbstractProject.class);
- projects.add(project);
+ if (br.buildNumber != 0) {
+ builds.add((project != null) ? project.getBuildByNumber(br.buildNumber) : null);
+ }
}
+ return builds;
}
- return projects;
- }
-
- /**
- * Handle cases from older builds so that they still add old variables if
- * needed to. Should not show any UI as there will be no data added.
- *
- * @return
- */
- public Object readResolve() {
- if (this.lastReference == null) {
- this.lastReference = new BuildReference(this.buildName, this.buildNumber, Result.NOT_BUILT);
- }
- if (this.builds == null) {
- this.builds = new ArrayList<>();
+
+ /**
+ * Gets all the projects that triggered from this one which were non blocking,
+ * which we don't have a builds for. Does not include builds that are returned
+ * in #link{getTriggeredBuilds} Used in the UI for see Summary.groovy
+ *
+ * @return List of Projects that are triggered by this build. May contains null if a project is deleted.
+ */
+ @Exported(visibility = 1)
+ public List> getTriggeredProjects() {
+ List> projects = new ArrayList<>();
+
+ for (BuildReference br : this.builds) {
+ if (br.buildNumber == 0) {
+ AbstractProject, ? extends AbstractBuild, ?>> project =
+ Jenkins.get().getItemByFullName(br.projectName, AbstractProject.class);
+ projects.add(project);
+ }
+ }
+ return projects;
}
- if (this.buildRefs != null) {
- for (List buildReferences : buildRefs.values()) {
- this.builds.addAll(buildReferences);
+
+ /**
+ * Handle cases from older builds so that they still add old variables if
+ * needed to. Should not show any UI as there will be no data added.
+ *
+ * @return
+ */
+ public Object readResolve() {
+ if (this.lastReference == null) {
+ this.lastReference = new BuildReference(this.buildName, this.buildNumber, Result.NOT_BUILT);
+ }
+ if (this.builds == null) {
+ this.builds = new ArrayList<>();
}
+ if (this.buildRefs != null) {
+ for (List buildReferences : buildRefs.values()) {
+ this.builds.addAll(buildReferences);
+ }
+ }
+ return this;
}
- return this;
- }
-
- /**
- * Gets a string for all of the build numbers
- *
- * @param refs List of build references to process.
- * @param separator
- * @return String containing all the build numbers from refs, never null but
- * can be empty
- */
- private String getBuildNumbersString(List refs, String separator) {
- StringBuilder buf = new StringBuilder();
- boolean first = true;
-
- for (BuildReference s : refs) {
- if (s.buildNumber != 0) {
- if (first) {
- first = false;
- } else {
- buf.append(separator);
+
+ /**
+ * Gets a string for all of the build numbers
+ *
+ * @param refs List of build references to process.
+ * @param separator
+ * @return String containing all the build numbers from refs, never null but
+ * can be empty
+ */
+ private String getBuildNumbersString(List refs, String separator) {
+ StringBuilder buf = new StringBuilder();
+ boolean first = true;
+
+ for (BuildReference s : refs) {
+ if (s.buildNumber != 0) {
+ if (first) {
+ first = false;
+ } else {
+ buf.append(separator);
+ }
+ buf.append(s.buildNumber);
+ }
}
- buf.append(s.buildNumber);
- }
+ return buf.toString();
}
- return buf.toString();
- }
-
- /**
- * Get a list of projects as a string using the separator
- *
- * @param separator
- * @return list of projects separated by separator
- */
- protected String getProjectListString(String separator) {
- Set refs = getProjectsWithBuilds();
- StringBuilder buf = new StringBuilder();
- boolean first = true;
-
- for (String s : refs) {
- if (first) {
- first = false;
- } else {
- buf.append(separator);
- }
- buf.append(s.replaceAll("[^a-zA-Z0-9]+", "_"));
+
+ /**
+ * Get a list of projects as a string using the separator
+ *
+ * @param separator
+ * @return list of projects separated by separator
+ */
+ protected String getProjectListString(String separator) {
+ Set refs = getProjectsWithBuilds();
+ StringBuilder buf = new StringBuilder();
+ boolean first = true;
+
+ for (String s : refs) {
+ if (first) {
+ first = false;
+ } else {
+ buf.append(separator);
+ }
+ buf.append(s.replaceAll("[^a-zA-Z0-9]+", "_"));
+ }
+ return buf.toString();
}
- return buf.toString();
- }
-
- /**
- * Gets the unique set of project names that have a linked build.
- *
- * @return Set of project names that have at least one build linked.
- */
- private Set getProjectsWithBuilds() {
- Set projects = new HashSet();
-
- for (BuildReference br : this.builds) {
- if (br.buildNumber != 0) {
- projects.add(br.projectName);
+
+ /**
+ * Gets the unique set of project names that have a linked build.
+ *
+ * @return Set of project names that have at least one build linked.
+ */
+ private Set getProjectsWithBuilds() {
+ Set projects = new HashSet();
+
+ for (BuildReference br : this.builds) {
+ if (br.buildNumber != 0) {
+ projects.add(br.projectName);
+ }
}
+ return projects;
}
- return projects;
- }
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTrigger.java b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTrigger.java
index 0bf7cc7b..c8b3d4d9 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTrigger.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTrigger.java
@@ -18,10 +18,6 @@
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
-import jenkins.model.DependencyDeclarer;
-import jenkins.model.Jenkins;
-import org.kohsuke.stapler.DataBoundConstructor;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -32,167 +28,168 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
+import jenkins.model.DependencyDeclarer;
+import jenkins.model.Jenkins;
+import org.kohsuke.stapler.DataBoundConstructor;
public class BuildTrigger extends Notifier implements DependencyDeclarer {
- private final ArrayList configs;
+ private final ArrayList configs;
@DataBoundConstructor
- public BuildTrigger(List configs) {
- this.configs = new ArrayList<>(Util.fixNull(configs));
- }
-
- public BuildTrigger(BuildTriggerConfig... configs) {
- this(Arrays.asList(configs));
- }
-
- public List getConfigs() {
- return configs;
- }
-
- @Override
- public boolean needsToRunAfterFinalized() {
- return true;
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- @Override
- public Collection extends Action> getProjectActions(AbstractProject, ?> project) {
- return Collections.singletonList(new DynamicProjectAction(configs));
- }
-
- @Override @SuppressWarnings("deprecation")
- public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
- Map downstreamMap = new HashMap<>();
- Map buildMap = new HashMap<>();
- boolean hasEnvVariables = false;
-
- HashSet alreadyFired = new HashSet<>();
-
- // If this project has non-abstract projects, we need to fire them
- for (BuildTriggerConfig config : configs) {
- boolean hasNonAbstractProject = false;
- hasEnvVariables = hasEnvVariables || hasEnvVariables(config, build.getEnvironment(listener));
-
- List jobs = config.getJobs(build.getRootBuild().getProject().getParent(), build.getEnvironment(listener));
-
-
- for (Job j : jobs) {
- if (!(j instanceof AbstractProject)) {
- hasNonAbstractProject = true;
- break;
- }
- }
- // Fire this config's projects if not already fired
- if (hasNonAbstractProject) {
- config.perform(build, launcher, listener);
- alreadyFired.add(config);
- }
- }
-
- if (canDeclare(build.getProject()) && !hasEnvVariables) {
- // job will get triggered by dependency graph, so we have to capture buildEnvironment NOW before
- // hudson.model.AbstractBuild.AbstractBuildExecution#cleanUp is called and reset
- EnvVars env = build.getEnvironment(listener);
- build.addAction(new CapturedEnvironmentAction(env));
- }
- else { // Not using dependency graph
- for (BuildTriggerConfig config : configs) {
- if (!alreadyFired.contains(config)) {
- //config.perform(build, launcher, listener);
- List> futures = config.perform(build, launcher, listener);
- for (QueueTaskFuture future : futures) {
- AbstractBuild abstractBuild = null;
- try {
- abstractBuild = (AbstractBuild) future.get();
- if (null != abstractBuild) {
- downstreamMap.put(abstractBuild.getProject().getFullName(), abstractBuild);
- }
- } catch (ExecutionException e) {
- listener.getLogger().println("Failed to execute downstream build");
- }
- }
-
- String[] projects = config.getProjects(build.getEnvironment(listener)).split(",");
- String[] vars = config.getProjects().split(",");
- for (int i = 0; i < projects.length; i++) {
- if (vars[i].trim().contains("$")) {
- AbstractBuild abstractBuild = downstreamMap.get(projects[i]);
- if (null != abstractBuild) {
- listener.getLogger().println(makeLogEntry(projects[i].trim()));
- buildMap.put(abstractBuild.getProject().getFullName(), abstractBuild.getNumber());
- }
- }
- }
-
- }
- DynamicBuildAction action = new DynamicBuildAction(buildMap);
- build.addAction(action);
- }
- }
-
- return true;
- }
-
- private String makeLogEntry(String name) {
- String url = name;
- url = Jenkins.get().getRootUrl() + "job/" + url.replaceAll("/", "/job/");
- name = name.replaceAll("/", " » ");
- String link = ModelHyperlinkNote.encodeTo(url, name);
- StringBuilder sb = new StringBuilder();
- sb.append("Triggering a new build of ");
- sb.append(link);
- return sb.toString();
- }
-
- private boolean hasEnvVariables(BuildTriggerConfig config, EnvVars env) {
- return !config.getProjects().equalsIgnoreCase(config.getProjects(env));
- }
-
- @Override
- public void buildDependencyGraph(AbstractProject owner, DependencyGraph graph) {
- if (!canDeclare(owner)) return;
-
- for (BuildTriggerConfig config : configs) {
- List projectList = config.getProjectList(owner.getParent(), null);
- for (AbstractProject project : projectList) {
- if (config.isTriggerFromChildProjects() && owner instanceof ItemGroup) {
- ItemGroup- parent = (ItemGroup) owner;
- for (Item item : parent.getItems()) {
- if(item instanceof AbstractProject){
- AbstractProject child = (AbstractProject) item;
- ParameterizedDependency.add(child, project, config, graph);
- }
- }
- }
- else{
- ParameterizedDependency.add(owner, project, config, graph);
-
- }
- }
- }
- }
-
- private boolean canDeclare(AbstractProject owner) {
- // See HUDSON-5679 -- dependency graph is also not used when triggered from a promotion
- return !owner.getClass().getName().equals("hudson.plugins.promoted_builds.PromotionProcess");
- }
-
- @Extension
- public static class DescriptorImpl extends BuildStepDescriptor {
- @Override
- public String getDisplayName() {
- return "Trigger parameterized build on other projects";
- }
-
- @Override
- public boolean isApplicable(Class extends AbstractProject> jobType) {
- return true;
- }
-
- }
+ public BuildTrigger(List configs) {
+ this.configs = new ArrayList<>(Util.fixNull(configs));
+ }
+
+ public BuildTrigger(BuildTriggerConfig... configs) {
+ this(Arrays.asList(configs));
+ }
+
+ public List getConfigs() {
+ return configs;
+ }
+
+ @Override
+ public boolean needsToRunAfterFinalized() {
+ return true;
+ }
+
+ @Override
+ public BuildStepMonitor getRequiredMonitorService() {
+ return BuildStepMonitor.NONE;
+ }
+
+ @Override
+ public Collection extends Action> getProjectActions(AbstractProject, ?> project) {
+ return Collections.singletonList(new DynamicProjectAction(configs));
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
+ Map downstreamMap = new HashMap<>();
+ Map buildMap = new HashMap<>();
+ boolean hasEnvVariables = false;
+
+ HashSet alreadyFired = new HashSet<>();
+
+ // If this project has non-abstract projects, we need to fire them
+ for (BuildTriggerConfig config : configs) {
+ boolean hasNonAbstractProject = false;
+ hasEnvVariables = hasEnvVariables || hasEnvVariables(config, build.getEnvironment(listener));
+
+ List jobs =
+ config.getJobs(build.getRootBuild().getProject().getParent(), build.getEnvironment(listener));
+
+ for (Job j : jobs) {
+ if (!(j instanceof AbstractProject)) {
+ hasNonAbstractProject = true;
+ break;
+ }
+ }
+ // Fire this config's projects if not already fired
+ if (hasNonAbstractProject) {
+ config.perform(build, launcher, listener);
+ alreadyFired.add(config);
+ }
+ }
+
+ if (canDeclare(build.getProject()) && !hasEnvVariables) {
+ // job will get triggered by dependency graph, so we have to capture buildEnvironment NOW before
+ // hudson.model.AbstractBuild.AbstractBuildExecution#cleanUp is called and reset
+ EnvVars env = build.getEnvironment(listener);
+ build.addAction(new CapturedEnvironmentAction(env));
+ } else { // Not using dependency graph
+ for (BuildTriggerConfig config : configs) {
+ if (!alreadyFired.contains(config)) {
+ // config.perform(build, launcher, listener);
+ List> futures = config.perform(build, launcher, listener);
+ for (QueueTaskFuture future : futures) {
+ AbstractBuild abstractBuild = null;
+ try {
+ abstractBuild = (AbstractBuild) future.get();
+ if (null != abstractBuild) {
+ downstreamMap.put(abstractBuild.getProject().getFullName(), abstractBuild);
+ }
+ } catch (ExecutionException e) {
+ listener.getLogger().println("Failed to execute downstream build");
+ }
+ }
+
+ String[] projects =
+ config.getProjects(build.getEnvironment(listener)).split(",");
+ String[] vars = config.getProjects().split(",");
+ for (int i = 0; i < projects.length; i++) {
+ if (vars[i].trim().contains("$")) {
+ AbstractBuild abstractBuild = downstreamMap.get(projects[i]);
+ if (null != abstractBuild) {
+ listener.getLogger().println(makeLogEntry(projects[i].trim()));
+ buildMap.put(abstractBuild.getProject().getFullName(), abstractBuild.getNumber());
+ }
+ }
+ }
+ }
+ DynamicBuildAction action = new DynamicBuildAction(buildMap);
+ build.addAction(action);
+ }
+ }
+
+ return true;
+ }
+
+ private String makeLogEntry(String name) {
+ String url = name;
+ url = Jenkins.get().getRootUrl() + "job/" + url.replaceAll("/", "/job/");
+ name = name.replaceAll("/", " » ");
+ String link = ModelHyperlinkNote.encodeTo(url, name);
+ StringBuilder sb = new StringBuilder();
+ sb.append("Triggering a new build of ");
+ sb.append(link);
+ return sb.toString();
+ }
+
+ private boolean hasEnvVariables(BuildTriggerConfig config, EnvVars env) {
+ return !config.getProjects().equalsIgnoreCase(config.getProjects(env));
+ }
+
+ @Override
+ public void buildDependencyGraph(AbstractProject owner, DependencyGraph graph) {
+ if (!canDeclare(owner)) return;
+
+ for (BuildTriggerConfig config : configs) {
+ List projectList = config.getProjectList(owner.getParent(), null);
+ for (AbstractProject project : projectList) {
+ if (config.isTriggerFromChildProjects() && owner instanceof ItemGroup) {
+ ItemGroup
- parent = (ItemGroup) owner;
+ for (Item item : parent.getItems()) {
+ if (item instanceof AbstractProject) {
+ AbstractProject child = (AbstractProject) item;
+ ParameterizedDependency.add(child, project, config, graph);
+ }
+ }
+ } else {
+ ParameterizedDependency.add(owner, project, config, graph);
+ }
+ }
+ }
+ }
+
+ private boolean canDeclare(AbstractProject owner) {
+ // See HUDSON-5679 -- dependency graph is also not used when triggered from a promotion
+ return !owner.getClass().getName().equals("hudson.plugins.promoted_builds.PromotionProcess");
+ }
+
+ @Extension
+ public static class DescriptorImpl extends BuildStepDescriptor {
+ @Override
+ public String getDisplayName() {
+ return "Trigger parameterized build on other projects";
+ }
+
+ @Override
+ public boolean isApplicable(Class extends AbstractProject> jobType) {
+ return true;
+ }
+ }
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java
index a81a192b..e261c296 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/BuildTriggerConfig.java
@@ -2,17 +2,20 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
+import edu.umd.cs.findbugs.annotations.CheckForNull;
+import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.Extension;
import hudson.Launcher;
+import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.AutoCompletionCandidates;
import hudson.model.BuildListener;
import hudson.model.Cause;
-import hudson.model.CauseAction;
import hudson.model.Cause.UpstreamCause;
+import hudson.model.CauseAction;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Item;
@@ -22,27 +25,12 @@
import hudson.model.ParametersAction;
import hudson.model.Run;
import hudson.model.TaskListener;
-import hudson.model.queue.Tasks;
import hudson.model.queue.QueueTaskFuture;
+import hudson.model.queue.Tasks;
import hudson.plugins.parameterizedtrigger.AbstractBuildParameters.DontTriggerException;
import hudson.plugins.promoted_builds.Promotion;
import hudson.security.ACL;
-import hudson.Util;
import hudson.util.FormValidation;
-import hudson.util.VersionNumber;
-
-import jenkins.model.Jenkins;
-import jenkins.model.ParameterizedJobMixIn;
-import jenkins.security.QueueItemAuthenticatorConfiguration;
-import org.acegisecurity.Authentication;
-import org.apache.commons.lang.StringUtils;
-import org.kohsuke.accmod.Restricted;
-import org.kohsuke.accmod.restrictions.DoNotUse;
-import org.kohsuke.stapler.AncestorInPath;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-
-import edu.umd.cs.findbugs.annotations.CheckForNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -55,24 +43,38 @@
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.acegisecurity.AccessDeniedException;
-import edu.umd.cs.findbugs.annotations.NonNull;
+import jenkins.model.Jenkins;
+import jenkins.model.ParameterizedJobMixIn;
import jenkins.security.QueueItemAuthenticator;
+import jenkins.security.QueueItemAuthenticatorConfiguration;
+import org.acegisecurity.AccessDeniedException;
+import org.acegisecurity.Authentication;
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.DoNotUse;
+import org.kohsuke.stapler.AncestorInPath;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
public class BuildTriggerConfig implements Describable {
-
+
private static final Logger LOGGER = Logger.getLogger(BuildTriggerConfig.class.getName());
- private final List configs;
+ private final List configs;
private final List configFactories;
- private String projects;
- private final ResultCondition condition;
- private final boolean triggerWithNoParameters;
- private final boolean triggerFromChildProjects;
+ private String projects;
+ private final ResultCondition condition;
+ private final boolean triggerWithNoParameters;
+ private final boolean triggerFromChildProjects;
- public BuildTriggerConfig(String projects, ResultCondition condition, boolean triggerWithNoParameters,
- List configFactories, List configs, boolean triggerFromChildProjects) {
+ public BuildTriggerConfig(
+ String projects,
+ ResultCondition condition,
+ boolean triggerWithNoParameters,
+ List configFactories,
+ List configs,
+ boolean triggerFromChildProjects) {
this.projects = projects;
this.condition = condition;
this.triggerWithNoParameters = triggerWithNoParameters;
@@ -82,58 +84,70 @@ public BuildTriggerConfig(String projects, ResultCondition condition, boolean tr
}
@Deprecated
- public BuildTriggerConfig(String projects, ResultCondition condition,
- boolean triggerWithNoParameters, List configFactories, List configs) {
+ public BuildTriggerConfig(
+ String projects,
+ ResultCondition condition,
+ boolean triggerWithNoParameters,
+ List configFactories,
+ List configs) {
this(projects, condition, triggerWithNoParameters, configFactories, configs, false);
}
@DataBoundConstructor
- public BuildTriggerConfig(String projects, ResultCondition condition,
- boolean triggerWithNoParameters, List configs, boolean triggerFromChildProjects) {
+ public BuildTriggerConfig(
+ String projects,
+ ResultCondition condition,
+ boolean triggerWithNoParameters,
+ List configs,
+ boolean triggerFromChildProjects) {
this(projects, condition, triggerWithNoParameters, null, configs, triggerFromChildProjects);
}
-
- public BuildTriggerConfig(String projects, ResultCondition condition,
- boolean triggerWithNoParameters, List configs) {
+
+ public BuildTriggerConfig(
+ String projects,
+ ResultCondition condition,
+ boolean triggerWithNoParameters,
+ List configs) {
this(projects, condition, triggerWithNoParameters, null, configs, false);
}
- public BuildTriggerConfig(String projects, ResultCondition condition,
- AbstractBuildParameters... configs) {
- this(projects, condition, false, null, Arrays.asList(configs), false);
- }
+ public BuildTriggerConfig(String projects, ResultCondition condition, AbstractBuildParameters... configs) {
+ this(projects, condition, false, null, Arrays.asList(configs), false);
+ }
- public BuildTriggerConfig(String projects, ResultCondition condition,
+ public BuildTriggerConfig(
+ String projects,
+ ResultCondition condition,
List configFactories,
- AbstractBuildParameters... configs) {
- this(projects, condition, false, configFactories, Arrays.asList(configs), false);
- }
+ AbstractBuildParameters... configs) {
+ this(projects, condition, false, configFactories, Arrays.asList(configs), false);
+ }
- public List getConfigs() {
- return configs;
- }
+ public List getConfigs() {
+ return configs;
+ }
public List getConfigFactories() {
return configFactories;
}
public String getProjects() {
- return projects;
- }
+ return projects;
+ }
public String getProjects(EnvVars env) {
return (env != null ? env.expand(projects) : projects);
}
- public ResultCondition getCondition() {
- return condition;
- }
+ public ResultCondition getCondition() {
+ return condition;
+ }
- public boolean getTriggerWithNoParameters() {
+ public boolean getTriggerWithNoParameters() {
return triggerWithNoParameters;
}
-
- public boolean isTriggerFromChildProjects(){
+
+ public boolean isTriggerFromChildProjects() {
return triggerFromChildProjects;
}
@@ -155,9 +169,9 @@ public List getProjectList(EnvVars env) {
* Use {@link #getJobs(ItemGroup, EnvVars)}
*/
@Deprecated
- public List getProjectList(ItemGroup context, EnvVars env) {
+ public List getProjectList(ItemGroup context, EnvVars env) {
return Util.filter(getJobs(context, env), AbstractProject.class);
- }
+ }
/**
* Get list of all projects, including workflow job types
@@ -232,7 +246,7 @@ private static void iterateBuilds(AbstractProject context, String projects, SubP
if (currentBuild == null) {
// But we can still get statically defined project
subProjectData.getFixed().addAll(readableItemsFromNameList(context.getParent(), projects, Job.class));
-
+
// Remove them from unsolved
for (Job staticProject : subProjectData.getFixed()) {
subProjectData.getUnresolved().remove(staticProject.getFullName());
@@ -254,11 +268,11 @@ private static void iterateBuilds(AbstractProject context, String projects, SubP
// If oldBuild is null then we have already examined LastSuccessfulBuild as well.
if (currentBuild != null && context.getLastSuccessfulBuild() != null) {
- resolveProject((AbstractBuild)context.getLastSuccessfulBuild(), subProjectData);
+ resolveProject((AbstractBuild) context.getLastSuccessfulBuild(), subProjectData);
}
}
}
-
+
/**
* Retrieves readable items from the list.
* @param Type of the item
@@ -272,8 +286,8 @@ private static List readableItemsFromNameList(
Jenkins hudson = Jenkins.get();
List r = new ArrayList<>();
- StringTokenizer tokens = new StringTokenizer(list,",");
- while(tokens.hasMoreTokens()) {
+ StringTokenizer tokens = new StringTokenizer(list, ",");
+ while (tokens.hasMoreTokens()) {
String fullName = tokens.nextToken().trim();
T item = null;
try {
@@ -285,8 +299,7 @@ private static List readableItemsFromNameList(
throw x;
}
}
- if(item!=null)
- r.add(item);
+ if (item != null) r.add(item);
}
return r;
}
@@ -301,7 +314,8 @@ private static List readableItemsFromNameList(
*/
private static void resolveProject(AbstractBuild build, SubProjectData subProjectData) {
- Iterator unsolvedProjectIterator = subProjectData.getUnresolved().iterator();
+ Iterator unsolvedProjectIterator =
+ subProjectData.getUnresolved().iterator();
while (unsolvedProjectIterator.hasNext()) {
@@ -324,7 +338,8 @@ private static void resolveProject(AbstractBuild build, SubProjectData subProjec
if (build != null) {
Job resolvedProject = null;
try {
- resolvedProject = Jenkins.get().getItem(unresolvedProjectName, build.getProject().getParent(), Job.class);
+ resolvedProject = Jenkins.get()
+ .getItem(unresolvedProjectName, build.getProject().getParent(), Job.class);
} catch (RuntimeException x) {
if (x.getClass().getSimpleName().startsWith("AccessDeniedException")) {
// Permission check failure (DISCOVER w/o READ) => we leave the job unresolved
@@ -340,56 +355,60 @@ private static void resolveProject(AbstractBuild build, SubProjectData subProjec
}
if (build != null && build.getAction(BuildInfoExporterAction.class) != null) {
- String triggeredProjects = build.getAction(BuildInfoExporterAction.class).getProjectListString(",");
- subProjectData.getTriggered().addAll(readableItemsFromNameList(build.getParent().getParent(), triggeredProjects, AbstractProject.class));
+ String triggeredProjects =
+ build.getAction(BuildInfoExporterAction.class).getProjectListString(",");
+ subProjectData
+ .getTriggered()
+ .addAll(readableItemsFromNameList(
+ build.getParent().getParent(), triggeredProjects, AbstractProject.class));
}
}
-
- List getBaseActions(AbstractBuild,?> build, TaskListener listener)
+ List getBaseActions(AbstractBuild, ?> build, TaskListener listener)
throws IOException, InterruptedException, DontTriggerException {
return getBaseActions(configs, build, listener);
}
- List getBaseActions(Collection configs, AbstractBuild,?> build, TaskListener listener)
+ List getBaseActions(
+ Collection configs, AbstractBuild, ?> build, TaskListener listener)
throws IOException, InterruptedException, DontTriggerException {
- List actions = new ArrayList<>();
- ParametersAction params = null;
- for (AbstractBuildParameters config : configs) {
- Action a = config.getAction(build, listener);
- if (a instanceof ParametersAction) {
- params = params == null ? (ParametersAction)a
- : ParameterizedTriggerUtils.mergeParameters(params, (ParametersAction)a);
- } else if (a != null) {
- actions.add(a);
- }
- }
- if (params != null) actions.add(params);
- return actions;
- }
-
- List getBuildActions(List baseActions, Job,?> project) {
+ List actions = new ArrayList<>();
+ ParametersAction params = null;
+ for (AbstractBuildParameters config : configs) {
+ Action a = config.getAction(build, listener);
+ if (a instanceof ParametersAction) {
+ params = params == null
+ ? (ParametersAction) a
+ : ParameterizedTriggerUtils.mergeParameters(params, (ParametersAction) a);
+ } else if (a != null) {
+ actions.add(a);
+ }
+ }
+ if (params != null) actions.add(params);
+ return actions;
+ }
+
+ List getBuildActions(List baseActions, Job, ?> project) {
List actions = new ArrayList<>(baseActions);
ProjectSpecificParametersActionFactory transformer = new ProjectSpecificParametersActionFactory(
- new ProjectSpecificParameterValuesActionTransform(),
- new DefaultParameterValuesActionsTransform()
- );
+ new ProjectSpecificParameterValuesActionTransform(), new DefaultParameterValuesActionsTransform());
return transformer.getProjectSpecificBuildActions(actions, project);
}
/**
* Note that with Hudson 1.341, trigger should be using
- * {@link BuildTrigger#buildDependencyGraph(AbstractProject, hudson.model.DependencyGraph)}.
- */
- public List> perform(AbstractBuild, ?> build, Launcher launcher,
- BuildListener listener) throws InterruptedException, IOException {
+ * {@link BuildTrigger#buildDependencyGraph(AbstractProject, hudson.model.DependencyGraph)}.
+ */
+ public List> perform(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
EnvVars env = build.getEnvironment(listener);
env.overrideAll(build.getBuildVariables());
try {
- if (condition.isMet(build.getResult())) {
+ if (condition.isMet(build.getResult())) {
QueueTaskFuture future = null;
List> futures = new ArrayList<>();
@@ -397,11 +416,10 @@ public List> perform(AbstractBuild, ?> build, L
List buildParams = new ArrayList<>(configs);
buildParams.addAll(addConfigs);
buildParams = Collections.unmodifiableList(buildParams);
- List actions = getBaseActions(buildParams,
- build, listener);
+ List actions = getBaseActions(buildParams, build, listener);
for (Job project : getJobs(build.getRootBuild().getProject().getParent(), env)) {
List list = getBuildActions(actions, project);
- //Future can be null as schedule can return null
+ // Future can be null as schedule can return null
future = schedule(build, project, list, listener);
if (future != null) {
futures.add(future);
@@ -412,47 +430,57 @@ public List> perform(AbstractBuild, ?> build, L
}
return futures;
- }
- } catch (DontTriggerException e) {
- // don't trigger on this configuration
- }
+ }
+ } catch (DontTriggerException e) {
+ // don't trigger on this configuration
+ }
return Collections.emptyList();
}
- private void reportSchedulingError(@NonNull Run, ?> run, @NonNull Job, ?> jobToTrigger, @NonNull BuildListener listener) {
+ private void reportSchedulingError(
+ @NonNull Run, ?> run, @NonNull Job, ?> jobToTrigger, @NonNull BuildListener listener) {
// Do not print details to Build Listener, they have been reported previously in #canTriggerProject()
listener.error("Skipping " + jobToTrigger.getFullName() + "...");
if (LOGGER.isLoggable(Level.CONFIG)) {
- String message = String.format("Cannot schedule project %s. Job type is not parameterized, "
- + "or there is no Job/Build permission for the current authentication %s. "
- + "Skipping...", jobToTrigger, Jenkins.getAuthentication().getName());
- LOGGER.log(Level.CONFIG, String.format("%s: %s", run, message),
- new UnsupportedOperationException("Cannot schedule job " + jobToTrigger.getFullName()));
+ String message = String.format(
+ "Cannot schedule project %s. Job type is not parameterized, "
+ + "or there is no Job/Build permission for the current authentication %s. "
+ + "Skipping...",
+ jobToTrigger, Jenkins.getAuthentication().getName());
+ LOGGER.log(
+ Level.CONFIG,
+ String.format("%s: %s", run, message),
+ new UnsupportedOperationException("Cannot schedule job " + jobToTrigger.getFullName()));
}
}
-
+
/**
- * @deprecated
- * Use {@link #perform3(AbstractBuild, Launcher, BuildListener)}
- */
+ * @deprecated
+ * Use {@link #perform3(AbstractBuild, Launcher, BuildListener)}
+ */
@Deprecated
- public ListMultimap> perform2(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ public ListMultimap> perform2(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
ListMultimap> initialResult = perform3(build, launcher, listener);
ListMultimap> output = ArrayListMultimap.create();
for (Map.Entry> entry : initialResult.entries()) {
if (entry.getKey() instanceof AbstractProject) {
// Due to type erasure we can't check if the Future is a Future
- // Plugins extending the method and dependent on the perform2 method will break if we trigger on a WorkflowJob
- output.put((AbstractProject)entry.getKey(), (QueueTaskFuture)entry.getValue());
+ // Plugins extending the method and dependent on the perform2 method will break if we trigger on a
+ // WorkflowJob
+ output.put((AbstractProject) entry.getKey(), (QueueTaskFuture) entry.getValue());
}
}
return output;
}
- //Replaces perform2 with more general form
- public ListMultimap> perform3(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
+ // Replaces perform2 with more general form
+ public ListMultimap> perform3(
+ AbstractBuild, ?> build, Launcher launcher, BuildListener listener)
+ throws InterruptedException, IOException {
EnvVars env = build.getEnvironment(listener);
env.overrideAll(build.getBuildVariables());
@@ -461,7 +489,8 @@ public ListMultimap> perform3(AbstractBuild<
ListMultimap> futures = ArrayListMultimap.create();
for (List addConfigs : getDynamicBuildParameters(build, listener)) {
- List actions = getBaseActions(CollectionUtils.immutableList(configs, addConfigs), build, listener);
+ List actions =
+ getBaseActions(CollectionUtils.immutableList(configs, addConfigs), build, listener);
for (Job project : getJobs(build.getRootBuild().getProject().getParent(), env)) {
List list = getBuildActions(actions, project);
@@ -486,7 +515,9 @@ public ListMultimap> perform3(AbstractBuild<
* Inner list represents a set of build parameters used together for one invocation of a project,
* and outer list represents multiple invocations of the same project.
*/
- private List
> getDynamicBuildParameters(AbstractBuild,?> build, BuildListener listener) throws DontTriggerException, IOException, InterruptedException {
+ private List> getDynamicBuildParameters(
+ AbstractBuild, ?> build, BuildListener listener)
+ throws DontTriggerException, IOException, InterruptedException {
if (configFactories == null || configFactories.isEmpty()) {
return Collections.singletonList(Collections.emptyList());
} else {
@@ -496,8 +527,9 @@ private List> getDynamicBuildParameters(AbstractBu
for (AbstractBuildParameterFactory configFactory : configFactories) {
List> newDynParameters = new ArrayList();
List factoryParameters = configFactory.getParameters(build, listener);
- // if factory returns 0 parameters we need to skip assigning newDynParameters to dynamicBuildParameters as we would add invalid list
- if(factoryParameters.size() > 0) {
+ // if factory returns 0 parameters we need to skip assigning newDynParameters to dynamicBuildParameters
+ // as we would add invalid list
+ if (factoryParameters.size() > 0) {
for (AbstractBuildParameters config : factoryParameters) {
for (List dynamicBuildParameter : dynamicBuildParameters) {
newDynParameters.add(CollectionUtils.immutableList(dynamicBuildParameter, config));
@@ -520,15 +552,15 @@ private List> getDynamicBuildParameters(AbstractBu
* @return UpstreamCause
*/
protected Cause createUpstreamCause(Run, ?> build) {
- if(Jenkins.getInstance().getPlugin("promoted-builds") != null) {
+ if (Jenkins.getInstance().getPlugin("promoted-builds") != null) {
// Test only when promoted-builds is installed.
- if(build instanceof Promotion) {
- Promotion promotion = (Promotion)build;
+ if (build instanceof Promotion) {
+ Promotion promotion = (Promotion) build;
// This cannot be done for PromotionCause#PromotionCause is in a package scope.
// return new PromotionCause(build, promotion.getTarget());
- return new UpstreamCause((Run,?>)promotion.getTargetBuild());
+ return new UpstreamCause((Run, ?>) promotion.getTargetBuild());
}
}
return new UpstreamCause(build);
@@ -539,14 +571,21 @@ protected Cause createUpstreamCause(Run, ?> build) {
*/
@CheckForNull
@Deprecated
- protected QueueTaskFuture schedule(AbstractBuild, ?> build, final Job project, int quietPeriod, List list) throws InterruptedException, IOException {
+ protected QueueTaskFuture schedule(AbstractBuild, ?> build, final Job project, int quietPeriod, List list)
+ throws InterruptedException, IOException {
return schedule(build, project, quietPeriod, list, TaskListener.NULL);
}
-
+
@CheckForNull
- protected QueueTaskFuture schedule(@NonNull AbstractBuild, ?> build, @NonNull final Job project, int quietPeriod,
- @NonNull List list, @NonNull TaskListener listener) throws InterruptedException, IOException {
- // TODO Once it's in core (since 1.621) and LTS is out, switch to use new ParameterizedJobMixIn convenience method
+ protected QueueTaskFuture schedule(
+ @NonNull AbstractBuild, ?> build,
+ @NonNull final Job project,
+ int quietPeriod,
+ @NonNull List list,
+ @NonNull TaskListener listener)
+ throws InterruptedException, IOException {
+ // TODO Once it's in core (since 1.621) and LTS is out, switch to use new ParameterizedJobMixIn convenience
+ // method
// From https://github.com/jenkinsci/jenkins/pull/1771
Cause cause = createUpstreamCause(build);
List queueActions = new ArrayList<>(list);
@@ -560,21 +599,21 @@ protected QueueTaskFuture schedule(@NonNull AbstractBuild, ?> build, @NonNull
return project;
}
};
-
+
// We check the user permissions.
// QueueItemAuthenticator should provide the user if it is configured correctly.
- //TODO: It would be also great to print it to the build log, but there is no TaskListener
+ // TODO: It would be also great to print it to the build log, but there is no TaskListener
if (!canTriggerProject(build, project, listener)) {
return null;
}
-
+
return parameterizedJobMixIn.scheduleBuild2(quietPeriod, queueActions.toArray(new Action[0]));
}
// Trigger is not compatible with un-parameterized jobs
return null;
}
-
+
/**
* Checks if the build can trigger a project.
* @param build Build, which is about to trigger the project
@@ -583,30 +622,33 @@ protected QueueTaskFuture schedule(@NonNull AbstractBuild, ?> build, @NonNull
* @return {@code true} if the project can be scheduled.
* {@code false} if there is a lack of permissions, details will be printed to the logs then.
*/
- /*package*/ static boolean canTriggerProject(@NonNull AbstractBuild, ?> build,
- @NonNull final Job job, @NonNull TaskListener taskListener) {
+ /*package*/ static boolean canTriggerProject(
+ @NonNull AbstractBuild, ?> build, @NonNull final Job job, @NonNull TaskListener taskListener) {
if (!job.hasPermission(Item.BUILD)) {
- String message = String.format("Cannot schedule the build of %s from %s. "
- + "The authenticated build user %s has no Job.BUILD permission",
- job.getFullDisplayName(), build.getFullDisplayName(), Jenkins.getAuthentication().getName());
+ String message = String.format(
+ "Cannot schedule the build of %s from %s. "
+ + "The authenticated build user %s has no Job.BUILD permission",
+ job.getFullDisplayName(),
+ build.getFullDisplayName(),
+ Jenkins.getAuthentication().getName());
LOGGER.log(Level.WARNING, message);
taskListener.error(message);
return false;
}
return true;
}
-
+
/**
* Checks if the project is buildable.
* The method also takes the security implications from {@link QueueItemAuthenticator} into account.
* @param job Job to be checked
- * @return true if the job can be scheduled from the
+ * @return true if the job can be scheduled from the
*/
protected boolean canBeScheduled(@NonNull Job, ?> job) {
if (!job.isBuildable()) {
return false;
}
-
+
return job.hasPermission(Item.BUILD);
}
@@ -614,14 +656,25 @@ protected boolean canBeScheduled(@NonNull Job, ?> job) {
* @deprecated Use {@link #schedule(hudson.model.AbstractBuild, hudson.model.Job, int, java.util.List, hudson.model.TaskListener)}
*/
@Deprecated
- protected QueueTaskFuture schedule(AbstractBuild, ?> build, Job project, List list) throws InterruptedException, IOException {
+ protected QueueTaskFuture schedule(AbstractBuild, ?> build, Job project, List list)
+ throws InterruptedException, IOException {
return schedule(build, project, list, TaskListener.NULL);
}
-
+
@CheckForNull
- protected QueueTaskFuture schedule(@NonNull AbstractBuild, ?> build, @NonNull Job project, @NonNull List list, @NonNull TaskListener listener) throws InterruptedException, IOException {
+ protected QueueTaskFuture schedule(
+ @NonNull AbstractBuild, ?> build,
+ @NonNull Job project,
+ @NonNull List list,
+ @NonNull TaskListener listener)
+ throws InterruptedException, IOException {
if (project instanceof ParameterizedJobMixIn.ParameterizedJob) {
- return schedule(build, project, ((ParameterizedJobMixIn.ParameterizedJob) project).getQuietPeriod(), list, listener);
+ return schedule(
+ build,
+ project,
+ ((ParameterizedJobMixIn.ParameterizedJob) project).getQuietPeriod(),
+ list,
+ listener);
} else {
return schedule(build, project, 0, list, listener);
}
@@ -640,16 +693,17 @@ protected QueueTaskFuture schedule(@NonNull AbstractBuild, ?> build, @NonNull
* @param context
* @return
*/
- private static String computeRelativeNamesAfterRenaming(String oldFullName, String newFullName, String relativeNames, ItemGroup> context) {
- StringTokenizer tokens = new StringTokenizer(relativeNames,",");
+ private static String computeRelativeNamesAfterRenaming(
+ String oldFullName, String newFullName, String relativeNames, ItemGroup> context) {
+ StringTokenizer tokens = new StringTokenizer(relativeNames, ",");
List newValue = new ArrayList<>();
- while(tokens.hasMoreTokens()) {
+ while (tokens.hasMoreTokens()) {
String relativeName = tokens.nextToken().trim();
String canonicalName = Items.getCanonicalName(context, relativeName);
if (canonicalName.equals(oldFullName) || canonicalName.startsWith(oldFullName + "/")) {
String newCanonicalName = newFullName + canonicalName.substring(oldFullName.length());
// relative name points to the renamed item, let's compute the new relative name
- newValue.add( computeRelativeNameAfterRenaming(canonicalName, newCanonicalName, relativeName) );
+ newValue.add(computeRelativeNameAfterRenaming(canonicalName, newCanonicalName, relativeName));
} else {
newValue.add(relativeName);
}
@@ -657,17 +711,18 @@ private static String computeRelativeNamesAfterRenaming(String oldFullName, Stri
return StringUtils.join(newValue, ",");
}
- private static String computeRelativeNameAfterRenaming(String oldFullName, String newFullName, String relativeName) {
+ private static String computeRelativeNameAfterRenaming(
+ String oldFullName, String newFullName, String relativeName) {
String[] a = oldFullName.split("/");
String[] n = newFullName.split("/");
assert a.length == n.length;
String[] r = relativeName.split("/");
- int j = a.length-1;
- for(int i=r.length-1;i>=0;i--) {
+ int j = a.length - 1;
+ for (int i = r.length - 1; i >= 0; i--) {
String part = r[i];
- if (part.equals("") && i==0) {
+ if (part.equals("") && i == 0) {
continue;
}
if (part.equals(".")) {
@@ -688,14 +743,14 @@ private static String computeRelativeNameAfterRenaming(String oldFullName, Strin
public boolean onJobRenamed(ItemGroup context, String oldName, String newName) {
String newProjects = computeRelativeNamesAfterRenaming(oldName, newName, projects, context);
- boolean changed = !projects.equals(newProjects);
+ boolean changed = !projects.equals(newProjects);
projects = newProjects;
- return changed;
+ return changed;
}
public boolean onDeleted(ItemGroup context, String oldName) {
List newNames = new ArrayList<>();
- StringTokenizer tokens = new StringTokenizer(projects,",");
+ StringTokenizer tokens = new StringTokenizer(projects, ",");
while (tokens.hasMoreTokens()) {
String relativeName = tokens.nextToken().trim();
String fullName = Items.getCanonicalName(context, relativeName);
@@ -712,10 +767,10 @@ public Descriptor getDescriptor() {
}
@Override
- public String toString() {
- return getClass().getName()+" [projects=" + projects + ", condition="
- + condition + ", configs=" + configs + "]";
- }
+ public String toString() {
+ return getClass().getName() + " [projects=" + projects + ", condition=" + condition + ", configs=" + configs
+ + "]";
+ }
@Extension
public static class DescriptorImpl extends Descriptor {
@@ -733,7 +788,7 @@ public List> getBuilderConfigFactoryDe
}
@Restricted(DoNotUse.class)
- public boolean isItemGroup(AbstractProject project){
+ public boolean isItemGroup(AbstractProject project) {
return project instanceof ItemGroup;
}
@@ -742,34 +797,37 @@ public boolean isItemGroup(AbstractProject project){
*
* Copied from hudson.tasks.BuildTrigger.doCheck(Item project, String value)
*/
- public FormValidation doCheckProjects(@AncestorInPath Job,?> project, @QueryParameter String value ) {
+ public FormValidation doCheckProjects(@AncestorInPath Job, ?> project, @QueryParameter String value) {
// JENKINS-32527: Check that it behaves gracefully for an unknown context
if (project == null) return FormValidation.ok("Context Unknown: the value specified cannot be validated");
// Require CONFIGURE permission on this project
- if(!project.hasPermission(Item.CONFIGURE)){
- return FormValidation.ok();
+ if (!project.hasPermission(Item.CONFIGURE)) {
+ return FormValidation.ok();
}
- StringTokenizer tokens = new StringTokenizer(Util.fixNull(value),",");
+ StringTokenizer tokens = new StringTokenizer(Util.fixNull(value), ",");
boolean hasProjects = false;
- while(tokens.hasMoreTokens()) {
+ while (tokens.hasMoreTokens()) {
String projectName = tokens.nextToken().trim();
if (StringUtils.isBlank(projectName)) {
return FormValidation.error("Blank project name in the list");
}
- Item item = Jenkins.get().getItem(projectName,project,Item.class); // only works after version 1.410
- if(item==null){
+ Item item = Jenkins.get().getItem(projectName, project, Item.class); // only works after version 1.410
+ if (item == null) {
Item nearest = Items.findNearest(Job.class, projectName, Jenkins.get());
String alternative = nearest != null ? nearest.getRelativeNameFrom(project) : "?";
return FormValidation.error(Messages.BuildTrigger_NoSuchProject(projectName, alternative));
}
- if(!(item instanceof Job) || !(item instanceof ParameterizedJobMixIn.ParameterizedJob)) {
+ if (!(item instanceof Job) || !(item instanceof ParameterizedJobMixIn.ParameterizedJob)) {
return FormValidation.error(Messages.BuildTrigger_NotBuildable(projectName));
}
// check whether the supposed user is expected to be able to build
- Authentication auth = Tasks.getAuthenticationOf((ParameterizedJobMixIn.ParameterizedJob)project);
- if (auth.equals(ACL.SYSTEM) && !QueueItemAuthenticatorConfiguration.get().getAuthenticators().isEmpty()) {
+ Authentication auth = Tasks.getAuthenticationOf((ParameterizedJobMixIn.ParameterizedJob) project);
+ if (auth.equals(ACL.SYSTEM)
+ && !QueueItemAuthenticatorConfiguration.get()
+ .getAuthenticators()
+ .isEmpty()) {
auth = Jenkins.ANONYMOUS;
}
if (!item.getACL().hasPermission(auth, Item.BUILD)) {
@@ -779,7 +837,7 @@ public FormValidation doCheckProjects(@AncestorInPath Job,?> project, @QueryPa
hasProjects = true;
}
if (!hasProjects) {
- return FormValidation.error(Messages.BuildTrigger_NoProjectSpecified());
+ return FormValidation.error(Messages.BuildTrigger_NoProjectSpecified());
}
return FormValidation.ok();
@@ -793,10 +851,11 @@ public FormValidation doCheckProjects(@AncestorInPath Job,?> project, @QueryPa
* @param value
* @return
*/
- public AutoCompletionCandidates doAutoCompleteProjects(@QueryParameter String value, @AncestorInPath ItemGroup context) {
+ public AutoCompletionCandidates doAutoCompleteProjects(
+ @QueryParameter String value, @AncestorInPath ItemGroup context) {
AutoCompletionCandidates candidates = new AutoCompletionCandidates();
List jobs = Jenkins.get().getAllItems(Job.class);
- for (Job job: jobs) {
+ for (Job job : jobs) {
String relativeName = job.getRelativeNameFrom(context);
if (relativeName.startsWith(value)) {
if (job.hasPermission(Item.READ)) {
@@ -806,6 +865,5 @@ public AutoCompletionCandidates doAutoCompleteProjects(@QueryParameter String va
}
return candidates;
}
-
}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java
index 26589090..cf0a694c 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/CapturedEnvironmentAction.java
@@ -4,16 +4,16 @@
import hudson.diagnosis.OldDataMonitor;
import hudson.model.InvisibleAction;
import hudson.model.Run;
-import jenkins.model.RunAction2;
-
import java.util.Collections;
+import jenkins.model.RunAction2;
/**
* @author Nicolas De Loof
*/
public class CapturedEnvironmentAction extends InvisibleAction implements RunAction2 {
- static final String OLD_DATA_MESSAGE = "The build.xml contains captured environment variables at the time of building which could contain sensitive data.";
+ static final String OLD_DATA_MESSAGE =
+ "The build.xml contains captured environment variables at the time of building which could contain sensitive data.";
private transient volatile EnvVars env;
public CapturedEnvironmentAction(EnvVars env) {
@@ -26,7 +26,7 @@ public EnvVars getCapturedEnvironment() {
@Override
public void onAttached(final Run, ?> r) {
- //noop
+ // noop
}
@Override
@@ -34,7 +34,8 @@ public void onLoad(final Run, ?> r) {
if (env != null) {
OldDataMonitor.report(r, Collections.singletonList(new AssertionError(OLD_DATA_MESSAGE)));
}
- //If it is not null then we loaded old data that needs to be cleaned, if it is null then it needs to be something.
+ // If it is not null then we loaded old data that needs to be cleaned, if it is null then it needs to be
+ // something.
env = new EnvVars();
}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/CounterBuildParameterFactory.java b/src/main/java/hudson/plugins/parameterizedtrigger/CounterBuildParameterFactory.java
index b7f18125..a3acdc73 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/CounterBuildParameterFactory.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/CounterBuildParameterFactory.java
@@ -7,14 +7,13 @@
import hudson.model.TaskListener;
import hudson.util.FormValidation;
import hudson.util.VariableResolver;
-import org.apache.commons.lang.StringUtils;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
/**
* A BuildParameterFactory generating Predefined Parameters for a counter
@@ -30,24 +29,27 @@ public class CounterBuildParameterFactory extends AbstractBuildParameterFactory
private final SteppingValidationEnum validationFail;
public enum SteppingValidationEnum {
- FAIL("Fail the build step"), // previous behaviour (default)
- SKIP("Don't trigger these projects"){
+ FAIL("Fail the build step"), // previous behaviour (default)
+ SKIP("Don't trigger these projects") {
@Override
public void failCheck(TaskListener listener) throws AbstractBuildParameters.DontTriggerException {
listener.getLogger().println(Messages.CounterBuildParameterFactory_CountingWillNotTerminateSkipping());
throw new AbstractBuildParameters.DontTriggerException();
- }},
- NOPARMS("Skip these parameters"){
+ }
+ },
+ NOPARMS("Skip these parameters") {
@Override
public void failCheck(TaskListener listener) throws AbstractBuildParameters.DontTriggerException {
listener.getLogger().println(Messages.CounterBuildParameterFactory_CountingWillNotTerminateIgnore());
- }};
+ }
+ };
private final String description;
public String getDescription() {
return description;
}
+
SteppingValidationEnum(String description) {
this.description = description;
}
@@ -60,7 +62,9 @@ public void failCheck(TaskListener listener) throws AbstractBuildParameters.Dont
public CounterBuildParameterFactory(long from, long to, long step, String paramExpr) {
this(Long.toString(from), Long.toString(to), Long.toString(step), paramExpr);
}
- public CounterBuildParameterFactory(long from, long to, long step, String paramExpr, SteppingValidationEnum validationFail) {
+
+ public CounterBuildParameterFactory(
+ long from, long to, long step, String paramExpr, SteppingValidationEnum validationFail) {
this(Long.toString(from), Long.toString(to), Long.toString(step), paramExpr, validationFail);
}
@@ -70,7 +74,8 @@ public CounterBuildParameterFactory(String from, String to, String step, String
}
@DataBoundConstructor
- public CounterBuildParameterFactory(String from, String to, String step, String paramExpr, SteppingValidationEnum validationFail) {
+ public CounterBuildParameterFactory(
+ String from, String to, String step, String paramExpr, SteppingValidationEnum validationFail) {
this.from = from;
this.to = to;
this.step = step;
@@ -78,9 +83,9 @@ public CounterBuildParameterFactory(String from, String to, String step, String
this.validationFail = validationFail;
}
-
@Override
- public List getParameters(AbstractBuild, ?> build, TaskListener listener) throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
+ public List getParameters(AbstractBuild, ?> build, TaskListener listener)
+ throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
EnvVars envVars = build.getEnvironment(listener);
long fromNum = Long.parseLong(envVars.expand(from));
@@ -118,11 +123,14 @@ public String getDisplayName() {
return Messages.CounterBuildParameterFactory_CounterBuildParameterFactory();
}
- public FormValidation doCheckFrom(@QueryParameter String value) { return validateNumberField(value);
+ public FormValidation doCheckFrom(@QueryParameter String value) {
+ return validateNumberField(value);
}
+
public FormValidation doCheckTo(@QueryParameter String value) {
return validateNumberField(value);
}
+
public FormValidation doCheckStep(@QueryParameter String value) {
return validateNumberField(value);
}
@@ -175,5 +183,4 @@ public String resolve(String name) {
return "";
}
};
-
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/CurrentBuildParameters.java b/src/main/java/hudson/plugins/parameterizedtrigger/CurrentBuildParameters.java
index a8d61f9e..80852ea3 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/CurrentBuildParameters.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/CurrentBuildParameters.java
@@ -8,45 +8,38 @@
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.TaskListener;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-
import org.kohsuke.stapler.DataBoundConstructor;
public class CurrentBuildParameters extends AbstractBuildParameters {
- @DataBoundConstructor
- public CurrentBuildParameters() {
- }
-
- @Override
- public Action getAction(AbstractBuild,?> build, TaskListener listener)
- throws IOException {
-
- ParametersAction action = build.getAction(ParametersAction.class);
- if (action == null) {
- listener.getLogger().println(Plugin.LOG_TAG + " Current build has no parameters.");
- return null;
- } else {
- List values = new ArrayList<>(action.getParameters().size());
- for (ParameterValue value : action.getParameters())
- // FileParameterValue is currently not reusable, so omit these:
- if (!(value instanceof FileParameterValue))
- values.add(value);
- return new ParametersAction(values);
- }
- }
-
- @Extension
- public static class DescriptorImpl extends Descriptor {
-
- @Override
- public String getDisplayName() {
- return "Current build parameters";
- }
-
- }
-
+ @DataBoundConstructor
+ public CurrentBuildParameters() {}
+
+ @Override
+ public Action getAction(AbstractBuild, ?> build, TaskListener listener) throws IOException {
+
+ ParametersAction action = build.getAction(ParametersAction.class);
+ if (action == null) {
+ listener.getLogger().println(Plugin.LOG_TAG + " Current build has no parameters.");
+ return null;
+ } else {
+ List values = new ArrayList<>(action.getParameters().size());
+ for (ParameterValue value : action.getParameters())
+ // FileParameterValue is currently not reusable, so omit these:
+ if (!(value instanceof FileParameterValue)) values.add(value);
+ return new ParametersAction(values);
+ }
+ }
+
+ @Extension
+ public static class DescriptorImpl extends Descriptor {
+
+ @Override
+ public String getDisplayName() {
+ return "Current build parameters";
+ }
+ }
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/DefaultParameterValuesActionsTransform.java b/src/main/java/hudson/plugins/parameterizedtrigger/DefaultParameterValuesActionsTransform.java
index a1e29075..764a9083 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/DefaultParameterValuesActionsTransform.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/DefaultParameterValuesActionsTransform.java
@@ -1,9 +1,8 @@
package hudson.plugins.parameterizedtrigger;
import hudson.model.*;
-
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
/**
* Ensure the given project's parameters with default values exist in the parameter list.
@@ -11,11 +10,11 @@
* If they do not, append them with the specified default value.
*/
public class DefaultParameterValuesActionsTransform implements ITransformProjectParametersAction {
- public ParametersAction transformParametersAction(ParametersAction a, Job,?> project) {
+ public ParametersAction transformParametersAction(ParametersAction a, Job, ?> project) {
return ParameterizedTriggerUtils.mergeParameters(getDefaultParameters(project), a);
}
- private static ParametersAction getDefaultParameters(Job,?> project) {
+ private static ParametersAction getDefaultParameters(Job, ?> project) {
ParametersDefinitionProperty property = project.getProperty(ParametersDefinitionProperty.class);
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/DifferentiatingAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/DifferentiatingAction.java
index c53bdf08..7dbcdb74 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/DifferentiatingAction.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/DifferentiatingAction.java
@@ -3,7 +3,6 @@
import hudson.model.Action;
import hudson.model.InvisibleAction;
import hudson.model.Queue;
-
import java.util.List;
/**
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/DynamicBuildAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/DynamicBuildAction.java
index b9c3992c..30909a19 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/DynamicBuildAction.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/DynamicBuildAction.java
@@ -4,12 +4,11 @@
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Run;
-import jenkins.model.Jenkins;
-import jenkins.model.RunAction2;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import jenkins.model.Jenkins;
+import jenkins.model.RunAction2;
/**
* Shows a list of a dynamic downstream builds
@@ -23,14 +22,10 @@ public DynamicBuildAction(Map buildsMap) {
}
@Override
- public void onAttached(Run, ?> run) {
-
- }
+ public void onAttached(Run, ?> run) {}
@Override
- public void onLoad(Run, ?> run) {
-
- }
+ public void onLoad(Run, ?> run) {}
public List> getBuilds() {
List> builds = new ArrayList<>();
@@ -49,7 +44,6 @@ public void onLoad(Run, ?> run) {
return builds;
}
-
@Override
public String getIconFileName() {
return null;
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/DynamicProjectAction.java b/src/main/java/hudson/plugins/parameterizedtrigger/DynamicProjectAction.java
index e3696498..077fe87a 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/DynamicProjectAction.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/DynamicProjectAction.java
@@ -1,7 +1,6 @@
package hudson.plugins.parameterizedtrigger;
import hudson.model.Action;
-
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameterFactory.java b/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameterFactory.java
index 69f43679..1212ff0b 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameterFactory.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameterFactory.java
@@ -11,10 +11,6 @@
import hudson.model.AbstractBuild;
import hudson.model.TaskListener;
import hudson.util.FormValidation;
-import org.apache.commons.lang.StringUtils;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
@@ -23,7 +19,9 @@
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
-
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
/**
* For each matching property file, invoke a build.
@@ -38,23 +36,26 @@ public class FileBuildParameterFactory extends AbstractBuildParameterFactory {
*
*/
public enum NoFilesFoundEnum {
- SKIP("Don't trigger these projects"){ // previous behaviour (default)
+ SKIP("Don't trigger these projects") { // previous behaviour (default)
@Override
public void failCheck(TaskListener listener) throws AbstractBuildParameters.DontTriggerException {
listener.getLogger().println(Messages.FileBuildParameterFactory_NoFilesFoundSkipping());
throw new AbstractBuildParameters.DontTriggerException();
- }},
- NOPARMS("Skip these parameters"){
+ }
+ },
+ NOPARMS("Skip these parameters") {
@Override
public void failCheck(TaskListener listener) throws AbstractBuildParameters.DontTriggerException {
listener.getLogger().println(Messages.FileBuildParameterFactory_NoFilesFoundIgnore());
- }},
- FAIL("Fail the build step"){
+ }
+ },
+ FAIL("Fail the build step") {
@Override
public void failCheck(TaskListener listener) throws AbstractBuildParameters.DontTriggerException {
listener.getLogger().println(Messages.FileBuildParameterFactory_NoFilesFoundTerminate());
throw new RuntimeException();
- }};
+ }
+ };
private final String description;
@@ -101,7 +102,8 @@ public NoFilesFoundEnum getNoFilesFoundAction() {
}
@Override
- public List getParameters(AbstractBuild, ?> build, TaskListener listener) throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
+ public List getParameters(AbstractBuild, ?> build, TaskListener listener)
+ throws IOException, InterruptedException, AbstractBuildParameters.DontTriggerException {
EnvVars env = build.getEnvironment(listener);
@@ -110,12 +112,13 @@ public List getParameters(AbstractBuild, ?> build, Ta
try {
FilePath workspace = getWorkspace(build);
FilePath[] files = workspace.list(env.expand(getFilePattern()));
- if(files.length == 0) {
+ if (files.length == 0) {
noFilesFoundAction.failCheck(listener);
} else {
- for(FilePath f: files) {
+ for (FilePath f : files) {
String parametersStr = ParameterizedTriggerUtils.readFileToString(f, getEncoding());
- Logger.getLogger(FileBuildParameterFactory.class.getName()).log(Level.INFO, null, "Triggering build with " + f.getName());
+ Logger.getLogger(FileBuildParameterFactory.class.getName())
+ .log(Level.INFO, null, "Triggering build with " + f.getName());
result.add(new PredefinedBuildParameters(parametersStr));
}
}
@@ -140,14 +143,14 @@ public static class DescriptorImpl extends AbstractBuildParameterFactoryDescript
public String getDisplayName() {
return Messages.FileBuildParameterFactory_FileBuildParameterFactory();
}
-
+
public FormValidation doCheckEncoding(@QueryParameter String encoding) {
if (!StringUtils.isBlank(encoding)) {
try {
Charset.forName(encoding.trim());
- } catch(UnsupportedCharsetException e) {
+ } catch (UnsupportedCharsetException e) {
return FormValidation.error("Unsupported Encoding");
- } catch(IllegalCharsetNameException e) {
+ } catch (IllegalCharsetNameException e) {
return FormValidation.error("Bad Encoding Name");
}
}
diff --git a/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameters.java b/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameters.java
index 13fb9e38..9a796548 100644
--- a/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameters.java
+++ b/src/main/java/hudson/plugins/parameterizedtrigger/FileBuildParameters.java
@@ -18,11 +18,6 @@
import hudson.model.TaskListener;
import hudson.model.TextParameterValue;
import hudson.util.FormValidation;
-
-import org.apache.commons.lang.StringUtils;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
@@ -36,212 +31,234 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jenkins.util.VirtualFile;
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.QueryParameter;
public class FileBuildParameters extends AbstractBuildParameters {
- private final String propertiesFile;
- private final String encoding;
- private final boolean failTriggerOnMissing;
- private final boolean textParamValueOnNewLine;
-
- /*properties used for a matrix project*/
- private final boolean useMatrixChild;
- private final String combinationFilter;
- private final boolean onlyExactRuns;
-
- @DataBoundConstructor
- public FileBuildParameters(String propertiesFile, String encoding, boolean failTriggerOnMissing, boolean useMatrixChild, String combinationFilter, boolean onlyExactRuns, boolean textParamValueOnNewLine) {
- this.propertiesFile = propertiesFile;
- this.encoding = Util.fixEmptyAndTrim(encoding);
- this.failTriggerOnMissing = failTriggerOnMissing;
- this.useMatrixChild = useMatrixChild;
- if (this.useMatrixChild) {
- this.combinationFilter = combinationFilter;
- this.onlyExactRuns = onlyExactRuns;
- } else {
- this.combinationFilter = null;
- this.onlyExactRuns = false;
- }
- this.textParamValueOnNewLine = textParamValueOnNewLine;
- }
-
- public FileBuildParameters(String propertiesFile, String encoding, boolean failTriggerOnMissing, boolean useMatrixChild, String combinationFilter, boolean onlyExactRuns) {
- this(propertiesFile, encoding, failTriggerOnMissing, useMatrixChild, combinationFilter, onlyExactRuns, false);
- }
-
- public FileBuildParameters(String propertiesFile, String encoding, boolean failTriggerOnMissing) {
- this(propertiesFile, encoding, failTriggerOnMissing, false, null, false);
- }
-
- public FileBuildParameters(String propertiesFile, boolean failTriggerOnMissing) {
- this(propertiesFile, null, failTriggerOnMissing);
- }
-
- public FileBuildParameters(String propertiesFile) {
- this(propertiesFile, false);
- }
-
- /**
- * This function returns the Action that should be passed to the triggered build
- * to not trigger the build it can throw the {@link DontTriggerException}
- *
- * @return Action to be passed to the triggered build, can be Null if no parameters.
- */
- public Action getAction(AbstractBuild,?> build, TaskListener listener)
- throws IOException, InterruptedException, DontTriggerException{
-
- EnvVars env = getEnvironment(build, listener);
-
- String resolvedPropertiesFile = env.expand(propertiesFile);
-
- String[] allFiles = Util.tokenize(resolvedPropertiesFile, ",");
- String[] trimmedFiles = new String[allFiles.length];
- for (int i = 0; i < allFiles.length; i++)
- trimmedFiles[i] = allFiles[i].trim();
-
- List values = new ArrayList<>();
-
- // builds to scan.
- Collection extends AbstractBuild,?>> targetBuilds = getTargetBuilds(build);
-
- for (AbstractBuild,?> targetBuild: targetBuilds) {
- values.addAll(extractAllValues(targetBuild, listener, trimmedFiles));
- }
- //Values might be empty, in that case don't return anything.
- return values.size() == 0 ? null :new ParametersAction(values);
- }
-
- private List extractAllValues(AbstractBuild,?> build, TaskListener listener, String[] allFiles) throws IOException, InterruptedException, DontTriggerException {
- List values = new ArrayList<>();
- EnvVars env = getEnvironment(build, listener);
- for(String file:allFiles) {
- String s = null;
- VirtualFile artifact = build.getArtifactManager().root().child(file);
- if (artifact.isFile()) {
- s = ParameterizedTriggerUtils.readFileToString(artifact);
- }
-
- if (s == null) {
- FilePath workspace = build.getWorkspace();
- if (workspace == null) {
- listener.getLogger().printf(Plugin.LOG_TAG + " Could not load workspace of build %s%n", build.getFullDisplayName());
- } else {
- FilePath f = workspace.child(file);
- if (f.exists()) {
- s = ParameterizedTriggerUtils.readFileToString(f, getEncoding());
- }
- }
- }
-
- if (s == null) {
- listener.getLogger().println(Plugin.LOG_TAG + " Properties file "
- + file + " did not exist.");
- if (getFailTriggerOnMissing()) {
- listener.getLogger().println("Not triggering due to missing file - did you archive it as a build artifact ?");
- throw new DontTriggerException();
- }
- // goto next file.
- continue;
- }
-
- s = env.expand(s);
- Properties p = ParameterizedTriggerUtils.loadProperties(s);
-
- for (Map.Entry