();
+
+ // api-isNotBlankversion
+ if (isNotBlank(apiVersion_)) {
+ args.add("-api-version");
+ args.add(apiVersion_);
+ }
+
+ // @argfile
+ if (!argFile_.isEmpty()) {
+ argFile_.forEach(f -> args.add("@" + f));
+ }
+
+ // classpath
+ if (!classpath_.isEmpty()) {
+ args.add("-classpath");
+ args.add(String.join(File.pathSeparator, classpath_));
+ }
+
+ // java-parameters
+ if (javaParameters_) {
+ args.add("-java-parameters");
+ }
+
+ // jvm-target
+ if (isNotBlank(jvmTarget_)) {
+ args.add("-jvm-target");
+ args.add(jvmTarget_);
+ }
+
+ // include-runtime
+ if (includeRuntime_) {
+ args.add("-include-runtime");
+ }
+
+ // jdk-home
+ if (isNotBlank(jdkHome_)) {
+ args.add("-jdk-home");
+ args.add(jdkHome_);
+ }
+
+ // jdk-release
+ if (isNotBlank(jdkRelease_)) {
+ args.add("-Xjdk-release=" + jdkRelease_);
+ }
+
+ // kotlin-home
+ if (isNotBlank(kotlinHome_)) {
+ args.add("-kotlin-home");
+ args.add(kotlinHome_);
+ }
+
+ // language-version
+ if (isNotBlank(languageVersion_)) {
+ args.add("-language-version");
+ args.add(languageVersion_);
+ }
+
+ // module-name
+ if (isNotBlank(moduleName_)) {
+ args.add("-module-name");
+ args.add(moduleName_);
+ }
+
+ // no-jdk
+ if (noJdk_) {
+ args.add("-no-jdk");
+ }
+
+ // no-reflect
+ if (noReflect_) {
+ args.add("-no-reflect");
+ }
+
+ // no-std-lib
+ if (noStdLib_) {
+ args.add("-no-stdlib");
+ }
+
+ // no-warn
+ if (noWarn_) {
+ args.add("-no-warn");
+ }
+
+ // opt-in
+ optIn_.stream().filter(CompileKotlinOperation::isNotBlank).forEach(o -> {
+ args.add("-opt-in");
+ args.add(o);
+ });
+
+ // options
+ if (!options_.isEmpty()) {
+ args.addAll(options_);
+ }
+
+ // path
+ if (isNotBlank(path_)) {
+ args.add("-d");
+ args.add(path_);
+ }
+
+ // plugin
+ plugin_.stream().filter(CompileKotlinOperation::isNotBlank).forEach(p -> {
+ args.add("-P");
+ args.add("plugin:" + p);
+ });
+
+ // progressive
+ if (progressive_) {
+ args.add("-progressive");
+ }
+
+ // script-templates
+ if (!scriptTemplates_.isEmpty()) {
+ args.add("-script-templates");
+ args.add(String.join(",", scriptTemplates_));
+ }
+
+ // verbose
+ if (verbose_) {
+ args.add("-verbose");
+ }
+
+ // Werror
+ if (wError_) {
+ args.add("-Werror");
+ }
+
+ return args;
+ }
+
+ /**
+ * Search for class files in the specified paths.
+ *
+ * The classpath can contain file and directory paths, ZIP, or JAR files.
+ *
+ * @param paths one pr more paths
+ * @return this operation instance
+ */
+ public CompileKotlinOptions classpath(String... paths) {
+ classpath_.addAll(List.of(paths));
+ return this;
+ }
+
+ /**
+ * Search for class files in the specified paths.
+ *
+ * The classpath can contain file and directory paths, ZIP, or JAR files.
+ *
+ * @param paths the list of paths
+ * @return this operation instance
+ */
+ public CompileKotlinOptions classpath(Collection paths) {
+ classpath_.addAll(paths);
+ return this;
+ }
+
+ /**
+ * Indicates whether the {@link #jdkRelease(String) jdkRelease} was set.
+ *
+ * @return {@code true} if the release was set; or {@code false} otherwise
+ */
+ public boolean hasRelease() {
+ return jdkRelease_ != null;
+ }
+
+ /**
+ * Include the Kotlin runtime into the resulting JAR file. Makes the resulting archive runnable on any Java-enabled
+ * environment.
+ *
+ * @param includeRuntime {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions includeRuntime(boolean includeRuntime) {
+ includeRuntime_ = includeRuntime;
+ return this;
+ }
+
+ /**
+ * Generate metadata for Java 1.8 reflection on method parameters.
+ *
+ * @param javaParameters {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions javaParameters(boolean javaParameters) {
+ javaParameters_ = javaParameters;
+ return this;
+ }
+
+ /**
+ * 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 CompileKotlinOptions jdkHome(String jdkHome) {
+ jdkHome_ = jdkHome;
+ return this;
+ }
+
+ /**
+ * Specify the target version of the generated JVM bytecode.
+ *
+ * Limit the API of the JDK in the classpath to the specified Java version. Automatically sets
+ * {@link #jvmTarget(String) JVM target} version.
+ *
+ * Possible values are 1.8, 9, 10, ..., 21. The default value is 1.8.
+ *
+ * @param version the target version
+ * @return this operation instance
+ */
+ public CompileKotlinOptions jdkRelease(String version) {
+ jdkRelease_ = version;
+ return this;
+ }
+
+ /**
+ * Specify the target version of the generated JVM bytecode.
+ *
+ * @param version the target version
+ * @return this operation instance
+ * @see #jdkRelease(String)
+ */
+ public CompileKotlinOptions jdkRelease(int version) {
+ jdkRelease_ = String.valueOf(version);
+ return this;
+ }
+
+ /**
+ * Specify the target version of the generated JVM bytecode.
+ *
+ * Possible values are 1.8, 9, 10, ..., 21. The default value is 1.8.
+ *
+ * @param target the target version
+ * @return this operation instance
+ */
+ public CompileKotlinOptions jvmTarget(String target) {
+ jvmTarget_ = target;
+ return this;
+ }
+
+ /**
+ * Specify the target version of the generated JVM bytecode.
+ *
+ * @param target the target version
+ * @return this operation instance
+ * @see #jvmTarget(String)
+ */
+ public CompileKotlinOptions jvmTarget(int target) {
+ jvmTarget_ = String.valueOf(target);
+ return this;
+ }
+
+ /**
+ * 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 CompileKotlinOptions kotlinHome(String path) {
+ kotlinHome_ = path;
+ return this;
+ }
+
+ /**
+ * Provide source compatibility with the specified version of Kotlin.
+ *
+ * @param version the language version
+ * @return this operation instance
+ */
+ public CompileKotlinOptions languageVersion(String version) {
+ languageVersion_ = version;
+ return this;
+ }
+
+ /**
+ * Set a custom name for the generated {@code .kotlin_module} file.
+ *
+ * @param name the module name
+ * @return this operation instance
+ */
+ public CompileKotlinOptions moduleName(String name) {
+ moduleName_ = name;
+ return this;
+ }
+
+ /**
+ * Don't automatically include the Java runtime into the classpath.
+ *
+ * @param noJdk {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions noJdk(boolean noJdk) {
+ noJdk_ = noJdk;
+ return this;
+ }
+
+ /**
+ * Don't automatically include the Kotlin reflection ({@code kotlin-reflect.jar}) into the classpath.
+ *
+ * @param noReflect {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions noReflect(boolean noReflect) {
+ noReflect_ = noReflect;
+ return this;
+ }
+
+ /**
+ * Don't automatically include the Kotlin/JVM stdlib ({@code kotlin-stdlib.jar}) and Kotlin reflection
+ * ({@code kotlin-reflect.jar}) into the classpath.
+ *
+ * @param noStdLib {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions noStdLib(boolean noStdLib) {
+ noStdLib_ = noStdLib;
+ return this;
+ }
+
+ /**
+ * Suppress the compiler from displaying warnings during compilation.
+ *
+ * @param noWarn {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions noWarn(boolean noWarn) {
+ noWarn_ = noWarn;
+ return this;
+ }
+
+ /**
+ * Enable usages of API that requires opt-in with a requirement annotation with the given fully qualified name.
+ *
+ * @param annotations one or more annotation names
+ * @return this operation instance
+ */
+ public CompileKotlinOptions optIn(String... annotations) {
+ optIn_.addAll(List.of(annotations));
+ return this;
+ }
+
+ /**
+ * Enable usages of API that requires opt-in with a requirement annotation with the given fully qualified name.
+ *
+ * @param annotations list of annotation names
+ * @return this operation instance
+ */
+ public CompileKotlinOptions optIn(Collection annotations) {
+ optIn_.addAll(annotations);
+ return this;
+ }
+
+ /**
+ * Specify additional compiler options.
+ *
+ * @param options one or more compiler options
+ * @return this operation instance
+ */
+ public CompileKotlinOptions options(String... options) {
+ options_.addAll(List.of(options));
+ return this;
+ }
+
+ /**
+ * Specify additional compiler options.
+ *
+ * @param options list of compiler options
+ * @return this operation instance
+ */
+ public CompileKotlinOptions options(Collection options) {
+ options_.addAll(options);
+ return this;
+ }
+
+ /**
+ * Place the generated class files into the specified location.
+ *
+ * The location can be a directory, a ZIP, or a JAR file.
+ *
+ * @param path the location path
+ * @return this operation instance
+ */
+ public CompileKotlinOptions path(File path) {
+ path_ = path.getAbsolutePath();
+ return this;
+ }
+
+ /**
+ * Place the generated class files into the specified location.
+ *
+ * The location can be a directory, a ZIP, or a JAR file.
+ *
+ * @param path the location path
+ * @return this operation instance
+ */
+ public CompileKotlinOptions path(String path) {
+ path_ = path;
+ return this;
+ }
+
+ /**
+ * Pass an option to a plugin.
+ *
+ * @param id the plugin ID
+ * @param optionName the plugin option name
+ * @param value the plugin option value
+ * @return this operation instance
+ */
+ public CompileKotlinOptions plugin(String id, String optionName, String value) {
+ plugin_.add(id + ':' + optionName + ':' + value);
+ return this;
+ }
+
+ /**
+ * Allow using declarations only from the specified version of Kotlin bundled libraries.
+ *
+ * @param progressive {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions progressive(boolean progressive) {
+ progressive_ = progressive;
+ return this;
+ }
+
+ /**
+ * Script definition template classes.
+ *
+ * Use fully qualified class names.
+ *
+ * @param classNames one or more class names
+ * @return this operation instance
+ */
+ public CompileKotlinOptions scriptTemplates(String... classNames) {
+ scriptTemplates_.addAll(List.of(classNames));
+ return this;
+ }
+
+ /**
+ * Script definition template classes.
+ *
+ * Use fully qualified class names.
+ *
+ * @param classNames the list class names
+ * @return this operation instance
+ */
+ public CompileKotlinOptions scriptTemplates(Collection classNames) {
+ scriptTemplates_.addAll(classNames);
+ return this;
+ }
+
+ /**
+ * Enable verbose logging output which includes details of the compilation process.
+ *
+ * @param verbose {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions verbose(boolean verbose) {
+ verbose_ = verbose;
+ return this;
+ }
+
+ /**
+ * Turn any warnings into a compilation error.
+ *
+ * @param wError {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public CompileKotlinOptions wError(boolean wError) {
+ wError_ = wError;
+ return this;
+ }
+}
diff --git a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java
new file mode 100644
index 0000000..bddafbf
--- /dev/null
+++ b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension;
+
+/**
+ * Defines the known Kotlin compiler plugins match (regex) strings.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public enum CompileKotlinPlugin {
+ ALL_OPEN("^allopen-compiler-plugin-.*$"),
+ ASSIGNMENT("^assignment-compiler-plugin-.*$"),
+ KOTLIN_IMPORTS_DUMPER("^kotlin-imports-dumper-compiler-plugin-.*$"),
+ KOTLIN_SERIALIZATION("^kotlin-serialization-compiler-plugin-.*$"),
+ KOTLINX_SERIALIZATION("^kotlinx-serialization-compiler-plugin-.*$"),
+ LOMBOK("^lombok-compiler-plugin-.*$"),
+ NOARG("^noarg-compiler-plugin-.*$"),
+ SAM_WITH_RECEIVER("^sam-with-receiver-compiler-plugin-.*$");
+
+ public final String label;
+
+ CompileKotlinPlugin(String label) {
+ this.label = label;
+ }
+}
diff --git a/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java b/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java
new file mode 100644
index 0000000..dd6ff1a
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+/**
+ * Dokka's analysis platforms.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public enum AnalysisPlatform {
+ JVM, JS, NATIVE, COMMON, ANDROID
+}
diff --git a/src/main/java/rife/bld/extension/dokka/DocumentedVisibility.java b/src/main/java/rife/bld/extension/dokka/DocumentedVisibility.java
new file mode 100644
index 0000000..dae65a4
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/DocumentedVisibility.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+/**
+ * Dokka documented visibilities.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public enum DocumentedVisibility {
+ PUBLIC, PRIVATE, PROTECTED, INTERNAL, PACKAGE
+}
diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java
new file mode 100644
index 0000000..0b0936e
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+import rife.bld.BaseProject;
+import rife.bld.extension.CompileKotlinOperation;
+import rife.bld.operations.AbstractProcessOperation;
+import rife.tools.StringUtils;
+
+import java.io.File;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static rife.bld.extension.CompileKotlinOperation.isNotBlank;
+
+/**
+ * Builds documentation (javadoc, HTML, etc.) using Dokka.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+@SuppressWarnings("PMD.AvoidThrowingRawExceptionTypes")
+public class DokkaOperation extends AbstractProcessOperation {
+ private final static String GFM_PLUGIN_REGEXP =
+ "^.*(dokka-base|analysis-kotlin-descriptors|gfm-plugin|freemarker).*\\.jar$";
+ private final static String HTML_PLUGIN_REGEXP =
+ "^.*(dokka-base|analysis-kotlin-descriptors|kotlinx-html-jvm|freemarker).*\\.jar$";
+ private final static String JAVADOC_PLUGIN_REGEXP =
+ "^.*(dokka-base|analysis-kotlin-descriptors|javadoc-plugin|kotlin-as-java-plugin|korte-jvm).*\\.jar$";
+ private final static String JEKYLL_PLUGIN_REGEXP =
+ "^.*(dokka-base|analysis-kotlin-descriptors|jekyll-plugin|gfm-plugin|freemarker).*\\.jar$";
+ private final Logger LOGGER = Logger.getLogger(DokkaOperation.class.getName());
+ private final Map globalLinks_ = new ConcurrentHashMap<>();
+ private final Collection globalPackageOptions_ = new ArrayList<>();
+ private final Collection globalSrcLinks_ = new ArrayList<>();
+ private final Collection includes_ = new ArrayList<>();
+ private final Map pluginConfiguration_ = new ConcurrentHashMap<>();
+ private final Collection pluginsClasspath_ = new ArrayList<>();
+ private boolean delayTemplateSubstitution_;
+ private boolean failOnWarning_;
+ private LoggingLevel loggingLevel_;
+ private String moduleName_;
+ private String moduleVersion_;
+ private boolean noSuppressObviousFunctions_;
+ private boolean offlineMode_;
+ private File outputDir_;
+ private BaseProject project_;
+ private SourceSet sourceSet_;
+ private boolean suppressInheritedMembers_;
+
+ /**
+ * Sets the delay substitution of some elements.
+ *
+ * Used in incremental builds of multimodule projects.
+ *
+ * @param delayTemplateSubstitution the delay
+ * @return this operation instance
+ */
+ public DokkaOperation delayTemplateSubstitution(Boolean delayTemplateSubstitution) {
+ delayTemplateSubstitution_ = delayTemplateSubstitution;
+ return this;
+ }
+
+ /**
+ * Part of the {@link #execute execute} operation, constructs the command list to use for building the process.
+ *
+ * @since 1.5
+ */
+ @Override
+ protected List executeConstructProcessCommandList() {
+ if (project_ == null) {
+ throw new IllegalArgumentException("A project must be specified.");
+ }
+
+ final List args = new ArrayList<>();
+
+ // java
+ args.add(javaTool());
+
+ var cli = CompileKotlinOperation.getJarList(project_.libBldDirectory(), "^.*dokka-cli.*\\.jar$");
+
+ if (cli.size() != 1) {
+ throw new RuntimeException("The dokka-cli JAR could not be found.");
+ }
+
+ // -jar dokka-cli
+ args.add("-jar");
+ args.add(cli.get(0));
+
+ // -pluginClasspath
+ if (!pluginsClasspath_.isEmpty()) {
+ args.add("-pluginsClasspath");
+ args.add(String.join(";", pluginsClasspath_));
+ }
+
+ // -sourceSet
+ var sourceSetArgs = sourceSet_.args();
+ if (sourceSetArgs.isEmpty()) {
+ throw new IllegalArgumentException("At least one sourceSet is required.");
+ } else {
+ args.add("-sourceSet");
+ args.add(String.join(" ", sourceSet_.args()));
+ }
+
+ // -outputDir
+ if (outputDir_ != null) {
+ if (!outputDir_.exists() && !outputDir_.mkdirs()) {
+ throw new RuntimeException("Could not create: " + outputDir_.getAbsolutePath());
+ }
+
+ args.add("-outputDir");
+ args.add(outputDir_.getAbsolutePath());
+ }
+
+ // -delayTemplateSubstitution
+ if (delayTemplateSubstitution_) {
+ args.add("-delayTemplateSubstitution");
+ args.add(String.valueOf(delayTemplateSubstitution_));
+ }
+
+ // -failOnWarning
+ if (failOnWarning_) {
+ args.add("-failOnWarning");
+ args.add(String.valueOf(failOnWarning_));
+ }
+
+ // -globalLinks_
+ if (!globalLinks_.isEmpty()) {
+ args.add("-globalLinks");
+ var links = new ArrayList();
+ globalLinks_.forEach((k, v) ->
+ links.add(String.format("%s^%s", k, v)));
+ args.add(String.join("^^", links));
+ }
+
+ // -globalPackageOptions
+ if (!globalPackageOptions_.isEmpty()) {
+ args.add("-globalPackageOptions");
+ args.add(String.join(";", globalPackageOptions_));
+ }
+
+ // -globalSrcLinks
+ if (!globalSrcLinks_.isEmpty()) {
+ args.add("-globalSrcLinks_");
+ args.add(String.join(";", globalSrcLinks_));
+ }
+
+ // -includes
+ if (!includes_.isEmpty()) {
+ args.add("-includes");
+ args.add(String.join(";", includes_));
+ }
+
+ // -loggingLevel
+ if (loggingLevel_ != null) {
+ args.add("-loggingLevel");
+ args.add(loggingLevel_.name().toLowerCase());
+ }
+
+ // -moduleName
+ if (isNotBlank(moduleName_)) {
+ args.add("-moduleName");
+ args.add(moduleName_);
+ }
+
+ // -moduleVersion
+ if (isNotBlank(moduleVersion_)) {
+ args.add("-moduleVersion");
+ args.add(moduleVersion_);
+ }
+
+ // -noSuppressObviousFunctions
+ if (noSuppressObviousFunctions_) {
+ args.add("-noSuppressObviousFunctions");
+ args.add(String.valueOf(noSuppressObviousFunctions_));
+ }
+
+ // -offlineMode
+ if (offlineMode_) {
+ args.add("-offlineMode");
+ args.add(String.valueOf(offlineMode_));
+ }
+
+ // -pluginConfiguration
+ if (!pluginConfiguration_.isEmpty()) {
+ args.add("-pluginConfiguration");
+ var confs = new ArrayList();
+ pluginConfiguration_.forEach((k, v) ->
+ confs.add(String.format("{%s}={%s}", StringUtils.encodeJson(k), StringUtils.encodeJson(v))));
+ args.add(String.join("^^", confs));
+ }
+
+ // -suppressInheritedMembers
+ if (suppressInheritedMembers_) {
+ args.add("-suppressInheritedMembers");
+ args.add(String.valueOf(suppressInheritedMembers_));
+ }
+
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine(String.join(" ", args));
+ }
+
+ return args;
+ }
+
+ /**
+ * Configures the operation from a {@link BaseProject}.
+ *
+ * Sets the {@link #sourceSet sourceSet}, {@link SourceSet#jdkVersion jdkVersion} and {@link #moduleName moduleName}
+ * from the project.
+ *
+ * @param project the project to configure the operation from
+ */
+ @Override
+ public DokkaOperation fromProject(BaseProject project) {
+ project_ = project;
+ sourceSet_ = new SourceSet().src(new File(project.srcMainDirectory(), "kotlin").getAbsolutePath());
+ if (project.javaRelease() != null) {
+ sourceSet_ = sourceSet_.jdkVersion(project.javaRelease());
+ }
+ moduleName_ = project.name();
+ return this;
+ }
+
+ /**
+ * Sets whether to fail documentation generation if Dokka has emitted a warning or an error.
+ *
+ * Whether to fail documentation generation if Dokka has emitted a warning or an error. The process waits until all
+ * errors and warnings have been emitted first.
+ *
+ * This setting works well with {@link SourceSet#reportUndocumented}
+ *
+ * @param failOnWarning {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public DokkaOperation failOnWarning(Boolean failOnWarning) {
+ failOnWarning_ = failOnWarning;
+ return this;
+ }
+
+ /**
+ * Set the global external documentation links.
+ *
+ * @param url the external documentation URL
+ * @param packageListUrl the external documentation package list URL
+ * @return this operation instance
+ */
+ public DokkaOperation globalLinks(String url, String packageListUrl) {
+ globalLinks_.put(url, packageListUrl);
+ return this;
+ }
+
+ /**
+ * Set the global external documentation links.
+ *
+ * @param globalLinks the map of global links
+ * @return this operation instance
+ * @see #globalSrcLink(String...) #globalSrcLink(String...)#globalSrcLink(String...)
+ */
+ public DokkaOperation globalLinks(Map globalLinks) {
+ globalLinks_.putAll(globalLinks);
+ return this;
+ }
+
+ /**
+ * Sets the global list of package configurations.
+ *
+ * Using format:
+ *
+ * - matchingRegexp
+ * - -deprecated
+ * - -privateApi
+ * - +warnUndocumented
+ * - +suppress
+ * - +visibility:PUBLIC
+ * - ...
+ *
+ *
+ * @param options ome pr more package configurations
+ * @return this operation instance
+ */
+ public DokkaOperation globalPackageOptions(String... options) {
+ globalPackageOptions_.addAll(Arrays.asList(options));
+ return this;
+ }
+
+ /**
+ * Sets the global list of package configurations.
+ *
+ * Using format:
+ *
+ * - matchingRegexp
+ * - -deprecated
+ * - -privateApi
+ * - +warnUndocumented
+ * - +suppress
+ * - +visibility:PUBLIC
+ * - ...
+ *
+ *
+ * @param options the list of package configurations
+ * @return this operation instance
+ */
+ public DokkaOperation globalPackageOptions(Collection options) {
+ globalPackageOptions_.addAll(options);
+ return this;
+ }
+
+ /**
+ * Sets the global mapping between a source directory and a Web service for browsing the code.
+ *
+ * @param links one or more links mapping
+ * @return this operation instance
+ */
+ public DokkaOperation globalSrcLink(String... links) {
+ globalSrcLinks_.addAll(Arrays.asList(links));
+ return this;
+ }
+
+ /**
+ * Sets the global mapping between a source directory and a Web service for browsing the code.
+ *
+ * @param links the links mapping
+ * @return this operation instance
+ */
+ public DokkaOperation globalSrcLink(Collection links) {
+ globalSrcLinks_.addAll(links);
+ return this;
+ }
+
+ /**
+ * Sets the Markdown files that contain module and package documentation.
+ *
+ * The contents of specified files are parsed and embedded into documentation as module and package descriptions.
+ *
+ * This can be configured on per-package basis.
+ *
+ * @param files one or more files
+ * @return this operation instance
+ */
+ public DokkaOperation includes(String... files) {
+ includes_.addAll(Arrays.asList(files));
+ return this;
+ }
+
+ /**
+ * Sets the Markdown files that contain module and package documentation.
+ *
+ * The contents of specified files are parsed and embedded into documentation as module and package descriptions.
+ *
+ * This can be configured on per-package basis.
+ *
+ * @param files the list of files
+ * @return this operation instance
+ */
+ public DokkaOperation includes(Collection files) {
+ includes_.addAll(files);
+ return this;
+ }
+
+ /**
+ * Sets the logging level.
+ *
+ * @param loggingLevel the logging level
+ * @return this operation instance
+ */
+ public DokkaOperation loggingLevel(LoggingLevel loggingLevel) {
+ loggingLevel_ = loggingLevel;
+ return this;
+ }
+
+ /**
+ * Sets the name of the project/module. Default is {@code root}.
+ *
+ * The display name used to refer to the module. It is used for the table of contents, navigation, logging, etc.
+ *
+ * @param moduleName the project/module name
+ * @return this operation instance
+ */
+ public DokkaOperation moduleName(String moduleName) {
+ moduleName_ = moduleName;
+ return this;
+ }
+
+ /**
+ * Set the documented version.
+ *
+ * @param version the version
+ * @return this operation instance
+ */
+ public DokkaOperation moduleVersion(String version) {
+ moduleVersion_ = version;
+ return this;
+ }
+
+ /**
+ * Sets whether to suppress obvious functions such as inherited from
+ * kotlin.Any and {@link java.lang.Object}.
+ *
+ * A function is considered to be obvious if it is:
+ *
+ * - Inherited from kotlin.Any,
+ * Kotlin.Enum, {@link java.lang.Object}
+ * or {@link java.lang.Enum}, such as {@code equals}, {@code hashCode}, {@code toString}.
+ *
- Synthetic (generated by the compiler) and does not have any documentation, such as
+ * {@code dataClass.componentN} or {@code dataClass.copy}.
+ *
+ *
+ * @param noSuppressObviousFunctions {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public DokkaOperation noSuppressObviousFunctions(Boolean noSuppressObviousFunctions) {
+ noSuppressObviousFunctions_ = noSuppressObviousFunctions;
+ return this;
+ }
+
+ /**
+ * Sets whether to resolve remote files/links over network.
+ *
+ * This includes package-lists used for generating external documentation links. For example, to make classes from
+ * the standard library clickable.
+ *
+ * Setting this to true can significantly speed up build times in certain cases, but can also worsen documentation
+ * quality and user experience. For example, by not resolving class/member links from your dependencies, including
+ * the standard library.
+ *
+ * Note: You can cache fetched files locally and provide them to Dokka as local paths.
+ *
+ * @param offlineMode the offline mode
+ * @return this operation instance
+ * @see SourceSet#externalDocumentationLinks(String, String)
+ */
+ public DokkaOperation offlineMode(Boolean offlineMode) {
+ offlineMode_ = offlineMode;
+ return this;
+ }
+
+ /**
+ * Sets the output directory path, {@code ./dokka} by default.
+ *
+ * The directory to where documentation is generated, regardless of output format.
+ *
+ * @param outputDir the output directory
+ * @return this operation instance
+ */
+ public DokkaOperation outputDir(File outputDir) {
+ outputDir_ = outputDir;
+ return this;
+ }
+
+ /**
+ * Sets the output directory path, {@code ./dokka} by default.
+ *
+ * @param outputDir the output directory
+ * @return this operation instance
+ */
+ public DokkaOperation outputDir(String outputDir) {
+ outputDir_ = new File(outputDir);
+ return this;
+ }
+
+ /**
+ * Sets the Dokka {@link OutputFormat output format}.
+ *
+ * @param format The {@link OutputFormat output format}
+ * @return this operation instance
+ */
+ public DokkaOperation outputFormat(OutputFormat format) {
+ pluginsClasspath_.clear();
+ if (format.equals(OutputFormat.JAVADOC)) {
+ pluginsClasspath_.addAll(CompileKotlinOperation.getJarList(project_.libBldDirectory(),
+ JAVADOC_PLUGIN_REGEXP));
+ } else if (format.equals(OutputFormat.HTML)) {
+ pluginsClasspath_.addAll(CompileKotlinOperation.getJarList(project_.libBldDirectory(),
+ HTML_PLUGIN_REGEXP));
+ } else if (format.equals(OutputFormat.MARKDOWN)) {
+ pluginsClasspath_.addAll(CompileKotlinOperation.getJarList(project_.libBldDirectory(),
+ GFM_PLUGIN_REGEXP));
+ } else if (format.equals(OutputFormat.JEKYLL)) {
+ pluginsClasspath_.addAll(CompileKotlinOperation.getJarList(project_.libBldDirectory(),
+ JEKYLL_PLUGIN_REGEXP));
+ }
+ return this;
+ }
+
+ /**
+ * Sets the configuration for Dokka plugins.
+ *
+ * @param name The fully-qualified plugin name
+ * @param jsonConfiguration The plugin JSON configuration
+ * @return this operation instance
+ */
+ public DokkaOperation pluginConfiguration(String name, String jsonConfiguration) {
+ pluginConfiguration_.put(name, jsonConfiguration);
+ return this;
+ }
+
+ /**
+ * Sets the configuration for Dokka plugins.
+ *
+ * @param pluginConfiguration the map of configurations
+ * @return this operation instance
+ * @see #pluginConfiguration(String, String)
+ */
+ public DokkaOperation pluginConfiguration(Map pluginConfiguration) {
+ pluginConfiguration_.putAll(pluginConfiguration);
+ return this;
+ }
+
+ /**
+ * Sets the list of jars with Dokka plugins and their dependencies.
+ *
+ * @param jars one or more jars
+ * @return this operation instance
+ */
+ public DokkaOperation pluginsClasspath(String... jars) {
+ pluginsClasspath_.addAll(Arrays.asList(jars));
+ return this;
+ }
+
+ /**
+ * Sets the list of jars with Dokka plugins and their dependencies.
+ *
+ * @param jars the list of jars
+ * @return this operation instance
+ */
+ public DokkaOperation pluginsClasspath(Collection jars) {
+ pluginsClasspath_.addAll(jars);
+ return this;
+ }
+
+ /**
+ * Clears the list of Dokka plugins.
+ *
+ * @param clear set to clear the list
+ * @return this operation instance
+ */
+ public DokkaOperation pluginsClasspath(boolean clear) {
+ if (clear) {
+ pluginsClasspath_.clear();
+ }
+ return this;
+ }
+
+ /**
+ * Sets the configurations for a source set.
+ *
+ * Individual and additional configuration of Kotlin source sets.
+ *
+ * @param sourceSet the source set configurations
+ * @return this operation instance
+ */
+ public DokkaOperation sourceSet(SourceSet sourceSet) {
+ sourceSet_ = sourceSet;
+ return this;
+ }
+
+ /**
+ * Sets whether to suppress inherited members that aren't explicitly overridden in a given class.
+ *
+ * @param suppressInheritedMembers {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public DokkaOperation suppressInheritedMembers(Boolean suppressInheritedMembers) {
+ suppressInheritedMembers_ = suppressInheritedMembers;
+ return this;
+ }
+}
diff --git a/src/main/java/rife/bld/extension/dokka/LoggingLevel.java b/src/main/java/rife/bld/extension/dokka/LoggingLevel.java
new file mode 100644
index 0000000..b493e11
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/LoggingLevel.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+/**
+ * Dokka logging levels.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public enum LoggingLevel {
+ DEBUG, PROGRESS, INFO, WARN, ERROR
+}
diff --git a/src/main/java/rife/bld/extension/dokka/OutputFormat.java b/src/main/java/rife/bld/extension/dokka/OutputFormat.java
new file mode 100644
index 0000000..0d4a2c0
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/OutputFormat.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+/**
+ * Dokka output formats.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public enum OutputFormat {
+ JAVADOC, JEKYLL, HTML, MARKDOWN
+}
diff --git a/src/main/java/rife/bld/extension/dokka/SourceSet.java b/src/main/java/rife/bld/extension/dokka/SourceSet.java
new file mode 100644
index 0000000..4a2dfb9
--- /dev/null
+++ b/src/main/java/rife/bld/extension/dokka/SourceSet.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Configuration for a Dokka source set.
+ *
+ * @author Erik C. Thauvin
+ * @since 1.0
+ */
+public class SourceSet {
+ private static final String SEMICOLON = ";";
+ private final Collection classpath_ = new ArrayList<>();
+ private final Map dependentSourceSets_ = new ConcurrentHashMap<>();
+ private final Collection documentedVisibilities_ = new ArrayList<>();
+ private final Map externalDocumentationLinks_ = new ConcurrentHashMap<>();
+ private final Collection includes_ = new ArrayList<>();
+ private final Collection perPackageOptions_ = new ArrayList<>();
+ private final Collection samples_ = new ArrayList<>();
+ private final Map srcLinks_ = new ConcurrentHashMap<>();
+ private final Collection src_ = new ArrayList<>();
+ private final Collection suppressedFiles_ = new ArrayList<>();
+ private AnalysisPlatform analysisPlatform_;
+ private String apiVersion_;
+ private String displayName_;
+ private int jdkVersion_;
+ private String languageVersion_;
+ private boolean noJdkLink_;
+ private boolean noSkipEmptyPackages_;
+ private boolean noStdlibLink_;
+ private boolean reportUndocumented_;
+ private boolean skipDeprecated_;
+ private String sourceSetName_;
+
+ /**
+ * Sets the platform used for setting up analysis. Default is {@link AnalysisPlatform#JVM JVM}
+ *
+ * Platform to be used for setting up code analysis and {@code @sample} environment.
+ *
+ * @param analysisPlatform the analysis platform
+ * @return this operation instance
+ */
+ public SourceSet analysisPlatform(AnalysisPlatform analysisPlatform) {
+ analysisPlatform_ = analysisPlatform;
+ return this;
+ }
+
+ /**
+ * Sets the Kotlin API version used for setting up analysis and samples.
+ *
+ * @param apiVersion the api version
+ * @return this operation instance
+ */
+ public SourceSet apiVersion(String apiVersion) {
+ apiVersion_ = apiVersion;
+ return this;
+ }
+
+ /**
+ * Returns the formatted arguments.
+ *
+ * @return the arguments
+ */
+ public List args() {
+ var args = new ArrayList();
+
+ // -analysisPlatform
+ if (analysisPlatform_ != null) {
+ args.add("-analysisPlatform");
+ args.add(analysisPlatform_.name().toLowerCase());
+ }
+
+ // -apiVersion
+ if (apiVersion_ != null) {
+ args.add("-apiVersion");
+ args.add(apiVersion_);
+ }
+
+ // -classpath
+ if (!classpath_.isEmpty()) {
+ args.add("-classpath");
+ args.add(String.join(SEMICOLON, classpath_));
+ }
+
+ // -dependentSourceSets
+ if (!dependentSourceSets_.isEmpty()) {
+ args.add("-dependentSourceSets");
+ var deps = new ArrayList();
+ dependentSourceSets_.forEach((k, v) -> deps.add(String.format("%s/%s", k, v)));
+ args.add(String.join(SEMICOLON, deps));
+ }
+
+ // -displayName
+ if (displayName_ != null) {
+ args.add("-displayName");
+ args.add(displayName_);
+ }
+
+ // -documentedVisibilities
+ if (!documentedVisibilities_.isEmpty()) {
+ args.add("-documentedVisibilities");
+ var vis = new ArrayList();
+ documentedVisibilities_.forEach(d -> vis.add(d.name().toLowerCase()));
+ args.add(String.join(SEMICOLON, vis));
+ }
+
+ // -externalDocumentationLinks
+ if (!externalDocumentationLinks_.isEmpty()) {
+ args.add("-externalDocumentationLinks");
+ var links = new ArrayList();
+ externalDocumentationLinks_.forEach((k, v) -> links.add(String.format("%s^%s", k, v)));
+ args.add(String.join("^^", links));
+ }
+
+ // -jdkVersion
+ if (jdkVersion_ > 0) {
+ args.add("-jdkVersion");
+ args.add(String.valueOf(jdkVersion_));
+ }
+
+ // -includes
+ if (!includes_.isEmpty()) {
+ args.add("-includes");
+ args.add(String.join(SEMICOLON, includes_));
+ }
+
+ // -languageVersion
+ if (languageVersion_ != null) {
+ args.add("-languageVersion");
+ args.add(languageVersion_);
+ }
+
+ // -noJdkLink
+ if (noJdkLink_) {
+ args.add("-noJdkLink");
+ args.add(String.valueOf(noJdkLink_));
+ }
+
+ // -noSkipEmptyPackages
+ if (noSkipEmptyPackages_) {
+ args.add("-noSkipEmptyPackages");
+ args.add(String.valueOf(noSkipEmptyPackages_));
+ }
+
+ // -noStdlibLink
+ if (noStdlibLink_) {
+ args.add("-noStdlibLink");
+ args.add(String.valueOf(noStdlibLink_));
+ }
+
+ // -reportUndocumented
+ if (reportUndocumented_) {
+ args.add("-reportUndocumented");
+ args.add(String.valueOf(reportUndocumented_));
+ }
+
+ // -perPackageOptions
+ if (!perPackageOptions_.isEmpty()) {
+ args.add("-perPackageOptions");
+ args.add(String.join(SEMICOLON, perPackageOptions_));
+ }
+
+ // -samples
+ if (!samples_.isEmpty()) {
+ args.add("-samples");
+ args.add(String.join(SEMICOLON, samples_));
+ }
+
+ // -skipDeprecated
+ if (skipDeprecated_) {
+ args.add("-skipDeprecated");
+ args.add(String.valueOf(skipDeprecated_));
+ }
+
+ // -src
+ if (!src_.isEmpty()) {
+ args.add("-src");
+ args.add(String.join(SEMICOLON, src_));
+ }
+
+ // -srcLink
+ if (!srcLinks_.isEmpty()) {
+ args.add("-srcLink");
+ var links = new ArrayList();
+ srcLinks_.forEach((k, v) -> links.add(String.format("%s=%s", k, v)));
+ args.add(String.join(SEMICOLON, links));
+ }
+
+ // -sourceSetName
+ if (sourceSetName_ != null) {
+ args.add("-sourceSetName");
+ args.add(sourceSetName_);
+ }
+
+ // -suppressedFiles
+ if (!suppressedFiles_.isEmpty()) {
+ args.add("-suppressedFiles");
+ args.add(String.join(SEMICOLON, suppressedFiles_));
+ }
+
+ return args;
+ }
+
+ /**
+ * Sets classpath for analysis and interactive samples.
+ *
+ * This is useful if some types that come from dependencies are not resolved/picked up automatically.
+ *
+ * This option accepts both {@code .jar} and {@code .klib} files.
+ *
+ * @param classpath one or more classpath
+ * @return this operation instance
+ */
+ public SourceSet classpath(String... classpath) {
+ classpath_.addAll(Arrays.asList(classpath));
+ return this;
+ }
+
+ /**
+ * Sets classpath for analysis and interactive samples.
+ *
+ * This is useful if some types that come from dependencies are not resolved/picked up automatically.
+ *
+ * This option accepts both {@code .jar} and {@code .klib} files.
+ *
+ * @param classpath the list of classpath
+ * @return this operation instance
+ */
+ public SourceSet classpath(Collection classpath) {
+ classpath_.addAll(classpath);
+ return this;
+ }
+
+ /**
+ * Sets the names of dependent source sets.
+ *
+ * @param moduleName the module name
+ * @param sourceSetName the source set name
+ * @return this operation instance
+ */
+ public SourceSet dependentSourceSets(String moduleName, String sourceSetName) {
+ dependentSourceSets_.put(moduleName, sourceSetName);
+ return this;
+ }
+
+ /**
+ * Sets the names of dependent source sets.
+ *
+ * @param dependentSourceSets the map of dependent source set names
+ * @return this operation instance
+ * @see #dependentSourceSets(String, String)
+ */
+ public SourceSet dependentSourceSets(Map dependentSourceSets) {
+ dependentSourceSets_.putAll(dependentSourceSets);
+ return this;
+ }
+
+ /**
+ * Sets the display name of the source set, used both internally and externally.
+ *
+ * The name is used both externally (for example, the source set name is visible to documentation readers) and
+ * internally (for example, for logging messages of {@link #reportUndocumented reportUndocumented}).
+ *
+ * The platform name can be used if you don't have a better alternative.
+ *
+ * @param displayName the display name
+ * @return this operation instance
+ */
+ public SourceSet displayName(String displayName) {
+ displayName_ = displayName;
+ return this;
+ }
+
+ /**
+ * Sets visibilities to be documented.
+ *
+ * This can be used if you want to document protected/internal/private declarations, as well as if you want to
+ * exclude public declarations and only document internal API.
+ *
+ * This can be configured on per-package basis.
+ *
+ * @param visibilities one or more visibilities
+ * @return this operation instance
+ */
+ public SourceSet documentedVisibilities(DocumentedVisibility... visibilities) {
+ documentedVisibilities_.addAll(Arrays.asList(visibilities));
+ return this;
+ }
+
+ /**
+ * Sets the external documentation links.
+ *
+ * A set of parameters for external documentation links that is applied only for this source set.
+ *
+ * @param url the external documentation URL
+ * @param packageListUrl the external documentation package list URL
+ * @return this operation instance
+ */
+ public SourceSet externalDocumentationLinks(String url, String packageListUrl) {
+ externalDocumentationLinks_.put(url, packageListUrl);
+ return this;
+ }
+
+ /**
+ * Sets the external documentation links.
+ *
+ * A set of parameters for external documentation links that is applied only for this source set.
+ *
+ * @param externalDocumentationLinks the map of external documentation links
+ * @return this operation instance
+ * @see #externalDocumentationLinks(String, String)
+ */
+ public SourceSet externalDocumentationLinks(Map externalDocumentationLinks) {
+ externalDocumentationLinks_.putAll(externalDocumentationLinks);
+ return this;
+ }
+
+ /**
+ * Sets the Markdown files that contain module and package documentation.
+ *
+ * A list of Markdown files that contain module and package documentation.
+ *
+ * The contents of the specified files are parsed and embedded into documentation as module and package
+ * descriptions.
+ *
+ * @param files one or more files
+ * @return this operation instance
+ */
+ public SourceSet includes(String... files) {
+ includes_.addAll(Arrays.asList(files));
+ return this;
+ }
+
+ /**
+ * Sets the Markdown files that contain module and package documentation.
+ *
+ * A list of Markdown files that contain module and package documentation.
+ *
+ * The contents of the specified files are parsed and embedded into documentation as module and package
+ * descriptions.
+ *
+ * @param files the list of files
+ * @return this operation instance
+ */
+ public SourceSet includes(Collection files) {
+ includes_.addAll(files);
+ return this;
+ }
+
+ /**
+ * Sets the version of JDK to use for linking to JDK Javadocs.
+ *
+ * The JDK version to use when generating external documentation links for Java types.
+ *
+ * For example, if you use {@link java.util.UUID} in some public declaration signature, and this option is set to 8,
+ * Dokka generates an external documentation link to JDK 8 Javadocs for it.
+ *
+ * @param jdkVersion the JDK version
+ * @return this operation instance
+ */
+ public SourceSet jdkVersion(int jdkVersion) {
+ jdkVersion_ = jdkVersion;
+ return this;
+ }
+
+ /**
+ * Sets the language version used for setting up analysis and samples.
+ *
+ * @param languageVersion the language version
+ * @return this operation instance
+ */
+ public SourceSet languageVersion(String languageVersion) {
+ languageVersion_ = languageVersion;
+ return this;
+ }
+
+ /**
+ * Sets whether to generate links to JDK Javadocs.
+ *
+ * Whether to generate external documentation links to JDK's Javadocs.
+ *
+ * The version of JDK Javadocs is determined by the {@link #jdkVersion jdkVersion} option.
+ *
+ * Note: Links are generated when noJdkLink is set to false.
+ *
+ * @param noJdkLink {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public SourceSet noJdkLink(Boolean noJdkLink) {
+ noJdkLink_ = noJdkLink;
+ return this;
+ }
+
+ /**
+ * Sets whether to create pages for empty packages.
+ *
+ * Whether to skip packages that contain no visible declarations after various filters have been applied.
+ *
+ * @param noSkipEmptyPackages {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public SourceSet noSkipEmptyPackages(boolean noSkipEmptyPackages) {
+ noSkipEmptyPackages_ = noSkipEmptyPackages;
+ return this;
+ }
+
+ /**
+ * Sets whether to generate links to Standard library.
+ *
+ * Whether to generate external documentation links that lead to the API reference documentation of Kotlin's
+ * standard library.
+ *
+ * Note: Links are generated when noStdLibLink is set to {@code false}.
+ *
+ * @param noStdlibLink {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public SourceSet noStdlibLink(Boolean noStdlibLink) {
+ noStdlibLink_ = noStdlibLink;
+ return this;
+ }
+
+ /**
+ * Set the list of package source set configuration.
+ *
+ * A set of parameters specific to matched packages within this source set.
+ *
+ * Using format:
+ *
+ * - matchingRegexp
+ * - -deprecated
+ * - -privateApi
+ * - +warnUndocumented
+ * - +suppress
+ * - +visibility:PUBLIC
+ * - ...
+ *
+ *
+ * @param perPackageOptions the list of per package options
+ * @return this operation instance
+ */
+ public SourceSet perPackageOptions(Collection perPackageOptions) {
+ perPackageOptions_.addAll(perPackageOptions);
+ return this;
+ }
+
+ /**
+ * Set the list of package source set configuration.
+ *
+ * A set of parameters specific to matched packages within this source set.
+ *
+ * Using format:
+ *
+ * - matchingRegexp
+ * - -deprecated
+ * - -privateApi
+ * - +warnUndocumented
+ * - +suppress
+ * - +visibility:PUBLIC
+ * - ...
+ *
+ *
+ * @param perPackageOptions the list of per package options
+ * @return this operation instance
+ */
+ public SourceSet perPackageOptions(String... perPackageOptions) {
+ perPackageOptions_.addAll(List.of(perPackageOptions));
+ return this;
+ }
+
+ /**
+ * Sets whether to report undocumented declarations.
+ *
+ * Whether to emit warnings about visible undocumented declarations, that is declarations without KDocs after they
+ * have been filtered by documentedVisibilities and other filters.
+ *
+ * This setting works well with {@link DokkaOperation#failOnWarning}.
+ *
+ * This can be configured on per-package basis.
+ *
+ * @param reportUndocumented {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public SourceSet reportUndocumented(Boolean reportUndocumented) {
+ reportUndocumented_ = reportUndocumented;
+ return this;
+ }
+
+ /**
+ * Set the list of directories or files that contain sample functions.
+ *
+ * A list of directories or files that contain sample functions which are referenced via the {@code @sample} KDoc
+ * tag.
+ *
+ * @param samples the list of samples
+ * @return this operation instance
+ */
+ public SourceSet samples(Collection samples) {
+ samples_.addAll(samples);
+ return this;
+ }
+
+ /**
+ * Set the list of directories or files that contain sample functions.
+ *
+ * A list of directories or files that contain sample functions which are referenced via the {@code @sample} KDoc
+ * tag.
+ *
+ * @param samples nne or more samples
+ * @return this operation instance
+ */
+ public SourceSet samples(String... samples) {
+ samples_.addAll(List.of(samples));
+ return this;
+ }
+
+ /**
+ * Sets whether to skip deprecated declarations.
+ *
+ * Whether to document declarations annotated with {@code @Deprecated}.
+ *
+ * This can be configured on per-package basis.
+ *
+ * @param skipDeprecated {@code true} or {@code false}
+ * @return this operation instance
+ */
+ public SourceSet skipDeprecated(boolean skipDeprecated) {
+ skipDeprecated_ = skipDeprecated;
+ return this;
+ }
+
+ /**
+ * Sets the name of the source set. Default is {@code main}.
+ *
+ * @param sourceSetName the source set name.
+ * @return this operation instance
+ */
+ public SourceSet sourceSetName(String sourceSetName) {
+ sourceSetName_ = sourceSetName;
+ return this;
+ }
+
+ /**
+ * Sets the source code roots to be analyzed and documented.
+ *
+ * The source code roots to be analyzed and documented. Acceptable inputs are directories and individual
+ * {@code .kt} / {@code .java} files.
+ *
+ * @param src the list of source code roots
+ * @return this operation instance
+ */
+ public SourceSet src(Collection src) {
+ src_.addAll(src);
+ return this;
+ }
+
+ /**
+ * Sets the source code roots to be analyzed and documented.
+ *
+ * The source code roots to be analyzed and documented. Acceptable inputs are directories and individual
+ * {@code .kt} / {@code .java} files.
+ *
+ * @param src pne ore moe source code roots
+ * @return this operation instance
+ */
+ public SourceSet src(String... src) {
+ src_.addAll(List.of(src));
+ return this;
+ }
+
+ /**
+ * Sets the mapping between a source directory and a Web service for browsing the code.
+ *
+ * @param srcPath the source path
+ * @param remotePath the remote path
+ * @param lineSuffix the line suffix
+ * @return this operation instance
+ */
+ public SourceSet srcLink(String srcPath, String remotePath, String lineSuffix) {
+ srcLinks_.put(srcPath, remotePath + lineSuffix);
+ return this;
+ }
+
+ /**
+ * Sets the paths to files to be suppressed.
+ *
+ * The files to be suppressed when generating documentation.
+ *
+ * @param suppressedFiles the list of suppressed files
+ * @return this operation instance
+ */
+ public SourceSet suppressedFiles(Collection suppressedFiles) {
+ suppressedFiles_.addAll(suppressedFiles);
+ return this;
+ }
+
+ /**
+ * Sets the paths to files to be suppressed.
+ *
+ * The files to be suppressed when generating documentation.
+ *
+ * @param suppressedFiles one or moe suppressed files
+ * @return this operation instance
+ */
+ public SourceSet suppressedFiles(String... suppressedFiles) {
+ suppressedFiles_.addAll(Arrays.asList(suppressedFiles));
+ return this;
+ }
+}
diff --git a/src/main/java/rife/bld/extension/kotlin/CompileOptions.java b/src/main/java/rife/bld/extension/kotlin/CompileOptions.java
deleted file mode 100644
index e43adc8..0000000
--- a/src/main/java/rife/bld/extension/kotlin/CompileOptions.java
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Copyright 2023-2025 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
- *
- * https://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 rife.bld.extension.kotlin;
-
-import rife.bld.extension.CompileKotlinOperation;
-import rife.bld.operations.AbstractToolProviderOperation;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static rife.bld.extension.CompileKotlinOperation.isNotBlank;
-
-/**
- * Configuration for the Kotlin compiler options.
- *
- * @author Erik C. Thauvin
- * @since 1.0
- */
-public class CompileOptions {
- private static final Logger LOGGER = Logger.getLogger(CompileOptions.class.getName());
- private final Collection advancedOptions_ = new ArrayList<>();
- private final Collection argFile_ = new ArrayList<>();
- private final Collection classpath_ = new ArrayList<>();
- private final Collection optIn_ = new ArrayList<>();
- private final Collection options_ = new ArrayList<>();
- private final Collection plugin_ = new ArrayList<>();
- private final Collection scriptTemplates_ = new ArrayList<>();
- private String apiVersion_;
- private String expression_;
- private boolean includeRuntime_;
- private boolean javaParameters_;
- private File jdkHome_;
- private String jdkRelease_;
- private String jvmTarget_;
- private File kotlinHome_;
- private String languageVersion_;
- private String moduleName_;
- private boolean noJdk_;
- private boolean noReflect_;
- private boolean noStdLib_;
- private boolean noWarn_;
- private File path_;
- private boolean progressive_;
- private boolean verbose_;
- private boolean wError_;
- private boolean wExtra_;
-
- /**
- * Specify advanced compiler options.
- *
- * @param options one or more advanced options
- * @return this operation instance
- */
- public CompileOptions advancedOptions(String... options) {
- return advancedOptions(List.of(options));
- }
-
- /**
- * Specify advanced compiler options.
- *
- * @param options the compiler options
- * @return this operation instance
- */
- public CompileOptions advancedOptions(Collection options) {
- advancedOptions_.addAll(options);
- return this;
- }
-
- /**
- * Retrieves advanced compiler options.
- *
- * @return the advanced compiler options
- */
- public Collection advancedOptions() {
- 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
- * @return this operation instance
- */
- public CompileOptions apiVersion(String version) {
- apiVersion_ = version;
- return this;
- }
-
- /**
- * Allow using declarations only from the specified version of Kotlin bundled libraries.
- *
- * @param version the API version
- * @return this operation instance
- */
- public CompileOptions apiVersion(int version) {
- return apiVersion(String.valueOf(version));
- }
-
- /**
- * Read the compiler options from the given files.
- *
- * 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:
- *
- * - {@code -include-runtime -d hello.jar hello.kt}
- *
- * 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 (\).
- *
- * - {@code -include-runtime -d 'My folder'}
- *
- * If the files reside in locations different from the current directory, use relative paths.
- *
- * @param files one or more files
- * @return this operation instance
- * @see #argFileStrings(Collection)
- */
- public CompileOptions argFile(String... files) {
- 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(File...)
- */
- public CompileOptions argFile(Collection files) {
- argFile_.addAll(files);
- return this;
- }
-
- /**
- * Read the compiler options from the given files.
- *
- * 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:
- *
- * - {@code -include-runtime -d hello.jar hello.kt}
- *
- * 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 (\).
- *
- * - {@code -include-runtime -d 'My folder'}
- *
- * If the files reside in locations different from the current directory, use relative paths.
- *
- * @param files one or more files
- * @return this operation instance
- * @see #argFile(Collection)
- */
- public CompileOptions argFile(File... files) {
- return argFile(List.of(files));
- }
-
- /**
- * Read the compiler options from the given files.
- *
- * 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:
- *
- * - {@code -include-runtime -d hello.jar hello.kt}
- *
- * 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 (\).
- *
- * - {@code -include-runtime -d 'My folder'}
- *
- * If the files reside in locations different from the current directory, use relative paths.
- *
- * @param files one or more files
- * @return this operation instance
- * @see #argFilePaths(Collection)
- */
- public CompileOptions argFile(Path... files) {
- return argFilePaths(List.of(files));
- }
-
- /**
- * Retrieves the files containing compiler options.
- *
- * @return the compiler options files
- */
- public Collection argFile() {
- return argFile_;
- }
-
- /**
- * Read the compiler options from the given files.
- *
- * @param files the compiler options files
- * @return this operation instance
- * @see #argFile(Path...)
- */
- public CompileOptions argFilePaths(Collection 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 files) {
- return argFile(files.stream().map(File::new).toList());
- }
-
- /**
- * Returns the formatted arguments.
- *
- * @return the arguments
- */
- public List args() {
- var args = new ArrayList();
-
- // api-version
- if (isNotBlank(apiVersion_)) {
- args.add("-api-version");
- args.add(apiVersion_);
- }
-
- // @argfile
- if (!argFile_.isEmpty()) {
- argFile_.forEach(f -> {
- if (f.exists()) {
- try {
- try (var reader = Files.newBufferedReader(f.toPath(), Charset.defaultCharset())) {
- var tokenizer = new AbstractToolProviderOperation.CommandLineTokenizer(reader);
- String token;
- while ((token = tokenizer.nextToken()) != null) {
- args.add(token);
- }
- }
- } catch (IOException e) {
- if (LOGGER.isLoggable(Level.WARNING)) {
- LOGGER.log(Level.WARNING, "Could not read: " + f.getAbsolutePath(), e);
- }
- }
- } else {
- if (LOGGER.isLoggable(Level.WARNING)) {
- LOGGER.warning("File not found: " + f.getAbsolutePath());
- }
- }
- });
- }
-
- // expression
- if (isNotBlank(expression_)) {
- args.add("-expression");
- args.add(expression_);
- }
-
- // java-parameters
- if (javaParameters_) {
- args.add("-java-parameters");
- }
-
- // jvm-target
- if (isNotBlank(jvmTarget_)) {
- args.add("-jvm-target");
- args.add(jvmTarget_);
- }
-
- // include-runtime
- if (includeRuntime_) {
- args.add("-include-runtime");
- }
-
- // jdk-home
- if (jdkHome_ != null) {
- args.add("-jdk-home");
- args.add(jdkHome_.getAbsolutePath());
- }
-
- // jdk-release
- if (isNotBlank(jdkRelease_)) {
- args.add("-Xjdk-release=" + jdkRelease_);
- }
-
- // kotlin-home
- if (kotlinHome_ != null) {
- args.add("-kotlin-home");
- args.add(kotlinHome_.getAbsolutePath());
- }
-
- // language-version
- if (isNotBlank(languageVersion_)) {
- args.add("-language-version");
- args.add(languageVersion_);
- }
-
- // module-name
- if (isNotBlank(moduleName_)) {
- args.add("-module-name");
- args.add(moduleName_);
- }
-
- // no-jdk
- if (noJdk_) {
- args.add("-no-jdk");
- }
-
- // no-reflect
- if (noReflect_) {
- args.add("-no-reflect");
- }
-
- // no-std-lib
- if (noStdLib_) {
- args.add("-no-stdlib");
- }
-
- // no-warn
- if (noWarn_) {
- args.add("-nowarn");
- }
-
- // opt-in
- optIn_.stream().filter(CompileKotlinOperation::isNotBlank).forEach(o -> {
- args.add("-opt-in");
- args.add(o);
- });
-
- // options
- if (!options_.isEmpty()) {
- args.addAll(options_);
- }
-
- // path
- if (path_ != null) {
- args.add("-d");
- args.add(path_.getAbsolutePath());
- }
-
- // plugin
- plugin_.stream().filter(CompileKotlinOperation::isNotBlank).forEach(p -> {
- args.add("-P");
- args.add("plugin:" + p);
- });
-
- // progressive
- if (progressive_) {
- args.add("-progressive");
- }
-
- // script-templates
- if (!scriptTemplates_.isEmpty()) {
- args.add("-script-templates");
- args.add(String.join(",", scriptTemplates_));
- }
-
- // verbose
- if (verbose_) {
- args.add("-verbose");
- }
-
- // Werror
- if (wError_) {
- args.add("-Werror");
- }
-
- // Wextra
- if (wExtra_) {
- args.add("-Wextra");
- }
-
- // advanced options (X)
- if (!advancedOptions_.isEmpty()) {
- advancedOptions_.forEach(it -> {
- if (it.startsWith("-X")) {
- args.add(it);
- } else {
- args.add("-X" + it);
- }
- });
- }
-
- return args;
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths one pr more paths
- * @return this operation instance
- * @see #classpathStrings(Collection)
- */
- public CompileOptions classpath(String... paths) {
- return classpathStrings(List.of(paths));
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths one or more path
- * @return this operation instance
- * @see #classpath(Collection)
- */
- public CompileOptions classpath(File... paths) {
- return classpath(List.of(paths));
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths one or more path
- * @return this operation instance
- * @see #classpathPaths(Collection)
- */
- public CompileOptions classpath(Path... paths) {
- return classpathPaths(List.of(paths));
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths the search paths
- * @return this operation instance
- * @see #classpath(File...)
- */
- public CompileOptions classpath(Collection paths) {
- classpath_.addAll(paths);
- return this;
- }
-
- /**
- * Retrieves the class files classpath.
- *
- * @return the class files classpath
- */
- public Collection classpath() {
- return classpath_;
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths one pr more paths
- * @return this operation instance
- * @see #classpath(Path...)
- */
- public CompileOptions classpathPaths(Collection paths) {
- return classpath(paths.stream().map(Path::toFile).toList());
- }
-
- /**
- * Search for class files in the specified paths.
- *
- * The classpath can contain file and directory paths, ZIP, or JAR files.
- *
- * @param paths one pr more paths
- * @return this operation instance
- * @see #classpath(String...)
- */
- public CompileOptions classpathStrings(Collection 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.
- *
- * @param expression the expression
- * @return this operation instance
- */
- public CompileOptions expression(String expression) {
- expression_ = expression;
- return this;
- }
-
- /**
- * Indicates whether the {@link #jdkRelease(String) jdkRelease} was set.
- *
- * @return {@code true} if the release was set; or {@code false} otherwise
- */
- public boolean hasRelease() {
- return jdkRelease_ != null;
- }
-
- /**
- * Include the Kotlin runtime into the resulting JAR file. Makes the resulting archive runnable on any Java-enabled
- * environment.
- *
- * @param includeRuntime {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions includeRuntime(boolean includeRuntime) {
- includeRuntime_ = includeRuntime;
- 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.
- *
- * @return {@code true} if verbose was set; or {@code false} otherwise
- */
- public boolean isVerbose() {
- return verbose_;
- }
-
- /**
- * Indicates whether warnings are turned into a compilation error.
- *
- * @return {@code true} or {@code false}
- */
- public boolean isWError() {
- return wError_;
- }
-
- /**
- * Indicates whether additional declaration, expression, and type compiler checks emit warnings.
- *
- * @return {@code true} or {@code false}
- */
- public boolean isWExtra() {
- return wExtra_;
- }
-
- /**
- * Generate metadata for Java 1.8 reflection on method parameters.
- *
- * @param javaParameters {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions javaParameters(boolean javaParameters) {
- javaParameters_ = javaParameters;
- return this;
- }
-
- /**
- * 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(File jdkHome) {
- jdkHome_ = jdkHome;
- return this;
- }
-
- /**
- * 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(String jdkHome) {
- return jdkHome(new File(jdkHome));
- }
-
- /**
- * 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.
- *
- * Limit the API of the JDK in the classpath to the specified Java version. Automatically sets
- * {@link #jvmTarget(String) JVM target} version.
- *
- * Possible values are 1.8, 9, 10, ..., 23. The default value is 1.8.
- *
- * @param version the target version
- * @return this operation instance
- */
- public CompileOptions jdkRelease(String version) {
- jdkRelease_ = version;
- return this;
- }
-
- /**
- * Compile against the specified JDK API version.
- *
- * Limit the API of the JDK in the classpath to the specified Java version. Automatically sets
- * {@link #jvmTarget(String) JVM target} version.
- *
- * @param version the target version
- * @return this operation instance
- * @see #jdkRelease(String)
- */
- public CompileOptions jdkRelease(int version) {
- return jdkRelease(String.valueOf(version));
- }
-
- /**
- * Specify the target version of the generated JVM bytecode.
- *
- * @param target the target version
- * @return this operation instance
- * @see #jvmTarget(String)
- */
- public CompileOptions jvmTarget(int target) {
- return jvmTarget(String.valueOf(target));
- }
-
- /**
- * Specify the target version of the generated JVM bytecode.
- *
- * Possible values are 1.8, 9, 10, ..., 23. 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.
- *
- * @param path the Kotlin home path
- * @return this operation instance
- */
- public CompileOptions kotlinHome(File path) {
- kotlinHome_ = path;
- 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.
- *
- * @param path the Kotlin home path
- * @return this operation instance
- */
- public CompileOptions kotlinHome(String path) {
- return kotlinHome(new File(path));
- }
-
- /**
- * Provide source compatibility with the specified version of Kotlin.
- *
- * @param version the language version
- * @return this operation instance
- */
- public CompileOptions languageVersion(String version) {
- languageVersion_ = version;
- 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.
- *
- * @param name the module name
- * @return this operation instance
- */
- public CompileOptions moduleName(String name) {
- moduleName_ = name;
- 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.
- *
- * @param noJdk {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions noJdk(boolean noJdk) {
- noJdk_ = noJdk;
- return this;
- }
-
- /**
- * Don't automatically include the Kotlin reflection ({@code kotlin-reflect.jar}) into the classpath.
- *
- * @param noReflect {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions noReflect(boolean noReflect) {
- noReflect_ = noReflect;
- return this;
- }
-
- /**
- * Don't automatically include the Kotlin/JVM stdlib ({@code kotlin-stdlib.jar}) and Kotlin reflection
- * ({@code kotlin-reflect.jar}) into the classpath.
- *
- * @param noStdLib {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions noStdLib(boolean noStdLib) {
- noStdLib_ = noStdLib;
- return this;
- }
-
- /**
- * Suppress the compiler from displaying warnings during compilation.
- *
- * @param noWarn {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions noWarn(boolean noWarn) {
- noWarn_ = noWarn;
- return this;
- }
-
- /**
- * Enable usages of API that requires opt-in with a requirement annotation with the given fully qualified name.
- *
- * @param annotations one or more annotation names
- * @return this operation instance
- */
- public CompileOptions optIn(String... annotations) {
- return optIn(List.of(annotations));
- }
-
- /**
- * Retrieves the opt-in fully qualified names.
- *
- * @return the fully qualified names
- */
- public Collection optIn() {
- return optIn_;
- }
-
- /**
- * Enable usages of API that requires opt-in with a requirement annotation with the given fully qualified name.
- *
- * @param annotations the annotation names
- * @return this operation instance
- */
- public CompileOptions optIn(Collection annotations) {
- optIn_.addAll(annotations);
- return this;
- }
-
- /**
- * Specify additional compiler options.
- *
- * @param options one or more compiler options
- * @return this operation instance
- */
- public CompileOptions options(String... options) {
- return options(List.of(options));
- }
-
- /**
- * Retrieves additional compiler options.
- *
- * @return the compiler options
- */
- public Collection options() {
- return options_;
- }
-
- /**
- * Specify additional compiler options.
- *
- * @param options the compiler options
- * @return this operation instance
- */
- public CompileOptions options(Collection options) {
- options_.addAll(options);
- return this;
- }
-
- /**
- * Place the generated class files into the specified location.
- *
- * The location can be a directory, a ZIP, or a JAR file.
- *
- * @param path the location path
- * @return this operation instance
- */
- public CompileOptions path(File path) {
- path_ = path;
- 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.
- *
- * 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.
- *
- * The location can be a directory, a ZIP, or a JAR file.
- *
- * @param path the location path
- * @return this operation instance
- */
- public CompileOptions path(String path) {
- return path(new File(path));
- }
-
- /**
- * Pass an option to a plugin.
- *
- * @param id the plugin ID
- * @param optionName the plugin option name
- * @param value the plugin option value
- * @return this operation instance
- */
- public CompileOptions plugin(String id, String optionName, String value) {
- plugin_.add(id + ':' + optionName + ':' + value);
- return this;
- }
-
- /**
- * Retrieves the plugin options.
- *
- * @return the plugin options.
- */
- public Collection plugin() {
- return plugin_;
- }
-
- /**
- * Allow using declarations only from the specified version of Kotlin bundled libraries.
- *
- * @param progressive {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions progressive(boolean progressive) {
- progressive_ = progressive;
- return this;
- }
-
- /**
- * Script definition template classes.
- *
- * Use fully qualified class names.
- *
- * @param classNames one or more class names
- * @return this operation instance
- */
- public CompileOptions scriptTemplates(String... classNames) {
- return scriptTemplates(List.of(classNames));
- }
-
- /**
- * Retrieves the script templates.
- *
- * @return the script templates.
- */
- public Collection scriptTemplates() {
- return scriptTemplates_;
- }
-
- /**
- * Script definition template classes.
- *
- * Use fully qualified class names.
- *
- * @param classNames the class names
- * @return this operation instance
- */
- public CompileOptions scriptTemplates(Collection classNames) {
- scriptTemplates_.addAll(classNames);
- return this;
- }
-
- /**
- * Enable verbose logging output which includes details of the compilation process.
- *
- * @param verbose {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions verbose(boolean verbose) {
- verbose_ = verbose;
- return this;
- }
-
- /**
- * Turn any warnings into a compilation error.
- *
- * @param wError {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions wError(boolean wError) {
- wError_ = wError;
- return this;
- }
-
- /**
- * Enable additional declaration, expression, and type compiler checks that emit warnings if {@code true}.
- *
- * @param wExtra {@code true} or {@code false}
- * @return this operation instance
- */
- public CompileOptions wExtra(boolean wExtra) {
- wExtra_ = wExtra;
- return this;
- }
-}
diff --git a/src/main/java/rife/bld/extension/kotlin/CompilerPlugin.java b/src/main/java/rife/bld/extension/kotlin/CompilerPlugin.java
deleted file mode 100644
index f1fd584..0000000
--- a/src/main/java/rife/bld/extension/kotlin/CompilerPlugin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2023-2025 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
- *
- * https://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 rife.bld.extension.kotlin;
-
-/**
- * @author Erik C. Thauvin
- * Defines the known Kotlin compiler plugin JARs.
- *
- * @author Erik C. Thauvin
- * @since 1.0
- */
-public enum CompilerPlugin {
- ALL_OPEN("allopen-compiler-plugin.jar"),
- ASSIGNMENT("assignment-compiler-plugin.jar"),
- COMPOSE("compose-compiler-plugin.jar"),
- KOTLIN_IMPORTS_DUMPER("kotlin-imports-dumper-compiler-plugin.jar"),
- KOTLINX_SERIALIZATION("kotlinx-serialization-compiler-plugin.jar"),
- KOTLIN_SERIALIZATION("kotlin-serialization-compiler-plugin.jar"),
- LOMBOK("lombok-compiler-plugin.jar"),
- NOARG("noarg-compiler-plugin.jar"),
- POWER_ASSERT("power-assert-compiler-plugin.jar"),
- SAM_WITH_RECEIVER("sam-with-receiver-compiler-plugin.jar");
-
- public final String jar;
-
- CompilerPlugin(String jar) {
- this.jar = jar;
- }
-}
diff --git a/src/main/java/rife/bld/extension/kotlin/JvmOptions.java b/src/main/java/rife/bld/extension/kotlin/JvmOptions.java
deleted file mode 100644
index 7e2ec62..0000000
--- a/src/main/java/rife/bld/extension/kotlin/JvmOptions.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2023-2025 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
- *
- * https://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 rife.bld.extension.kotlin;
-
-import rife.tools.StringUtils;
-
-import java.io.Serial;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Java Virtual Machine options.
- *
- * @author Erik C. Thauvin
- * @since 1.1.0
- */
-@SuppressWarnings("PMD.LooseCoupling")
-public class JvmOptions extends ArrayList {
- /**
- * Keyword to enable native access for all code on the class path.
- */
- public final static String ALL_UNNAMED = "ALL-UNNAMED";
-
- @Serial
- private static final long serialVersionUID = 1L;
-
- /**
- * Modules that are permitted to perform restricted native operations.
- * The module name can also be {@link #ALL_UNNAMED}.
- *
- * @param modules the module names
- * @return this list of options
- */
- public JvmOptions enableNativeAccess(String... modules) {
- return enableNativeAccess(List.of(modules));
- }
-
- /**
- * Modules that are permitted to perform restricted native operations.
- * The module name can also be {@link #ALL_UNNAMED}.
- *
- * @param modules the module names
- * @return this list of options
- */
- public JvmOptions enableNativeAccess(Collection modules) {
- add("--enable-native-access=" + StringUtils.join(modules, ","));
- return this;
- }
-
- /**
- * Controls what action the Java runtime takes when native access is not enabled for a module.
- *
- * @param access the access mode
- * @return this list of options
- */
- public JvmOptions illegalNativeAccess(NativeAccess access) {
- add("--illegal-native-access=" + access.mode);
- return this;
- }
-
- /**
- * Illegal native access modes.
- */
- public enum NativeAccess {
- ALLOW("allow"),
- DENY("deny"),
- WARN("warn");
-
- public final String mode;
-
- NativeAccess(String mode) {
- this.mode = mode;
- }
- }
-}
diff --git a/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java b/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java
index 4e0182e..f64e6d3 100644
--- a/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java
+++ b/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023-2025 the original author or authors.
+ * Copyright 2023-2024 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.
@@ -16,22 +16,17 @@
package rife.bld.extension;
-import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import rife.bld.BaseProject;
import rife.bld.blueprints.BaseProjectBlueprint;
-import rife.bld.extension.kotlin.CompileOptions;
-import rife.bld.extension.kotlin.CompilerPlugin;
-import rife.bld.extension.kotlin.JvmOptions;
import rife.tools.FileUtils;
import java.io.File;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import java.util.Objects;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
@@ -39,11 +34,7 @@ import java.util.logging.Logger;
import static org.assertj.core.api.Assertions.assertThat;
-@SuppressWarnings("PMD.AvoidDuplicateLiterals")
class CompileKotlinOperationTest {
- private static final String FILE_1 = "file1";
- private static final String FILE_2 = "file2";
-
@BeforeAll
static void beforeAll() {
var level = Level.ALL;
@@ -56,98 +47,7 @@ class CompileKotlinOperationTest {
}
@Test
- void testBuildMainDirectory() {
- var foo = new File("foo");
- var bar = new File("bar");
-
- var op = new CompileKotlinOperation().buildMainDirectory(foo);
- assertThat(op.buildMainDirectory()).as("as file").isEqualTo(foo);
-
- op = op.buildMainDirectory(bar.toPath());
- assertThat(op.buildMainDirectory()).as("as path").isEqualTo(bar);
-
- op = new CompileKotlinOperation().buildMainDirectory("foo");
- assertThat(op.buildMainDirectory()).as("as string").isEqualTo(foo);
- }
-
- @Test
- void testBuildTestDirectory() {
- var foo = new File("foo");
- var bar = new File("bar");
-
- var op = new CompileKotlinOperation().buildTestDirectory(foo);
- assertThat(op.buildTestDirectory()).as("as file").isEqualTo(foo);
-
- op = op.buildTestDirectory(bar.toPath());
- assertThat(op.buildTestDirectory()).as("as path").isEqualTo(bar);
-
- op = new CompileKotlinOperation().buildTestDirectory("foo");
- assertThat(op.buildTestDirectory()).as("as string").isEqualTo(foo);
- }
-
- @Test
- void testCollections() {
- var op = new CompileKotlinOperation()
- .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example", "Example", "Example"))
- .kotlinHome("/kotlin_home")
- .kotlinc("kotlinc")
- .workDir("work_dir")
- .compileMainClasspath("path1", "path2")
- .compileOptions(new CompileOptions().jdkRelease("17").verbose(true))
- .mainSourceDirectories("dir1", "dir2")
- .mainSourceDirectories(List.of(new File("dir3"), new File("dir4")))
- .mainSourceFiles("file1", "file2")
- .mainSourceFiles(List.of(new File("file3"), new File("file4")))
- .mainSourceFiles(new File("file5"), new File("file6"))
- .testSourceDirectories("tdir1", "tdir2")
- .testSourceDirectories(List.of(new File("tdir3"), new File("tdir4")))
- .testSourceFiles("tfile1", "tfile2")
- .testSourceFiles(List.of(new File("tfile3"), new File("tfile4")))
- .testSourceFiles(new File("tfile5"), new File("tfile6"))
- .plugins("plugin1", "plugin2")
- .plugins(CompilerPlugin.KOTLIN_SERIALIZATION, CompilerPlugin.ASSIGNMENT, CompilerPlugin.COMPOSE)
- .plugins(new File("lib/compile"), CompilerPlugin.LOMBOK, CompilerPlugin.POWER_ASSERT)
- .plugins(Path.of("lib/compile"), CompilerPlugin.NOARG, CompilerPlugin.ALL_OPEN,
- CompilerPlugin.KOTLIN_IMPORTS_DUMPER)
- .plugins("lib/compile", CompilerPlugin.KOTLINX_SERIALIZATION, CompilerPlugin.SAM_WITH_RECEIVER)
- .plugins(List.of("plugin3", "plugin4"));
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(op.kotlinHome().getName()).as("kotlin_home").isEqualTo("kotlin_home");
- softly.assertThat(op.kotlinc().getName()).as("kotlinc").isEqualTo("kotlinc");
- softly.assertThat(op.workDir().getName()).as("work_dir").isEqualTo("work_dir");
- softly.assertThat(op.compileMainClasspath()).as("compileMainClassPath")
- .containsAll(List.of("path1", "path2"));
- softly.assertThat(op.compileOptions().hasRelease()).as("hasRelease").isTrue();
- softly.assertThat(op.compileOptions().isVerbose()).as("isVerbose").isTrue();
- softly.assertThat(op.mainSourceDirectories()).as("mainSourceDirectories").containsExactly(
- Path.of("examples", "src", "main", "kotlin").toFile(), new File("dir1"),
- new File("dir2"), new File("dir3"), new File("dir4"));
- softly.assertThat(op.testSourceDirectories()).as("testSourceDirectories").containsOnly(
- Path.of("examples", "src", "test", "kotlin").toFile(), new File("tdir1"),
- new File("tdir2"), new File("tdir3"), new File("tdir4"));
- softly.assertThat(op.mainSourceFiles()).as("mainSourceFiles").containsOnly(
- new File("file1"), new File("file2"), new File("file3"),
- new File("file4"), new File("file5"), new File("file6"));
- softly.assertThat(op.testSourceFiles()).as("testSourceFiles").containsOnly(
- new File("tfile1"), new File("tfile2"), new File("tfile3"),
- new File("tfile4"), new File("tfile5"), new File("tfile6"));
- softly.assertThat(op.plugins()).as("plugins").contains("plugin1", "plugin2", "plugin3", "plugin4",
- new File("/kotlin_home/lib/kotlin-serialization-compiler-plugin.jar").getAbsolutePath(),
- new File("/kotlin_home/lib/assignment-compiler-plugin.jar").getAbsolutePath(),
- new File("/kotlin_home/lib/compose-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "lombok-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "power-assert-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "noarg-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "allopen-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "kotlin-imports-dumper-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "kotlinx-serialization-compiler-plugin.jar").getAbsolutePath(),
- new File("lib/compile", "sam-with-receiver-compiler-plugin.jar").getAbsolutePath());
- }
- }
-
- @Test
- void testExecute() throws Exception {
+ void testExecute() throws IOException {
var tmpDir = Files.createTempDirectory("bld-kotlin").toFile();
try {
@@ -155,10 +55,8 @@ class CompileKotlinOperationTest {
var mainDir = new File(buildDir, "main");
var testDir = new File(buildDir, "test");
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(mainDir.mkdirs()).as("make mainDir").isTrue();
- softly.assertThat(testDir.mkdirs()).as("make testDir").isTrue();
- }
+ assertThat(mainDir.mkdirs()).isTrue();
+ assertThat(testDir.mkdirs()).isTrue();
var compileJars = new ArrayList();
for (var f : Objects.requireNonNull(new File("examples/lib/compile").listFiles())) {
@@ -171,7 +69,8 @@ class CompileKotlinOperationTest {
}
var op = new CompileKotlinOperation()
- .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example", "Example", "Example"))
+ .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example",
+ "Example"))
.buildMainDirectory(mainDir)
.buildTestDirectory(testDir)
.compileMainClasspath(compileJars)
@@ -180,268 +79,26 @@ class CompileKotlinOperationTest {
.compileTestClasspath(mainDir.getAbsolutePath());
op.compileOptions().verbose(true);
- op.compileOptions().argFile("src/test/resources/argfile.txt", "src/test/resources/argfile2.txt");
-
- if (!CompileKotlinOperation.isWindows()) {
- op.jvmOptions().enableNativeAccess(JvmOptions.ALL_UNNAMED);
- assertThat(op.jvmOptions()).containsExactly("--enable-native-access=ALL-UNNAMED");
- }
+ op.compileOptions().jdkRelease("17");
var args = op.compileOptions().args();
- var matches = List.of("-Xjdk-release=17", "-no-reflect", "-progressive", "-include-runtime", "-no-stdlib",
- "-verbose");
- assertThat(args).as(args + " == " + matches).isEqualTo(matches);
+ var matches = List.of("-Xjdk-release=17", "-no-stdlib", "-verbose");
+ assertThat(args).isEqualTo(matches);
op.execute();
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(tmpDir).as("tmpDir").isNotEmptyDirectory();
- softly.assertThat(mainDir).as("mainDir").isNotEmptyDirectory();
- softly.assertThat(testDir).as("testDir").isNotEmptyDirectory();
- }
+ assertThat(tmpDir).isNotEmptyDirectory();
+ assertThat(mainDir).isNotEmptyDirectory();
+ assertThat(testDir).isNotEmptyDirectory();
var mainOut = Path.of(mainDir.getAbsolutePath(), "com", "example").toFile();
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(new File(mainOut, "Example.class")).as("Example.class").exists();
- softly.assertThat(new File(mainOut, "Example$Companion.class"))
- .as("ExampleCompanion.class").exists();
- }
+ assertThat(new File(mainOut, "Example.class")).exists();
+ assertThat(new File(mainOut, "Example$Companion.class")).exists();
var testOut = Path.of(testDir.getAbsolutePath(), "com", "example").toFile();
- assertThat(new File(testOut, "ExampleTest.class")).as("ExampleTest.class").exists();
+ assertThat(new File(testOut, "ExampleTest.class")).exists();
} finally {
FileUtils.deleteDirectory(tmpDir);
}
}
-
- @Test
- void testFindKotlincPath() {
- assertThat(CompileKotlinOperation.findKotlincPath()).doesNotStartWith("kotlinc");
- }
-
- @Test
- void testFromProject() {
- var examples = new File("examples");
- var op = new CompileKotlinOperation().fromProject(
- new BaseProjectBlueprint(examples, "com.example", "examples", "examples"));
- assertThat(op.mainSourceDirectories()).containsExactly(new File(examples, "src/main/kotlin"));
- assertThat(op.testSourceDirectories()).containsExactly(new File(examples, "src/test/kotlin"));
- }
-
- @Test
- void testFromProjectNoKotlin() {
- var op = new CompileKotlinOperation().fromProject(
- new BaseProjectBlueprint(new File("foo"), "org.example", "foo", "foo"));
- assertThat(op.mainSourceDirectories()).isEmpty();
- assertThat(op.testSourceDirectories()).isEmpty();
- }
-
- @Test
- void testIsOS() {
- var osName = System.getProperty("os.name");
- if (osName != null) {
- var os = osName.toLowerCase(Locale.US);
- if (os.contains("win")) {
- assertThat(CompileKotlinOperation.isWindows()).isTrue();
- } else if (os.contains("linux") || os.contains("unix")) {
- assertThat(CompileKotlinOperation.isLinux()).isTrue();
- } else if (os.contains("mac") || os.contains("darwin")) {
- assertThat(CompileKotlinOperation.isMacOS()).isTrue();
- }
- }
- }
-
- @Test
- void testKotlinHome() {
- var foo = new File("foo");
- var bar = new File("bar");
-
- var op = new CompileKotlinOperation().kotlinHome(foo);
- assertThat(op.kotlinHome()).as("as file").isEqualTo(foo);
-
- op = op.kotlinHome(bar.toPath());
- assertThat(op.kotlinHome()).as("as path").isEqualTo(bar);
-
- op = new CompileKotlinOperation().kotlinHome("foo");
- assertThat(op.kotlinHome()).as("as string").isEqualTo(foo);
- }
-
- @Test
- void testKotlinc() {
- var foo = new File("foo");
- var bar = new File("bar");
-
- var op = new CompileKotlinOperation().kotlinc(foo);
- assertThat(op.kotlinc()).as("as file").isEqualTo(foo);
-
- op = op.kotlinc(bar.toPath());
- assertThat(op.kotlinc()).as("as path").isEqualTo(bar);
-
- op = new CompileKotlinOperation().kotlinc("foo");
- assertThat(op.kotlinc()).as("as string").isEqualTo(foo);
- }
-
- @Test
- void testMainSourceDirectories() {
- var op = new CompileKotlinOperation();
-
- op.mainSourceDirectories(List.of(new File(FILE_1), new File(FILE_2)));
- assertThat(op.mainSourceDirectories()).as("List(File...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
-
- op.mainSourceDirectories(new File(FILE_1), new File(FILE_2));
- assertThat(op.mainSourceDirectories()).as("File...").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
-
- op.mainSourceDirectories(FILE_1, FILE_2);
- assertThat(op.mainSourceDirectories()).as("String...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
-
- op = op.mainSourceDirectories(Path.of(FILE_1), Path.of(FILE_2));
- assertThat(op.mainSourceDirectories()).as("Path...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
-
- op.mainSourceDirectoriesPaths(List.of(new File(FILE_1).toPath(), new File(FILE_2).toPath()));
- assertThat(op.mainSourceDirectories()).as("List(Path...)")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
-
- op.mainSourceDirectoriesStrings(List.of(FILE_1, FILE_2));
- assertThat(op.mainSourceDirectories()).as("List(String...)")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceDirectories().clear();
- }
-
- @Test
- void testMainSourceFiles() {
- var op = new CompileKotlinOperation();
-
- op.mainSourceFiles(List.of(new File(FILE_1), new File(FILE_2)));
- assertThat(op.mainSourceFiles()).as("List(File...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
-
- op.mainSourceFiles(new File(FILE_1), new File(FILE_2));
- assertThat(op.mainSourceFiles()).as("File...").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
-
- op.mainSourceFiles(FILE_1, FILE_2);
- assertThat(op.mainSourceFiles()).as("String...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
-
- op = op.mainSourceFiles(Path.of(FILE_1), Path.of(FILE_2));
- assertThat(op.mainSourceFiles()).as("Path...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
-
- op.mainSourceFilesPaths(List.of(new File(FILE_1).toPath(), new File(FILE_2).toPath()));
- assertThat(op.mainSourceFiles()).as("List(Path...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
-
- op.mainSourceFilesStrings(List.of(FILE_1, FILE_2));
- assertThat(op.mainSourceFiles()).as("List(String...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.mainSourceFiles().clear();
- }
-
- @Test
- @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
- void testPlugins() {
- var op = new CompileKotlinOperation()
- .fromProject(new BaseProject())
- .plugins(CompilerPlugin.ALL_OPEN,
- CompilerPlugin.ASSIGNMENT,
- CompilerPlugin.COMPOSE,
- CompilerPlugin.KOTLIN_IMPORTS_DUMPER,
- CompilerPlugin.KOTLINX_SERIALIZATION,
- CompilerPlugin.KOTLIN_SERIALIZATION,
- CompilerPlugin.LOMBOK,
- CompilerPlugin.NOARG,
- CompilerPlugin.POWER_ASSERT,
- CompilerPlugin.SAM_WITH_RECEIVER);
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- for (var p : op.plugins()) {
- softly.assertThat(new File(p)).as(p).exists();
- }
- }
- }
-
- @Test
- void testTestSourceDirectories() {
- var op = new CompileKotlinOperation();
-
- op.testSourceDirectories(List.of(new File(FILE_1), new File(FILE_2)));
- assertThat(op.testSourceDirectories()).as("List(File...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
-
- op.testSourceDirectories(new File(FILE_1), new File(FILE_2));
- assertThat(op.testSourceDirectories()).as("File...").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
-
- op.testSourceDirectories(FILE_1, FILE_2);
- assertThat(op.testSourceDirectories()).as("String...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
-
- op = op.testSourceDirectories(Path.of(FILE_1), Path.of(FILE_2));
- assertThat(op.testSourceDirectories()).as("Path...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
-
- op.testSourceDirectoriesPaths(List.of(new File(FILE_1).toPath(), new File(FILE_2).toPath()));
- assertThat(op.testSourceDirectories()).as("List(Path...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
-
- op.testSourceDirectoriesStrings(List.of(FILE_1, FILE_2));
- assertThat(op.testSourceDirectories()).as("List(String...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceDirectories().clear();
- }
-
- @Test
- void testTestSourceFiles() {
- var op = new CompileKotlinOperation();
-
- op.testSourceFiles(List.of(new File(FILE_1), new File(FILE_2)));
- assertThat(op.testSourceFiles()).as("List(File...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
-
- op.testSourceFiles(new File(FILE_1), new File(FILE_2));
- assertThat(op.testSourceFiles()).as("File...").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
-
- op.testSourceFiles(FILE_1, FILE_2);
- assertThat(op.testSourceFiles()).as("String...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
-
- op = op.testSourceFiles(Path.of(FILE_1), Path.of(FILE_2));
- assertThat(op.testSourceFiles()).as("Path...")
- .containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
-
- op.testSourceFilesPaths(List.of(new File(FILE_1).toPath(), new File(FILE_2).toPath()));
- assertThat(op.testSourceFiles()).as("List(Path...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
-
- op.testSourceFilesStrings(List.of(FILE_1, FILE_2));
- assertThat(op.testSourceFiles()).as("List(String...)").containsExactly(new File(FILE_1), new File(FILE_2));
- op.testSourceFiles().clear();
- }
-
- @Test
- void testWorkDir() {
- var foo = new File("foo");
- var bar = new File("bar");
-
- var op = new CompileKotlinOperation().workDir(foo);
- assertThat(op.workDir()).as("as file").isEqualTo(foo);
-
- op = op.workDir(bar.toPath());
- assertThat(op.workDir()).as("as path").isEqualTo(bar);
-
- op = new CompileKotlinOperation().workDir("foo");
- assertThat(op.workDir()).as("as string").isEqualTo(foo);
- }
}
diff --git a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java
new file mode 100644
index 0000000..f19663d
--- /dev/null
+++ b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.util.List;
+import java.util.stream.IntStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SuppressWarnings("PMD.AvoidDuplicateLiterals")
+class CompileKotlinOptionsTest {
+ @Test
+ void argsCollectionTest() {
+ var args = new CompileKotlinOptions()
+ .argFile(List.of("arg1.txt", "arg2.txt"))
+ .classpath(List.of("path1", "path2"))
+ .noStdLib(false)
+ .optIn(List.of("opt1", "opt2"))
+ .options(List.of("-foo", "-bar"))
+ .scriptTemplates(List.of("temp1", "temp2"))
+ .args();
+ var matches = List.of(
+ "@arg1.txt", "@arg2.txt",
+ "-classpath", "path1:path2",
+ "-opt-in", "opt1",
+ "-opt-in", "opt2",
+ "-foo",
+ "-bar",
+ "-script-templates", "temp1,temp2");
+
+ assertThat(args).hasSize(matches.size());
+
+ IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i)));
+
+
+ }
+
+ @Test
+ void argsTest() {
+ var args = new CompileKotlinOptions()
+ .apiVersion("11")
+ .argFile("file.txt", "file2.txt")
+ .classpath("path1", "path2")
+ .javaParameters(true)
+ .jvmTarget("11")
+ .includeRuntime(true)
+ .jdkHome("path")
+ .jdkRelease("11")
+ .kotlinHome("path")
+ .languageVersion("1.0")
+ .moduleName("module")
+ .noJdk(true)
+ .noReflect(true)
+ .noWarn(true)
+ .optIn("opt1", "opt2")
+ .options("-foo", "-bar")
+ .path("path")
+ .plugin("id", "name", "value")
+ .progressive(true)
+ .scriptTemplates("name", "name2")
+ .verbose(true)
+ .wError(true)
+ .args();
+
+ var matches = List.of(
+ "-api-version", "11",
+ "@file.txt", "@file2.txt",
+ "-classpath", "path1" + File.pathSeparator + "path2",
+ "-java-parameters",
+ "-jvm-target", "11",
+ "-include-runtime",
+ "-jdk-home", "path",
+ "-Xjdk-release=11",
+ "-kotlin-home", "path",
+ "-language-version", "1.0",
+ "-module-name", "module",
+ "-no-jdk",
+ "-no-reflect",
+ "-no-warn",
+ "-opt-in", "opt1",
+ "-opt-in", "opt2",
+ "-foo",
+ "-bar",
+ "-d", "path",
+ "-P", "plugin:id:name:value",
+ "-progressive",
+ "-script-templates", "name,name2",
+ "-verbose",
+ "-Werror");
+
+ assertThat(args).hasSize(matches.size());
+
+ IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i)));
+ }
+}
diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java
new file mode 100644
index 0000000..637b1f2
--- /dev/null
+++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+import org.junit.jupiter.api.Test;
+import rife.bld.blueprints.BaseProjectBlueprint;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.IntStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DokkaOperationTest {
+ @Test
+ @SuppressWarnings({"ExtractMethodRecommender", "PMD.AvoidDuplicateLiterals"})
+ void executeConstructProcessCommandListTest() {
+ var examples = new File("examples");
+ var args = new DokkaOperation()
+ .fromProject(new BaseProjectBlueprint(examples, "com.example", "Example"))
+ .globalLinks("s", "link")
+ .globalLinks(Map.of("s2", "link2"))
+ .globalPackageOptions("option1", "option2")
+ .globalPackageOptions(List.of("option3", "option4"))
+ .globalSrcLink("link1", "link2")
+ .globalSrcLink(List.of("link3", "link4"))
+ .includes("file1", "file2")
+ .pluginConfiguration("name", "\"json\"")
+ .pluginConfiguration(Map.of("\"name2\"", "json2"))
+ .pluginsClasspath("path1", "path2")
+ .pluginsClasspath(List.of("path3", "path4"))
+ .delayTemplateSubstitution(true)
+ .failOnWarning(true)
+ .loggingLevel(LoggingLevel.DEBUG)
+ .moduleName("name")
+ .moduleVersion("1.0")
+ .noSuppressObviousFunctions(true)
+ .offlineMode(true)
+ .outputDir(new File(examples, "build"))
+ .outputFormat(OutputFormat.JAVADOC)
+ .suppressInheritedMembers(true)
+ .executeConstructProcessCommandList();
+
+ var path = examples.getAbsolutePath();
+ var matches = List.of("java",
+ "-jar", path + "/lib/bld/dokka-cli-1.9.10.jar",
+ "-pluginsClasspath", path + "/lib/bld/dokka-base-1.9.10.jar;" +
+ path + "/lib/bld/analysis-kotlin-descriptors-1.9.10.jar;" +
+ path + "/lib/bld/javadoc-plugin-1.9.10.jar;" +
+ path + "/lib/bld/korte-jvm-2.7.0.jar;" +
+ path + "/lib/bld/kotlin-as-java-plugin-1.9.10.jar;path1;path2;path3;path4",
+ "-sourceSet", "-src " + path + "/src/main/kotlin",
+ "-outputDir", path + "/build",
+ "-delayTemplateSubstitution", "true",
+ "-failOnWarning", "true",
+ "-globalLinks", "s^link^^s2^link2",
+ "-globalPackageOptions", "option1;option2;option3;option4",
+ "-globalSrcLinks_", "link1;link2;link3;link4",
+ "-includes", "file1;file2",
+ "-loggingLevel", "debug",
+ "-moduleName", "name",
+ "-moduleVersion", "1.0",
+ "-noSuppressObviousFunctions", "true",
+ "-offlineMode", "true",
+ "-pluginConfiguration", "{name}={\\\"json\\\"}^^{\\\"name2\\\"}={json2}",
+ "-suppressInheritedMembers", "true");
+
+ assertThat(args).hasSize(matches.size());
+
+ IntStream.range(0, args.size()).forEach(i -> {
+ if (args.get(i).contains(".jar;")) {
+ var jars = args.get(i).split(";");
+ Arrays.stream(jars).forEach(jar -> assertThat(matches.get(i)).contains(jar));
+ } else {
+ assertThat(args.get(i)).isEqualTo(matches.get(i));
+ }
+ });
+ }
+}
diff --git a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java
new file mode 100644
index 0000000..4edefe0
--- /dev/null
+++ b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2023-2024 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
+ *
+ * https://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 rife.bld.extension.dokka;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.IntStream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SourceSetTest {
+ @Test
+ void sourceSetCollectionsTest() {
+ var args = new SourceSet()
+ .classpath(List.of("path1", "path2"))
+ .dependentSourceSets(Map.of("set1", "set2", "set3", "set4"))
+ .externalDocumentationLinks(Map.of("link1", "link2", "link3", "link4"))
+ .perPackageOptions(List.of("option1", "option2"))
+ .samples(List.of("samples1", "samples1"))
+ .suppressedFiles(List.of("sup1", "sup2"))
+ .args();
+
+ var matches = List.of(
+ "-classpath", "path1;path2",
+ "-dependentSourceSets", "set1/set2;set3/set4",
+ "-externalDocumentationLinks", "link3^link4^^link1^link2",
+ "-perPackageOptions", "option1;option2",
+ "-samples", "samples1;samples1",
+ "-suppressedFiles", "sup1;sup2"
+ );
+
+ assertThat(args).hasSize(matches.size());
+
+ IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i)));
+ }
+
+ @Test
+ @SuppressWarnings("PMD.AvoidDuplicateLiterals")
+ void sourceSetTest() {
+ var args = new SourceSet()
+ .classpath("classpath1", "classpath2")
+ .dependentSourceSets("moduleName", "sourceSetName")
+ .documentedVisibilities(DocumentedVisibility.PACKAGE, DocumentedVisibility.PRIVATE)
+ .externalDocumentationLinks("url1", "packageListUrl1")
+ .externalDocumentationLinks("url2", "packageListUrl2")
+ .includes("includes1", "includes2")
+ .perPackageOptions("options1", "options2")
+ .samples("samples1", "sample2")
+ .srcLink("path1", "remote1", "#suffix1")
+ .srcLink("path2", "remote2", "#suffix2")
+ .src("src1", "src2")
+ .suppressedFiles("sup1", "sup2")
+ .analysisPlatform(AnalysisPlatform.JVM)
+ .apiVersion("1.0")
+ .displayName("name")
+ .jdkVersion(18)
+ .languageVersion("2.0")
+ .noJdkLink(true)
+ .noSkipEmptyPackages(true)
+ .noStdlibLink(true)
+ .reportUndocumented(true)
+ .skipDeprecated(true)
+ .sourceSetName("setName")
+ .args();
+
+ var matches = List.of(
+ "-analysisPlatform", "jvm",
+ "-apiVersion", "1.0",
+ "-classpath", "classpath1;classpath2",
+ "-dependentSourceSets", "moduleName/sourceSetName",
+ "-displayName", "name",
+ "-documentedVisibilities", "package;private",
+ "-externalDocumentationLinks", "url1^packageListUrl1^^url2^packageListUrl2",
+ "-jdkVersion", "18",
+ "-includes", "includes1;includes2",
+ "-languageVersion", "2.0",
+ "-noJdkLink", "true",
+ "-noSkipEmptyPackages", "true",
+ "-noStdlibLink", "true",
+ "-reportUndocumented", "true",
+ "-perPackageOptions", "options1;options2",
+ "-samples", "samples1;sample2",
+ "-skipDeprecated", "true",
+ "-src", "src1;src2",
+ "-srcLink", "path1=remote1#suffix1;path2=remote2#suffix2",
+ "-sourceSetName", "setName",
+ "-suppressedFiles", "sup1;sup2");
+
+ assertThat(args).hasSize(matches.size());
+
+ IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i)));
+ }
+}
diff --git a/src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java b/src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java
deleted file mode 100644
index c6e6965..0000000
--- a/src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright 2023-2025 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
- *
- * https://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 rife.bld.extension.kotlin;
-
-import org.assertj.core.api.AutoCloseableSoftAssertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledOnOs;
-import org.junit.jupiter.api.condition.OS;
-
-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;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@SuppressWarnings("PMD.AvoidDuplicateLiterals")
-class CompileOptionsTest {
- /**
- * Returns the local path of the given file names.
- *
- * @param fileNames The file names
- * @return the local path
- */
- private String localPath(String... fileNames) {
- return Arrays.stream(fileNames).map(it -> new File(it).getAbsolutePath())
- .collect(Collectors.joining(File.pathSeparator));
- }
-
- @Test
- @SuppressWarnings("PMD.UnitTestShouldIncludeAssert")
- void testArgs() {
- var options = new CompileOptions()
- .apiVersion("11")
- .javaParameters(true)
- .jvmTarget("11")
- .includeRuntime(true)
- .jdkHome(new File("path"))
- .jdkRelease("11")
- .kotlinHome(new File("path"))
- .languageVersion("1.0")
- .moduleName("module")
- .noJdk(true)
- .noReflect(true)
- .noWarn(true)
- .optIn("opt1", "opt2")
- .options("-foo", "-bar")
- .path("path")
- .plugin("id", "name", "value")
- .progressive(true)
- .scriptTemplates("name", "name2")
- .verbose(true)
- .wError(true)
- .wExtra(true);
-
- var matches = List.of(
- "-api-version", "11",
- "-java-parameters",
- "-jvm-target", "11",
- "-include-runtime",
- "-jdk-home", localPath("path"),
- "-Xjdk-release=11",
- "-kotlin-home", localPath("path"),
- "-language-version", "1.0",
- "-module-name", "module",
- "-no-jdk",
- "-no-reflect",
- "-nowarn",
- "-opt-in", "opt1",
- "-opt-in", "opt2",
- "-foo",
- "-bar",
- "-d", localPath("path"),
- "-P", "plugin:id:name:value",
- "-progressive",
- "-script-templates", "name,name2",
- "-verbose",
- "-Werror",
- "-Wextra");
-
- var args = new ArrayList>();
- args.add(options.args());
- args.add(options.apiVersion(11).jvmTarget(11).args());
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- for (var a : args) {
- IntStream.range(0, a.size()).forEach(i -> softly.assertThat(a.get(i))
- .as(a.get(i) + " == " + matches.get(i)).isEqualTo(matches.get(i)));
- }
- }
- }
-
- @Test
- void testArgsCollections() {
- var advanceOptions = List.of("-Xoption1", "option=2");
- var argFile = List.of(new File("arg1.txt"), new File("arg2.txt"));
- var classpath = List.of(new File("path1"), new File("path2"));
- var optIn = List.of("opt1", "opt2");
- var options = List.of("-foo", "-bar");
- var plugin = List.of("id:name:value", "id2:name2:value2");
- var scriptTemplates = List.of("temp1", "temp2");
-
- var op = new CompileOptions()
- .advancedOptions(advanceOptions)
- .argFile(argFile)
- .classpath(classpath)
- .noStdLib(false)
- .optIn(optIn)
- .options(options)
- .scriptTemplates(scriptTemplates);
-
- plugin.forEach(it -> {
- var p = it.split(":");
- op.plugin(p[0], p[1], p[2]);
- });
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(op.advancedOptions()).as("advancedOptions")
- .hasSize(advanceOptions.size()).containsAll(advanceOptions);
- softly.assertThat(op.argFile()).as("argFile")
- .hasSize(argFile.size()).containsAll(argFile);
- softly.assertThat(op.classpath()).as("classpath")
- .hasSize(classpath.size()).containsAll(classpath);
- softly.assertThat(op.optIn()).as("optIn")
- .hasSize(optIn.size()).containsAll(optIn);
- softly.assertThat(op.options()).as("options")
- .hasSize(options.size()).containsAll(options);
- softly.assertThat(op.plugin()).as("plugin")
- .hasSize(plugin.size()).containsAll(plugin);
- softly.assertThat(op.scriptTemplates()).as("scriptTemplates")
- .hasSize(scriptTemplates.size()).containsAll(scriptTemplates);
- }
-
- var matches = List.of(
- '@' + localPath("arg1.txt"), '@' + localPath("arg2.txt"),
- "-classpath", localPath("path1", "path2"),
- "-Joption1", "-Joption2",
- "-opt-in", "opt1",
- "-opt-in", "opt2",
- "-foo", "-bar",
- "-script-templates",
- "temp1,temp2",
- "-Xoption1", "-Xoption=2",
- "-P", "plugin:id:name:value",
- "-P", "plugin:id2:name2:value2");
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- var args = op.args();
- for (var arg : args) {
- var found = false;
- for (var match : matches) {
- if (match.equals(arg)) {
- found = true;
- break;
- }
- }
- softly.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 = options.argFile(foo);
- assertThat(options.argFile()).contains(foo);
- options.argFile().clear();
- assertThat(options.argFile()).isEmpty();
-
- options.argFile(foo, bar);
- assertThat(options.argFile()).contains(foo, bar);
- options.argFile().clear();
- assertThat(options.argFile()).isEmpty();
-
- options = options.argFile(foo.toPath(), bar.toPath());
- assertThat(options.argFile()).contains(foo, bar);
- options.argFile().clear();
- assertThat(options.argFile()).isEmpty();
-
- options = options.argFile(foo.getAbsolutePath(), bar.getAbsolutePath());
- assertThat(options.argFile()).contains(new File(foo.getAbsolutePath()), new File(bar.getAbsolutePath()));
- }
-
- @Test
- @EnabledOnOs(OS.LINUX)
- void testCheckAllParams() throws IOException {
- var args = Files.readAllLines(Paths.get("src", "test", "resources", "kotlinc-args.txt"));
-
- assertThat(args).isNotEmpty();
-
- var params = new CompileOptions()
- .advancedOptions("Xoption")
- .apiVersion("11")
- .expression("expression")
- .includeRuntime(true)
- .javaParameters(true)
- .jdkHome("jdkhome")
- .jvmTarget(12)
- .kotlinHome("kotlin")
- .languageVersion("1.0")
- .moduleName("moduleName")
- .noJdk(true)
- .noReflect(true)
- .noStdLib(true)
- .noWarn(true)
- .optIn("annotation")
- .options("option")
- .path(new File("path"))
- .plugin("id", "option", "value")
- .progressive(true)
- .scriptTemplates("template")
- .verbose(true)
- .wError(true)
- .wExtra(true);
-
- var skipArgs = List.of("-J", "-classpath", "@");
- assertThat(args).as(skipArgs + " not found.").containsAll(skipArgs);
- args.removeAll(skipArgs);
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- for (var p : args) {
- var found = false;
- for (var a : params.args()) {
- if (a.startsWith(p)) {
- found = true;
- break;
- }
- }
- softly.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 = options.classpath(foo);
- assertThat(options.classpath()).as("File").containsExactly(foo);
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
-
- options.classpath(foo, bar);
- assertThat(options.classpath()).as("File...").containsExactly(foo, bar);
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
-
- options.classpath(List.of(foo, bar));
- assertThat(options.classpath()).as("List(File...)").containsExactly(foo, bar);
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
-
- options = options.classpath(foo.toPath(), bar.toPath());
- assertThat(options.classpath()).as("Path...").containsExactly(foo, bar);
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
-
- options = options.classpathPaths(List.of(foo.toPath(), bar.toPath()));
- assertThat(options.classpath()).as("List(Path...)").containsExactly(foo, bar);
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
-
- options.classpath(foo.getAbsolutePath(), bar.getAbsolutePath());
- assertThat(options.classpath()).as("String...")
- .containsExactly(new File(foo.getAbsolutePath()), new File(bar.getAbsolutePath()));
- options.classpath().clear();
- assertThat(options.argFile()).isEmpty();
-
- options.classpathStrings(List.of(foo.getAbsolutePath(), bar.getAbsolutePath()));
- assertThat(options.classpath()).as("List(String...)")
- .containsExactly(new File(foo.getAbsolutePath()), new File(bar.getAbsolutePath()));
- }
-
- @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)
- .wExtra(true);
-
- try (var softly = new AutoCloseableSoftAssertions()) {
- softly.assertThat(options.advancedOptions()).containsExactly("xopt1", "xopt2");
- softly.assertThat(options.apiVersion()).isEqualTo("11");
- softly.assertThat(options.argFile()).containsExactly(new File("args.txt"));
- softly.assertThat(options.classpath()).containsExactly(new File("classpath"));
- softly.assertThat(options.expression()).isEqualTo("expression");
- softly.assertThat(options.isIncludeRuntime()).isTrue();
- softly.assertThat(options.isJavaParameters()).isTrue();
- softly.assertThat(options.isNoJdk()).isTrue();
- softly.assertThat(options.isNoReflect()).isTrue();
- softly.assertThat(options.isNoStdLib()).isTrue();
- softly.assertThat(options.isNoWarn()).isTrue();
- softly.assertThat(options.isProgressive()).isTrue();
- softly.assertThat(options.isVerbose()).isTrue();
- softly.assertThat(options.jdkHome()).isEqualTo(new File("jdk-home"));
- softly.assertThat(options.jdkRelease()).isEqualTo("22");
- softly.assertThat(options.jvmTarget()).isEqualTo("9");
- softly.assertThat(options.kotlinHome()).isEqualTo(new File("kotlin-home"));
- softly.assertThat(options.languageVersion()).isEqualTo("1.0");
- softly.assertThat(options.moduleName()).isEqualTo("module");
- softly.assertThat(options.optIn()).containsExactly("opt1", "opt2");
- softly.assertThat(options.options()).containsExactly("-foo", "-bar");
- softly.assertThat(options.path()).isEqualTo(new File("path"));
- softly.assertThat(options.plugin()).containsExactly("id:name:value");
- softly.assertThat(options.scriptTemplates()).containsExactly("name", "name2");
- softly.assertThat(options.isWError()).isTrue();
- softly.assertThat(options.isWExtra()).isTrue();
- }
- }
-}
diff --git a/src/test/java/rife/bld/extension/kotlin/JvmOptionsTest.java b/src/test/java/rife/bld/extension/kotlin/JvmOptionsTest.java
deleted file mode 100644
index 6f8474f..0000000
--- a/src/test/java/rife/bld/extension/kotlin/JvmOptionsTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2023-2025 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
- *
- * https://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 rife.bld.extension.kotlin;
-
-import org.junit.jupiter.api.Test;
-import rife.bld.extension.CompileKotlinOperation;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@SuppressWarnings("PMD.AvoidDuplicateLiterals")
-class JvmOptionsTest {
- @Test
- void testop() {
- var op = new CompileKotlinOperation().jvmOptions(new JvmOptions().enableNativeAccess(JvmOptions.ALL_UNNAMED));
- assertThat(op.jvmOptions()).as(JvmOptions.ALL_UNNAMED).containsExactly("--enable-native-access=ALL-UNNAMED");
-
- op = new CompileKotlinOperation().jvmOptions(new JvmOptions().enableNativeAccess("m1", "m2"));
- assertThat(op.jvmOptions()).as("m1,m2").containsExactly("--enable-native-access=m1,m2");
- }
-
- @Test
- void testEnableNativeAccess() {
- var options = new JvmOptions().enableNativeAccess(JvmOptions.ALL_UNNAMED);
- assertThat(options).as(JvmOptions.ALL_UNNAMED).containsExactly("--enable-native-access=ALL-UNNAMED");
-
- options = new JvmOptions().enableNativeAccess("m1");
- assertThat(options).as("m1").containsExactly("--enable-native-access=m1");
-
- options = new JvmOptions().enableNativeAccess("m1", "m2");
- assertThat(options).as("m1,m2").containsExactly("--enable-native-access=m1,m2");
- }
-
- @Test
- void testIllegalNativeAccess() {
- var options = new JvmOptions().illegalNativeAccess(JvmOptions.NativeAccess.ALLOW);
- assertThat(options).as("ALLOW").containsExactly("--illegal-native-access=allow");
-
- options = new JvmOptions().illegalNativeAccess(JvmOptions.NativeAccess.DENY);
- assertThat(options).as("DENY").containsExactly("--illegal-native-access=deny");
-
- options = new JvmOptions().illegalNativeAccess(JvmOptions.NativeAccess.WARN);
- assertThat(options).as("WARN").containsExactly("--illegal-native-access=warn");
- }
-
- @Test
- void testJvmOptions() {
- var op = new CompileKotlinOperation().jvmOptions("option1", "option2");
- assertThat(op.jvmOptions()).as("option1,option2").containsExactly("option1", "option2");
-
- op = new CompileKotlinOperation().jvmOptions(List.of("option1", "option2"));
- assertThat(op.jvmOptions()).as("List.of(option1,option2)").containsExactly("option1", "option2");
-
- op = op.jvmOptions(new JvmOptions().enableNativeAccess(JvmOptions.ALL_UNNAMED));
- assertThat(op.jvmOptions()).as("List.of(option1,option2,ALL_UNNAMED)")
- .containsExactly("option1", "option2", "--enable-native-access=ALL-UNNAMED");
-
- op = op.jvmOptions(new JvmOptions().illegalNativeAccess(JvmOptions.NativeAccess.ALLOW));
- assertThat(op.jvmOptions()).as("allow")
- .containsExactly("option1", "option2", "--enable-native-access=ALL-UNNAMED",
- "--illegal-native-access=allow");
- }
-}
diff --git a/src/test/resources/argfile.txt b/src/test/resources/argfile.txt
deleted file mode 100644
index d128d62..0000000
--- a/src/test/resources/argfile.txt
+++ /dev/null
@@ -1,3 +0,0 @@
--Xjdk-release=17 -no-reflect
-
--progressive
diff --git a/src/test/resources/argfile2.txt b/src/test/resources/argfile2.txt
deleted file mode 100644
index 93f9181..0000000
--- a/src/test/resources/argfile2.txt
+++ /dev/null
@@ -1 +0,0 @@
--include-runtime
\ No newline at end of file
diff --git a/src/test/resources/kotlinc-args.txt b/src/test/resources/kotlinc-args.txt
deleted file mode 100644
index e764231..0000000
--- a/src/test/resources/kotlinc-args.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-@
--api-version
--classpath
--d
--expression
--include-runtime
--J
--java-parameters
--jdk-home
--jvm-target
--kotlin-home
--language-version
--module-name
--no-jdk
--no-reflect
--no-stdlib
--nowarn
--opt-in
--P
--progressive
--script
--script-templates
--verbose
--Werror
--Wextra
--X