Add support for custom script compilation and execution to maven plugin, add simple test, relevant refactorings on the compiler side

This commit is contained in:
Ilya Chernikov
2016-09-19 14:15:04 +02:00
parent 86ece30330
commit 1a137357e5
10 changed files with 269 additions and 142 deletions
@@ -23,6 +23,16 @@
<artifactId>kotlin-reflect</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-script-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-js-library</artifactId>
@@ -75,6 +85,7 @@
<!--This could speed up test by providing local repo as remote repo for test but might be tricky on different OS-->
<!--<settingsFile>src/it/settings.xml</settingsFile>-->
<localRepositoryPath>local-repo</localRepositoryPath>
<showErrors>true</showErrors>
<postBuildHookScript>verify</postBuildHookScript>
<streamLogs>false</streamLogs>
<invokerPropertiesFile>invoker.properties</invokerPropertiesFile>
@@ -0,0 +1,76 @@
<?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-executeKotlinScriptFile</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-script-util</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<properties>
<kotlin.compiler.scriptTemplates>org.jetbrains.kotlin.script.util.StandardScript</kotlin.compiler.scriptTemplates>
<kotlin.compiler.scriptClasspath>${org.jetbrains.kotlin:kotlin-script-util:jar}</kotlin.compiler.scriptClasspath>
</properties>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-script-util</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>execute-kotlin-script</id>
<phase>compile</phase>
<goals>
<goal>script</goal>
</goals>
<configuration>
<scriptFile>script.kts</scriptFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,5 @@
if (!args.isEmpty())
println("some args passed")
println("Hello from Kotlin script file!")
@@ -0,0 +1,3 @@
source(new File(basedir, "../../../verify-common.bsh").getAbsolutePath());
assertBuildLogHasLine("Hello from Kotlin script file!")
@@ -35,6 +35,7 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.repository.ComponentDependency;
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
import org.jetbrains.kotlin.cli.common.ReflectionUtilKt;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
@@ -49,16 +50,14 @@ import org.jetbrains.kotlin.config.KotlinSourceRoot;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtScript;
import org.jetbrains.kotlin.script.StandardScriptDefinition;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
@@ -108,6 +107,15 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
@Parameter(defaultValue = "${localRepository}", required = true, readonly = true)
private ArtifactRepository localRepository;
@Parameter(property = "kotlin.compiler.scriptTemplates", required = false, readonly = false)
protected List<String> scriptTemplates;
@Parameter(property = "kotlin.compiler.scriptArguments", required = false, readonly = false)
protected List<String> scriptArguments;
@Parameter(property = "kotlin.compiler.scriptClasspath", required = false, readonly = false)
protected List<String> scriptClasspath;
@Component
private ArtifactHandlerManager artifactHandlerManager;
@@ -176,7 +184,8 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, new KotlinSourceRoot(scriptFile.getAbsolutePath()));
configuration.put(CommonConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME);
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition.INSTANCE);
K2JVMCompiler.Companion.configureScriptDefinitions(scriptTemplates.toArray(new String[scriptTemplates.size()]), configuration, messageCollector, new HashMap<String, Object>());
KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
@@ -192,17 +201,9 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
try {
Class<?> klass = classLoader.loadClass(nameForScript.asString());
Constructor<?> constructor = klass.getConstructor(String[].class);
ExecuteKotlinScriptMojo.INSTANCE = this;
constructor.newInstance(new Object[]{new String[]{}});
} catch (InstantiationException e) {
throw new ScriptExecutionException(scriptFile, "internal error", e);
} catch (InvocationTargetException e) {
throw new ScriptExecutionException(scriptFile, "script threw an exception", e.getCause());
} catch (NoSuchMethodException e) {
throw new ScriptExecutionException(scriptFile, "internal error", e);
} catch (IllegalAccessException e) {
throw new ScriptExecutionException(scriptFile, "internal error", e);
if (ReflectionUtilKt.tryConstructScriptClass(klass, scriptArguments) == null)
throw new ScriptExecutionException(scriptFile, "unable to construct script");
} catch (ClassNotFoundException e) {
throw new ScriptExecutionException(scriptFile, "internal error", e);
}
@@ -221,6 +222,10 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
deps.addAll(getThisPluginDependencies());
for (String cp: scriptClasspath) {
deps.add(new File(cp));
}
return deps;
}
@@ -65,6 +65,9 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase<K2JVMCompilerArgumen
@Parameter(property = "kotlin.compiler.jdkHome", required = false, readonly = false)
protected String jdkHome;
@Parameter(property = "kotlin.compiler.scriptTemplates", required = false, readonly = false)
protected List<String> scriptTemplates;
@NotNull
@Override
protected K2JVMCompiler createCompiler() {
@@ -114,5 +117,9 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase<K2JVMCompilerArgumen
getLog().info("Overriding JDK home path with: " + jdkHome);
arguments.jdkHome = jdkHome;
}
if (scriptTemplates != null && !scriptTemplates.isEmpty()) {
arguments.scriptTemplates = scriptTemplates.toArray(new String[0]);
}
}
}