diff --git a/pitest-command-line/src/main/java/org/pitest/mutationtest/commandline/PluginFilter.java b/pitest-command-line/src/main/java/org/pitest/mutationtest/commandline/PluginFilter.java index 2e5d812dd..c794115a0 100644 --- a/pitest-command-line/src/main/java/org/pitest/mutationtest/commandline/PluginFilter.java +++ b/pitest-command-line/src/main/java/org/pitest/mutationtest/commandline/PluginFilter.java @@ -20,6 +20,8 @@ public class PluginFilter implements Predicate { public PluginFilter(final PluginServices plugin) { FCollection.mapTo(plugin.findClientClasspathPlugins(), classToLocation(), this.includedClassPathElement); + FCollection.mapTo(plugin.findClientClasspathPluginDescriptors(), fileToLocation(), + this.includedClassPathElement); } private static Function classToLocation() { @@ -41,6 +43,24 @@ private PitError createPitErrorForExceptionOnClass(final Exception ex, }; } + private static Function fileToLocation() { + return new Function() { + @Override + public String apply(final File a) { + try { + return a.getCanonicalPath(); + } catch (final IOException ex) { + throw createPitErrorForExceptionOnClass(ex, a); + } + } + + private PitError createPitErrorForExceptionOnClass(final Exception ex, + final File file) { + return new PitError("Error getting location of file " + file, ex); + } + }; + } + @Override public boolean test(final String a) { return this.includedClassPathElement.contains(a); diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java index de35bb627..9283842ec 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/PluginServices.java @@ -18,6 +18,7 @@ import org.pitest.testapi.TestPluginFactory; import org.pitest.util.IsolationUtils; +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -75,6 +76,17 @@ public List findClientClasspathPlugins() { return l; } + public Iterable findClientClasspathPluginDescriptors() { + final List l = new ArrayList<>(); + l.addAll(findMutationEngineDescriptors()); + l.addAll(findMutationOperatorDescriptors()); + l.addAll(findTestFrameworkPluginDescriptors()); + l.addAll(nullPluginDescriptors()); + l.addAll(loader.findPluginDescriptors(TransformationPlugin.class)); + l.addAll(loader.findPluginDescriptors(EnvironmentResetPlugin.class)); + return l; + } + public Collection findConfigurationUpdaters() { return load(ConfigurationUpdater.class); } @@ -83,10 +95,18 @@ public Collection findMutationOperators() { return load(MethodMutatorFactory.class); } + Collection findMutationOperatorDescriptors() { + return loader.findPluginDescriptors(MethodMutatorFactory.class); + } + Collection findTestFrameworkPlugins() { return load(TestPluginFactory.class); } + Collection findTestFrameworkPluginDescriptors() { + return loader.findPluginDescriptors(TestPluginFactory.class); + } + Collection findGroupers() { return load(MutationGrouperFactory.class); } @@ -99,6 +119,10 @@ Collection findMutationEngines() { return load(MutationEngineFactory.class); } + Collection findMutationEngineDescriptors() { + return loader.findPluginDescriptors(MutationEngineFactory.class); + } + Collection findTestPrioritisers() { return load(TestPrioritiserFactory.class); } @@ -107,6 +131,10 @@ private Collection nullPlugins() { return load(ClientClasspathPlugin.class); } + private Collection nullPluginDescriptors() { + return loader.findPluginDescriptors(ClientClasspathPlugin.class); + } + public Collection findInterceptors() { return load(MutationInterceptorFactory.class); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/Services.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/Services.java index e82cb56c2..9ef894578 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/Services.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/Services.java @@ -1,7 +1,9 @@ package org.pitest.mutationtest.config; +import java.io.File; import java.util.Collection; public interface Services { Collection load(Class ifc); + Collection findPluginDescriptors(Class ifc); } diff --git a/pitest-entry/src/main/java/org/pitest/mutationtest/config/ServicesFromClassLoader.java b/pitest-entry/src/main/java/org/pitest/mutationtest/config/ServicesFromClassLoader.java index cb3ba1aba..f690e0d31 100644 --- a/pitest-entry/src/main/java/org/pitest/mutationtest/config/ServicesFromClassLoader.java +++ b/pitest-entry/src/main/java/org/pitest/mutationtest/config/ServicesFromClassLoader.java @@ -1,8 +1,16 @@ package org.pitest.mutationtest.config; +import org.pitest.util.PitError; import org.pitest.util.ServiceLoader; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; public class ServicesFromClassLoader implements Services { private final ClassLoader loader; @@ -15,4 +23,21 @@ public ServicesFromClassLoader(ClassLoader loader) { public Collection load(Class ifc) { return ServiceLoader.load(ifc, loader); } + + @Override + public Collection findPluginDescriptors(Class ifc) { + try { + final Collection pluginDescriptors = new ArrayList<>(); + Enumeration e = this.loader.getResources("META-INF/services/" + ifc.getName()); + while (e.hasMoreElements()) { + URL url = e.nextElement(); + if ("file".equals(url.getProtocol())) { + pluginDescriptors.add(Paths.get(url.toURI()).getParent().getParent().getParent().toFile()); + } + } + return pluginDescriptors; + } catch (final IOException | URISyntaxException ex) { + throw new PitError("Error finding plugin descriptor for " + ifc.getName(), ex); + } + } }