diff --git a/.idea/runConfigurations/Run Tests.xml b/.idea/runConfigurations/Run Tests.xml
deleted file mode 100644
index 057a90e..0000000
--- a/.idea/runConfigurations/Run Tests.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index d0d0ff9..06ce2cb 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,14 @@ for all available configuration options.
Please make sure the Kotlin compiler is [installed](https://kotlinlang.org/docs/command-line.html#install-the-compiler).
+The plugin will look in common locations such as:
+- `KOTLIN_HOME`
+- `PATH`
+- SDKMAN!
+- Homebrew
+- JetBrains Toolbox (IntelliJ IDEA, Android Studio)
+- etc.
+
You can also manually configure the Kotlin home location as follows:
```java
diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java
index 570ff14..f1c912b 100644
--- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java
+++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java
@@ -26,9 +26,7 @@ import rife.tools.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -40,6 +38,9 @@ import java.util.logging.Logger;
*/
public class CompileKotlinOperation extends AbstractOperation {
private static final Logger LOGGER = Logger.getLogger(CompileKotlinOperation.class.getName());
+ private static final String OS_NAME =
+ System.getProperty("os.name") != null ? System.getProperty("os.name").toLowerCase(Locale.US) : null;
+ private static final String KOTLINC_EXECUTABLE = "kotlinc" + (isWindows() ? ".bat" : "");
private final Collection compileMainClasspath_ = new ArrayList<>();
private final Collection compileTestClasspath_ = new ArrayList<>();
private final Collection mainSourceDirectories_ = new ArrayList<>();
@@ -55,6 +56,145 @@ public class CompileKotlinOperation extends AbstractOperation commonPaths = new ArrayList<>();
+
+ if (isLinux()) {
+ commonPaths.add("/usr/bin");
+ commonPaths.add("/usr/local/bin");
+ commonPaths.add("/usr/local/kotlin/bin");
+ commonPaths.add("/opt/kotlin/bin");
+ var userHome = System.getProperty("user.home");
+ if (userHome != null) {
+ commonPaths.add(userHome + "/.sdkman/candidates/kotlin/current/bin"); // SDKMAN!
+ commonPaths.add(userHome + "/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate/plugins/Kotlin/bin"); // Toolbox IDEA Ultimate
+ commonPaths.add(userHome + "/.local/share/JetBrains/Toolbox/apps/intellij-idea-community-edition/plugins/Kotlin/bin"); // Toolbox IDEA CE
+ commonPaths.add(userHome + "/.local/share/JetBrains/Toolbox/apps/android-studio/plugins/Kotlin/bin"); // Toolbox Android Studio
+ }
+ } else if (isWindows()) {
+ var localAppData = System.getenv("LOCALAPPDATA");
+ if (localAppData != null) {
+ commonPaths.add(localAppData + "\\Programs\\IntelliJ IDEA Ultimate\\plugins\\Kotlin\\kotlinc\\bin"); // Toolbox IDEA Ultimate
+ commonPaths.add(localAppData + "\\Programs\\IntelliJ IDEA Community Edition\\plugins\\Kotlin\\kotlinc\\bin"); // Toolbox IDEA CE
+ commonPaths.add(localAppData + "\\Programs\\Android Studio\\plugins\\Kotlin\\kotlinc\\bin"); // Toolbox Android Studio
+ }
+ var programFiles = System.getenv("ProgramFiles");
+ if (programFiles != null) {
+ commonPaths.add(programFiles + File.separator + "Kotlin");
+ }
+ } else if (isMacOS()) {
+ commonPaths.add("/usr/local/bin"); // Homebrew
+ commonPaths.add("/opt/homebrew/bin"); // Homebrew
+ var userHome = System.getProperty("user.home");
+ if (userHome != null) {
+ commonPaths.add(userHome + "/.sdkman/candidates/kotlin/current/bin"); // SDKMAN!
+ }
+ commonPaths.add("/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/Kotlin/bin"); //IntelliJ IDEA Ultimate
+ commonPaths.add("/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/bin"); //IntelliJ IDEA
+ commonPaths.add("/Applications/Android Studio.app/Contents/plugins/Kotlin/bin"); //Android Studio
+ }
+
+ for (var location : commonPaths) {
+ kotlincPath = findKotlincInDir(location);
+ if (kotlincPath != null) {
+ return kotlincPath;
+ }
+ }
+
+ // Try 'which' or 'where' commands (less reliable but sometimes works)
+ try {
+ Process process;
+ if (isWindows()) {
+ process = Runtime.getRuntime().exec("where kotlinc");
+ } else {
+ process = Runtime.getRuntime().exec("which kotlinc");
+ }
+
+ try (var scanner = new Scanner(process.getInputStream())) {
+ if (scanner.hasNextLine()) {
+ kotlincPath = scanner.nextLine().trim();
+ if (isExecutable(new File(kotlincPath))) {
+ return kotlincPath;
+ }
+ }
+ }
+ } catch (Exception ignored) {
+ // Ignore exceptions from which/where, as they might not be available
+ }
+
+ return KOTLINC_EXECUTABLE;
+ }
+
+ private static boolean isExecutable(File file) {
+ return file != null && file.exists() && file.isFile() && file.canExecute();
+ }
+
+ /**
+ * Determines if the operating system is Linux.
+ *
+ * @return true if the operating system is Linux, false otherwise.
+ */
+ public static boolean isLinux() {
+ return OS_NAME != null && (OS_NAME.contains("linux") || OS_NAME.contains("unix")); // Consider Unix-like systems as well.
+ }
+
+ /**
+ * Determines if the current operating system is macOS.
+ *
+ * @return true if the OS is macOS, false otherwise.
+ */
+ public static boolean isMacOS() {
+ return OS_NAME != null && (OS_NAME.contains("mac") || OS_NAME.contains("darwin"));
+ }
+
/**
* Determines if the given string is not blank.
*
@@ -65,6 +205,15 @@ public class CompileKotlinOperation extends AbstractOperation();
// kotlinc
- args.add(kotlinCompiler());
+ if (kotlinc_ != null) {
+ args.add(kotlinc_.getAbsolutePath());
+ } else if (kotlinHome_ != null) {
+ args.add(Objects.requireNonNullElseGet(findKotlincInDir(kotlinHome_.getAbsolutePath()),
+ CompileKotlinOperation::findKotlincPath));
+ } else {
+ args.add(findKotlincPath());
+ }
// classpath
if (classpath != null && !classpath.isEmpty()) {
@@ -386,7 +542,6 @@ public class CompileKotlinOperation extends AbstractOperation
* Sets the following from the project:
*
- * - {@link #kotlinHome() kotlinHome} to the {@code KOTLIN_HOME} environment variable, if set.
* - {@link #workDir() workDir} to the project's directory.
* - {@link #buildMainDirectory() buildMainDirectory}
* - {@link #buildTestDirectory() buildTestDirectory}
@@ -405,14 +560,6 @@ public class CompileKotlinOperation extends AbstractOperation