Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a353d07

Browse files
author
Cyrille Le Clerc
committedDec 14, 2017
[JENKINS-46785] Strategy to enable / disable publishers in pipelines.
Default strategy, "IMPLICIT" is the current strategy to implicitly enable all publishers unless they are explicitly disabled. The second available strategy, "EXPLICIT", requires to explicitly enable the publishers in the "withMaven(options: [...])" attribute
1 parent 6db3148 commit a353d07

File tree

7 files changed

+249
-143
lines changed

7 files changed

+249
-143
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,16 @@
11
package org.jenkinsci.plugins.pipeline.maven;
22

3-
import hudson.DescriptorExtensionList;
43
import hudson.ExtensionPoint;
54
import hudson.model.AbstractDescribableImpl;
65
import hudson.model.Descriptor;
7-
import hudson.model.TaskListener;
8-
import jenkins.model.Jenkins;
9-
import org.apache.commons.beanutils.BeanUtils;
10-
import org.apache.commons.beanutils.BeanUtilsBean2;
11-
import org.apache.commons.beanutils.PropertyUtils;
126
import org.jenkinsci.plugins.workflow.steps.StepContext;
137
import org.kohsuke.stapler.DataBoundSetter;
148
import org.w3c.dom.Element;
159

16-
import java.beans.PropertyDescriptor;
1710
import java.io.IOException;
18-
import java.io.PrintWriter;
1911
import java.io.Serializable;
20-
import java.lang.reflect.Method;
21-
import java.util.ArrayList;
22-
import java.util.Collections;
23-
import java.util.HashMap;
24-
import java.util.List;
25-
import java.util.Map;
26-
import java.util.logging.Level;
2712
import java.util.logging.Logger;
2813

29-
import javax.annotation.CheckForNull;
3014
import javax.annotation.Nonnull;
3115
import javax.annotation.Nullable;
3216

@@ -105,125 +89,5 @@ public int compareTo(DescriptorImpl o) {
10589
}
10690
}
10791

108-
/**
109-
* <p>Build the list of {@link MavenPublisher}s that should be invoked for the build execution of the given {@link TaskListener}
110-
* with the desired configuration.
111-
* </p>
112-
* <p>
113-
* The desired configuration is based on:
114-
* </p>
115-
* <ul>
116-
* <li>The default configuration of the publishers</li>
117-
* <li>The global configuration of the publishers defined in the "Global Tools Configuration' section</li>
118-
* <li>The configuration specified in the {@code withMaven(options=[...])} step</li>
119-
* </ul>
120-
*
121-
* @param configuredPublishers
122-
* @param listener
123-
*/
124-
@Nonnull
125-
public static List<MavenPublisher> buildPublishersList(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener) {
126-
127-
// configuration passed as parameter of "withMaven(options=[...]){}"
128-
// mavenPublisher.descriptor.id -> mavenPublisher
129-
Map<String, MavenPublisher> configuredPublishersById = new HashMap<>();
130-
for (MavenPublisher mavenPublisher : configuredPublishers) {
131-
if (mavenPublisher == null) {
132-
// skip null publisher options injected by Jenkins pipeline, probably caused by a missing plugin
133-
} else {
134-
configuredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher);
135-
}
136-
}
137-
138-
// configuration defined globally
139-
Map<String, MavenPublisher> globallyConfiguredPublishersById = new HashMap<>();
140-
GlobalPipelineMavenConfig globalPipelineMavenConfig = GlobalPipelineMavenConfig.get();
141-
142-
List<MavenPublisher> globallyConfiguredPublishers = globalPipelineMavenConfig == null ? Collections.<MavenPublisher>emptyList() : globalPipelineMavenConfig.getPublisherOptions();
143-
if (globallyConfiguredPublishers == null) {
144-
globallyConfiguredPublishers = Collections.emptyList();
145-
}
146-
for (MavenPublisher mavenPublisher : globallyConfiguredPublishers) {
147-
globallyConfiguredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher);
148-
}
149-
150-
151-
// mavenPublisher.descriptor.id -> mavenPublisher
152-
Map<String, MavenPublisher> defaultPublishersById = new HashMap<>();
153-
DescriptorExtensionList<MavenPublisher, Descriptor<MavenPublisher>> descriptorList = Jenkins.getInstance().getDescriptorList(MavenPublisher.class);
154-
for (Descriptor<MavenPublisher> descriptor : descriptorList) {
155-
try {
156-
defaultPublishersById.put(descriptor.getId(), descriptor.clazz.newInstance());
157-
} catch (InstantiationException | IllegalAccessException e) {
158-
PrintWriter error = listener.error("[withMaven] Exception instantiation default config for Maven Publisher '" + descriptor.getDisplayName() + "' / " + descriptor.getId() + ": " + e);
159-
e.printStackTrace(error);
160-
error.close();
161-
LOGGER.log(Level.WARNING, "Exception instantiating " + descriptor.clazz + ": " + e, e);
162-
e.printStackTrace();
163-
}
164-
}
165-
166-
167-
if (LOGGER.isLoggable(Level.FINE)) {
168-
listener.getLogger().println("[withMaven] Maven Publishers with configuration provided by the pipeline: " + configuredPublishersById.values());
169-
listener.getLogger().println("[withMaven] Maven Publishers with configuration defined globally: " + globallyConfiguredPublishersById.values());
170-
listener.getLogger().println("[withMaven] Maven Publishers with default configuration: " + defaultPublishersById.values());
171-
}
17292

173-
// TODO FILTER
174-
List<MavenPublisher> results = new ArrayList<>();
175-
for (Map.Entry<String, MavenPublisher> entry : defaultPublishersById.entrySet()) {
176-
String publisherId = entry.getKey();
177-
MavenPublisher publisher = buildConfiguredMavenPublisher(
178-
configuredPublishersById.get(publisherId),
179-
globallyConfiguredPublishersById.get(publisherId),
180-
entry.getValue(),
181-
listener);
182-
results.add(publisher);
183-
}
184-
Collections.sort(results);
185-
return results;
186-
}
187-
188-
public static MavenPublisher buildConfiguredMavenPublisher(@Nullable MavenPublisher pipelinePublisher, @Nullable MavenPublisher globallyConfiguredPublisher, @Nonnull MavenPublisher defaultPublisher, @Nonnull TaskListener listener) {
189-
190-
MavenPublisher result;
191-
String logMessage;
192-
193-
if (pipelinePublisher == null && globallyConfiguredPublisher == null) {
194-
result = defaultPublisher;
195-
logMessage = "default";
196-
} else if (pipelinePublisher == null && globallyConfiguredPublisher != null) {
197-
result = globallyConfiguredPublisher;
198-
logMessage = "globally";
199-
} else if (pipelinePublisher != null && globallyConfiguredPublisher == null) {
200-
result = pipelinePublisher;
201-
logMessage = "pipeline";
202-
} else if (pipelinePublisher != null && globallyConfiguredPublisher != null) {
203-
// workaround FindBugs "Bug kind and pattern: NP - NP_NULL_ON_SOME_PATH"
204-
// check pipelinePublisher and globallyConfiguredPublisher are non null even if it is useless
205-
206-
result = pipelinePublisher;
207-
logMessage = "pipeline";
208-
listener.getLogger().println("[withMaven] WARNING merging publisher configuration defined in the 'Global Tool Configuration' and at the pipeline level is not yet supported." +
209-
" Use pipeline level configuration for '" + result.getDescriptor().getDisplayName() + "'");
210-
//
211-
// PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(defaultPublisher);
212-
// for(PropertyDescriptor propertyDescriptor: propertyDescriptors) {
213-
// Method readMethod = propertyDescriptor.getReadMethod();
214-
// Method writeMethod = propertyDescriptor.getWriteMethod();
215-
//
216-
// Object defaultValue = readMethod.invoke(defaultPublisher);
217-
// Object globallyDefinedValue = readMethod.invoke(globallyConfiguredPublisher);
218-
// Object pipelineValue = readMethod.invoke(pipelinePublisher);
219-
// }
220-
} else {
221-
throw new IllegalStateException("Should not happen, workaround for Findbugs NP_NULL_ON_SOME_PATH above");
222-
}
223-
224-
if (LOGGER.isLoggable(Level.FINE))
225-
listener.getLogger().println("[withMaven] Use " + logMessage + " defined publisher for '" + result.getDescriptor().getDisplayName() + "'");
226-
return result;
227-
228-
}
22993
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package org.jenkinsci.plugins.pipeline.maven;
2+
3+
import hudson.DescriptorExtensionList;
4+
import hudson.model.Descriptor;
5+
import hudson.model.TaskListener;
6+
import jenkins.model.Jenkins;
7+
8+
import java.io.PrintWriter;
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.HashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.logging.Level;
15+
import java.util.logging.Logger;
16+
17+
import javax.annotation.Nonnull;
18+
import javax.annotation.Nullable;
19+
20+
/**
21+
* @author <a href="mailto:cleclerc@cloudbees.com">Cyrille Le Clerc</a>
22+
*/
23+
public enum MavenPublisherStrategy {
24+
25+
IMPLICIT("Implicit") {
26+
/**
27+
* <p>Build the list of {@link MavenPublisher}s that should be invoked for the build execution of the given {@link TaskListener}
28+
* with the desired configuration.
29+
* </p>
30+
* <p>
31+
* The desired configuration is based on:
32+
* </p>
33+
* <ul>
34+
* <li>The default configuration of the publishers</li>
35+
* <li>The global configuration of the publishers defined in the "Global Tools Configuration' section</li>
36+
* <li>The configuration specified in the {@code withMaven(options=[...])} step</li>
37+
* </ul>
38+
* @param configuredPublishers
39+
* @param listener
40+
*/
41+
@Nonnull
42+
public List<MavenPublisher> buildPublishersList(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener) {
43+
44+
// configuration passed as parameter of "withMaven(options=[...]){}"
45+
// mavenPublisher.descriptor.id -> mavenPublisher
46+
Map<String, MavenPublisher> configuredPublishersById = new HashMap<>();
47+
for (MavenPublisher mavenPublisher : configuredPublishers) {
48+
if (mavenPublisher == null) {
49+
// skip null publisher options injected by Jenkins pipeline, probably caused by a missing plugin
50+
} else {
51+
configuredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher);
52+
}
53+
}
54+
55+
// configuration defined globally
56+
Map<String, MavenPublisher> globallyConfiguredPublishersById = new HashMap<>();
57+
GlobalPipelineMavenConfig globalPipelineMavenConfig = GlobalPipelineMavenConfig.get();
58+
59+
List<MavenPublisher> globallyConfiguredPublishers = globalPipelineMavenConfig == null ? Collections.<MavenPublisher>emptyList() : globalPipelineMavenConfig.getPublisherOptions();
60+
if (globallyConfiguredPublishers == null) {
61+
globallyConfiguredPublishers = Collections.emptyList();
62+
}
63+
for (MavenPublisher mavenPublisher : globallyConfiguredPublishers) {
64+
globallyConfiguredPublishersById.put(mavenPublisher.getDescriptor().getId(), mavenPublisher);
65+
}
66+
67+
68+
// mavenPublisher.descriptor.id -> mavenPublisher
69+
Map<String, MavenPublisher> defaultPublishersById = new HashMap<>();
70+
DescriptorExtensionList<MavenPublisher, Descriptor<MavenPublisher>> descriptorList = Jenkins.getInstance().getDescriptorList(MavenPublisher.class);
71+
for (Descriptor<MavenPublisher> descriptor : descriptorList) {
72+
try {
73+
defaultPublishersById.put(descriptor.getId(), descriptor.clazz.newInstance());
74+
} catch (InstantiationException | IllegalAccessException e) {
75+
PrintWriter error = listener.error("[withMaven] Exception instantiation default config for Maven Publisher '" + descriptor.getDisplayName() + "' / " + descriptor.getId() + ": " + e);
76+
e.printStackTrace(error);
77+
error.close();
78+
LOGGER.log(Level.WARNING, "Exception instantiating " + descriptor.clazz + ": " + e, e);
79+
e.printStackTrace();
80+
}
81+
}
82+
83+
84+
if (LOGGER.isLoggable(Level.FINE)) {
85+
listener.getLogger().println("[withMaven] Maven Publishers with configuration provided by the pipeline: " + configuredPublishersById.values());
86+
listener.getLogger().println("[withMaven] Maven Publishers with configuration defined globally: " + globallyConfiguredPublishersById.values());
87+
listener.getLogger().println("[withMaven] Maven Publishers with default configuration: " + defaultPublishersById.values());
88+
}
89+
90+
// TODO FILTER
91+
List<MavenPublisher> results = new ArrayList<>();
92+
for (Map.Entry<String, MavenPublisher> entry : defaultPublishersById.entrySet()) {
93+
String publisherId = entry.getKey();
94+
MavenPublisher publisher = buildConfiguredMavenPublisher(
95+
configuredPublishersById.get(publisherId),
96+
globallyConfiguredPublishersById.get(publisherId),
97+
entry.getValue(),
98+
listener);
99+
results.add(publisher);
100+
}
101+
Collections.sort(results);
102+
return results;
103+
}
104+
},
105+
106+
EXPLICIT("Explicit") {
107+
@Nonnull
108+
@Override
109+
public List<MavenPublisher> buildPublishersList
110+
(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener) {
111+
112+
// filter null entries caused by missing plugins
113+
List<MavenPublisher> result = new ArrayList<>();
114+
for(MavenPublisher publisher: configuredPublishers) {
115+
if (publisher != null) {
116+
result.add(publisher);
117+
}
118+
}
119+
120+
if (LOGGER.isLoggable(Level.FINE)) {
121+
listener.getLogger().println("[withMaven] Maven Publishers: " + result);
122+
}
123+
return result;
124+
}
125+
};
126+
final String description;
127+
128+
MavenPublisherStrategy(String description) {
129+
this.description = description;
130+
}
131+
132+
public MavenPublisher buildConfiguredMavenPublisher(@Nullable MavenPublisher pipelinePublisher, @Nullable MavenPublisher globallyConfiguredPublisher, @Nonnull MavenPublisher defaultPublisher, @Nonnull TaskListener listener) {
133+
134+
MavenPublisher result;
135+
String logMessage;
136+
137+
if (pipelinePublisher == null && globallyConfiguredPublisher == null) {
138+
result = defaultPublisher;
139+
logMessage = "default";
140+
} else if (pipelinePublisher == null && globallyConfiguredPublisher != null) {
141+
result = globallyConfiguredPublisher;
142+
logMessage = "globally";
143+
} else if (pipelinePublisher != null && globallyConfiguredPublisher == null) {
144+
result = pipelinePublisher;
145+
logMessage = "pipeline";
146+
} else if (pipelinePublisher != null && globallyConfiguredPublisher != null) {
147+
// workaround FindBugs "Bug kind and pattern: NP - NP_NULL_ON_SOME_PATH"
148+
// check pipelinePublisher and globallyConfiguredPublisher are non null even if it is useless
149+
150+
result = pipelinePublisher;
151+
logMessage = "pipeline";
152+
listener.getLogger().println("[withMaven] WARNING merging publisher configuration defined in the 'Global Tool Configuration' and at the pipeline level is not yet supported." +
153+
" Use pipeline level configuration for '" + result.getDescriptor().getDisplayName() + "'");
154+
//
155+
// PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(defaultPublisher);
156+
// for(PropertyDescriptor propertyDescriptor: propertyDescriptors) {
157+
// Method readMethod = propertyDescriptor.getReadMethod();
158+
// Method writeMethod = propertyDescriptor.getWriteMethod();
159+
//
160+
// Object defaultValue = readMethod.invoke(defaultPublisher);
161+
// Object globallyDefinedValue = readMethod.invoke(globallyConfiguredPublisher);
162+
// Object pipelineValue = readMethod.invoke(pipelinePublisher);
163+
// }
164+
} else {
165+
throw new IllegalStateException("Should not happen, workaround for Findbugs NP_NULL_ON_SOME_PATH above");
166+
}
167+
168+
if (LOGGER.isLoggable(Level.FINE))
169+
listener.getLogger().println("[withMaven] Use " + logMessage + " defined publisher for '" + result.getDescriptor().getDisplayName() + "'");
170+
return result;
171+
172+
}
173+
174+
public String getDescription() {
175+
return description;
176+
}
177+
178+
/**
179+
* <p>Build the list of {@link MavenPublisher}s that should be invoked for the build execution of the given {@link TaskListener}
180+
* with the desired configuration.
181+
* </p>
182+
* <p>
183+
* The desired configuration is based on:
184+
* </p>
185+
* <ul>
186+
* <li>The default configuration of the publishers</li>
187+
* <li>The global configuration of the publishers defined in the "Global Tools Configuration' section</li>
188+
* <li>The configuration specified in the {@code withMaven(options=[...])} step</li>
189+
* </ul>
190+
* @param configuredPublishers
191+
* @param listener
192+
*/
193+
@Nonnull
194+
public abstract List<MavenPublisher> buildPublishersList(@Nonnull List<MavenPublisher> configuredPublishers, @Nonnull TaskListener listener);
195+
196+
private final static Logger LOGGER = Logger.getLogger(MavenPublisherStrategy.class.getName());
197+
}

‎jenkins-plugin/src/main/java/org/jenkinsci/plugins/pipeline/maven/MavenSpyLogProcessor.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public class MavenSpyLogProcessor implements Serializable {
5858

5959
private static final Logger LOGGER = Logger.getLogger(MavenSpyLogProcessor.class.getName());
6060

61-
public void processMavenSpyLogs(StepContext context, FilePath mavenSpyLogFolder, List<MavenPublisher> options) throws IOException, InterruptedException {
61+
public void processMavenSpyLogs(@Nonnull StepContext context, @Nonnull FilePath mavenSpyLogFolder, @Nonnull List<MavenPublisher> options,
62+
@Nonnull MavenPublisherStrategy publisherStrategy) throws IOException, InterruptedException {
6263
FilePath[] mavenSpyLogsList = mavenSpyLogFolder.list("maven-spy-*.log");
6364
LOGGER.log(Level.FINE, "Found {0} maven execution reports in {1}", new Object[]{mavenSpyLogsList.length, mavenSpyLogFolder});
6465

@@ -79,7 +80,7 @@ public void processMavenSpyLogs(StepContext context, FilePath mavenSpyLogFolder,
7980
for (FilePath mavenSpyLogs : mavenSpyLogsList) {
8081
try {
8182
if (LOGGER.isLoggable(Level.FINE)) {
82-
listener.getLogger().println("[withMaven] Evaluate Maven Spy logs: " + mavenSpyLogs.getRemote());
83+
listener.getLogger().println("[withMaven] Evaluate Maven Spy logs: " + mavenSpyLogs.getRemote());
8384
}
8485
InputStream mavenSpyLogsInputStream = mavenSpyLogs.read();
8586
if (mavenSpyLogsInputStream == null) {
@@ -94,7 +95,10 @@ public void processMavenSpyLogs(StepContext context, FilePath mavenSpyLogFolder,
9495

9596
Element mavenSpyLogsElt = documentBuilder.parse(mavenSpyLogsInputStream).getDocumentElement();
9697

97-
List<MavenPublisher> mavenPublishers = MavenPublisher.buildPublishersList(options, listener);
98+
if (LOGGER.isLoggable(Level.FINE)){
99+
listener.getLogger().println("[withMaven] Maven Publisher Strategy: " + publisherStrategy.getDescription());
100+
}
101+
List<MavenPublisher> mavenPublishers = publisherStrategy.buildPublishersList(options, listener);
98102
for (MavenPublisher mavenPublisher : mavenPublishers) {
99103
String skipFileName = mavenPublisher.getDescriptor().getSkipFileName();
100104
if (Boolean.TRUE.equals(mavenPublisher.isDisabled())) {

0 commit comments

Comments
 (0)
Please sign in to comment.