Cleaned up API to match bld operations and options APIs

This commit is contained in:
Erik C. Thauvin 2024-08-27 00:34:30 -07:00
parent a1ded46894
commit c1565e784b
Signed by: erik
GPG key ID: 776702A6A2DA330E
10 changed files with 468 additions and 64 deletions

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
</state>
</component>

6
examples/.idea/bld.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

View file

@ -1,7 +1,7 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.downloadLocation=
bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.0
bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.1-SNAPSHOT
bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.sourceDirectories=
bld.version=2.0.1

View file

@ -1,5 +1,5 @@
#!/bin/bash
kotlinc -h 2> >(grep "^ ") |\
sed -e "s/^ //" -e "s/ .*//" -e "s/<.*//" -e '/-help/d' -e '/-version/d' -e '/^$/d'|\
sort > "src/test/resources/kotlinc-args.txt"
kotlinc -h 2> >(grep "^ ") |
sed -e "s/^ //" -e "s/ .*//" -e "s/<.*//" -e '/-help/d' -e '/^-version/d' -e '/^$/d' |
sort >"src/test/resources/kotlinc-args.txt"

View file

@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project {
public CompileKotlinOperationBuild() {
pkg = "rife.bld.extension";
name = "bld-kotlin";
version = version(1, 0, 0);
version = version(1, 0, 1, "SNAPSHOT");
javaRelease = 17;

View file

@ -413,7 +413,7 @@ public class CompileKotlinOperation extends AbstractOperation<CompileKotlinOpera
}
/**
* Returns the Kotlin home directory.
* Retrieves the Kotlin home directory.
*
* @return the directory
*/

View file

@ -19,8 +19,8 @@ package rife.bld.extension.kotlin;
import rife.bld.extension.CompileKotlinOperation;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@ -92,10 +92,19 @@ public class CompileOptions {
return advancedOptions_;
}
/**
* Retrieves the version of Kotlin bundled libraries.
*
* @return the API version
*/
public String apiVersion() {
return apiVersion_;
}
/**
* Allow using declarations only from the specified version of Kotlin bundled libraries.
*
* @param version the api version
* @param version the API version
* @return this operation instance
*/
public CompileOptions apiVersion(String version) {
@ -103,10 +112,11 @@ public class CompileOptions {
return this;
}
/**
* Allow using declarations only from the specified version of Kotlin bundled libraries.
*
* @param version the api version
* @param version the API version
* @return this operation instance
*/
public CompileOptions apiVersion(int version) {
@ -133,7 +143,18 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions argFile(String... files) {
argFile_.addAll(Arrays.stream(files).map(File::new).toList());
return argFileStrings(List.of(files));
}
/**
* Read the compiler options from the given files.
*
* @param files the compiler options files
* @return this operation instance
* @see #argFile(String...)
*/
public CompileOptions argFile(Collection<File> files) {
argFile_.addAll(files);
return this;
}
@ -156,21 +177,29 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions argFile(File... files) {
argFile_.addAll(List.of(files));
return this;
return argFile(List.of(files));
}
/**
* Read the compiler options from the given files.
* <p>
* Such a file can contain compiler options with values and paths to the source files.
* Options and paths should be separated by whitespaces. For example:
* <ul>
* <li>{@code -include-runtime -d hello.jar hello.kt}</li>
* </ul>
* To pass values that contain whitespaces, surround them with single ({@code '}) or double ({@code "}) quotes.
* If a value contains quotation marks in it, escape them with a backslash (\).
* <ul>
* <li>{@code -include-runtime -d 'My folder'}</li>
* </ul>
* If the files reside in locations different from the current directory, use relative paths.
*
* @param files the compiler options files
* @param files one or more files
* @return this operation instance
* @see #argFile(String...)
*/
public CompileOptions argFile(Collection<File> files) {
argFile_.addAll(files);
return this;
public CompileOptions argFile(Path... files) {
return argFilePaths(List.of(files));
}
/**
@ -182,6 +211,28 @@ public class CompileOptions {
return argFile_;
}
/**
* Read the compiler options from the given files.
*
* @param files the compiler options files
* @return this operation instance
* @see #argFile(String...)
*/
public CompileOptions argFilePaths(Collection<Path> files) {
return argFile(files.stream().map(Path::toFile).toList());
}
/**
* Read the compiler options from the given files.
*
* @param files the compiler options files
* @return this operation instance
* @see #argFile(String...)
*/
public CompileOptions argFileStrings(Collection<String> files) {
return argFile(files.stream().map(File::new).toList());
}
/**
* Returns the formatted arguments.
*
@ -344,8 +395,7 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions classpath(String... paths) {
classpath_.addAll(Arrays.stream(paths).map(File::new).toList());
return this;
return classpathStrings(List.of(paths));
}
/**
@ -357,8 +407,19 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions classpath(File... paths) {
classpath_.addAll(List.of(paths));
return this;
return classpath(List.of(paths));
}
/**
* Search for class files in the specified paths.
* <p>
* The classpath can contain file and directory paths, ZIP, or JAR files.
*
* @param paths one or more path
* @return this operation instance
*/
public CompileOptions classpath(Path... paths) {
return classpathPaths(List.of(paths));
}
/**
@ -383,6 +444,39 @@ public class CompileOptions {
return classpath_;
}
/**
* Search for class files in the specified paths.
* <p>
* The classpath can contain file and directory paths, ZIP, or JAR files.
*
* @param paths one pr more paths
* @return this operation instance
*/
public CompileOptions classpathPaths(Collection<Path> paths) {
return classpath(paths.stream().map(Path::toFile).toList());
}
/**
* Search for class files in the specified paths.
* <p>
* The classpath can contain file and directory paths, ZIP, or JAR files.
*
* @param paths one pr more paths
* @return this operation instance
*/
public CompileOptions classpathStrings(Collection<String> paths) {
return classpath(paths.stream().map(File::new).toList());
}
/**
* Retrieves the string to evaluate as a Kotlin script.
*
* @return the expression
*/
public String expression() {
return expression_;
}
/**
* Evaluate the given string as a Kotlin script.
*
@ -415,6 +509,69 @@ public class CompileOptions {
return this;
}
/**
* Indicates whether the {@link #includeRuntime(boolean)} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isIncludeRuntime() {
return includeRuntime_;
}
/**
* Indicates whether {@link #javaParameters(boolean)} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isJavaParameters() {
return javaParameters_;
}
/**
* Indicates whether {@link #noJdk(boolean) noJdk} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isNoJdk() {
return noJdk_;
}
/**
* Indicates whether {@link #noReflect(boolean) noRflect} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isNoReflect() {
return noReflect_;
}
/**
* Indicates whether {@link #noStdLib(boolean) noStdLib} +was set.
*
* @return {@code true} or {@code false}
*/
public boolean isNoStdLib() {
return noStdLib_;
}
/**
* Indicates whether {@link #noWarn(boolean) noWarn} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isNoWarn() {
return noWarn_;
}
/**
* Indicates whether {@link #progressive(boolean) progressive} was set.
*
* @return {@code true} or {@code false}
*/
public boolean isProgressive() {
return progressive_;
}
/**
* Indicates whether {@link #verbose(boolean)} was set.
*
@ -424,6 +581,15 @@ public class CompileOptions {
return verbose_;
}
/**
* Indicates whether warnings are turned into a compilation error.
*
* @return {@code true} or {@code false}
*/
public boolean isWError() {
return wError_;
}
/**
* Generate metadata for Java 1.8 reflection on method parameters.
*
@ -441,8 +607,8 @@ public class CompileOptions {
* @param jdkHome the JDK home path
* @return this operation instance
*/
public CompileOptions jdkHome(String jdkHome) {
jdkHome_ = new File(jdkHome);
public CompileOptions jdkHome(File jdkHome) {
jdkHome_ = jdkHome;
return this;
}
@ -452,18 +618,45 @@ public class CompileOptions {
* @param jdkHome the JDK home path
* @return this operation instance
*/
public CompileOptions jdkHome(File jdkHome) {
jdkHome_ = jdkHome;
return this;
public CompileOptions jdkHome(String jdkHome) {
return jdkHome(new File(jdkHome));
}
/**
* Specify the target version of the generated JVM bytecode.
* Use a custom JDK home directory to include into the classpath if it differs from the default {@code JAVA_HOME}.
*
* @param jdkHome the JDK home path
* @return this operation instance
*/
public CompileOptions jdkHome(Path jdkHome) {
return jdkHome(jdkHome.toFile());
}
/**
* Retrieves the custom JDK home directory.
*
* @return the JDK home path.
*/
public File jdkHome() {
return jdkHome_;
}
/**
* Return the specified JDK API version.
*
* @return the API version
*/
public String jdkRelease() {
return jdkRelease_;
}
/**
* Compile against the specified JDK API version.
* <p>
* Limit the API of the JDK in the classpath to the specified Java version. Automatically sets
* {@link #jvmTarget(String) JVM target} version.
* <p>
* Possible values are 1.8, 9, 10, ..., 21. The default value is 1.8.
* Possible values are 1.8, 9, 10, ..., 22. The default value is 1.8.
*
* @param version the target version
* @return this operation instance
@ -474,7 +667,12 @@ public class CompileOptions {
}
/**
* Specify the target version of the generated JVM bytecode.
* Compile against the specified JDK API version.
* <p>
* Limit the API of the JDK in the classpath to the specified Java version. Automatically sets
* {@link #jvmTarget(String) JVM target} version.
* <p>
* Possible values are 1.8, 9, 10, ..., 22. The default value is 1.8.
*
* @param version the target version
* @return this operation instance
@ -485,17 +683,6 @@ public class CompileOptions {
return this;
}
/**
* Pass an option directly to JVM
*
* @param jvmOptions one or more JVM option
* @return this operation instance
*/
public CompileOptions jvmOptions(String... jvmOptions) {
jvmOptions_.addAll(List.of(jvmOptions));
return this;
}
/**
* Retrieves the Java Virtual Machine options.
*
@ -517,16 +704,13 @@ public class CompileOptions {
}
/**
* Specify the target version of the generated JVM bytecode.
* <p>
* Possible values are 1.8, 9, 10, ..., 21. The default value is 1.8.
* Pass an option directly to JVM
*
* @param target the target version
* @param jvmOptions one or more JVM option
* @return this operation instance
*/
public CompileOptions jvmTarget(String target) {
jvmTarget_ = target;
return this;
public CompileOptions jvmOptions(String... jvmOptions) {
return jvmOptions(List.of(jvmOptions));
}
/**
@ -541,6 +725,28 @@ public class CompileOptions {
return this;
}
/**
* Specify the target version of the generated JVM bytecode.
* <p>
* Possible values are 1.8, 9, 10, ..., 22. The default value is 1.8.
*
* @param target the target version
* @return this operation instance
*/
public CompileOptions jvmTarget(String target) {
jvmTarget_ = target;
return this;
}
/**
* Retrieves the target version of the generated JVM bytecode.
*
* @return the target version
*/
public String jvmTarget() {
return jvmTarget_;
}
/**
* Specify a custom path to the Kotlin compiler used for the discovery of runtime libraries.
*
@ -552,6 +758,25 @@ public class CompileOptions {
return this;
}
/**
* Retrieves the custom path of the Kotlin compiler.
*
* @return the Kotlin home path
*/
public File kotlinHome() {
return kotlinHome_;
}
/**
* Specify a custom path to the Kotlin compiler used for the discovery of runtime libraries.
*
* @param path the Kotlin home path
* @return this operation instance
*/
public CompileOptions kotlinHome(Path path) {
return kotlinHome(path.toFile());
}
/**
* Specify a custom path to the Kotlin compiler used for the discovery of runtime libraries.
*
@ -559,8 +784,7 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions kotlinHome(String path) {
kotlinHome_ = new File(path);
return this;
return kotlinHome(new File(path));
}
/**
@ -574,6 +798,15 @@ public class CompileOptions {
return this;
}
/**
* Retrieves the {@link #languageVersion(String) language version}.
*
* @return the language version
*/
public String languageVersion() {
return languageVersion_;
}
/**
* Set a custom name for the generated {@code .kotlin_module} file.
*
@ -585,6 +818,15 @@ public class CompileOptions {
return this;
}
/**
* Retrieves the {@link #moduleName(String) module name}.
*
* @return the module name
*/
public String moduleName() {
return moduleName_;
}
/**
* Don't automatically include the Java runtime into the classpath.
*
@ -705,6 +947,27 @@ public class CompileOptions {
return this;
}
/**
* Retrieves the location to place generated class files into.
*
* @return the location path.
*/
public File path() {
return path_;
}
/**
* Place the generated class files into the specified location.
* <p>
* The location can be a directory, a ZIP, or a JAR file.
*
* @param path the location path
* @return this operation instance
*/
public CompileOptions path(Path path) {
return path(path.toFile());
}
/**
* Place the generated class files into the specified location.
* <p>
@ -714,8 +977,7 @@ public class CompileOptions {
* @return this operation instance
*/
public CompileOptions path(String path) {
path_ = new File(path);
return this;
return path(new File(path));
}
/**
@ -734,7 +996,7 @@ public class CompileOptions {
/**
* Retrieves the plugin options.
*
* @return the plugin ofoptions.
* @return the plugin options.
*/
public Collection<String> plugin() {
return plugin_;

View file

@ -108,8 +108,8 @@ class CompileKotlinOperationTest {
var mainDir = new File(buildDir, "main");
var testDir = new File(buildDir, "test");
assertThat(mainDir.mkdirs()).isTrue();
assertThat(testDir.mkdirs()).isTrue();
assertThat(mainDir.mkdirs()).as("make mainDir").isTrue();
assertThat(testDir.mkdirs()).as("make testDir").isTrue();
var compileJars = new ArrayList<String>();
for (var f : Objects.requireNonNull(new File("examples/lib/compile").listFiles())) {
@ -136,20 +136,20 @@ class CompileKotlinOperationTest {
var args = op.compileOptions().args();
var matches = List.of("-Xjdk-release=17", "-no-stdlib", "-verbose");
assertThat(args).isEqualTo(matches);
assertThat(args).as(args + " == " + matches).isEqualTo(matches);
op.execute();
assertThat(tmpDir).isNotEmptyDirectory();
assertThat(mainDir).isNotEmptyDirectory();
assertThat(testDir).isNotEmptyDirectory();
assertThat(tmpDir).as("tmpDir").isNotEmptyDirectory();
assertThat(mainDir).as("mainDir").isNotEmptyDirectory();
assertThat(testDir).as("testDir").isNotEmptyDirectory();
var mainOut = Path.of(mainDir.getAbsolutePath(), "com", "example").toFile();
assertThat(new File(mainOut, "Example.class")).exists();
assertThat(new File(mainOut, "Example$Companion.class")).exists();
assertThat(new File(mainOut, "Example.class")).as("Example.class").exists();
assertThat(new File(mainOut, "Example$Companion.class")).as("ExampleCompanion.class").exists();
var testOut = Path.of(testDir.getAbsolutePath(), "com", "example").toFile();
assertThat(new File(testOut, "ExampleTest.class")).exists();
assertThat(new File(testOut, "ExampleTest.class")).as("ExampleTest.class").exists();
} finally {
FileUtils.deleteDirectory(tmpDir);
}

View file

@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
@ -43,6 +44,7 @@ class CompileOptionsTest {
.collect(Collectors.joining(File.pathSeparator));
}
@Test
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
void testArgs() {
@ -101,7 +103,8 @@ class CompileOptionsTest {
args.add(options.apiVersion(11).jvmTarget(11).args());
for (var a : args) {
IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i)).isEqualTo(matches.get(i)));
IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i))
.as(a.get(i) + " == " + matches.get(i)).isEqualTo(matches.get(i)));
}
}
@ -170,10 +173,29 @@ class CompileOptionsTest {
break;
}
}
assertThat(found).as(arg).isTrue();
assertThat(found).as(arg + " not found.").isTrue();
}
}
@Test
void testArgsFile() {
var foo = new File("foo.txt");
var bar = new File("bar.txt");
var options = new CompileOptions();
options.argFile(foo, bar);
assertThat(options.argFile()).contains(foo, bar);
options.argFile().clear();
options = options.argFile(foo.toPath(), bar.toPath());
assertThat(options.argFile()).contains(foo, bar);
options.argFile().clear();
options.argFile(foo.getAbsolutePath(), bar.getAbsolutePath());
assertThat(options.argFile()).contains(new File(foo.getAbsolutePath()), new File(bar.getAbsolutePath()));
options.argFile().clear();
}
@Test
void testCheckAllParams() throws IOException {
var args = Files.readAllLines(Paths.get("src", "test", "resources", "kotlinc-args.txt"));
@ -182,6 +204,7 @@ class CompileOptionsTest {
var params = new CompileOptions()
.advancedOptions("Xoption")
.apiVersion("11")
.argFile("file")
.classpath("classpath")
.expression("expression")
@ -191,6 +214,7 @@ class CompileOptionsTest {
.jdkHome("jdkhome")
.jvmTarget(12)
.kotlinHome("kotlin")
.languageVersion("1.0")
.moduleName("moduleName")
.noJdk(true)
.noReflect(true)
@ -216,4 +240,109 @@ class CompileOptionsTest {
assertThat(found).as(p + " not found.").isTrue();
}
}
@Test
void testClasspath() {
var foo = new File("foo.txt");
var bar = new File("bar.txt");
var options = new CompileOptions();
options.classpath(foo, bar);
assertThat(options.classpath()).contains(foo, bar);
options.classpath().clear();
options = options.classpath(foo.toPath(), bar.toPath());
assertThat(options.classpath()).contains(foo, bar);
options.classpath().clear();
options.classpath(foo.getAbsolutePath(), bar.getAbsolutePath());
assertThat(options.classpath()).contains(new File(foo.getAbsolutePath()), new File(bar.getAbsolutePath()));
options.classpath().clear();
}
@Test
void testJdkHome() {
var foo = new File("foo.txt");
var options = new CompileOptions();
options.jdkHome(foo);
assertThat(options.jdkHome()).isEqualTo(foo);
options = options.jdkHome(foo.toPath());
assertThat(options.jdkHome()).isEqualTo(foo);
options.jdkHome(foo.getAbsolutePath());
assertThat(options.jdkHome().getAbsolutePath()).isEqualTo(foo.getAbsolutePath());
}
@Test
void testKotlinHome() {
var foo = new File("foo.txt");
var options = new CompileOptions();
options.kotlinHome(foo);
assertThat(options.kotlinHome()).isEqualTo(foo);
options = options.kotlinHome(foo.toPath());
assertThat(options.kotlinHome()).isEqualTo(foo);
options.kotlinHome(foo.getAbsolutePath());
assertThat(options.kotlinHome().getAbsolutePath()).isEqualTo(foo.getAbsolutePath());
}
@Test
void testOptions() {
var options = new CompileOptions()
.advancedOptions("xopt1", "xopt2")
.apiVersion("11")
.argFile(Path.of("args.txt"))
.classpath("classpath")
.expression("expression")
.includeRuntime(true)
.javaParameters(true)
.jdkHome("jdk-home")
.jdkRelease("22")
.jvmTarget("9")
.kotlinHome("kotlin-home")
.languageVersion("1.0")
.moduleName("module")
.noJdk(true)
.noReflect(true)
.noStdLib(true)
.noWarn(true)
.optIn("opt1", "opt2")
.options("-foo", "-bar")
.path(Path.of("path"))
.plugin("id", "name", "value")
.progressive(true)
.scriptTemplates("name", "name2")
.verbose(true)
.wError(true);
assertThat(options.advancedOptions()).containsExactly("xopt1", "xopt2");
assertThat(options.apiVersion()).isEqualTo("11");
assertThat(options.argFile()).containsExactly(new File("args.txt"));
assertThat(options.classpath()).containsExactly(new File("classpath"));
assertThat(options.expression()).isEqualTo("expression");
assertThat(options.isIncludeRuntime()).isTrue();
assertThat(options.isJavaParameters()).isTrue();
assertThat(options.isNoJdk()).isTrue();
assertThat(options.isNoReflect()).isTrue();
assertThat(options.isNoStdLib()).isTrue();
assertThat(options.isNoWarn()).isTrue();
assertThat(options.isProgressive()).isTrue();
assertThat(options.isVerbose()).isTrue();
assertThat(options.jdkHome()).isEqualTo(new File("jdk-home"));
assertThat(options.jdkRelease()).isEqualTo("22");
assertThat(options.jvmTarget()).isEqualTo("9");
assertThat(options.kotlinHome()).isEqualTo(new File("kotlin-home"));
assertThat(options.languageVersion()).isEqualTo("1.0");
assertThat(options.moduleName()).isEqualTo("module");
assertThat(options.optIn()).containsExactly("opt1", "opt2");
assertThat(options.options()).containsExactly("-foo", "-bar");
assertThat(options.path()).isEqualTo(new File("path"));
assertThat(options.plugin()).containsExactly("id:name:value");
assertThat(options.scriptTemplates()).containsExactly("name", "name2");
assertThat(options.isWError()).isTrue();
}
}

View file

@ -1,4 +1,5 @@
@
-api-version
-classpath
-d
-expression
@ -8,6 +9,7 @@
-jdk-home
-jvm-target
-kotlin-home
-language-version
-module-name
-no-jdk
-no-reflect