Allopen: Add Maven plugin for all-open

This commit is contained in:
Yan Zhulanow
2016-10-20 21:42:43 +03:00
committed by Yan Zhulanow
parent 0f5d51a5c2
commit 4d638c2cfd
19 changed files with 702 additions and 62 deletions
+1
View File
@@ -101,6 +101,7 @@
<module>tools/kotlin-js-tests-junit</module>
<module>tools/kotlin-annotation-processing</module>
<module>tools/kotlin-allopen</module>
<module>tools/kotlin-maven-allopen</module>
<module>tools/kotlin-gradle-plugin</module>
<module>tools/kotlin-gradle-plugin-api</module>
+131
View File
@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.version>3.0.5</maven.version>
<allopen.src>${basedir}/../../../plugins/allopen/allopen-cli/src</allopen.src>
<allopen.maven.plugin.src>${basedir}/src/main/kotlin</allopen.maven.plugin.src>
<allopen.maven.plugin.resources>${basedir}/src/main/resources</allopen.maven.plugin.resources>
<allopen.target-src>${basedir}/target/src/main/kotlin</allopen.target-src>
<allopen.target-resources>${basedir}/target/resource</allopen.target-resources>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-project</artifactId>
<version>1.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>kotlin-maven-allopen</artifactId>
<packaging>jar</packaging>
<description>All-open plugin for Maven</description>
<repositories>
<repository>
<id>jetbrains-utils</id>
<url>http://repository.jetbrains.com/utils</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${allopen.target-src}</sourceDirectory>
<resources>
<resource>
<directory>${allopen.target-resources}</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>copy-sources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${allopen.target-src}</outputDirectory>
<resources>
<resource><directory>${allopen.src}</directory></resource>
<resource><directory>${allopen.maven.plugin.src}</directory></resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${allopen.target-resources}/META-INF</outputDirectory>
<resources>
<resource><directory>${allopen.src}/META-INF</directory></resource>
<resource><directory>${allopen.maven.plugin.resources}/META-INF</directory></resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${project.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${allopen.target-src}</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
<version>1.7.1</version>
<executions>
<execution>
<id>process-classes</id>
<goals>
<goal>generate-metadata</goal>
</goals>
</execution>
<execution>
<id>process-test-classes</id>
<goals>
<goal>generate-test-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.test
import org.apache.maven.plugin.*
import org.apache.maven.project.*
import org.codehaus.plexus.component.annotations.*
import org.codehaus.plexus.logging.*
import org.jetbrains.kotlin.maven.*
val ALLOPEN_COMPILER_PLUGIN_ID = "org.jetbrains.kotlin.allopen"
@Component(role = KotlinMavenPluginExtension::class, hint = "all-open")
class KotlinAllOpenMavenPluginExtension : KotlinMavenPluginExtension {
@Requirement
lateinit var logger: Logger
override fun getCompilerPluginId() = ALLOPEN_COMPILER_PLUGIN_ID
override fun isApplicable(project: MavenProject, execution: MojoExecution) = true
override fun getPluginOptions(project: MavenProject, execution: MojoExecution): List<PluginOption> {
logger.debug("Loaded Maven plugin " + javaClass.name)
return emptyList()
}
}
@Component(role = KotlinMavenPluginExtension::class, hint = "spring")
class KotlinSpringMavenPluginExtension : KotlinMavenPluginExtension {
private companion object {
val ANNOTATIONS_ARG_NAME = "annotation"
val SPRING_ANNOTATIONS = listOf(
"org.springframework.stereotype.Component",
"org.springframework.transaction.annotation.Transactional",
"org.springframework.scheduling.annotation.Async",
"org.springframework.cache.annotation.Cacheable"
)
}
override fun getCompilerPluginId() = ALLOPEN_COMPILER_PLUGIN_ID
@Requirement
lateinit var logger: Logger
override fun isApplicable(project: MavenProject, execution: MojoExecution) = true
override fun getPluginOptions(project: MavenProject, execution: MojoExecution): List<PluginOption> {
logger.debug("Loaded Maven plugin " + javaClass.name)
return SPRING_ANNOTATIONS.map { PluginOption(ALLOPEN_COMPILER_PLUGIN_ID, ANNOTATIONS_ARG_NAME, it) }
}
}
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>test-allopen-simple</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-runtime</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
</plugin>
</plugins>
</pluginManagement>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>all-open</plugin>
</compilerPlugins>
<pluginOptions>
<option>all-open:annotation=test.AllOpen</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test
annotation class AllOpen
annotation class AllClose
@AllOpen
class OpenClass
@AllClose
class ClosedClass
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import java.lang.reflect.Modifier;
public class AllOpenSimpleTest {
@Test
public void greeting() {
assertEquals(false, Modifier.isFinal(OpenClass.class.getModifiers()));
assertEquals(true, Modifier.isFinal(ClosedClass.class.getModifiers()));
}
}
@@ -0,0 +1,6 @@
import java.io.*;
File file = new File(basedir, "target/test-allopen-simple-1.0-SNAPSHOT.jar");
if (!file.exists() || !file.isFile()) {
throw new FileNotFoundException("Could not find generated JAR: " + file);
}
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>test-allopen-spring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-runtime</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
</plugin>
</plugins>
</pluginManagement>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,60 @@
/**
* This file was copied from the spring framework:
* https://github.com/spring-projects/spring-framework
*/
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.stereotype;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that an annotated class is a "component".
* Such classes are considered as candidates for auto-detection
* when using annotation-based configuration and classpath scanning.
*
* <p>Other class-level annotations may be considered as identifying
* a component as well, typically a special kind of component:
* e.g. the {@link Repository @Repository} annotation or AspectJ's
* {@link org.aspectj.lang.annotation.Aspect @Aspect} annotation.
*
* @ author Mark Fisher
* @since 2.5
* @see Repository
* @see Service
* @see Controller
* @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";
}
@@ -0,0 +1,5 @@
package org.springframework.stereotype
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class Component
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test
@org.springframework.stereotype.Component
class OpenClass
class ClosedClass
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package test;
import org.junit.Test;
import static junit.framework.Assert.assertEquals;
import java.lang.reflect.Modifier;
public class AllOpenSimpleTest {
@Test
public void greeting() {
assertEquals(false, Modifier.isFinal(OpenClass.class.getModifiers()));
assertEquals(true, Modifier.isFinal(ClosedClass.class.getModifiers()));
}
}
@@ -0,0 +1,6 @@
import java.io.*;
File file = new File(basedir, "target/test-allopen-spring-1.0-SNAPSHOT.jar");
if (!file.exists() || !file.isFile()) {
throw new FileNotFoundException("Could not find generated JAR: " + file);
}
@@ -7,8 +7,8 @@
[INFO] Compiling Kotlin sources from [/use-test-extension/src/main/kotlin]
[INFO] Module name is use-test-extension
[INFO] Applicability test for project use-test-extension
[INFO] Applying plugin test-me
[INFO] Configuring test plugin with arguments
[INFO] Options for plugin test-me: [plugin:org.jetbrains.kotlin.test.test-plugin:test-option=my-special-value]
[INFO] Plugin applied
[INFO] Option value: my-special-value
[INFO] Kotlin Compiler version @snapshot@
@@ -17,9 +17,14 @@ class MavenPluginComponent : KotlinMavenPluginExtension {
return true
}
override fun getPluginArguments(project: MavenProject, execution: MojoExecution): MutableList<String> {
override fun getCompilerPluginId() = TestCommandLineProcessor.TestPluginId
override fun getPluginOptions(project: MavenProject, execution: MojoExecution): List<PluginOption> {
logger.info("Configuring test plugin with arguments")
return mutableListOf("plugin:${TestCommandLineProcessor.TestPluginId}:${TestCommandLineProcessor.MyTestOption.name}=my-special-value")
return listOf(PluginOption(
TestCommandLineProcessor.TestPluginId,
TestCommandLineProcessor.MyTestOption.name,
"my-special-value"))
}
}
}
@@ -58,11 +58,6 @@
<compilerPlugins>
<plugin>test-me</plugin>
</compilerPlugins>
<pluginArguments>
<argument>plugin:test-me:...=....</argument>
<!--<argument>plugin:allopen:annotations=ferfre</argument>-->
</pluginArguments>
</configuration>
<dependencies>
@@ -24,10 +24,7 @@ import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.*;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
@@ -43,9 +40,9 @@ import org.jetbrains.kotlin.config.Services;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> extends AbstractMojo {
@Component
@@ -70,16 +67,14 @@ public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> e
private List<String> compilerPlugins;
/**
* A classpaths required for kotlin compiler plugin(s). Useful if you don't use extensions due to some reason
* A list of plugin options in format (pluginId):(parameter)=(value)
*/
@Parameter
private List<String> compilerPluginsClassPaths;
private List<String> pluginOptions;
/**
* A list of plugin options in format plugin:(pluginId):(parameter)=(value)
*/
@Parameter
private List<String> pluginArguments;
private List<String> getAppliedCompilerPlugins() {
return (compilerPlugins == null) ? Collections.<String>emptyList() : compilerPlugins;
}
protected List<String> getSourceFilePaths() {
if (sourceDirs != null && !sourceDirs.isEmpty()) return sourceDirs;
@@ -150,6 +145,8 @@ public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> e
@Parameter
public List<String> args;
private final static Pattern OPTION_PATTERN = Pattern.compile("([^:]+):([^=]+)=(.*)");
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
@@ -231,13 +228,9 @@ public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> e
protected abstract void configureSpecificCompilerArguments(@NotNull A arguments) throws MojoExecutionException;
protected List<String> getCompilerPluginsClassPaths() {
private List<String> getCompilerPluginClassPaths() {
ArrayList<String> result = new ArrayList<String>();
if (compilerPluginsClassPaths != null) {
result.addAll(compilerPluginsClassPaths);
}
List<File> files = new ArrayList<File>();
for (Dependency dependency : mojoExecution.getPlugin().getDependencies()) {
@@ -260,38 +253,88 @@ public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> e
return result;
}
protected List<String> getCompilerPluginArguments() throws ComponentLookupException {
return configureCompilerPlugins();
@NotNull
private Map<String, KotlinMavenPluginExtension> loadCompilerPlugins() throws PluginNotFoundException {
Map<String, KotlinMavenPluginExtension> loadedPlugins = new HashMap<String, KotlinMavenPluginExtension>();
for (String pluginName : getAppliedCompilerPlugins()) {
getLog().debug("Looking for plugin " + pluginName);
try {
KotlinMavenPluginExtension extension = container.lookup(KotlinMavenPluginExtension.class, pluginName);
loadedPlugins.put(pluginName, extension);
getLog().debug("Got plugin instance" + pluginName + " of type " + extension.getClass().getName());
} catch (ComponentLookupException e) {
getLog().debug("Unable to get plugin instance" + pluginName);
throw new PluginNotFoundException(pluginName, e);
}
}
return loadedPlugins;
}
private List<String> configureCompilerPlugins() throws ComponentLookupException {
@NotNull
private List<String> renderCompilerPluginOptions(@NotNull List<PluginOption> options) {
List<String> renderedOptions = new ArrayList<String>(options.size());
for (PluginOption option : options) {
renderedOptions.add(option.toString());
}
return renderedOptions;
}
@NotNull
private List<PluginOption> getCompilerPluginOptions() throws PluginNotFoundException, PluginOptionIllegalFormatException {
if (mojoExecution == null) {
throw new IllegalStateException("No mojoExecution injected");
}
List<String> pluginArguments = new ArrayList<String>();
List<PluginOption> pluginOptions = new ArrayList<PluginOption>();
if (this.pluginArguments != null) {
pluginArguments.addAll(this.pluginArguments);
}
Map<String, KotlinMavenPluginExtension> plugins = loadCompilerPlugins();
if (compilerPlugins != null) {
for (String pluginId : compilerPlugins) {
getLog().debug("Looking for plugin " + pluginId);
KotlinMavenPluginExtension extension = container.lookup(KotlinMavenPluginExtension.class, pluginId);
getLog().debug("Got plugin instance" + pluginId + " of type " + extension.getClass().getName());
// Get options for extension-provided compiler plugins
if (extension.isApplicable(project, mojoExecution)) {
getLog().info("Applying plugin " + pluginId);
pluginArguments.addAll(extension.getPluginArguments(project, mojoExecution));
// TODO here we can use artifact resolver to build exact dependency tree
for (Map.Entry<String, KotlinMavenPluginExtension> pluginEntry : plugins.entrySet()) {
String pluginName = pluginEntry.getKey();
KotlinMavenPluginExtension plugin = pluginEntry.getValue();
container.getComponentDescriptor(KotlinMavenPluginExtension.class.getName(), pluginId).getRealm();
}
if (plugin.isApplicable(project, mojoExecution)) {
List<PluginOption> optionsForPlugin = plugin.getPluginOptions(project, mojoExecution);
getLog().info("Options for plugin " + pluginName + ": " + optionsForPlugin);
pluginOptions.addAll(optionsForPlugin);
}
}
return pluginArguments;
if (this.pluginOptions != null) {
pluginOptions.addAll(parseUserProvidedPluginOptions(this.pluginOptions, plugins));
}
return pluginOptions;
}
@NotNull
private static List<PluginOption> parseUserProvidedPluginOptions(
@NotNull List<String> rawOptions,
@NotNull Map<String, KotlinMavenPluginExtension> plugins
) throws PluginOptionIllegalFormatException, PluginNotFoundException {
List<PluginOption> pluginOptions = new ArrayList<PluginOption>(rawOptions.size());
for (String rawOption : rawOptions) {
Matcher matcher = OPTION_PATTERN.matcher(rawOption);
if (!matcher.matches()) {
throw new PluginOptionIllegalFormatException(rawOption);
}
String pluginName = matcher.group(1);
String key = matcher.group(2);
String value = matcher.group(3);
KotlinMavenPluginExtension plugin = plugins.get(pluginName);
if (plugin == null) {
throw new PluginNotFoundException(pluginName);
}
pluginOptions.add(new PluginOption(plugin.getCompilerPluginId(), key, value));
}
return pluginOptions;
}
private void configureCompilerArguments(@NotNull A arguments, @NotNull CLICompiler<A> compiler) throws MojoExecutionException {
@@ -334,26 +377,45 @@ public abstract class KotlinCompileMojoBase<A extends CommonCompilerArguments> e
getLog().info("Method inlining is turned off");
}
try {
List<String> pluginArguments = getCompilerPluginArguments();
if (pluginArguments != null && !pluginArguments.isEmpty()) {
if (getLog().isDebugEnabled()) {
getLog().debug("Plugin options are: " + Joiner.on(", ").join(pluginArguments));
}
arguments.pluginOptions = pluginArguments.toArray(new String[pluginArguments.size()]);
List<String> pluginClassPaths = getCompilerPluginClassPaths();
if (pluginClassPaths != null && !pluginClassPaths.isEmpty()) {
if (getLog().isDebugEnabled()) {
getLog().debug("Plugin classpaths are: " + Joiner.on(", ").join(pluginClassPaths));
}
} catch (ComponentLookupException e) {
throw new MojoExecutionException("Failed to lookup kotlin compiler plugins", e);
arguments.pluginClasspaths = pluginClassPaths.toArray(new String[pluginClassPaths.size()]);
}
List<String> classPaths = getCompilerPluginsClassPaths();
List<String> pluginArguments;
try {
pluginArguments = renderCompilerPluginOptions(getCompilerPluginOptions());
} catch (PluginNotFoundException e) {
throw new MojoExecutionException(e.getMessage(), e);
} catch (PluginOptionIllegalFormatException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
if (classPaths != null && !classPaths.isEmpty()) {
if (!pluginArguments.isEmpty()) {
if (getLog().isDebugEnabled()) {
getLog().debug("Plugin classpaths are: " + Joiner.on(", ").join(classPaths));
getLog().debug("Plugin options are: " + Joiner.on(", ").join(pluginArguments));
}
arguments.pluginClasspaths = classPaths.toArray(new String[classPaths.size()]);
arguments.pluginOptions = pluginArguments.toArray(new String[pluginArguments.size()]);
}
}
public static class PluginNotFoundException extends Exception {
PluginNotFoundException(String pluginId, Throwable cause) {
super("Plugin not found: " + pluginId, cause);
}
PluginNotFoundException(String pluginId) {
super("Plugin not found: " + pluginId);
}
}
public static class PluginOptionIllegalFormatException extends Exception {
PluginOptionIllegalFormatException(String option) {
super("Plugin option has an illegal format: " + option);
}
}
}
@@ -9,6 +9,8 @@ import java.util.List;
public interface KotlinMavenPluginExtension {
boolean isApplicable(@NotNull MavenProject project, @NotNull MojoExecution execution);
String getCompilerPluginId();
@NotNull
List<String> getPluginArguments(@NotNull MavenProject project, @NotNull MojoExecution execution);
List<PluginOption> getPluginOptions(@NotNull MavenProject project, @NotNull MojoExecution execution);
}
@@ -0,0 +1,18 @@
package org.jetbrains.kotlin.maven;
public class PluginOption {
public final String pluginId;
public final String key;
public final String value;
public PluginOption(String pluginId, String key, String value) {
this.pluginId = pluginId;
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "plugin:" + pluginId + ":" + key + "=" + value;
}
}