Skip to content

Commit

Permalink
[FIXED JENKINS-15834] Allow multiple properties files
Browse files Browse the repository at this point in the history
Support the passing of multiple property files via a
comma seperated list.
Correct help messages and add behaviour to correctly
skip triggering downstream if a file is missing.
  • Loading branch information
cjo9900 committed Nov 17, 2012
1 parent 1658624 commit d8758e4
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 30 deletions.
Expand Up @@ -3,6 +3,7 @@
import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.Action;
import hudson.model.Descriptor;
Expand All @@ -23,48 +24,70 @@
public class FileBuildParameters extends AbstractBuildParameters {

private final String propertiesFile;
private final boolean failTriggerOnMissing;

@DataBoundConstructor
public FileBuildParameters(String propertiesFile) {
public FileBuildParameters(String propertiesFile, boolean failTriggerOnMissing) {
this.propertiesFile = propertiesFile;
this.failTriggerOnMissing = 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 DontTriggerException
*
* @returns Action to be passed to the triggered build, can be Null if no parameters.
*/
public Action getAction(AbstractBuild<?,?> build, TaskListener listener)
throws IOException, InterruptedException {
throws IOException, InterruptedException, DontTriggerException{

EnvVars env = getEnvironment(build, listener);

String resolvedPropertiesFile = env.expand(propertiesFile);
FilePath f = build.getWorkspace().child(resolvedPropertiesFile);
if (!f.exists()) {
listener
.getLogger()
.println(
"[parameterizedtrigger] Could not trigger downstream project, as properties file "
+ resolvedPropertiesFile
+ " did not exist.");
return null;
}

String s = f.readToString();
s = env.expand(s);
Properties p = new Properties();
p.load(new StringInputStream(s));

String[] allFiles = Util.tokenize(resolvedPropertiesFile, ",");
List<ParameterValue> values = new ArrayList<ParameterValue>();
for (Map.Entry<Object, Object> entry : p.entrySet()) {
values.add(new StringParameterValue(entry.getKey().toString(),
entry.getValue().toString()));
}

return new ParametersAction(values);
for(String file:allFiles) {
FilePath f = build.getWorkspace().child(file);
if (!f.exists()) {
listener.getLogger().println("[parameterizedtrigger] Properties file "
+ file + " did not exist.");
if(getFailTriggerOnMissing() == true) {
listener.getLogger().println("Not triggering due to missing file");
throw new DontTriggerException();
}
// goto next file.
continue;
}

String s = f.readToString();
s = env.expand(s);
Properties p = new Properties();
p.load(new StringInputStream(s));

for (Map.Entry<Object, Object> entry : p.entrySet()) {
values.add(new StringParameterValue(entry.getKey().toString(),
entry.getValue().toString()));
}
}
//Values might be empty, in that case don't return anything.
return values.size() == 0 ? null :new ParametersAction(values);

}

public String getPropertiesFile() {
return propertiesFile;
}

public boolean getFailTriggerOnMissing() {
return failTriggerOnMissing;
}

@Extension
public static class DescriptorImpl extends Descriptor<AbstractBuildParameters> {
@Override
Expand Down
@@ -1,7 +1,10 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<f:entry field="propertiesFile" title="Use properties from file">
<f:textbox />
</f:entry>

</j:jelly>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">

<f:entry field="propertiesFile" title="${%Use properties from file}">
<f:textbox />
</f:entry>
<f:entry field="failTriggerOnMissing" title="${%Don't trigger if any files are missing}">
<f:checkbox default="false" />
</f:entry>

</j:jelly>
@@ -0,0 +1,4 @@
<div>
When enabled blocks the triggering of the downstream jobs if
any of the files are not found in the workspace.
</div>
@@ -1,5 +1,5 @@
<div>
The path to a file in the workspace that contains the parameters for the new project.
Comma seperated list of paths to file(s) in the workspace that contains the parameters for the new project.
The file should have KEY=value pairs, one per line (Java properties file format).
Backslashes are used for escaping, so use "\\" for a single backslash.
<p/>
Expand Down
Expand Up @@ -32,6 +32,7 @@
import org.jvnet.hudson.test.CaptureEnvironmentBuilder;
import org.jvnet.hudson.test.HudsonTestCase;
import org.jvnet.hudson.test.SingleFileSCM;
import org.jvnet.hudson.test.ExtractResourceSCM;

public class FileBuildTriggerConfigTest extends HudsonTestCase {

Expand All @@ -57,4 +58,55 @@ public void test() throws Exception {
assertNotNull("builder should record environment", builder.getEnvVars());
assertEquals("value", builder.getEnvVars().get("KEY"));
}

public void test_multiplefiles() throws Exception {

Project projectA = createFreeStyleProject("projectA");
projectA.setScm(new ExtractResourceSCM(getClass().getResource("multiple_property_files.zip")));
projectA.getPublishersList().add(
new BuildTrigger(
new BuildTriggerConfig("projectB", ResultCondition.SUCCESS,
new FileBuildParameters("a_properties.txt,z_properties.txt"))));

CaptureEnvironmentBuilder builder = new CaptureEnvironmentBuilder();
Project projectB = createFreeStyleProject("projectB");
projectB.getBuildersList().add(builder);
projectB.setQuietPeriod(1);
hudson.rebuildDependencyGraph();

projectA.scheduleBuild2(0).get();
hudson.getQueue().getItem(projectB).getFuture().get();

assertNotNull("builder should record environment", builder.getEnvVars());
// test from first file
assertEquals("These_three_values_should", builder.getEnvVars().get("A_TEST_01"));
assertEquals("be_from_file_a_properties_txt", builder.getEnvVars().get("A_TEST_02"));
assertEquals("which_has_three_definitions", builder.getEnvVars().get("A_TEST_03"));
// test from second file
assertEquals("These_two_values_should", builder.getEnvVars().get("Z_TEST_100"));
assertEquals("be_from_file_z_properties_txt", builder.getEnvVars().get("Z_TEST_101"));

}

public void test_failOnMissingFile() throws Exception {

Project projectA = createFreeStyleProject("projectA");
projectA.setScm(new ExtractResourceSCM(getClass().getResource("multiple_property_files.zip")));
projectA.getPublishersList().add(
new BuildTrigger(
new BuildTriggerConfig("projectB", ResultCondition.SUCCESS,
new FileBuildParameters("a_properties.txt,missing_file.txt,z_properties.txt",true))));

CaptureEnvironmentBuilder builder = new CaptureEnvironmentBuilder();
Project projectB = createFreeStyleProject("projectB");
projectB.getBuildersList().add(builder);
projectB.setQuietPeriod(1);
hudson.rebuildDependencyGraph();

projectA.scheduleBuild2(0).get();
waitUntilNoActivity();

// There should be no builds of projectB as not triggered.
assertEquals(0, projectB.getBuilds().size());
}
}
Binary file not shown.

0 comments on commit d8758e4

Please sign in to comment.