Skip to content
Permalink
Browse files

Merge pull request #49 from jglick/metadata-JENKINS-47634

[JENKINS-47634] Pick up split plugin metadata automatically
  • Loading branch information
andresrc committed Oct 27, 2017
2 parents 4d97244 + 8908832 commit f0217f1e43b841874605a7b06145a3ab2cd0770c
@@ -42,6 +42,11 @@
</build>

<dependencies>
<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>version-number</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.tests</groupId>
<artifactId>plugins-compat-tester-model</artifactId>
@@ -241,5 +246,10 @@
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</project>
@@ -76,6 +76,7 @@
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
@@ -109,6 +110,9 @@
private PluginCompatTesterConfig config;
private final MavenRunner runner;

private String[] splits;
private String[] splitCycles;

public PluginCompatTester(PluginCompatTesterConfig config){
this.config = config;
runner = config.getExternalMaven() == null ? new InternalMavenRunner() : new ExternalMavenRunner(config.getExternalMaven());
@@ -142,6 +146,15 @@ public PluginCompatTester(PluginCompatTesterConfig config){
public PluginCompatReport testPlugins()
throws PlexusContainerException, IOException, MavenEmbedderException
{
File war = config.getWar();
if (war != null) {
populateSplits(war);
} else {
// TODO find a way to load the local version of jenkins.war acc. to UC metadata
splits = HISTORICAL_SPLITS;
splitCycles = HISTORICAL_SPLIT_CYCLES;
}

PluginCompatTesterHooks pcth = new PluginCompatTesterHooks(config.getHookPrefixes());
// Providing XSL Stylesheet along xml report file
if(config.reportFile != null){
@@ -426,7 +439,7 @@ private TestExecutionResult testPluginAgainst(MavenCoordinates coreCoordinates,
// Much simpler to do use the parent POM to set up the test classpath.
MavenPom pom = new MavenPom(pluginCheckoutDir);
try {
addSplitPluginDependencies(plugin.name, mconfig, pluginCheckoutDir, pom, otherPlugins, pluginGroupIds);
addSplitPluginDependencies(plugin.name, mconfig, pluginCheckoutDir, pom, otherPlugins, pluginGroupIds, coreCoordinates.version);
} catch (Exception x) {
x.printStackTrace();
pomData.getWarningMessages().add(Functions.printThrowable(x));
@@ -586,7 +599,7 @@ private boolean onlyOnePluginIncluded() {
}
}

private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mconfig, File pluginCheckoutDir, MavenPom pom, Map<String,Plugin> otherPlugins, Map<String, String> pluginGroupIds) throws PomExecutionException, IOException {
private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mconfig, File pluginCheckoutDir, MavenPom pom, Map<String,Plugin> otherPlugins, Map<String, String> pluginGroupIds, String coreVersion) throws PomExecutionException, IOException {
File tmp = File.createTempFile("dependencies", ".log");
VersionNumber coreDep = null;
Map<String,VersionNumber> pluginDeps = new HashMap<String,VersionNumber>();
@@ -657,48 +670,20 @@ private void addSplitPluginDependencies(String thisPlugin, MavenRunner.Config mc
}
System.out.println("Analysis: coreDep=" + coreDep + " pluginDeps=" + pluginDeps + " pluginDepsTest=" + pluginDepsTest);
if (coreDep != null) {
// Synchronize with ClassicPluginStrategy.DETACHED_LIST:
String[] splits = {
"maven-plugin:1.296:1.296",
"subversion:1.310:1.0",
"cvs:1.340:0.1",
"ant:1.430.*:1.0",
"javadoc:1.430.*:1.0",
"external-monitor-job:1.467.*:1.0",
"ldap:1.467.*:1.0",
"pam-auth:1.467.*:1.0",
"mailer:1.493.*:1.2",
"matrix-auth:1.535.*:1.0.2",
"windows-slaves:1.547.*:1.0",
"antisamy-markup-formatter:1.553.*:1.0",
"matrix-project:1.561.*:1.0",
"junit:1.577.*:1.0",
"bouncycastle-api:2.16.*:2.16.0",
};
// Synchronize with ClassicPluginStrategy.BREAK_CYCLES:
String[] exceptions = {
"script-security/matrix-auth",
"script-security/windows-slaves",
"script-security/antisamy-markup-formatter",
"script-security/matrix-project",
"credentials/matrix-auth",
"credentials/windows-slaves"
};
Map<String,VersionNumber> toAdd = new HashMap<String,VersionNumber>();
Map<String,VersionNumber> toReplace = new HashMap<String,VersionNumber>();
Map<String,VersionNumber> toAddTest = new HashMap<String,VersionNumber>();
Map<String,VersionNumber> toReplaceTest = new HashMap<String,VersionNumber>();
for (String split : splits) {
String[] pieces = split.split(":");
String[] pieces = split.split(" ");
String plugin = pieces[0];
if (Arrays.asList(exceptions).contains(thisPlugin + "/" + plugin)) {
if (Arrays.asList(splitCycles).contains(thisPlugin + ' ' + plugin)) {
System.out.println("Skipping implicit dep " + thisPlugin + "" + plugin);
continue;
}
VersionNumber splitPoint = new VersionNumber(pieces[1]);
VersionNumber declaredMinimum = new VersionNumber(pieces[2]);
// TODO this should only happen if the tested core version is ≥ splitPoint
if (coreDep.compareTo(splitPoint) <= 0 && !pluginDeps.containsKey(plugin)) {
if (coreDep.compareTo(splitPoint) < 0 && new VersionNumber(coreVersion).compareTo(splitPoint) >=0 && !pluginDeps.containsKey(plugin)) {
Plugin bundledP = otherPlugins.get(plugin);
if (bundledP != null) {
VersionNumber bundledV;
@@ -795,6 +780,74 @@ private void updateAllDependents(String parent, Plugin dependent, Map<String,Ver
}
}

/** Use JENKINS-47634 to load metadata from jenkins-core.jar if available. */
private void populateSplits(File war) throws IOException {
System.out.println("Checking " + war + " for plugin split metadata…");
try (JarFile jf = new JarFile(war, false)) {
Enumeration<JarEntry> warEntries = jf.entries();
while (warEntries.hasMoreElements()) {
JarEntry coreJar = warEntries.nextElement();
if (coreJar.getName().matches("WEB-INF/lib/jenkins-core-.+[.]jar")) {
try (InputStream is = jf.getInputStream(coreJar);
JarInputStream jis = new JarInputStream(is, false)) {
JarEntry entry;
int found = 0;
while ((entry = jis.getNextJarEntry()) != null) {
if (entry.getName().equals("jenkins/split-plugins.txt")) {
List<String> lines = IOUtils.readLines(jis, StandardCharsets.UTF_8);
System.out.println("found splits: " + lines);
splits = lines.toArray(new String[lines.size()]);
found++;
} else if (entry.getName().equals("jenkins/split-plugin-cycles.txt")) {
List<String> lines = IOUtils.readLines(jis, StandardCharsets.UTF_8);
System.out.println("found split cycles: " + lines);
splitCycles = lines.toArray(new String[lines.size()]);
found++;
}
}
if (found == 0) {
System.out.println("None found, falling back to hard-coded historical values.");
splits = HISTORICAL_SPLITS;
splitCycles = HISTORICAL_SPLIT_CYCLES;
} else if (found != 2) {
throw new IOException("unexpected amount of metadata");
}
}
return;
}
}
}
throw new IOException("no jenkins-core-*.jar found in " + war);
}
private static final String[] HISTORICAL_SPLITS = {
"maven-plugin 1.296 1.296",
"subversion 1.310 1.0",
"cvs 1.340 0.1",
"ant 1.430 1.0",
"javadoc 1.430 1.0",
"external-monitor-job 1.467 1.0",
"ldap 1.467 1.0",
"pam-auth 1.467 1.0",
"mailer 1.493 1.2",
"matrix-auth 1.535 1.0.2",
"windows-slaves 1.547 1.0",
"antisamy-markup-formatter 1.553 1.0",
"matrix-project 1.561 1.0",
"junit 1.577 1.0",
"bouncycastle-api 2.16 2.16.0",
"command-launcher 2.86 1.0",
};
private static final String[] HISTORICAL_SPLIT_CYCLES = {
"script-security matrix-auth",
"script-security windows-slaves",
"script-security antisamy-markup-formatter",
"script-security matrix-project",
"script-security bouncycastle-api",
"script-security command-launcher",
"credentials matrix-auth",
"credentials windows-slaves"
};

/**
* Finds the difference of the given maps.
* In set theory: base - toAdd

0 comments on commit f0217f1

Please sign in to comment.