From b1592bc7c7df76d46cebb2d4c2c79ee1de1fd7be Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 4 Mar 2024 13:10:37 -0800 Subject: [PATCH 001/126] Bumped Dokka to version 1.9.20 --- examples/lib/bld/bld-wrapper.properties | 2 +- .../bld/extension/CompileKotlinOperationBuild.java | 4 ++-- .../bld/extension/dokka/DokkaOperationTest.java | 13 +++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 142e058..51b54ec 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.1 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.2 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 89cfc4a..a659dce 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,14 +33,14 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 1); + version = version(0, 9, 2); javaRelease = 17; downloadSources = true; autoDownloadPurge = true; repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); - var dokka = version(1, 9, 10); + var dokka = version(1, 9, 20); var kotlin = version(1, 9, 22); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index 637b1f2..fbdac6d 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -58,13 +58,14 @@ class DokkaOperationTest { .executeConstructProcessCommandList(); var path = examples.getAbsolutePath(); + var dokkaJar = "1.9.20.jar"; 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", + "-jar", path + "/lib/bld/dokka-cli-" + dokkaJar, + "-pluginsClasspath", path + "/lib/bld/dokka-base-" + dokkaJar + ';' + + path + "/lib/bld/analysis-kotlin-descriptors-" + dokkaJar + ';' + + path + "/lib/bld/javadoc-plugin-" + dokkaJar + ';' + + path + "/lib/bld/korte-jvm-4.0.10.jar;" + + path + "/lib/bld/kotlin-as-java-plugin-" + dokkaJar + ";path1;path2;path3;path4", "-sourceSet", "-src " + path + "/src/main/kotlin", "-outputDir", path + "/build", "-delayTemplateSubstitution", "true", From bafa4f4d7477346eae7e0fad9bf8ae5076421d3e Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Fri, 8 Mar 2024 20:36:08 -0800 Subject: [PATCH 002/126] Bumped Kotlin to version 1.9.23 --- README.md | 4 ++-- examples/lib/bld/bld-wrapper.properties | 2 +- examples/src/bld/java/com/example/ExampleBuild.java | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3d3ff62..cdc893e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![Kotlin](https://img.shields.io/badge/kotlin-1.9.22-7f52ff.svg)](https://kotlinlang.org) +[![Kotlin](https://img.shields.io/badge/kotlin-1.9.23-7f52ff.svg)](https://kotlinlang.org) [![bld](https://img.shields.io/badge/1.9.0-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-kotlin) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-kotlin) @@ -60,4 +60,4 @@ for all available configuration options. ## Template Project There is also a [Template Project](https://github.com/rife2/kotlin-bld-example) with support for Dokka and the -[Detekt](https://github.com/rife2/bld-detekt) extensions. \ No newline at end of file +[Detekt](https://github.com/rife2/bld-detekt) extensions. diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 51b54ec..6af6a57 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.2 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.3 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 83ae793..82fd1dc 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -34,7 +34,7 @@ public class ExampleBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); - final var kotlin = version(1, 9, 22); + final var kotlin = version(1, 9, 23); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin)); scope(test) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index a659dce..6edf7fb 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 2); + version = version(0, 9, 3); javaRelease = 17; downloadSources = true; @@ -41,7 +41,7 @@ public class CompileKotlinOperationBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); var dokka = version(1, 9, 20); - var kotlin = version(1, 9, 22); + var kotlin = version(1, 9, 23); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-annotation-processing", kotlin)) From 8fb0202e906d29d31261b1cc6d0a1c3dbde41345 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Thu, 21 Mar 2024 13:48:07 -0700 Subject: [PATCH 003/126] Added JDK 22 to CI --- .github/workflows/bld.yml | 8 ++++---- examples/lib/bld/bld-wrapper.jar | Bin 27319 -> 27319 bytes lib/bld/bld-wrapper.jar | Bin 27319 -> 27319 bytes 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index 99d5cec..28c6ce6 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -1,6 +1,6 @@ name: bld-ci -on: [ push, pull_request, workflow_dispatch ] +on: [push, pull_request, workflow_dispatch] jobs: build-bld-project: @@ -8,7 +8,7 @@ jobs: strategy: matrix: - java-version: [ 17, 20 ] + java-version: [17, 21, 22] steps: - name: Checkout source repository @@ -19,7 +19,7 @@ jobs: - name: Set up JDK ${{ matrix.java-version }} uses: actions/setup-java@v3 with: - distribution: 'zulu' + distribution: "zulu" java-version: ${{ matrix.java-version }} - name: Download the examples dependencies @@ -34,7 +34,7 @@ jobs: - name: Build examples documentation working-directory: examples - run : | + run: | ./bld javadoc ./bld dokka-html ./bld dokka-gfm diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index e63713531201055d2d5d71dfd5204bbdd65996a0..82762f1dd24fca63ea5add2e5d08292f16e8a107 100644 GIT binary patch delta 131 zcmdmfm2vx3M&1B#W)=|!4h{~6i6yxcdFz;g)W$v~V-UT0vvD^QnBi!~t_Nm#r<`X5 wGi1{Y!BUe0GweYElP705gXx69e;#vM+x;)DP07`l`ivR!s diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar index e63713531201055d2d5d71dfd5204bbdd65996a0..82762f1dd24fca63ea5add2e5d08292f16e8a107 100644 GIT binary patch delta 131 zcmdmfm2vx3M&1B#W)=|!4h{~6i6yxcdFz;g)W$v~V-UT0vvD^QnBi!~t_Nm#r<`X5 wGi1{Y!BUe0GweYElP705gXx69e;#vM+x;)DP07`l`ivR!s From ad7ddabe3b5de08232331ed68f99018630624de7 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Thu, 21 Mar 2024 15:19:58 -0700 Subject: [PATCH 004/126] Removed pmd from CI tests --- .github/workflows/bld.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index 28c6ce6..049adb1 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -47,4 +47,4 @@ jobs: run: ./bld download - name: Run tests - run: ./bld compile pmd test + run: ./bld compile test From f5712972f15c8f15c6345a09ff2d65a9c445634b Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Fri, 22 Mar 2024 04:16:54 -0700 Subject: [PATCH 005/126] Bumped PMD extension to 0.9.8 (PMD 7.0.0) --- config/pmd.xml | 11 +++++------ lib/bld/bld-wrapper.properties | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/config/pmd.xml b/config/pmd.xml index cb0b643..3d3203c 100644 --- a/config/pmd.xml +++ b/config/pmd.xml @@ -19,15 +19,15 @@ + - + - @@ -35,8 +35,9 @@ - + + @@ -52,8 +53,6 @@ - - @@ -107,4 +106,4 @@ - \ No newline at end of file + diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 69f1830..9973999 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.7 +bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.8 bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= From 18a1d406952b2bd9381a8191d50292aa3fdaeb78 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 7 May 2024 11:14:55 -0700 Subject: [PATCH 006/126] Bumped workflows actions to latest versions --- .github/workflows/bld.yml | 4 ++-- .github/workflows/pages.yml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index 049adb1..d897fcc 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -12,12 +12,12 @@ jobs: steps: - name: Checkout source repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: "zulu" java-version: ${{ matrix.java-version }} diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 2120d4c..e191f6d 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -30,14 +30,14 @@ jobs: steps: - name: Checkout source repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: - distribution: 'zulu' + distribution: "zulu" java-version: 17 - name: Build Javadocs @@ -50,8 +50,8 @@ jobs: uses: actions/upload-pages-artifact@v1 with: # Upload generated Javadocs repository - path: 'build/javadoc/' + path: "build/javadoc/" - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v1 \ No newline at end of file + uses: actions/deploy-pages@v1 From cb072c3a87fb3732a07f4eba59e12178c74b5e5d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 7 May 2024 11:16:24 -0700 Subject: [PATCH 007/126] Bumped bld to version 1.9.1 --- .idea/libraries/bld.xml | 4 ++-- .vscode/settings.json | 2 +- examples/.idea/libraries/bld.xml | 4 ++-- examples/.vscode/settings.json | 2 +- examples/lib/bld/bld-wrapper.jar | Bin 27319 -> 27319 bytes examples/lib/bld/bld-wrapper.properties | 2 +- lib/bld/bld-wrapper.jar | Bin 27319 -> 27319 bytes lib/bld/bld-wrapper.properties | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml index ad697f0..cde67cb 100644 --- a/.idea/libraries/bld.xml +++ b/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e8368e..d136e4d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.0.jar", + "${HOME}/.bld/dist/bld-1.9.1.jar", "lib/**/*.jar" ] } diff --git a/examples/.idea/libraries/bld.xml b/examples/.idea/libraries/bld.xml index 0b615c1..a2969be 100644 --- a/examples/.idea/libraries/bld.xml +++ b/examples/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json index 9e8368e..d136e4d 100644 --- a/examples/.vscode/settings.json +++ b/examples/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.0.jar", + "${HOME}/.bld/dist/bld-1.9.1.jar", "lib/**/*.jar" ] } diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index 82762f1dd24fca63ea5add2e5d08292f16e8a107..0bfc526f16abc52e5fc1af85df2d99b021f2d72d 100644 GIT binary patch delta 166 zcmdmfm2vx3M&1B#W)=|!4h{|mtDeOZdFz;g)W$v~V-UT0vvD^QnBi!~t_Nm#r<`X5 zGi1{Y!BUe0GZYnB7y`W6IrKB%X0tOeFt7q~fHxzP2m{>U$&)jjLE0wY%VOdrXNgNSGOa{$#vfXtd)lVuG6r^GdG delta 166 zcmdmfm2vx3M&1B#W)=|!4h{~6i6yxcdFz;g)W$v~V-UT0vvD^QnBi!~t_Nm#r<`X5 zGi1{Y!BUe0GZYmW7y`W6Id(?Al3{0HU|7KU$&)jjLE0wY%VOdrXNgNSGOa{$#vfXtd)lVuG6AICGi delta 166 zcmdmfm2vx3M&1B#W)=|!4h{~6i6yxcdFz;g)W$v~V-UT0vvD^QnBi!~t_Nm#r<`X5 zGi1{Y!BUe0GZYmW7y`W6Id(?Al3{0HU| Date: Tue, 7 May 2024 11:19:26 -0700 Subject: [PATCH 008/126] Bumped Kotlin to version 1.9.24 --- README.md | 4 ++-- examples/src/bld/java/com/example/ExampleBuild.java | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cdc893e..9c1ac0c 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![Kotlin](https://img.shields.io/badge/kotlin-1.9.23-7f52ff.svg)](https://kotlinlang.org) -[![bld](https://img.shields.io/badge/1.9.0-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) +[![Kotlin](https://img.shields.io/badge/kotlin-1.9.24-7f52ff.svg)](https://kotlinlang.org) +[![bld](https://img.shields.io/badge/1.9.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-kotlin) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-kotlin) [![GitHub CI](https://github.com/rife2/bld-kotlin/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/bld-kotlin/actions/workflows/bld.yml) diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 82fd1dc..d4ef292 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -34,7 +34,7 @@ public class ExampleBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); - final var kotlin = version(1, 9, 23); + final var kotlin = version(1, 9, 24); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin)); scope(test) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 6edf7fb..4d10ac2 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -41,7 +41,7 @@ public class CompileKotlinOperationBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); var dokka = version(1, 9, 20); - var kotlin = version(1, 9, 23); + var kotlin = version(1, 9, 24); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-annotation-processing", kotlin)) From cdf6294b39454ecdba4d8a48f7c1f22d6109191b Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 7 May 2024 11:32:54 -0700 Subject: [PATCH 009/126] Version 0.9.4 --- examples/lib/bld/bld-wrapper.properties | 2 +- .../rife/bld/extension/CompileKotlinOperationBuild.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 732b2f8..113b890 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.3 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.4 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 4d10ac2..1d413fb 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 3); + version = version(0, 9, 4); javaRelease = 17; downloadSources = true; @@ -52,7 +52,7 @@ public class CompileKotlinOperationBuild extends Project { .include(dependency("org.jetbrains.dokka", "javadoc-plugin", dokka)) .include(dependency("org.jetbrains.dokka", "gfm-plugin", dokka)) .include(dependency("org.jetbrains.dokka", "jekyll-plugin", dokka)) - .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 0))); + .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1))); scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) @@ -81,7 +81,7 @@ public class CompileKotlinOperationBuild extends Project { .license( new PublishLicense() .name("The Apache License, Version 2.0") - .url("http://www.apache.org/licenses/LICENSE-2.0.txt") + .url("https://www.apache.org/licenses/LICENSE-2.0.txt") ) .scm( new PublishScm() From 84c2474ffc23e73f99a871f66ed50ccdbe912a61 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 19 May 2024 02:35:39 -0700 Subject: [PATCH 010/126] Fixed boolean-type functions producing invalid parameters. Closes #1 --- examples/src/bld/java/com/example/ExampleBuild.java | 1 + .../java/rife/bld/extension/dokka/DokkaOperation.java | 5 ----- .../rife/bld/extension/dokka/DokkaOperationTest.java | 10 +++++----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index d4ef292..71edf27 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -111,6 +111,7 @@ public class ExampleBuild extends Project { public void javadoc() throws ExitStatusException, IOException, InterruptedException { new DokkaOperation() .fromProject(this) + .failOnWarning(true) .loggingLevel(LoggingLevel.INFO) // Create build/javadoc .outputDir(new File(buildDirectory(), "javadoc")) diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java index 0b0936e..6d51006 100644 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java @@ -131,13 +131,11 @@ public class DokkaOperation extends AbstractProcessOperation { // -delayTemplateSubstitution if (delayTemplateSubstitution_) { args.add("-delayTemplateSubstitution"); - args.add(String.valueOf(delayTemplateSubstitution_)); } // -failOnWarning if (failOnWarning_) { args.add("-failOnWarning"); - args.add(String.valueOf(failOnWarning_)); } // -globalLinks_ @@ -188,13 +186,11 @@ public class DokkaOperation extends AbstractProcessOperation { // -noSuppressObviousFunctions if (noSuppressObviousFunctions_) { args.add("-noSuppressObviousFunctions"); - args.add(String.valueOf(noSuppressObviousFunctions_)); } // -offlineMode if (offlineMode_) { args.add("-offlineMode"); - args.add(String.valueOf(offlineMode_)); } // -pluginConfiguration @@ -209,7 +205,6 @@ public class DokkaOperation extends AbstractProcessOperation { // -suppressInheritedMembers if (suppressInheritedMembers_) { args.add("-suppressInheritedMembers"); - args.add(String.valueOf(suppressInheritedMembers_)); } if (LOGGER.isLoggable(Level.FINE)) { diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index fbdac6d..864d6fa 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -68,8 +68,8 @@ class DokkaOperationTest { path + "/lib/bld/kotlin-as-java-plugin-" + dokkaJar + ";path1;path2;path3;path4", "-sourceSet", "-src " + path + "/src/main/kotlin", "-outputDir", path + "/build", - "-delayTemplateSubstitution", "true", - "-failOnWarning", "true", + "-delayTemplateSubstitution", + "-failOnWarning", "-globalLinks", "s^link^^s2^link2", "-globalPackageOptions", "option1;option2;option3;option4", "-globalSrcLinks_", "link1;link2;link3;link4", @@ -77,10 +77,10 @@ class DokkaOperationTest { "-loggingLevel", "debug", "-moduleName", "name", "-moduleVersion", "1.0", - "-noSuppressObviousFunctions", "true", - "-offlineMode", "true", + "-noSuppressObviousFunctions", + "-offlineMode", "-pluginConfiguration", "{name}={\\\"json\\\"}^^{\\\"name2\\\"}={json2}", - "-suppressInheritedMembers", "true"); + "-suppressInheritedMembers"); assertThat(args).hasSize(matches.size()); From f8e4354e35923df7a7e897536937bf4ba2a4eb92 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 19 May 2024 03:46:45 -0700 Subject: [PATCH 011/126] Version 0.9.5 --- examples/lib/bld/bld-wrapper.properties | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 113b890..81004ac 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.4 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.5 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 1d413fb..f24da97 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 4); + version = version(0, 9, 5); javaRelease = 17; downloadSources = true; From 37cdfd363dbc71c44716a6ac9265acc420e45e58 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 11:35:36 -0700 Subject: [PATCH 012/126] Improved testing of integer-type arguments --- .../rife/bld/extension/CompileKotlinOptions.java | 11 +++++++++++ .../bld/extension/CompileKotlinOptionsTest.java | 15 ++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOptions.java b/src/main/java/rife/bld/extension/CompileKotlinOptions.java index 343d1ba..778a9a5 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOptions.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOptions.java @@ -65,6 +65,17 @@ public class CompileKotlinOptions { return this; } + /** + * Allow using declarations only from the specified version of Kotlin bundled libraries. + * + * @param version the api version + * @return this operation instance + */ + public CompileKotlinOptions apiVersion(int version) { + apiVersion_ = String.valueOf(version); + return this; + } + /** * Read the compiler options from the given files. *

diff --git a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java index f19663d..6324765 100644 --- a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java +++ b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java @@ -19,6 +19,7 @@ package rife.bld.extension; import org.junit.jupiter.api.Test; import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -54,7 +55,7 @@ class CompileKotlinOptionsTest { @Test void argsTest() { - var args = new CompileKotlinOptions() + var options = new CompileKotlinOptions() .apiVersion("11") .argFile("file.txt", "file2.txt") .classpath("path1", "path2") @@ -76,8 +77,7 @@ class CompileKotlinOptionsTest { .progressive(true) .scriptTemplates("name", "name2") .verbose(true) - .wError(true) - .args(); + .wError(true); var matches = List.of( "-api-version", "11", @@ -105,8 +105,13 @@ class CompileKotlinOptionsTest { "-verbose", "-Werror"); - assertThat(args).hasSize(matches.size()); + var args = new ArrayList>(); + args.add(options.args()); + args.add(options.apiVersion(11).jvmTarget(11).args()); - IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i))); + for (var a: args) { + assertThat(a).hasSize(matches.size()); + IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i)).isEqualTo(matches.get(i))); + } } } From 01a41e0d467b5d2e94efab006f793eced2e9a1db Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 11:37:17 -0700 Subject: [PATCH 013/126] Bumped Kotlin to version 2.0.0 --- README.md | 2 +- examples/src/bld/java/com/example/ExampleBuild.java | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c1ac0c..2a464d9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![Kotlin](https://img.shields.io/badge/kotlin-1.9.24-7f52ff.svg)](https://kotlinlang.org) +[![Kotlin](https://img.shields.io/badge/kotlin-2.0.0-7f52ff.svg)](https://kotlinlang.org) [![bld](https://img.shields.io/badge/1.9.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-kotlin) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-kotlin) diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 71edf27..5cccf1a 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -34,7 +34,7 @@ public class ExampleBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); - final var kotlin = version(1, 9, 24); + final var kotlin = version(2, 0, 0); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin)); scope(test) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index f24da97..663f3c0 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -41,7 +41,7 @@ public class CompileKotlinOperationBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); var dokka = version(1, 9, 20); - var kotlin = version(1, 9, 24); + var kotlin = version(2, 0, 0); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-annotation-processing", kotlin)) From 79bce706804ca1a6095c42a65bfa603825b3097b Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 11:37:37 -0700 Subject: [PATCH 014/126] Version 0.9.6 --- examples/lib/bld/bld-wrapper.properties | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 81004ac..066d395 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.5 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.6 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 663f3c0..fe52487 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 5); + version = version(0, 9, 6); javaRelease = 17; downloadSources = true; From 9c99532298948578bec03be2971bc83c3a60c0c8 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 15:53:16 -0700 Subject: [PATCH 015/126] Added support for the Power Assert compiler plugin --- src/main/java/rife/bld/extension/CompileKotlinPlugin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java index bddafbf..47264b3 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java +++ b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java @@ -30,6 +30,7 @@ public enum CompileKotlinPlugin { KOTLINX_SERIALIZATION("^kotlinx-serialization-compiler-plugin-.*$"), LOMBOK("^lombok-compiler-plugin-.*$"), NOARG("^noarg-compiler-plugin-.*$"), + POWER_ASSERT("^power-assert-compiler-plugin-.*$"), SAM_WITH_RECEIVER("^sam-with-receiver-compiler-plugin-.*$"); public final String label; From 9548f6150f5db21d78d01343287398227e1ecfb9 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 16:12:51 -0700 Subject: [PATCH 016/126] Version 0.9.7 --- examples/lib/bld/bld-wrapper.properties | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 066d395..b32aeb6 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.6 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.7 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index fe52487..5f3eef4 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 6); + version = version(0, 9, 7); javaRelease = 17; downloadSources = true; diff --git a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java index 6324765..c6d8419 100644 --- a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java +++ b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java @@ -109,7 +109,7 @@ class CompileKotlinOptionsTest { args.add(options.args()); args.add(options.apiVersion(11).jvmTarget(11).args()); - for (var a: args) { + for (var a : args) { assertThat(a).hasSize(matches.size()); IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i)).isEqualTo(matches.get(i))); } From 3a5f4f04bd95949741fa9f50fc0c2f5aea1eb52f Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 22 May 2024 16:30:12 -0700 Subject: [PATCH 017/126] Improved integer-type arguments --- .../rife/bld/extension/dokka/SourceSet.java | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/main/java/rife/bld/extension/dokka/SourceSet.java b/src/main/java/rife/bld/extension/dokka/SourceSet.java index 4a2dfb9..2c83ef6 100644 --- a/src/main/java/rife/bld/extension/dokka/SourceSet.java +++ b/src/main/java/rife/bld/extension/dokka/SourceSet.java @@ -40,7 +40,7 @@ public class SourceSet { private AnalysisPlatform analysisPlatform_; private String apiVersion_; private String displayName_; - private int jdkVersion_; + private String jdkVersion_; private String languageVersion_; private boolean noJdkLink_; private boolean noSkipEmptyPackages_; @@ -73,6 +73,17 @@ public class SourceSet { 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(int apiVersion) { + apiVersion_ = String.valueOf(apiVersion); + return this; + } + /** * Returns the formatted arguments. * @@ -130,9 +141,9 @@ public class SourceSet { } // -jdkVersion - if (jdkVersion_ > 0) { + if (jdkVersion_ != null) { args.add("-jdkVersion"); - args.add(String.valueOf(jdkVersion_)); + args.add(jdkVersion_); } // -includes @@ -375,11 +386,27 @@ public class SourceSet { * @param jdkVersion the JDK version * @return this operation instance */ - public SourceSet jdkVersion(int jdkVersion) { + public SourceSet jdkVersion(String jdkVersion) { jdkVersion_ = jdkVersion; 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_ = String.valueOf(jdkVersion); + return this; + } + /** * Sets the language version used for setting up analysis and samples. * @@ -391,6 +418,17 @@ public class SourceSet { 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(int languageVersion) { + languageVersion_ = String.valueOf(languageVersion); + return this; + } + /** * Sets whether to generate links to JDK Javadocs. *

From deb66a2d20c3e87799325a38bd3bada1cef36a34 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Thu, 23 May 2024 01:49:15 -0700 Subject: [PATCH 018/126] Fixed invalid Dokka -pluginConfiguration argument. Closes #2 --- .../CompileKotlinOperationBuild.java | 2 +- .../bld/extension/dokka/DokkaOperation.java | 31 ++++++++++++------- .../extension/dokka/DokkaOperationTest.java | 6 ++-- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 5f3eef4..4e7b947 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 7); + version = version(0, 9, 8, "SNAPSHOT"); javaRelease = 17; downloadSources = true; diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java index 6d51006..5d68a3f 100644 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java @@ -50,7 +50,7 @@ public class DokkaOperation extends AbstractProcessOperation { 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 Map pluginsConfiguration_ = new ConcurrentHashMap<>(); private final Collection pluginsClasspath_ = new ArrayList<>(); private boolean delayTemplateSubstitution_; private boolean failOnWarning_; @@ -64,6 +64,15 @@ public class DokkaOperation extends AbstractProcessOperation { private SourceSet sourceSet_; private boolean suppressInheritedMembers_; + // Encodes to JSON adding braces as needed + private static String encodeJson(final String json) { + var sb = new StringBuilder(json); + if (!json.startsWith("{") || !json.endsWith("}")) { + sb.insert(0, "{").append("}"); + } + return StringUtils.encodeJson(sb.toString()); + } + /** * Sets the delay substitution of some elements. *

@@ -194,11 +203,11 @@ public class DokkaOperation extends AbstractProcessOperation { } // -pluginConfiguration - if (!pluginConfiguration_.isEmpty()) { - args.add("-pluginConfiguration"); + if (!pluginsConfiguration_.isEmpty()) { + args.add("-pluginsConfiguration"); var confs = new ArrayList(); - pluginConfiguration_.forEach((k, v) -> - confs.add(String.format("{%s}={%s}", StringUtils.encodeJson(k), StringUtils.encodeJson(v)))); + pluginsConfiguration_.forEach((k, v) -> + confs.add(String.format("%s=%s", encodeJson(k), encodeJson(v)))); args.add(String.join("^^", confs)); } @@ -501,20 +510,20 @@ public class DokkaOperation extends AbstractProcessOperation { * @param jsonConfiguration The plugin JSON configuration * @return this operation instance */ - public DokkaOperation pluginConfiguration(String name, String jsonConfiguration) { - pluginConfiguration_.put(name, jsonConfiguration); + public DokkaOperation pluginConfigurations(String name, String jsonConfiguration) { + pluginsConfiguration_.put(name, jsonConfiguration); return this; } /** * Sets the configuration for Dokka plugins. * - * @param pluginConfiguration the map of configurations + * @param pluginConfiguratione the map of configurations * @return this operation instance - * @see #pluginConfiguration(String, String) + * @see #pluginConfigurations(String, String) */ - public DokkaOperation pluginConfiguration(Map pluginConfiguration) { - pluginConfiguration_.putAll(pluginConfiguration); + public DokkaOperation pluginConfigurations(Map pluginConfiguratione) { + pluginsConfiguration_.putAll(pluginConfiguratione); return this; } diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index 864d6fa..110c909 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -41,8 +41,8 @@ class DokkaOperationTest { .globalSrcLink("link1", "link2") .globalSrcLink(List.of("link3", "link4")) .includes("file1", "file2") - .pluginConfiguration("name", "\"json\"") - .pluginConfiguration(Map.of("\"name2\"", "json2")) + .pluginConfigurations("name", "{\"json\"}") + .pluginConfigurations(Map.of("{\"name2\"}", "json2", "name3}", "{json3")) .pluginsClasspath("path1", "path2") .pluginsClasspath(List.of("path3", "path4")) .delayTemplateSubstitution(true) @@ -79,7 +79,7 @@ class DokkaOperationTest { "-moduleVersion", "1.0", "-noSuppressObviousFunctions", "-offlineMode", - "-pluginConfiguration", "{name}={\\\"json\\\"}^^{\\\"name2\\\"}={json2}", + "-pluginsConfiguration", "{\\\"name2\\\"}={json2}^^{name}={\\\"json\\\"}^^{name3}}={{json3}", "-suppressInheritedMembers"); assertThat(args).hasSize(matches.size()); From d2560125d748cc581f193eea0e2fbc480e918e2c Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sat, 25 May 2024 00:59:51 -0700 Subject: [PATCH 019/126] Added the compile and provided classpaths to the sourceSet when DokkaOperation().fromProject() is called. Closes #3 --- .../bld/extension/dokka/DokkaOperation.java | 11 +++++--- .../rife/bld/extension/dokka/SourceSet.java | 28 +++++++++++++++---- .../extension/dokka/DokkaOperationTest.java | 11 ++++++-- .../bld/extension/dokka/SourceSetTest.java | 11 ++++++-- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java index 5d68a3f..c73ed84 100644 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java @@ -50,8 +50,8 @@ public class DokkaOperation extends AbstractProcessOperation { private final Collection globalPackageOptions_ = new ArrayList<>(); private final Collection globalSrcLinks_ = new ArrayList<>(); private final Collection includes_ = new ArrayList<>(); - private final Map pluginsConfiguration_ = new ConcurrentHashMap<>(); private final Collection pluginsClasspath_ = new ArrayList<>(); + private final Map pluginsConfiguration_ = new ConcurrentHashMap<>(); private boolean delayTemplateSubstitution_; private boolean failOnWarning_; private LoggingLevel loggingLevel_; @@ -226,15 +226,18 @@ public class DokkaOperation extends AbstractProcessOperation { /** * Configures the operation from a {@link BaseProject}. *

- * Sets the {@link #sourceSet sourceSet}, {@link SourceSet#jdkVersion jdkVersion} and {@link #moduleName moduleName} - * from the project. + * Sets the {@link #sourceSet sourceSet}, {@link SourceSet#jdkVersion jdkVersion}, {@link #moduleName moduleName} + * and {@link SourceSet#classpath(String...) classpath} 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()); + sourceSet_ = new SourceSet() + .src(new File(project.srcMainDirectory(), "kotlin").getAbsolutePath()) + .classpath(project.compileClasspathJars()) + .classpath(project.providedClasspathJars()); if (project.javaRelease() != null) { sourceSet_ = sourceSet_.jdkVersion(project.javaRelease()); } diff --git a/src/main/java/rife/bld/extension/dokka/SourceSet.java b/src/main/java/rife/bld/extension/dokka/SourceSet.java index 2c83ef6..28aedd8 100644 --- a/src/main/java/rife/bld/extension/dokka/SourceSet.java +++ b/src/main/java/rife/bld/extension/dokka/SourceSet.java @@ -16,6 +16,7 @@ package rife.bld.extension.dokka; +import java.io.File; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -236,11 +237,11 @@ public class SourceSet { *

* This option accepts both {@code .jar} and {@code .klib} files. * - * @param classpath one or more classpath + * @param files one or more file * @return this operation instance */ - public SourceSet classpath(String... classpath) { - classpath_.addAll(Arrays.asList(classpath)); + public SourceSet classpath(String... files) { + classpath_.addAll(Arrays.asList(files)); return this; } @@ -251,11 +252,26 @@ public class SourceSet { *

* This option accepts both {@code .jar} and {@code .klib} files. * - * @param classpath the list of classpath + * @param files the list of files * @return this operation instance */ - public SourceSet classpath(Collection classpath) { - classpath_.addAll(classpath); + public SourceSet classpath(Collection files) { + classpath_.addAll(files); + 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 files the list of files + * @return this operation instance + */ + public SourceSet classpath(List files) { + files.forEach(it -> classpath_.add(it.getAbsolutePath())); return this; } diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index 110c909..b4f30a9 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -55,6 +55,11 @@ class DokkaOperationTest { .outputDir(new File(examples, "build")) .outputFormat(OutputFormat.JAVADOC) .suppressInheritedMembers(true) + .sourceSet(new SourceSet().classpath( + List.of( + new File("examples/foo.jar"), + new File("examples/bar.jar") + ))) .executeConstructProcessCommandList(); var path = examples.getAbsolutePath(); @@ -66,7 +71,7 @@ class DokkaOperationTest { path + "/lib/bld/javadoc-plugin-" + dokkaJar + ';' + path + "/lib/bld/korte-jvm-4.0.10.jar;" + path + "/lib/bld/kotlin-as-java-plugin-" + dokkaJar + ";path1;path2;path3;path4", - "-sourceSet", "-src " + path + "/src/main/kotlin", + "-sourceSet", "-src " + path + "/src/main/kotlin" + " -classpath " + path + "/foo.jar;" + path + "/bar.jar", "-outputDir", path + "/build", "-delayTemplateSubstitution", "-failOnWarning", @@ -87,9 +92,9 @@ class DokkaOperationTest { 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)); + Arrays.stream(jars).forEach(jar -> assertThat(matches.get(i)).as(matches.get(i)).contains(jar)); } else { - assertThat(args.get(i)).isEqualTo(matches.get(i)); + assertThat(args.get(i)).as(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 index 4edefe0..f48c26e 100644 --- a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java +++ b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java @@ -53,7 +53,7 @@ class SourceSetTest { @Test @SuppressWarnings("PMD.AvoidDuplicateLiterals") void sourceSetTest() { - var args = new SourceSet() + var sourceSet = new SourceSet() .classpath("classpath1", "classpath2") .dependentSourceSets("moduleName", "sourceSetName") .documentedVisibilities(DocumentedVisibility.PACKAGE, DocumentedVisibility.PRIVATE) @@ -76,8 +76,9 @@ class SourceSetTest { .noStdlibLink(true) .reportUndocumented(true) .skipDeprecated(true) - .sourceSetName("setName") - .args(); + .sourceSetName("setName"); + + var args = sourceSet.args(); var matches = List.of( "-analysisPlatform", "jvm", @@ -105,5 +106,9 @@ class SourceSetTest { assertThat(args).hasSize(matches.size()); IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i))); + + sourceSet.classpath(List.of("classpath1", "classpath2")); + + IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i))); } } From 6f5d20b2c061dffaa88b8b92a48e9e5b2f1ce167 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 May 2024 12:34:31 -0700 Subject: [PATCH 020/126] Added diff of sourceSet help --- checkcliargs.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/checkcliargs.sh b/checkcliargs.sh index bb873ac..7394fc1 100755 --- a/checkcliargs.sh +++ b/checkcliargs.sh @@ -3,12 +3,15 @@ TMPNEW=/tmp/checkcliargs-new TMPOLD=/tmp/checkcliargs-old -cd lib/compile -java -cp "*" -jar dokka-cli-*.jar -h >$TMPNEW - -cd ../../examples/lib/bld -java -cp "*" -jar dokka-cli-*.jar -h >$TMPOLD +java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -h >$TMPNEW +java -cp "/examples/lib/bld*" -jar examples/lib/bld/dokka-cli-*.jar -h >$TMPOLD diff $TMPOLD $TMPNEW +java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -sourceSet -h >$TMPNEW +java -cp "/examples/lib/bld*" -jar examples/lib/bld/dokka-cli-*.jar -sourceSet -h >$TMPOLD + +diff $TMPOLD $TMPNEW + + rm -rf $TMPNEW $TMPOLD From e82810eaedf843c885add5ec18121d0d76e2be50 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 May 2024 12:35:50 -0700 Subject: [PATCH 021/126] Bumped assertj-core to version 3.26.0 --- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 4e7b947..2cc8a2f 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -56,7 +56,7 @@ public class CompileKotlinOperationBuild extends Project { scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) - .include(dependency("org.assertj", "assertj-core", version(3, 25, 3))); + .include(dependency("org.assertj", "assertj-core", version(3, 26, 0))); javadocOperation() .javadocOptions() From 9de0095fbddaa6602ed378e654a980117449d657 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 May 2024 12:36:39 -0700 Subject: [PATCH 022/126] Added json configuration parameter --- .../rife/bld/extension/dokka/DokkaOperation.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java index c73ed84..2ea40ab 100644 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java @@ -54,6 +54,7 @@ public class DokkaOperation extends AbstractProcessOperation { private final Map pluginsConfiguration_ = new ConcurrentHashMap<>(); private boolean delayTemplateSubstitution_; private boolean failOnWarning_; + private File json; private LoggingLevel loggingLevel_; private String moduleName_; private String moduleVersion_; @@ -216,6 +217,11 @@ public class DokkaOperation extends AbstractProcessOperation { args.add("-suppressInheritedMembers"); } + // json + if (json != null) { + args.add(json.getAbsolutePath()); + } + if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(String.join(" ", args)); } @@ -381,6 +387,16 @@ public class DokkaOperation extends AbstractProcessOperation { return this; } + /** + * JSON configuration file path. + * + * @param configuration the configuration file path + */ + public DokkaOperation json(File configuration) { + json = configuration; + return this; + } + /** * Sets the logging level. * From 10fd25ebf61f036e3de81e51e1cc0919e4930cdc Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 May 2024 12:38:47 -0700 Subject: [PATCH 023/126] Added checks against all parameters --- .../extension/dokka/DokkaOperationTest.java | 36 +++++++++++++++++-- .../bld/extension/dokka/SourceSetTest.java | 34 ++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index b4f30a9..f115a27 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -31,7 +31,25 @@ class DokkaOperationTest { @Test @SuppressWarnings({"ExtractMethodRecommender", "PMD.AvoidDuplicateLiterals"}) void executeConstructProcessCommandListTest() { + var params = List.of( + "-moduleName", + "-moduleVersion", + "-outputDir", + "-sourceSet", + "-pluginsConfiguration", + "-pluginsClasspath", + "-offlineMode", + "-failOnWarning", + "-delayTemplateSubstitution", + "-noSuppressObviousFunctions", + "-includes", + "-suppressInheritedMembers", + "-globalPackageOptions", + "-globalLinks", + "-globalSrcLink", + "-loggingLevel"); var examples = new File("examples"); + var jsonConf = new File("config.json"); var args = new DokkaOperation() .fromProject(new BaseProjectBlueprint(examples, "com.example", "Example")) .globalLinks("s", "link") @@ -41,6 +59,7 @@ class DokkaOperationTest { .globalSrcLink("link1", "link2") .globalSrcLink(List.of("link3", "link4")) .includes("file1", "file2") + .includes(List.of("file3", "file4")) .pluginConfigurations("name", "{\"json\"}") .pluginConfigurations(Map.of("{\"name2\"}", "json2", "name3}", "{json3")) .pluginsClasspath("path1", "path2") @@ -60,8 +79,20 @@ class DokkaOperationTest { new File("examples/foo.jar"), new File("examples/bar.jar") ))) + .json(jsonConf) .executeConstructProcessCommandList(); + for (var p : params) { + var found = false; + for (var a : args) { + if (a.startsWith(p)) { + found = true; + break; + } + } + assertThat(found).as(p + " not found.").isTrue(); + } + var path = examples.getAbsolutePath(); var dokkaJar = "1.9.20.jar"; var matches = List.of("java", @@ -78,14 +109,15 @@ class DokkaOperationTest { "-globalLinks", "s^link^^s2^link2", "-globalPackageOptions", "option1;option2;option3;option4", "-globalSrcLinks_", "link1;link2;link3;link4", - "-includes", "file1;file2", + "-includes", "file1;file2;file3;file4", "-loggingLevel", "debug", "-moduleName", "name", "-moduleVersion", "1.0", "-noSuppressObviousFunctions", "-offlineMode", "-pluginsConfiguration", "{\\\"name2\\\"}={json2}^^{name}={\\\"json\\\"}^^{name3}}={{json3}", - "-suppressInheritedMembers"); + "-suppressInheritedMembers", + jsonConf.getAbsolutePath()); assertThat(args).hasSize(matches.size()); diff --git a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java index f48c26e..ac1c20b 100644 --- a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java +++ b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java @@ -53,6 +53,29 @@ class SourceSetTest { @Test @SuppressWarnings("PMD.AvoidDuplicateLiterals") void sourceSetTest() { + var params = List.of( + "-sourceSetName", + "-displayName", + "-classpath", + "-src", + "-dependentSourceSets", + "-samples", + "-includes", + "-documentedVisibilities", + "-reportUndocumented", + "-noSkipEmptyPackages", + "-skipDeprecated", + "-jdkVersion", + "-languageVersion", + "-apiVersion", + "-noStdlibLink", + "-noJdkLink", + "-suppressedFiles", + "-analysisPlatform", + "-perPackageOptions", + "-externalDocumentationLinks", + "-srcLink" + ); var sourceSet = new SourceSet() .classpath("classpath1", "classpath2") .dependentSourceSets("moduleName", "sourceSetName") @@ -80,6 +103,17 @@ class SourceSetTest { var args = sourceSet.args(); + for (var p : params) { + var found = false; + for (var a : args) { + if (a.startsWith(p)) { + found = true; + break; + } + } + assertThat(found).as(p + " not found.").isTrue(); + } + var matches = List.of( "-analysisPlatform", "jvm", "-apiVersion", "1.0", From 1bdbe86519b9da4840daf316c8593e8875d63c43 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 May 2024 21:18:29 -0700 Subject: [PATCH 024/126] Version 0.9.8 --- README.md | 2 +- examples/lib/bld/bld-wrapper.properties | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 3 ++- src/main/java/rife/bld/extension/dokka/DokkaOperation.java | 4 +++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2a464d9..c7801b6 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ for all available configuration options. To generate the Javadoc using [Dokka](https://github.com/Kotlin/dokka): ```java -@BuildCommand(summary = "Generates Javadoc for the project") +@Override public void javadoc() throws ExitStatusException, IOException, InterruptedException { new DokkaOperation() .fromProject(this) diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index b32aeb6..8c08ccc 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,6 +1,6 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.7 +bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.8 bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 2cc8a2f..c01eadd 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,9 +33,10 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 8, "SNAPSHOT"); + version = version(0, 9, 8); javaRelease = 17; + downloadSources = true; autoDownloadPurge = true; repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); diff --git a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java index 2ea40ab..7229c63 100644 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ b/src/main/java/rife/bld/extension/dokka/DokkaOperation.java @@ -69,7 +69,7 @@ public class DokkaOperation extends AbstractProcessOperation { private static String encodeJson(final String json) { var sb = new StringBuilder(json); if (!json.startsWith("{") || !json.endsWith("}")) { - sb.insert(0, "{").append("}"); + sb.insert(0, "{").append('}'); } return StringUtils.encodeJson(sb.toString()); } @@ -489,6 +489,8 @@ public class DokkaOperation extends AbstractProcessOperation { /** * 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 From 749f43b6b2394b1b453254b0bd5939a9394931c8 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 27 May 2024 16:11:40 -0700 Subject: [PATCH 025/126] Added script to list parameters --- cliargs.sh | 17 +++++++ .../extension/dokka/DokkaOperationTest.java | 42 ++++++++-------- .../bld/extension/dokka/SourceSetTest.java | 48 +++++++++---------- 3 files changed, 62 insertions(+), 45 deletions(-) create mode 100755 cliargs.sh diff --git a/cliargs.sh b/cliargs.sh new file mode 100755 index 0000000..26016e6 --- /dev/null +++ b/cliargs.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -h |\ +grep " -" |\ +sed -e "s/ -/\"-/" -e "s/ \[.*//" -e "s/ -.*//" -e "s/\$/\",/" -e '/help/d' |\ +sort |\ +sed -e '$s/,//' + +echo +echo ---------------------------------------- +echo + +java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -sourceSet -h |\ +grep " -" |\ +sed -e "s/ -/\"-/" -e "s/ \[.*//" -e "s/ -.*//" -e "s/\$/\",/" -e '/help/d' -e '/includeNonPublic/d' |\ +sort |\ +sed -e '$s/,//' diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index f115a27..f0be118 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -32,25 +32,27 @@ class DokkaOperationTest { @SuppressWarnings({"ExtractMethodRecommender", "PMD.AvoidDuplicateLiterals"}) void executeConstructProcessCommandListTest() { var params = List.of( + "-delayTemplateSubstitution", + "-failOnWarning", + "-globalLinks", + "-globalPackageOptions", + "-globalSrcLink", + "-includes", + "-loggingLevel", "-moduleName", "-moduleVersion", - "-outputDir", - "-sourceSet", - "-pluginsConfiguration", - "-pluginsClasspath", - "-offlineMode", - "-failOnWarning", - "-delayTemplateSubstitution", "-noSuppressObviousFunctions", - "-includes", - "-suppressInheritedMembers", - "-globalPackageOptions", - "-globalLinks", - "-globalSrcLink", - "-loggingLevel"); + "-offlineMode", + "-outputDir", + "-pluginsClasspath", + "-pluginsConfiguration", + "-sourceSet", + "-suppressInheritedMembers"); var examples = new File("examples"); var jsonConf = new File("config.json"); var args = new DokkaOperation() + .delayTemplateSubstitution(true) + .failOnWarning(true) .fromProject(new BaseProjectBlueprint(examples, "com.example", "Example")) .globalLinks("s", "link") .globalLinks(Map.of("s2", "link2")) @@ -60,12 +62,7 @@ class DokkaOperationTest { .globalSrcLink(List.of("link3", "link4")) .includes("file1", "file2") .includes(List.of("file3", "file4")) - .pluginConfigurations("name", "{\"json\"}") - .pluginConfigurations(Map.of("{\"name2\"}", "json2", "name3}", "{json3")) - .pluginsClasspath("path1", "path2") - .pluginsClasspath(List.of("path3", "path4")) - .delayTemplateSubstitution(true) - .failOnWarning(true) + .json(jsonConf) .loggingLevel(LoggingLevel.DEBUG) .moduleName("name") .moduleVersion("1.0") @@ -73,13 +70,16 @@ class DokkaOperationTest { .offlineMode(true) .outputDir(new File(examples, "build")) .outputFormat(OutputFormat.JAVADOC) - .suppressInheritedMembers(true) + .pluginConfigurations("name", "{\"json\"}") + .pluginConfigurations(Map.of("{\"name2\"}", "json2", "name3}", "{json3")) + .pluginsClasspath("path1", "path2") + .pluginsClasspath(List.of("path3", "path4")) .sourceSet(new SourceSet().classpath( List.of( new File("examples/foo.jar"), new File("examples/bar.jar") ))) - .json(jsonConf) + .suppressInheritedMembers(true) .executeConstructProcessCommandList(); for (var p : params) { diff --git a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java index ac1c20b..3b5226e 100644 --- a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java +++ b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java @@ -54,52 +54,52 @@ class SourceSetTest { @SuppressWarnings("PMD.AvoidDuplicateLiterals") void sourceSetTest() { var params = List.of( - "-sourceSetName", - "-displayName", + "-analysisPlatform", + "-apiVersion", "-classpath", - "-src", "-dependentSourceSets", - "-samples", - "-includes", + "-displayName", "-documentedVisibilities", - "-reportUndocumented", - "-noSkipEmptyPackages", - "-skipDeprecated", + "-externalDocumentationLinks", + "-includes", "-jdkVersion", "-languageVersion", - "-apiVersion", - "-noStdlibLink", "-noJdkLink", - "-suppressedFiles", - "-analysisPlatform", + "-noSkipEmptyPackages", + "-noStdlibLink", "-perPackageOptions", - "-externalDocumentationLinks", - "-srcLink" + "-reportUndocumented", + "-samples", + "-skipDeprecated", + "-sourceSetName", + "-src", + "-srcLink", + "-suppressedFiles" ); var sourceSet = new SourceSet() + .analysisPlatform(AnalysisPlatform.JVM) + .apiVersion("1.0") .classpath("classpath1", "classpath2") .dependentSourceSets("moduleName", "sourceSetName") + .displayName("name") .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) + .perPackageOptions("options1", "options2") .reportUndocumented(true) + .samples("samples1", "sample2") .skipDeprecated(true) - .sourceSetName("setName"); + .sourceSetName("setName") + .src("src1", "src2") + .srcLink("path1", "remote1", "#suffix1") + .srcLink("path2", "remote2", "#suffix2") + .suppressedFiles("sup1", "sup2"); var args = sourceSet.args(); From f363e7dcce045d6e0e571599cbde9ce04e2d80c6 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 27 May 2024 21:35:58 -0700 Subject: [PATCH 026/126] Read parameters from resource files --- cliargs.sh | 14 ++---- .../extension/dokka/DokkaOperationTest.java | 26 ++++------- .../bld/extension/dokka/SourceSetTest.java | 44 ++++++------------- src/test/resources/dokka-args.txt | 16 +++++++ src/test/resources/dokka-sourceset-args.txt | 21 +++++++++ 5 files changed, 63 insertions(+), 58 deletions(-) create mode 100644 src/test/resources/dokka-args.txt create mode 100644 src/test/resources/dokka-sourceset-args.txt diff --git a/cliargs.sh b/cliargs.sh index 26016e6..dda5b47 100755 --- a/cliargs.sh +++ b/cliargs.sh @@ -2,16 +2,10 @@ java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -h |\ grep " -" |\ -sed -e "s/ -/\"-/" -e "s/ \[.*//" -e "s/ -.*//" -e "s/\$/\",/" -e '/help/d' |\ -sort |\ -sed -e '$s/,//' - -echo -echo ---------------------------------------- -echo +sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' |\ +sort > "src/test/resources/dokka-args.txt" java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -sourceSet -h |\ grep " -" |\ -sed -e "s/ -/\"-/" -e "s/ \[.*//" -e "s/ -.*//" -e "s/\$/\",/" -e '/help/d' -e '/includeNonPublic/d' |\ -sort |\ -sed -e '$s/,//' +sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' -e '/includeNonPublic/d' |\ +sort > "src/test/resources/dokka-sourceset-args.txt" diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index f0be118..f0a2207 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -20,6 +20,9 @@ import org.junit.jupiter.api.Test; import rife.bld.blueprints.BaseProjectBlueprint; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -30,24 +33,11 @@ import static org.assertj.core.api.Assertions.assertThat; class DokkaOperationTest { @Test @SuppressWarnings({"ExtractMethodRecommender", "PMD.AvoidDuplicateLiterals"}) - void executeConstructProcessCommandListTest() { - var params = List.of( - "-delayTemplateSubstitution", - "-failOnWarning", - "-globalLinks", - "-globalPackageOptions", - "-globalSrcLink", - "-includes", - "-loggingLevel", - "-moduleName", - "-moduleVersion", - "-noSuppressObviousFunctions", - "-offlineMode", - "-outputDir", - "-pluginsClasspath", - "-pluginsConfiguration", - "-sourceSet", - "-suppressInheritedMembers"); + void executeConstructProcessCommandListTest() throws IOException { + var params = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-args.txt")); + + assertThat(params).isNotEmpty(); + var examples = new File("examples"); var jsonConf = new File("config.json"); var args = new DokkaOperation() diff --git a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java index 3b5226e..b503335 100644 --- a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java +++ b/src/test/java/rife/bld/extension/dokka/SourceSetTest.java @@ -18,6 +18,9 @@ package rife.bld.extension.dokka; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.stream.IntStream; @@ -52,30 +55,11 @@ class SourceSetTest { @Test @SuppressWarnings("PMD.AvoidDuplicateLiterals") - void sourceSetTest() { - var params = List.of( - "-analysisPlatform", - "-apiVersion", - "-classpath", - "-dependentSourceSets", - "-displayName", - "-documentedVisibilities", - "-externalDocumentationLinks", - "-includes", - "-jdkVersion", - "-languageVersion", - "-noJdkLink", - "-noSkipEmptyPackages", - "-noStdlibLink", - "-perPackageOptions", - "-reportUndocumented", - "-samples", - "-skipDeprecated", - "-sourceSetName", - "-src", - "-srcLink", - "-suppressedFiles" - ); + void sourceSetTest() throws IOException { + var args = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-sourceset-args.txt")); + + assertThat(args).isNotEmpty(); + var sourceSet = new SourceSet() .analysisPlatform(AnalysisPlatform.JVM) .apiVersion("1.0") @@ -101,11 +85,11 @@ class SourceSetTest { .srcLink("path2", "remote2", "#suffix2") .suppressedFiles("sup1", "sup2"); - var args = sourceSet.args(); + var params = sourceSet.args(); - for (var p : params) { + for (var p : args) { var found = false; - for (var a : args) { + for (var a : params) { if (a.startsWith(p)) { found = true; break; @@ -137,12 +121,12 @@ class SourceSetTest { "-sourceSetName", "setName", "-suppressedFiles", "sup1;sup2"); - assertThat(args).hasSize(matches.size()); + assertThat(params).hasSize(matches.size()); - IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i))); + IntStream.range(0, params.size()).forEach(i -> assertThat(params.get(i)).isEqualTo(matches.get(i))); sourceSet.classpath(List.of("classpath1", "classpath2")); - IntStream.range(0, args.size()).forEach(i -> assertThat(args.get(i)).isEqualTo(matches.get(i))); + IntStream.range(0, params.size()).forEach(i -> assertThat(params.get(i)).isEqualTo(matches.get(i))); } } diff --git a/src/test/resources/dokka-args.txt b/src/test/resources/dokka-args.txt new file mode 100644 index 0000000..4c9f29c --- /dev/null +++ b/src/test/resources/dokka-args.txt @@ -0,0 +1,16 @@ +-delayTemplateSubstitution +-failOnWarning +-globalLinks +-globalPackageOptions +-globalSrcLink +-includes +-loggingLevel +-moduleName +-moduleVersion +-noSuppressObviousFunctions +-offlineMode +-outputDir +-pluginsClasspath +-pluginsConfiguration +-sourceSet +-suppressInheritedMembers diff --git a/src/test/resources/dokka-sourceset-args.txt b/src/test/resources/dokka-sourceset-args.txt new file mode 100644 index 0000000..0699eb7 --- /dev/null +++ b/src/test/resources/dokka-sourceset-args.txt @@ -0,0 +1,21 @@ +-analysisPlatform +-apiVersion +-classpath +-dependentSourceSets +-displayName +-documentedVisibilities +-externalDocumentationLinks +-includes +-jdkVersion +-languageVersion +-noJdkLink +-noSkipEmptyPackages +-noStdlibLink +-perPackageOptions +-reportUndocumented +-samples +-skipDeprecated +-sourceSetName +-src +-srcLink +-suppressedFiles From b42190d9cf24efb765dd9020cac9306467b09e2d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 28 May 2024 13:26:34 -0700 Subject: [PATCH 027/126] Execute cligargs script prior to to running tests --- lib/bld/bld-wrapper.properties | 1 + checkcliargs.sh => scripts/checkcliargs.sh | 0 cliargs.sh => scripts/cliargs.sh | 0 .../rife/bld/extension/CompileKotlinOperationBuild.java | 9 +++++++++ 4 files changed, 10 insertions(+) rename checkcliargs.sh => scripts/checkcliargs.sh (100%) rename cliargs.sh => scripts/cliargs.sh (100%) diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 4cbfb76..b50fe85 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -1,6 +1,7 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.9 +bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.0 bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_RELEASES bld.downloadLocation= bld.sourceDirectories= diff --git a/checkcliargs.sh b/scripts/checkcliargs.sh similarity index 100% rename from checkcliargs.sh rename to scripts/checkcliargs.sh diff --git a/cliargs.sh b/scripts/cliargs.sh similarity index 100% rename from cliargs.sh rename to scripts/cliargs.sh diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index c01eadd..de179ad 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -98,6 +98,15 @@ public class CompileKotlinOperationBuild extends Project { new CompileKotlinOperationBuild().start(args); } + @Override + public void test() throws Exception { + new ExecOperation() + .fromProject(this) + .command("scripts/cliargs.sh") + .execute(); + super.test(); + } + @BuildCommand(summary = "Runs PMD analysis") public void pmd() { new PmdOperation() From 81ab2e829cda042790114b2c788caa76040ac5aa Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 28 May 2024 13:43:57 -0700 Subject: [PATCH 028/126] Cleaned up scripts for CI --- scripts/checkcliargs.sh | 20 ++++++++++---------- scripts/cliargs.sh | 6 ++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/scripts/checkcliargs.sh b/scripts/checkcliargs.sh index 7394fc1..f426f6b 100755 --- a/scripts/checkcliargs.sh +++ b/scripts/checkcliargs.sh @@ -1,17 +1,17 @@ #!/bin/bash -TMPNEW=/tmp/checkcliargs-new -TMPOLD=/tmp/checkcliargs-old +main=org.jetbrains.dokka.MainKt +new=/tmp/checkcliargs-new +old=/tmp/checkcliargs-old -java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -h >$TMPNEW -java -cp "/examples/lib/bld*" -jar examples/lib/bld/dokka-cli-*.jar -h >$TMPOLD +java -cp "lib/compile/*" $main -h >$new +java -cp "/examples/lib/bld*" $main -h >$old -diff $TMPOLD $TMPNEW +diff $old $new -java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -sourceSet -h >$TMPNEW -java -cp "/examples/lib/bld*" -jar examples/lib/bld/dokka-cli-*.jar -sourceSet -h >$TMPOLD +java -cp "lib/compile/*" $main -sourceSet -h >$new +java -cp "/examples/lib/bld*" $main -sourceSet -h >$old -diff $TMPOLD $TMPNEW +diff $old $new - -rm -rf $TMPNEW $TMPOLD +rm -rf $new $old diff --git a/scripts/cliargs.sh b/scripts/cliargs.sh index dda5b47..0fd649a 100755 --- a/scripts/cliargs.sh +++ b/scripts/cliargs.sh @@ -1,11 +1,13 @@ #!/bin/bash -java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -h |\ +main=org.jetbrains.dokka.MainKt + +java -cp "lib/compile/*" $main -h |\ grep " -" |\ sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' |\ sort > "src/test/resources/dokka-args.txt" -java -cp "lib/compile/*" -jar lib/compile/dokka-cli-*.jar -sourceSet -h |\ +java -cp "lib/compile/*" $main -sourceSet -h |\ grep " -" |\ sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' -e '/includeNonPublic/d' |\ sort > "src/test/resources/dokka-sourceset-args.txt" From b4c895253861acc6ceb546b4f659d78f54d3a570 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 28 May 2024 22:54:21 -0700 Subject: [PATCH 029/126] Use Collection.addAll wherever applicable. --- .../rife/bld/extension/CompileKotlinOperation.java | 10 +++++----- .../java/rife/bld/extension/CompileKotlinOptions.java | 11 ++++++----- .../java/rife/bld/extension/dokka/DokkaOperation.java | 8 ++++---- src/main/java/rife/bld/extension/dokka/SourceSet.java | 10 +++++----- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index 1465991..6576aac 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -154,7 +154,7 @@ public class CompileKotlinOperation extends AbstractOperation { * @return this operation instance */ public DokkaOperation globalPackageOptions(String... options) { - globalPackageOptions_.addAll(Arrays.asList(options)); + Collections.addAll(globalPackageOptions_, options); return this; } @@ -342,7 +342,7 @@ public class DokkaOperation extends AbstractProcessOperation { * @return this operation instance */ public DokkaOperation globalSrcLink(String... links) { - globalSrcLinks_.addAll(Arrays.asList(links)); + Collections.addAll(globalSrcLinks_, links); return this; } @@ -368,7 +368,7 @@ public class DokkaOperation extends AbstractProcessOperation { * @return this operation instance */ public DokkaOperation includes(String... files) { - includes_.addAll(Arrays.asList(files)); + Collections.addAll(includes_, files); return this; } @@ -555,7 +555,7 @@ public class DokkaOperation extends AbstractProcessOperation { * @return this operation instance */ public DokkaOperation pluginsClasspath(String... jars) { - pluginsClasspath_.addAll(Arrays.asList(jars)); + Collections.addAll(pluginsClasspath_, jars); return this; } diff --git a/src/main/java/rife/bld/extension/dokka/SourceSet.java b/src/main/java/rife/bld/extension/dokka/SourceSet.java index 28aedd8..e9457b5 100644 --- a/src/main/java/rife/bld/extension/dokka/SourceSet.java +++ b/src/main/java/rife/bld/extension/dokka/SourceSet.java @@ -241,7 +241,7 @@ public class SourceSet { * @return this operation instance */ public SourceSet classpath(String... files) { - classpath_.addAll(Arrays.asList(files)); + Collections.addAll(classpath_, files); return this; } @@ -371,7 +371,7 @@ public class SourceSet { * @return this operation instance */ public SourceSet includes(String... files) { - includes_.addAll(Arrays.asList(files)); + Collections.addAll(includes_, files); return this; } @@ -535,7 +535,7 @@ public class SourceSet { * @return this operation instance */ public SourceSet perPackageOptions(String... perPackageOptions) { - perPackageOptions_.addAll(List.of(perPackageOptions)); + Collections.addAll(perPackageOptions_, perPackageOptions); return this; } @@ -581,7 +581,7 @@ public class SourceSet { * @return this operation instance */ public SourceSet samples(String... samples) { - samples_.addAll(List.of(samples)); + Collections.addAll(samples_, samples); return this; } @@ -635,7 +635,7 @@ public class SourceSet { * @return this operation instance */ public SourceSet src(String... src) { - src_.addAll(List.of(src)); + Collections.addAll(src_, src); return this; } From 1623b902f9d05e6b7f74172e819a74f975d7af30 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 28 May 2024 22:57:56 -0700 Subject: [PATCH 030/126] Ensured all missing Kolin compiler arguments are handled --- scripts/checkcliargs.sh | 11 ++- scripts/cliargs.sh | 4 + .../CompileKotlinOperationBuild.java | 20 ++--- .../bld/extension/CompileKotlinOptions.java | 78 ++++++++++++++++++- .../extension/CompileKotlinOptionsTest.java | 74 +++++++++++++++--- .../extension/dokka/DokkaOperationTest.java | 20 ++--- src/test/resources/kotlinc-args.txt | 23 ++++++ 7 files changed, 197 insertions(+), 33 deletions(-) create mode 100644 src/test/resources/kotlinc-args.txt diff --git a/scripts/checkcliargs.sh b/scripts/checkcliargs.sh index f426f6b..aa2c55e 100755 --- a/scripts/checkcliargs.sh +++ b/scripts/checkcliargs.sh @@ -5,12 +5,19 @@ new=/tmp/checkcliargs-new old=/tmp/checkcliargs-old java -cp "lib/compile/*" $main -h >$new -java -cp "/examples/lib/bld*" $main -h >$old +java -cp "examples/lib/bld/*" $main -h >$old diff $old $new java -cp "lib/compile/*" $main -sourceSet -h >$new -java -cp "/examples/lib/bld*" $main -sourceSet -h >$old +java -cp "examples/lib/bld/*" $main -sourceSet -h >$old + +diff $old $new + +main=org.jetbrains.kotlin.cli.jvm.K2JVMCompiler + +java -cp "lib/compile/*" $main -h 2>$new +java -cp "examples/lib/bld/*" $main -h 2>$old diff $old $new diff --git a/scripts/cliargs.sh b/scripts/cliargs.sh index 0fd649a..9bceae4 100755 --- a/scripts/cliargs.sh +++ b/scripts/cliargs.sh @@ -1,5 +1,9 @@ #!/bin/bash +java -cp "lib/compile/*" org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -h 2> >(grep "^ ") |\ +sed -e "s/^ //" -e "s/ .*//" -e "s/<.*//" -e '/-help/d' -e '/-version/d' -e '/^$/d'|\ +sort > "src/test/resources/kotlinc-args.txt" + main=org.jetbrains.dokka.MainKt java -cp "lib/compile/*" $main -h |\ diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index de179ad..7d2e9b2 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -36,7 +36,7 @@ public class CompileKotlinOperationBuild extends Project { version = version(0, 9, 8); javaRelease = 17; - + downloadSources = true; autoDownloadPurge = true; repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); @@ -98,15 +98,6 @@ public class CompileKotlinOperationBuild extends Project { new CompileKotlinOperationBuild().start(args); } - @Override - public void test() throws Exception { - new ExecOperation() - .fromProject(this) - .command("scripts/cliargs.sh") - .execute(); - super.test(); - } - @BuildCommand(summary = "Runs PMD analysis") public void pmd() { new PmdOperation() @@ -115,4 +106,13 @@ public class CompileKotlinOperationBuild extends Project { .ruleSets("config/pmd.xml") .execute(); } + + @Override + public void test() throws Exception { + new ExecOperation() + .fromProject(this) + .command("scripts/cliargs.sh") + .execute(); + super.test(); + } } diff --git a/src/main/java/rife/bld/extension/CompileKotlinOptions.java b/src/main/java/rife/bld/extension/CompileKotlinOptions.java index 507c883..890f3c0 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOptions.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOptions.java @@ -31,13 +31,16 @@ import static rife.bld.extension.CompileKotlinOperation.isNotBlank; * @since 1.0 */ public class CompileKotlinOptions { + private final List advancedOptions_ = new ArrayList<>(); private final List argFile_ = new ArrayList<>(); private final List classpath_ = new ArrayList<>(); + private final List jvmOptions_ = new ArrayList<>(); private final List optIn_ = new ArrayList<>(); private final List options_ = new ArrayList<>(); private final List plugin_ = new ArrayList<>(); private final List scriptTemplates_ = new ArrayList<>(); private String apiVersion_; + private String expression_; private boolean includeRuntime_; private boolean javaParameters_; private String jdkHome_; @@ -55,6 +58,28 @@ public class CompileKotlinOptions { private boolean verbose_; private boolean wError_; + /** + * Specify advanced compiler options. + * + * @param options one or more advanced options + * @return this operation instance + */ + public CompileKotlinOptions advancedOptions(String... options) { + Collections.addAll(advancedOptions_, options); + return this; + } + + /** + * Specify advanced compiler options. + * + * @param options list of compiler options + * @return this operation instance + */ + public CompileKotlinOptions advancedOptions(Collection options) { + advancedOptions_.addAll(options); + return this; + } + /** * Allow using declarations only from the specified version of Kotlin bundled libraries. * @@ -120,7 +145,7 @@ public class CompileKotlinOptions { public List args() { var args = new ArrayList(); - // api-isNotBlankversion + // api-version if (isNotBlank(apiVersion_)) { args.add("-api-version"); args.add(apiVersion_); @@ -137,6 +162,12 @@ public class CompileKotlinOptions { args.add(String.join(File.pathSeparator, classpath_)); } + // expression + if (isNotBlank(expression_)) { + args.add("-expression"); + args.add(expression_); + } + // java-parameters if (javaParameters_) { args.add("-java-parameters"); @@ -164,6 +195,11 @@ public class CompileKotlinOptions { args.add("-Xjdk-release=" + jdkRelease_); } + // JVM options + if (!jvmOptions_.isEmpty()) { + jvmOptions_.forEach(s -> args.add("-J" + s)); + } + // kotlin-home if (isNotBlank(kotlinHome_)) { args.add("-kotlin-home"); @@ -199,7 +235,7 @@ public class CompileKotlinOptions { // no-warn if (noWarn_) { - args.add("-no-warn"); + args.add("-nowarn"); } // opt-in @@ -246,6 +282,11 @@ public class CompileKotlinOptions { args.add("-Werror"); } + // advanced option (X) + if (!advancedOptions_.isEmpty()) { + advancedOptions_.forEach(it -> args.add("-X" + it)); + } + return args; } @@ -275,6 +316,17 @@ public class CompileKotlinOptions { return this; } + /** + * Evaluate the given string as a Kotlin script. + * + * @param expression the expression + * @return this operation instance + */ + public CompileKotlinOptions expression(String expression) { + expression_ = expression; + return this; + } + /** * Indicates whether the {@link #jdkRelease(String) jdkRelease} was set. * @@ -346,6 +398,28 @@ public class CompileKotlinOptions { return this; } + /** + * Pass an option directly to JVM + * + * @param jvmOptions one or more JVM option + * @return this operation instance + */ + public CompileKotlinOptions jvmOptions(String... jvmOptions) { + Collections.addAll(jvmOptions_, jvmOptions); + return this; + } + + /** + * Pass an option directly to JVM + * + * @param jvmOptions the list JVM options + * @return this operation instance + */ + public CompileKotlinOptions jvmOptions(Collection jvmOptions) { + jvmOptions_.addAll(jvmOptions); + return this; + } + /** * Specify the target version of the generated JVM bytecode. *

diff --git a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java index c6d8419..5c075fb 100644 --- a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java +++ b/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java @@ -19,6 +19,9 @@ package rife.bld.extension; import org.junit.jupiter.api.Test; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -30,8 +33,10 @@ class CompileKotlinOptionsTest { @Test void argsCollectionTest() { var args = new CompileKotlinOptions() + .advancedOptions(List.of("Xoption1", "Xoption2")) .argFile(List.of("arg1.txt", "arg2.txt")) .classpath(List.of("path1", "path2")) + .jvmOptions(List.of("option1", "option2")) .noStdLib(false) .optIn(List.of("opt1", "opt2")) .options(List.of("-foo", "-bar")) @@ -40,19 +45,27 @@ class CompileKotlinOptionsTest { var matches = List.of( "@arg1.txt", "@arg2.txt", "-classpath", "path1:path2", + "-Joption1", "-Joption2", "-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))); - + "-foo", "-bar", + "-script-templates", + "temp1,temp2", + "-XXoption1", "-XXoption2"); + for (var arg : args) { + var found = false; + for (var match : matches) { + if (match.equals(arg)) { + found = true; + break; + } + } + assertThat(found).as(arg).isTrue(); + } } + @Test void argsTest() { var options = new CompileKotlinOptions() @@ -93,7 +106,7 @@ class CompileKotlinOptionsTest { "-module-name", "module", "-no-jdk", "-no-reflect", - "-no-warn", + "-nowarn", "-opt-in", "opt1", "-opt-in", "opt2", "-foo", @@ -114,4 +127,47 @@ class CompileKotlinOptionsTest { IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i)).isEqualTo(matches.get(i))); } } + + @Test + void checkAllParamsTest() throws IOException { + var args = Files.readAllLines(Paths.get("src", "test", "resources", "kotlinc-args.txt")); + + assertThat(args).isNotEmpty(); + + var params = new CompileKotlinOptions() + .advancedOptions("Xoption") + .argFile("file") + .classpath("classpath") + .expression("expression") + .jvmOptions("option") + .includeRuntime(true) + .javaParameters(true) + .jdkHome("jdkhome") + .jvmTarget(12) + .kotlinHome("kotlin") + .moduleName("moduleName") + .noJdk(true) + .noReflect(true) + .noStdLib(true) + .noWarn(true) + .optIn("annotation") + .options("option") + .path("path") + .plugin("id", "option", "value") + .progressive(true) + .scriptTemplates("template") + .verbose(true) + .wError(true); + + for (var p : args) { + var found = false; + for (var a : params.args()) { + if (a.startsWith(p)) { + found = true; + break; + } + } + assertThat(found).as(p + " not found.").isTrue(); + } + } } diff --git a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java index f0a2207..0e089ee 100644 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java @@ -34,13 +34,13 @@ class DokkaOperationTest { @Test @SuppressWarnings({"ExtractMethodRecommender", "PMD.AvoidDuplicateLiterals"}) void executeConstructProcessCommandListTest() throws IOException { - var params = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-args.txt")); + var args = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-args.txt")); - assertThat(params).isNotEmpty(); + assertThat(args).isNotEmpty(); var examples = new File("examples"); var jsonConf = new File("config.json"); - var args = new DokkaOperation() + var params = new DokkaOperation() .delayTemplateSubstitution(true) .failOnWarning(true) .fromProject(new BaseProjectBlueprint(examples, "com.example", "Example")) @@ -72,9 +72,9 @@ class DokkaOperationTest { .suppressInheritedMembers(true) .executeConstructProcessCommandList(); - for (var p : params) { + for (var p : args) { var found = false; - for (var a : args) { + for (var a : params) { if (a.startsWith(p)) { found = true; break; @@ -109,14 +109,14 @@ class DokkaOperationTest { "-suppressInheritedMembers", jsonConf.getAbsolutePath()); - assertThat(args).hasSize(matches.size()); + assertThat(params).hasSize(matches.size()); - IntStream.range(0, args.size()).forEach(i -> { - if (args.get(i).contains(".jar;")) { - var jars = args.get(i).split(";"); + IntStream.range(0, params.size()).forEach(i -> { + if (params.get(i).contains(".jar;")) { + var jars = params.get(i).split(";"); Arrays.stream(jars).forEach(jar -> assertThat(matches.get(i)).as(matches.get(i)).contains(jar)); } else { - assertThat(args.get(i)).as(args.get(i)).isEqualTo(matches.get(i)); + assertThat(params.get(i)).as(params.get(i)).isEqualTo(matches.get(i)); } }); } diff --git a/src/test/resources/kotlinc-args.txt b/src/test/resources/kotlinc-args.txt new file mode 100644 index 0000000..1f49a77 --- /dev/null +++ b/src/test/resources/kotlinc-args.txt @@ -0,0 +1,23 @@ +@ +-classpath +-d +-expression +-include-runtime +-J +-java-parameters +-jdk-home +-jvm-target +-kotlin-home +-module-name +-no-jdk +-no-reflect +-no-stdlib +-nowarn +-opt-in +-P +-progressive +-script +-script-templates +-verbose +-Werror +-X From 8d34f37af056ad163d33a90150c6dc3e16d514ca Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sat, 15 Jun 2024 21:31:36 -0700 Subject: [PATCH 031/126] Moved Dokka operation to its own extension --- .github/workflows/bld.yml | 8 - README.md | 27 +- examples/README.md | 9 - examples/lib/bld/bld-wrapper.properties | 4 +- .../bld/java/com/example/ExampleBuild.java | 65 +- lib/bld/bld-wrapper.properties | 6 +- scripts/checkcliargs.sh | 14 - scripts/cliargs.sh | 12 - .../CompileKotlinOperationBuild.java | 20 +- .../bld/extension/dokka/AnalysisPlatform.java | 27 - .../extension/dokka/DocumentedVisibility.java | 27 - .../bld/extension/dokka/DokkaOperation.java | 609 ---------------- .../bld/extension/dokka/LoggingLevel.java | 27 - .../bld/extension/dokka/OutputFormat.java | 27 - .../rife/bld/extension/dokka/SourceSet.java | 680 ------------------ .../extension/dokka/DokkaOperationTest.java | 123 ---- .../bld/extension/dokka/SourceSetTest.java | 132 ---- src/test/resources/dokka-args.txt | 16 - src/test/resources/dokka-sourceset-args.txt | 21 - 19 files changed, 26 insertions(+), 1828 deletions(-) delete mode 100644 src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java delete mode 100644 src/main/java/rife/bld/extension/dokka/DocumentedVisibility.java delete mode 100644 src/main/java/rife/bld/extension/dokka/DokkaOperation.java delete mode 100644 src/main/java/rife/bld/extension/dokka/LoggingLevel.java delete mode 100644 src/main/java/rife/bld/extension/dokka/OutputFormat.java delete mode 100644 src/main/java/rife/bld/extension/dokka/SourceSet.java delete mode 100644 src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java delete mode 100644 src/test/java/rife/bld/extension/dokka/SourceSetTest.java delete mode 100644 src/test/resources/dokka-args.txt delete mode 100644 src/test/resources/dokka-sourceset-args.txt diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index d897fcc..ceddff2 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -32,14 +32,6 @@ jobs: working-directory: examples run: ./bld compile test - - name: Build examples documentation - working-directory: examples - run: | - ./bld javadoc - ./bld dokka-html - ./bld dokka-gfm - ./bld dokka-jekyll - - name: Grant execute permission for bld run: chmod +x bld diff --git a/README.md b/README.md index c7801b6..8c1d080 100644 --- a/README.md +++ b/README.md @@ -33,31 +33,6 @@ public void compile() throws IOException { Please check the [Compile Operation documentation](https://rife2.github.io/bld-kotlin/rife/bld/extension/CompileKotlinOperation.html#method-summary) for all available configuration options. -## Generate Javadoc - -To generate the Javadoc using [Dokka](https://github.com/Kotlin/dokka): - -```java -@Override -public void javadoc() throws ExitStatusException, IOException, InterruptedException { - new DokkaOperation() - .fromProject(this) - .outputDir(new File(buildDirectory(), "javadoc")) - .outputFormat(OutputFormat.JAVADOC) - .execute(); -} -``` - -```console -./bld javadoc -``` - -- [View Examples Project](https://github.com/rife2/bld-kotlin/tree/main/examples/) - -Please check the [Dokka Operation documentation](https://rife2.github.io/bld-kotlin/rife/bld/extension/dokka/DokkaOperation.html#method-summary) -for all available configuration options. - ## Template Project -There is also a [Template Project](https://github.com/rife2/kotlin-bld-example) with support for Dokka and the -[Detekt](https://github.com/rife2/bld-detekt) extensions. +There is also a [Template Project](https://github.com/rife2/kotlin-bld-example) with support for the [Dokka](https://github.com/rife2/bld-dokka) and [Detekt](https://github.com/rife2/bld-detekt) extensions. diff --git a/examples/README.md b/examples/README.md index 1dbc9fb..e5a785f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -16,12 +16,3 @@ ```console ./bld test ``` - -## Build the documentation with [Dokka](https://github.com/Kotlin/dokka) - -```console -./bld javadoc -./bld dokka-html -./bld dokka-gfm -./bld dokka-jekyll -``` diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 8c08ccc..edf4d9d 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,7 +1,7 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-kotlin:0.9.8 -bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= +bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.0-SNAPSHOT +bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= bld.version=1.9.1 diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 5cccf1a..51fc4c5 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -3,9 +3,6 @@ package com.example; import rife.bld.BuildCommand; import rife.bld.Project; import rife.bld.extension.CompileKotlinOperation; -import rife.bld.extension.dokka.DokkaOperation; -import rife.bld.extension.dokka.LoggingLevel; -import rife.bld.extension.dokka.OutputFormat; import rife.bld.operations.exceptions.ExitStatusException; import java.io.File; @@ -48,14 +45,14 @@ public class ExampleBuild extends Project { public static void main(String[] args) { // Enable detailed logging for the Kotlin extension - // var level = Level.ALL; - // var logger = Logger.getLogger("rife.bld.extension"); - // var consoleHandler = new ConsoleHandler(); - - // consoleHandler.setLevel(level); - // logger.addHandler(consoleHandler); - // logger.setLevel(level); - // logger.setUseParentHandlers(false); +// var level = Level.ALL; +// var logger = Logger.getLogger("rife.bld.extension"); +// var consoleHandler = new ConsoleHandler(); +// +// consoleHandler.setLevel(level); +// logger.addHandler(consoleHandler); +// logger.setLevel(level); +// logger.setUseParentHandlers(false); new ExampleBuild().start(args); } @@ -72,50 +69,4 @@ public class ExampleBuild extends Project { // op.compileOptions().verbose(true); // op.execute(); } - - @BuildCommand(value = "dokka-gfm", summary = "Generates documentation in GitHub flavored markdown format") - public void dokkaGfm() throws ExitStatusException, IOException, InterruptedException { - new DokkaOperation() - .fromProject(this) - .loggingLevel(LoggingLevel.INFO) - // Create build/dokka/gfm - .outputDir(Path.of(buildDirectory().getAbsolutePath(), "dokka", "gfm").toFile()) - .outputFormat(OutputFormat.MARKDOWN) - .execute(); - } - - @BuildCommand(value = "dokka-html", summary = "Generates documentation in HTML format") - public void dokkaHtml() throws ExitStatusException, IOException, InterruptedException { - new DokkaOperation() - .fromProject(this) - .loggingLevel(LoggingLevel.INFO) - // Create build/dokka/html - .outputDir(Path.of(buildDirectory().getAbsolutePath(), "dokka", "html").toFile()) - .outputFormat(OutputFormat.HTML) - .execute(); - } - - @BuildCommand(value = "dokka-jekyll", summary = "Generates documentation in Jekyll flavored markdown format") - public void dokkaJekyll() throws ExitStatusException, IOException, InterruptedException { - new DokkaOperation() - .fromProject(this) - .loggingLevel(LoggingLevel.INFO) - // Create build/dokka/jekyll - .outputDir(Path.of(buildDirectory().getAbsolutePath(), "dokka", "jekkyl").toFile()) - .outputFormat(OutputFormat.JEKYLL) - .execute(); - } - - @BuildCommand(summary = "Generates Javadoc for the project") - @Override - public void javadoc() throws ExitStatusException, IOException, InterruptedException { - new DokkaOperation() - .fromProject(this) - .failOnWarning(true) - .loggingLevel(LoggingLevel.INFO) - // Create build/javadoc - .outputDir(new File(buildDirectory(), "javadoc")) - .outputFormat(OutputFormat.JAVADOC) - .execute(); - } } diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index b50fe85..aea9055 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -1,8 +1,8 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.9 -bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.0 -bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_RELEASES bld.downloadLocation= +bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.0 +bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.0.1 +bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_RELEASES bld.sourceDirectories= bld.version=1.9.1 diff --git a/scripts/checkcliargs.sh b/scripts/checkcliargs.sh index aa2c55e..7855fdc 100755 --- a/scripts/checkcliargs.sh +++ b/scripts/checkcliargs.sh @@ -1,19 +1,5 @@ #!/bin/bash -main=org.jetbrains.dokka.MainKt -new=/tmp/checkcliargs-new -old=/tmp/checkcliargs-old - -java -cp "lib/compile/*" $main -h >$new -java -cp "examples/lib/bld/*" $main -h >$old - -diff $old $new - -java -cp "lib/compile/*" $main -sourceSet -h >$new -java -cp "examples/lib/bld/*" $main -sourceSet -h >$old - -diff $old $new - main=org.jetbrains.kotlin.cli.jvm.K2JVMCompiler java -cp "lib/compile/*" $main -h 2>$new diff --git a/scripts/cliargs.sh b/scripts/cliargs.sh index 9bceae4..ebc70f7 100755 --- a/scripts/cliargs.sh +++ b/scripts/cliargs.sh @@ -3,15 +3,3 @@ java -cp "lib/compile/*" org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -h 2> >(grep "^ ") |\ sed -e "s/^ //" -e "s/ .*//" -e "s/<.*//" -e '/-help/d' -e '/-version/d' -e '/^$/d'|\ sort > "src/test/resources/kotlinc-args.txt" - -main=org.jetbrains.dokka.MainKt - -java -cp "lib/compile/*" $main -h |\ -grep " -" |\ -sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' |\ -sort > "src/test/resources/dokka-args.txt" - -java -cp "lib/compile/*" $main -sourceSet -h |\ -grep " -" |\ -sed -e "s/^ -/-/" -e "s/ \[.*//" -e "s/ ->.*//" -e '/help/d' -e '/includeNonPublic/d' |\ -sort > "src/test/resources/dokka-sourceset-args.txt" diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 7d2e9b2..a93cbf1 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -33,7 +33,7 @@ public class CompileKotlinOperationBuild extends Project { public CompileKotlinOperationBuild() { pkg = "rife.bld.extension"; name = "bld-kotlin"; - version = version(0, 9, 8); + version = version(1, 0, 0, "SNAPSHOT"); javaRelease = 17; @@ -41,18 +41,22 @@ public class CompileKotlinOperationBuild extends Project { autoDownloadPurge = true; repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); - var dokka = version(1, 9, 20); var kotlin = version(2, 0, 0); scope(compile) .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-annotation-processing", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-scripting-compiler", kotlin)) - .include(dependency("org.jetbrains.dokka", "dokka-cli", dokka)) - .include(dependency("org.jetbrains.dokka", "dokka-base", dokka)) - .include(dependency("org.jetbrains.dokka", "analysis-kotlin-descriptors", dokka)) - .include(dependency("org.jetbrains.dokka", "javadoc-plugin", dokka)) - .include(dependency("org.jetbrains.dokka", "gfm-plugin", dokka)) - .include(dependency("org.jetbrains.dokka", "jekyll-plugin", dokka)) + .include(dependency("org.jetbrains.kotlin", "kotlin-reflect", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin)) + .include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm", version(1, 9, 0 , "RC"))) +// .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-assignment-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-serialization-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-lombok-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-noarg-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-power-assert-compiler-plugin", kotlin)) +// .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1))); scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) diff --git a/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java b/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java deleted file mode 100644 index dd6ff1a..0000000 --- a/src/main/java/rife/bld/extension/dokka/AnalysisPlatform.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 deleted file mode 100644 index dae65a4..0000000 --- a/src/main/java/rife/bld/extension/dokka/DocumentedVisibility.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 deleted file mode 100644 index 56d2661..0000000 --- a/src/main/java/rife/bld/extension/dokka/DokkaOperation.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * 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 Collection pluginsClasspath_ = new ArrayList<>(); - private final Map pluginsConfiguration_ = new ConcurrentHashMap<>(); - private boolean delayTemplateSubstitution_; - private boolean failOnWarning_; - private File json; - 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_; - - // Encodes to JSON adding braces as needed - private static String encodeJson(final String json) { - var sb = new StringBuilder(json); - if (!json.startsWith("{") || !json.endsWith("}")) { - sb.insert(0, "{").append('}'); - } - return StringUtils.encodeJson(sb.toString()); - } - - /** - * 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"); - } - - // -failOnWarning - if (failOnWarning_) { - args.add("-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"); - } - - // -offlineMode - if (offlineMode_) { - args.add("-offlineMode"); - } - - // -pluginConfiguration - if (!pluginsConfiguration_.isEmpty()) { - args.add("-pluginsConfiguration"); - var confs = new ArrayList(); - pluginsConfiguration_.forEach((k, v) -> - confs.add(String.format("%s=%s", encodeJson(k), encodeJson(v)))); - args.add(String.join("^^", confs)); - } - - // -suppressInheritedMembers - if (suppressInheritedMembers_) { - args.add("-suppressInheritedMembers"); - } - - // json - if (json != null) { - args.add(json.getAbsolutePath()); - } - - 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}, {@link #moduleName moduleName} - * and {@link SourceSet#classpath(String...) classpath} 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()) - .classpath(project.compileClasspathJars()) - .classpath(project.providedClasspathJars()); - 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) { - Collections.addAll(globalPackageOptions_, 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) { - Collections.addAll(globalSrcLinks_, 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) { - Collections.addAll(includes_, 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; - } - - /** - * JSON configuration file path. - * - * @param configuration the configuration file path - */ - public DokkaOperation json(File configuration) { - json = configuration; - 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. - *

- * The directory to where documentation is generated, regardless of output format. - * - * @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 pluginConfigurations(String name, String jsonConfiguration) { - pluginsConfiguration_.put(name, jsonConfiguration); - return this; - } - - /** - * Sets the configuration for Dokka plugins. - * - * @param pluginConfiguratione the map of configurations - * @return this operation instance - * @see #pluginConfigurations(String, String) - */ - public DokkaOperation pluginConfigurations(Map pluginConfiguratione) { - pluginsConfiguration_.putAll(pluginConfiguratione); - 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) { - Collections.addAll(pluginsClasspath_, 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 deleted file mode 100644 index b493e11..0000000 --- a/src/main/java/rife/bld/extension/dokka/LoggingLevel.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0d4a2c0..0000000 --- a/src/main/java/rife/bld/extension/dokka/OutputFormat.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 deleted file mode 100644 index e9457b5..0000000 --- a/src/main/java/rife/bld/extension/dokka/SourceSet.java +++ /dev/null @@ -1,680 +0,0 @@ -/* - * 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.io.File; -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 String 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; - } - - /** - * Sets the Kotlin API version used for setting up analysis and samples. - * - * @param apiVersion the api version - * @return this operation instance - */ - public SourceSet apiVersion(int apiVersion) { - apiVersion_ = String.valueOf(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_ != null) { - args.add("-jdkVersion"); - args.add(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 files one or more file - * @return this operation instance - */ - public SourceSet classpath(String... files) { - Collections.addAll(classpath_, files); - 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 files the list of files - * @return this operation instance - */ - public SourceSet classpath(Collection files) { - classpath_.addAll(files); - 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 files the list of files - * @return this operation instance - */ - public SourceSet classpath(List files) { - files.forEach(it -> classpath_.add(it.getAbsolutePath())); - 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) { - Collections.addAll(includes_, 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(String jdkVersion) { - jdkVersion_ = jdkVersion; - 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_ = String.valueOf(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 the language version used for setting up analysis and samples. - * - * @param languageVersion the language version - * @return this operation instance - */ - public SourceSet languageVersion(int languageVersion) { - languageVersion_ = String.valueOf(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) { - Collections.addAll(perPackageOptions_, 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) { - Collections.addAll(samples_, 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) { - Collections.addAll(src_, 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/test/java/rife/bld/extension/dokka/DokkaOperationTest.java b/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java deleted file mode 100644 index 0e089ee..0000000 --- a/src/test/java/rife/bld/extension/dokka/DokkaOperationTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -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() throws IOException { - var args = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-args.txt")); - - assertThat(args).isNotEmpty(); - - var examples = new File("examples"); - var jsonConf = new File("config.json"); - var params = new DokkaOperation() - .delayTemplateSubstitution(true) - .failOnWarning(true) - .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") - .includes(List.of("file3", "file4")) - .json(jsonConf) - .loggingLevel(LoggingLevel.DEBUG) - .moduleName("name") - .moduleVersion("1.0") - .noSuppressObviousFunctions(true) - .offlineMode(true) - .outputDir(new File(examples, "build")) - .outputFormat(OutputFormat.JAVADOC) - .pluginConfigurations("name", "{\"json\"}") - .pluginConfigurations(Map.of("{\"name2\"}", "json2", "name3}", "{json3")) - .pluginsClasspath("path1", "path2") - .pluginsClasspath(List.of("path3", "path4")) - .sourceSet(new SourceSet().classpath( - List.of( - new File("examples/foo.jar"), - new File("examples/bar.jar") - ))) - .suppressInheritedMembers(true) - .executeConstructProcessCommandList(); - - for (var p : args) { - var found = false; - for (var a : params) { - if (a.startsWith(p)) { - found = true; - break; - } - } - assertThat(found).as(p + " not found.").isTrue(); - } - - var path = examples.getAbsolutePath(); - var dokkaJar = "1.9.20.jar"; - var matches = List.of("java", - "-jar", path + "/lib/bld/dokka-cli-" + dokkaJar, - "-pluginsClasspath", path + "/lib/bld/dokka-base-" + dokkaJar + ';' + - path + "/lib/bld/analysis-kotlin-descriptors-" + dokkaJar + ';' + - path + "/lib/bld/javadoc-plugin-" + dokkaJar + ';' + - path + "/lib/bld/korte-jvm-4.0.10.jar;" + - path + "/lib/bld/kotlin-as-java-plugin-" + dokkaJar + ";path1;path2;path3;path4", - "-sourceSet", "-src " + path + "/src/main/kotlin" + " -classpath " + path + "/foo.jar;" + path + "/bar.jar", - "-outputDir", path + "/build", - "-delayTemplateSubstitution", - "-failOnWarning", - "-globalLinks", "s^link^^s2^link2", - "-globalPackageOptions", "option1;option2;option3;option4", - "-globalSrcLinks_", "link1;link2;link3;link4", - "-includes", "file1;file2;file3;file4", - "-loggingLevel", "debug", - "-moduleName", "name", - "-moduleVersion", "1.0", - "-noSuppressObviousFunctions", - "-offlineMode", - "-pluginsConfiguration", "{\\\"name2\\\"}={json2}^^{name}={\\\"json\\\"}^^{name3}}={{json3}", - "-suppressInheritedMembers", - jsonConf.getAbsolutePath()); - - assertThat(params).hasSize(matches.size()); - - IntStream.range(0, params.size()).forEach(i -> { - if (params.get(i).contains(".jar;")) { - var jars = params.get(i).split(";"); - Arrays.stream(jars).forEach(jar -> assertThat(matches.get(i)).as(matches.get(i)).contains(jar)); - } else { - assertThat(params.get(i)).as(params.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 deleted file mode 100644 index b503335..0000000 --- a/src/test/java/rife/bld/extension/dokka/SourceSetTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -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() throws IOException { - var args = Files.readAllLines(Paths.get("src", "test", "resources", "dokka-sourceset-args.txt")); - - assertThat(args).isNotEmpty(); - - var sourceSet = new SourceSet() - .analysisPlatform(AnalysisPlatform.JVM) - .apiVersion("1.0") - .classpath("classpath1", "classpath2") - .dependentSourceSets("moduleName", "sourceSetName") - .displayName("name") - .documentedVisibilities(DocumentedVisibility.PACKAGE, DocumentedVisibility.PRIVATE) - .externalDocumentationLinks("url1", "packageListUrl1") - .externalDocumentationLinks("url2", "packageListUrl2") - .includes("includes1", "includes2") - .jdkVersion(18) - .languageVersion("2.0") - .noJdkLink(true) - .noSkipEmptyPackages(true) - .noStdlibLink(true) - .perPackageOptions("options1", "options2") - .reportUndocumented(true) - .samples("samples1", "sample2") - .skipDeprecated(true) - .sourceSetName("setName") - .src("src1", "src2") - .srcLink("path1", "remote1", "#suffix1") - .srcLink("path2", "remote2", "#suffix2") - .suppressedFiles("sup1", "sup2"); - - var params = sourceSet.args(); - - for (var p : args) { - var found = false; - for (var a : params) { - if (a.startsWith(p)) { - found = true; - break; - } - } - assertThat(found).as(p + " not found.").isTrue(); - } - - 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(params).hasSize(matches.size()); - - IntStream.range(0, params.size()).forEach(i -> assertThat(params.get(i)).isEqualTo(matches.get(i))); - - sourceSet.classpath(List.of("classpath1", "classpath2")); - - IntStream.range(0, params.size()).forEach(i -> assertThat(params.get(i)).isEqualTo(matches.get(i))); - } -} diff --git a/src/test/resources/dokka-args.txt b/src/test/resources/dokka-args.txt deleted file mode 100644 index 4c9f29c..0000000 --- a/src/test/resources/dokka-args.txt +++ /dev/null @@ -1,16 +0,0 @@ --delayTemplateSubstitution --failOnWarning --globalLinks --globalPackageOptions --globalSrcLink --includes --loggingLevel --moduleName --moduleVersion --noSuppressObviousFunctions --offlineMode --outputDir --pluginsClasspath --pluginsConfiguration --sourceSet --suppressInheritedMembers diff --git a/src/test/resources/dokka-sourceset-args.txt b/src/test/resources/dokka-sourceset-args.txt deleted file mode 100644 index 0699eb7..0000000 --- a/src/test/resources/dokka-sourceset-args.txt +++ /dev/null @@ -1,21 +0,0 @@ --analysisPlatform --apiVersion --classpath --dependentSourceSets --displayName --documentedVisibilities --externalDocumentationLinks --includes --jdkVersion --languageVersion --noJdkLink --noSkipEmptyPackages --noStdlibLink --perPackageOptions --reportUndocumented --samples --skipDeprecated --sourceSetName --src --srcLink --suppressedFiles From dcc68afdf3eed90848a219e228542826e7f6eb3d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sat, 15 Jun 2024 21:32:53 -0700 Subject: [PATCH 032/126] Removed unavailable compiler plugins --- src/main/java/rife/bld/extension/CompileKotlinPlugin.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java index 47264b3..16c0424 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java +++ b/src/main/java/rife/bld/extension/CompileKotlinPlugin.java @@ -25,9 +25,7 @@ package rife.bld.extension; 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-.*$"), POWER_ASSERT("^power-assert-compiler-plugin-.*$"), From 41e60f606a7e6a3c8ff8a4493e4914c594b2c885 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:04:44 -0700 Subject: [PATCH 033/126] Configure the main and test source directories from the project --- .../rife/bld/extension/CompileKotlinOperation.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index 6576aac..f8ce05e 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -364,12 +364,12 @@ public class CompileKotlinOperation extends AbstractOperation{@link #buildTestDirectory() buildTestDirectory} *

  • {@link #compileMainClasspath() compileMainClassPath}
  • *
  • {@link #compileTestClasspath() compilesTestClassPath}
  • - *
  • {@link #mainSourceFiles() mainSourceFiles} to the {@code kotlin} directory in + *
  • {@link #mainSourceDirectories()} () mainSourceDirectories} to the {@code kotlin} directory in * {@link BaseProject#srcMainDirectory() srcMainDirectory}
  • - *
  • {@link #testSourceFiles() testSourceFile} to the {@code kotlin} directory in + *
  • {@link #testSourceDirectories() testSourceDirectories} to the {@code kotlin} directory in * {@link BaseProject#srcTestDirectory() srcTestDirectory}
  • - *
  • {@link CompileKotlinOptions#jdkRelease jdkRelease} to {@link BaseProject#javaRelease() javaRelease}
  • - *
  • {@link CompileKotlinOptions#noStdLib(boolean) noStdLib} to {@code true}
  • + *
  • {@link CompileOptions#jdkRelease jdkRelease} to {@link BaseProject#javaRelease() javaRelease}
  • + *
  • {@link CompileOptions#noStdLib(boolean) noStdLib} to {@code true}
  • * * * @param project the project to configure the compile operation from @@ -381,8 +381,8 @@ public class CompileKotlinOperation extends AbstractOperation Date: Wed, 19 Jun 2024 08:07:19 -0700 Subject: [PATCH 034/126] Add compiler plugins to the dependencies --- .../CompileKotlinOperationBuild.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index a93cbf1..fa05161 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -48,15 +48,16 @@ public class CompileKotlinOperationBuild extends Project { .include(dependency("org.jetbrains.kotlin", "kotlin-scripting-compiler", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-reflect", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin)) - .include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm", version(1, 9, 0 , "RC"))) -// .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-assignment-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-serialization-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-lombok-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-noarg-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-power-assert-compiler-plugin", kotlin)) -// .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm", version(1, 9, 0, "RC"))) + // Compiler Plugins + .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-assignment-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-serialization-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-lombok-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-noarg-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-power-assert-compiler-plugin", kotlin)) + .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1))); scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) From 19d662a81f0e3bf7c19054146926e3f40a1b2e7a Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:09:52 -0700 Subject: [PATCH 035/126] Enable extension logging --- .../src/bld/java/com/example/ExampleBuild.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 51fc4c5..352cb20 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -3,11 +3,9 @@ package com.example; import rife.bld.BuildCommand; import rife.bld.Project; import rife.bld.extension.CompileKotlinOperation; -import rife.bld.operations.exceptions.ExitStatusException; import java.io.File; import java.io.IOException; -import java.nio.file.Path; import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; @@ -45,14 +43,14 @@ public class ExampleBuild extends Project { public static void main(String[] args) { // Enable detailed logging for the Kotlin extension -// var level = Level.ALL; -// var logger = Logger.getLogger("rife.bld.extension"); -// var consoleHandler = new ConsoleHandler(); -// -// consoleHandler.setLevel(level); -// logger.addHandler(consoleHandler); -// logger.setLevel(level); -// logger.setUseParentHandlers(false); + var level = Level.ALL; + var logger = Logger.getLogger("rife.bld.extension"); + var consoleHandler = new ConsoleHandler(); + + consoleHandler.setLevel(level); + logger.addHandler(consoleHandler); + logger.setLevel(level); + logger.setUseParentHandlers(false); new ExampleBuild().start(args); } From c151a49935907eb134dfea4266be1155c1c9a6cf Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:10:21 -0700 Subject: [PATCH 036/126] Fixed license template --- .idea/copyright/Apache_License.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.idea/copyright/Apache_License.xml b/.idea/copyright/Apache_License.xml index ade80da..4446c15 100644 --- a/.idea/copyright/Apache_License.xml +++ b/.idea/copyright/Apache_License.xml @@ -1,6 +1,6 @@ - - + \ No newline at end of file From c5956327324f7649f83f89e1b4d52dc6443e0543 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:17:30 -0700 Subject: [PATCH 037/126] Clean up and moved compile options and plugins to sub-package --- .../CompileOptions.java} | 272 +++++++++++++----- .../CompilerPlugin.java} | 22 +- 2 files changed, 219 insertions(+), 75 deletions(-) rename src/main/java/rife/bld/extension/{CompileKotlinOptions.java => kotlin/CompileOptions.java} (68%) rename src/main/java/rife/bld/extension/{CompileKotlinPlugin.java => kotlin/CompilerPlugin.java} (63%) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOptions.java b/src/main/java/rife/bld/extension/kotlin/CompileOptions.java similarity index 68% rename from src/main/java/rife/bld/extension/CompileKotlinOptions.java rename to src/main/java/rife/bld/extension/kotlin/CompileOptions.java index 890f3c0..7703105 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOptions.java +++ b/src/main/java/rife/bld/extension/kotlin/CompileOptions.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package rife.bld.extension; +package rife.bld.extension.kotlin; + +import rife.bld.extension.CompileKotlinOperation; import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import static rife.bld.extension.CompileKotlinOperation.isNotBlank; @@ -30,30 +30,30 @@ import static rife.bld.extension.CompileKotlinOperation.isNotBlank; * @author Erik C. Thauvin * @since 1.0 */ -public class CompileKotlinOptions { - private final List advancedOptions_ = new ArrayList<>(); - private final List argFile_ = new ArrayList<>(); - private final List classpath_ = new ArrayList<>(); - private final List jvmOptions_ = new ArrayList<>(); - private final List optIn_ = new ArrayList<>(); - private final List options_ = new ArrayList<>(); - private final List plugin_ = new ArrayList<>(); - private final List scriptTemplates_ = new ArrayList<>(); +public class CompileOptions { + private final Collection advancedOptions_ = new ArrayList<>(); + private final Collection argFile_ = new ArrayList<>(); + private final Collection classpath_ = new ArrayList<>(); + private final Collection jvmOptions_ = 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 String jdkHome_; + private File jdkHome_; private String jdkRelease_; private String jvmTarget_; - private String kotlinHome_; + private File kotlinHome_; private String languageVersion_; private String moduleName_; private boolean noJdk_; private boolean noReflect_; private boolean noStdLib_; private boolean noWarn_; - private String path_; + private File path_; private boolean progressive_; private boolean verbose_; private boolean wError_; @@ -64,7 +64,7 @@ public class CompileKotlinOptions { * @param options one or more advanced options * @return this operation instance */ - public CompileKotlinOptions advancedOptions(String... options) { + public CompileOptions advancedOptions(String... options) { Collections.addAll(advancedOptions_, options); return this; } @@ -75,18 +75,27 @@ public class CompileKotlinOptions { * @param options list of compiler options * @return this operation instance */ - public CompileKotlinOptions advancedOptions(Collection options) { + public CompileOptions advancedOptions(Collection options) { advancedOptions_.addAll(options); return this; } + /** + * Retrieves advanced compiler options. + * + * @return the advanced compiler options + */ + public Collection advancedOptions() { + return advancedOptions_; + } + /** * Allow using declarations only from the specified version of Kotlin bundled libraries. * * @param version the api version * @return this operation instance */ - public CompileKotlinOptions apiVersion(String version) { + public CompileOptions apiVersion(String version) { apiVersion_ = version; return this; } @@ -97,7 +106,7 @@ public class CompileKotlinOptions { * @param version the api version * @return this operation instance */ - public CompileKotlinOptions apiVersion(int version) { + public CompileOptions apiVersion(int version) { apiVersion_ = String.valueOf(version); return this; } @@ -120,11 +129,37 @@ public class CompileKotlinOptions { * @param files one or more files * @return this operation instance */ - public CompileKotlinOptions argFile(String... files) { + public CompileOptions argFile(String... files) { + Collections.addAll(argFile_, Arrays.stream(files) + .map(File::new) + .toArray(File[]::new)); + 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 + */ + public CompileOptions argFile(File... files) { Collections.addAll(argFile_, files); return this; } + /** * Read the compiler options from the given files. * @@ -132,11 +167,20 @@ public class CompileKotlinOptions { * @return this operation instance * @see #argFile(String...) */ - public CompileKotlinOptions argFile(Collection files) { + public CompileOptions argFile(Collection files) { argFile_.addAll(files); return this; } + /** + * Retrieves the files containing compiler options. + * + * @return the list of files + */ + public Collection argFile() { + return argFile_; + } + /** * Returns the formatted arguments. * @@ -153,13 +197,13 @@ public class CompileKotlinOptions { // @argfile if (!argFile_.isEmpty()) { - argFile_.forEach(f -> args.add("@" + f)); + argFile_.forEach(f -> args.add("@" + f.getAbsolutePath())); } // classpath if (!classpath_.isEmpty()) { args.add("-classpath"); - args.add(String.join(File.pathSeparator, classpath_)); + args.add(classpath_.stream().map(File::getAbsolutePath).collect(Collectors.joining(File.pathSeparator))); } // expression @@ -185,9 +229,9 @@ public class CompileKotlinOptions { } // jdk-home - if (isNotBlank(jdkHome_)) { + if (jdkHome_ != null) { args.add("-jdk-home"); - args.add(jdkHome_); + args.add(jdkHome_.getAbsolutePath()); } // jdk-release @@ -201,9 +245,9 @@ public class CompileKotlinOptions { } // kotlin-home - if (isNotBlank(kotlinHome_)) { + if (kotlinHome_ != null) { args.add("-kotlin-home"); - args.add(kotlinHome_); + args.add(kotlinHome_.getAbsolutePath()); } // language-version @@ -250,9 +294,9 @@ public class CompileKotlinOptions { } // path - if (isNotBlank(path_)) { + if (path_ != null) { args.add("-d"); - args.add(path_); + args.add(path_.getAbsolutePath()); } // plugin @@ -298,7 +342,22 @@ public class CompileKotlinOptions { * @param paths one pr more paths * @return this operation instance */ - public CompileKotlinOptions classpath(String... paths) { + public CompileOptions classpath(String... paths) { + Collections.addAll(classpath_, Arrays.stream(paths) + .map(File::new) + .toArray(File[]::new)); + return this; + } + + /** + * 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 + */ + public CompileOptions classpath(File... paths) { Collections.addAll(classpath_, paths); return this; } @@ -311,18 +370,27 @@ public class CompileKotlinOptions { * @param paths the list of paths * @return this operation instance */ - public CompileKotlinOptions classpath(Collection paths) { + public CompileOptions classpath(Collection paths) { classpath_.addAll(paths); return this; } + /** + * Retrieves the class files classpath. + * + * @return the list of classpath + */ + public Collection classpath() { + return classpath_; + } + /** * Evaluate the given string as a Kotlin script. * * @param expression the expression * @return this operation instance */ - public CompileKotlinOptions expression(String expression) { + public CompileOptions expression(String expression) { expression_ = expression; return this; } @@ -343,18 +411,27 @@ public class CompileKotlinOptions { * @param includeRuntime {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions includeRuntime(boolean includeRuntime) { + public CompileOptions includeRuntime(boolean includeRuntime) { includeRuntime_ = includeRuntime; return this; } + /** + * Indicates whether {@link #verbose(boolean)} was set. + * + * @return {@code true} if verbose was set; or {@code false} otherwise + */ + public boolean isVerbose() { + return verbose_; + } + /** * 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) { + public CompileOptions javaParameters(boolean javaParameters) { javaParameters_ = javaParameters; return this; } @@ -365,7 +442,18 @@ public class CompileKotlinOptions { * @param jdkHome the JDK home path * @return this operation instance */ - public CompileKotlinOptions jdkHome(String jdkHome) { + public CompileOptions jdkHome(String jdkHome) { + jdkHome_ = new File(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(File jdkHome) { jdkHome_ = jdkHome; return this; } @@ -381,7 +469,7 @@ public class CompileKotlinOptions { * @param version the target version * @return this operation instance */ - public CompileKotlinOptions jdkRelease(String version) { + public CompileOptions jdkRelease(String version) { jdkRelease_ = version; return this; } @@ -393,7 +481,7 @@ public class CompileKotlinOptions { * @return this operation instance * @see #jdkRelease(String) */ - public CompileKotlinOptions jdkRelease(int version) { + public CompileOptions jdkRelease(int version) { jdkRelease_ = String.valueOf(version); return this; } @@ -404,18 +492,27 @@ public class CompileKotlinOptions { * @param jvmOptions one or more JVM option * @return this operation instance */ - public CompileKotlinOptions jvmOptions(String... jvmOptions) { + public CompileOptions jvmOptions(String... jvmOptions) { Collections.addAll(jvmOptions_, jvmOptions); return this; } + /** + * Retrieves the JVM options. + * + * @return the list of options + */ + public Collection jvmOptions() { + return jvmOptions_; + } + /** * Pass an option directly to JVM * * @param jvmOptions the list JVM options * @return this operation instance */ - public CompileKotlinOptions jvmOptions(Collection jvmOptions) { + public CompileOptions jvmOptions(Collection jvmOptions) { jvmOptions_.addAll(jvmOptions); return this; } @@ -428,7 +525,7 @@ public class CompileKotlinOptions { * @param target the target version * @return this operation instance */ - public CompileKotlinOptions jvmTarget(String target) { + public CompileOptions jvmTarget(String target) { jvmTarget_ = target; return this; } @@ -440,7 +537,7 @@ public class CompileKotlinOptions { * @return this operation instance * @see #jvmTarget(String) */ - public CompileKotlinOptions jvmTarget(int target) { + public CompileOptions jvmTarget(int target) { jvmTarget_ = String.valueOf(target); return this; } @@ -451,18 +548,29 @@ public class CompileKotlinOptions { * @param path the Kotlin home path * @return this operation instance */ - public CompileKotlinOptions kotlinHome(String path) { + public CompileOptions kotlinHome(File path) { kotlinHome_ = path; 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 CompileOptions kotlinHome(String path) { + kotlinHome_ = new File(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) { + public CompileOptions languageVersion(String version) { languageVersion_ = version; return this; } @@ -473,7 +581,7 @@ public class CompileKotlinOptions { * @param name the module name * @return this operation instance */ - public CompileKotlinOptions moduleName(String name) { + public CompileOptions moduleName(String name) { moduleName_ = name; return this; } @@ -484,7 +592,7 @@ public class CompileKotlinOptions { * @param noJdk {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions noJdk(boolean noJdk) { + public CompileOptions noJdk(boolean noJdk) { noJdk_ = noJdk; return this; } @@ -495,7 +603,7 @@ public class CompileKotlinOptions { * @param noReflect {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions noReflect(boolean noReflect) { + public CompileOptions noReflect(boolean noReflect) { noReflect_ = noReflect; return this; } @@ -507,7 +615,7 @@ public class CompileKotlinOptions { * @param noStdLib {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions noStdLib(boolean noStdLib) { + public CompileOptions noStdLib(boolean noStdLib) { noStdLib_ = noStdLib; return this; } @@ -518,7 +626,7 @@ public class CompileKotlinOptions { * @param noWarn {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions noWarn(boolean noWarn) { + public CompileOptions noWarn(boolean noWarn) { noWarn_ = noWarn; return this; } @@ -529,18 +637,27 @@ public class CompileKotlinOptions { * @param annotations one or more annotation names * @return this operation instance */ - public CompileKotlinOptions optIn(String... annotations) { + public CompileOptions optIn(String... annotations) { Collections.addAll(optIn_, annotations); return this; } + /** + * Retrieves the opt-in fully qualified names. + * + * @return the list of 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 list of annotation names * @return this operation instance */ - public CompileKotlinOptions optIn(Collection annotations) { + public CompileOptions optIn(Collection annotations) { optIn_.addAll(annotations); return this; } @@ -551,18 +668,27 @@ public class CompileKotlinOptions { * @param options one or more compiler options * @return this operation instance */ - public CompileKotlinOptions options(String... options) { + public CompileOptions options(String... options) { Collections.addAll(options_, options); return this; } + /** + * Retrieves additional compiler options. + * + * @return the list of options + */ + public Collection options() { + return options_; + } + /** * Specify additional compiler options. * * @param options list of compiler options * @return this operation instance */ - public CompileKotlinOptions options(Collection options) { + public CompileOptions options(Collection options) { options_.addAll(options); return this; } @@ -575,8 +701,8 @@ public class CompileKotlinOptions { * @param path the location path * @return this operation instance */ - public CompileKotlinOptions path(File path) { - path_ = path.getAbsolutePath(); + public CompileOptions path(File path) { + path_ = path; return this; } @@ -588,8 +714,8 @@ public class CompileKotlinOptions { * @param path the location path * @return this operation instance */ - public CompileKotlinOptions path(String path) { - path_ = path; + public CompileOptions path(String path) { + path_ = new File(path); return this; } @@ -601,18 +727,27 @@ public class CompileKotlinOptions { * @param value the plugin option value * @return this operation instance */ - public CompileKotlinOptions plugin(String id, String optionName, String value) { + public CompileOptions plugin(String id, String optionName, String value) { plugin_.add(id + ':' + optionName + ':' + value); return this; } + /** + * Retrieves the plugin options. + * + * @return the list ofoptions. + */ + 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 CompileKotlinOptions progressive(boolean progressive) { + public CompileOptions progressive(boolean progressive) { progressive_ = progressive; return this; } @@ -625,11 +760,20 @@ public class CompileKotlinOptions { * @param classNames one or more class names * @return this operation instance */ - public CompileKotlinOptions scriptTemplates(String... classNames) { + public CompileOptions scriptTemplates(String... classNames) { Collections.addAll(scriptTemplates_, classNames); return this; } + /** + * Retrieves the script templates. + * + * @return the list of templates. + */ + public Collection scriptTemplates() { + return scriptTemplates_; + } + /** * Script definition template classes. *

    @@ -638,7 +782,7 @@ public class CompileKotlinOptions { * @param classNames the list class names * @return this operation instance */ - public CompileKotlinOptions scriptTemplates(Collection classNames) { + public CompileOptions scriptTemplates(Collection classNames) { scriptTemplates_.addAll(classNames); return this; } @@ -649,7 +793,7 @@ public class CompileKotlinOptions { * @param verbose {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions verbose(boolean verbose) { + public CompileOptions verbose(boolean verbose) { verbose_ = verbose; return this; } @@ -660,7 +804,7 @@ public class CompileKotlinOptions { * @param wError {@code true} or {@code false} * @return this operation instance */ - public CompileKotlinOptions wError(boolean wError) { + public CompileOptions 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/kotlin/CompilerPlugin.java similarity index 63% rename from src/main/java/rife/bld/extension/CompileKotlinPlugin.java rename to src/main/java/rife/bld/extension/kotlin/CompilerPlugin.java index 16c0424..7a3d94e 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinPlugin.java +++ b/src/main/java/rife/bld/extension/kotlin/CompilerPlugin.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package rife.bld.extension; +package rife.bld.extension.kotlin; /** * Defines the known Kotlin compiler plugins match (regex) strings. @@ -22,18 +22,18 @@ package rife.bld.extension; * @author Erik C. Thauvin * @since 1.0 */ -public enum CompileKotlinPlugin { - ALL_OPEN("^allopen-compiler-plugin-.*$"), - ASSIGNMENT("^assignment-compiler-plugin-.*$"), +public enum CompilerPlugin { + ALL_OPEN("^kotlin-allopen-compiler-plugin-.*$"), + ASSIGNMENT("^kotlin-assignment-compiler-plugin-.*$"), KOTLIN_SERIALIZATION("^kotlin-serialization-compiler-plugin-.*$"), - LOMBOK("^lombok-compiler-plugin-.*$"), - NOARG("^noarg-compiler-plugin-.*$"), - POWER_ASSERT("^power-assert-compiler-plugin-.*$"), - SAM_WITH_RECEIVER("^sam-with-receiver-compiler-plugin-.*$"); + LOMBOK("^kotlin-lombok-compiler-plugin-.*$"), + NOARG("^kotlin-noarg-compiler-plugin-.*$"), + POWER_ASSERT("^kotlin-power-assert-compiler-plugin-.*$"), + SAM_WITH_RECEIVER("^kotlin-sam-with-receiver-compiler-plugin-.*$"); - public final String label; + public final String regex; - CompileKotlinPlugin(String label) { - this.label = label; + CompilerPlugin(String regex) { + this.regex = regex; } } From c54672a7a0bf1987499ad9672f752fb4c609172d Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:18:32 -0700 Subject: [PATCH 038/126] Add string array parameters to overloaded methods where applicable --- .../bld/extension/CompileKotlinOperation.java | 150 ++++++++++++------ 1 file changed, 99 insertions(+), 51 deletions(-) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index f8ce05e..cc28873 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -18,6 +18,8 @@ package rife.bld.extension; import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import rife.bld.BaseProject; +import rife.bld.extension.kotlin.CompileOptions; +import rife.bld.extension.kotlin.CompilerPlugin; import rife.bld.operations.AbstractOperation; import rife.tools.FileUtils; @@ -26,7 +28,6 @@ import java.io.IOException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; /** * Compiles main and test Kotlin sources in the relevant build directories. @@ -35,10 +36,6 @@ import java.util.regex.Pattern; * @since 1.0 */ public class CompileKotlinOperation extends AbstractOperation { - /** - * The Kotlin file (.kt) pattern. - */ - public static final Pattern KOTLIN_FILE_PATTERN = Pattern.compile("^.*\\.kt$"); private static final Logger LOGGER = Logger.getLogger(CompileKotlinOperation.class.getName()); private final Collection compileMainClasspath_ = new ArrayList<>(); private final Collection compileTestClasspath_ = new ArrayList<>(); @@ -49,7 +46,7 @@ public class CompileKotlinOperation extends AbstractOperation testSourceFiles_ = new ArrayList<>(); private File buildMainDirectory_; private File buildTestDirectory_; - private CompileKotlinOptions compileOptions_ = new CompileKotlinOptions(); + private CompileOptions compileOptions_ = new CompileOptions(); private BaseProject project_; /** @@ -77,26 +74,6 @@ public class CompileKotlinOperation extends AbstractOperation getKotlinFileList(File directory) { - if (directory == null) { - return Collections.emptyList(); - } else if (!directory.exists()) { - if (LOGGER.isLoggable(Level.WARNING)) { - LOGGER.warning("Directory not found: " + directory.getAbsolutePath()); - } - return Collections.emptyList(); - } else { - return FileUtils.getFileList(directory, KOTLIN_FILE_PATTERN, null).stream().map((file) -> - new File(directory, file)).toList(); - } - } - /** * Determines if the given string is not blank. * @@ -121,7 +98,7 @@ public class CompileKotlinOperation extends AbstractOperation compileMainClasspath() { return compileMainClasspath_; @@ -181,9 +158,9 @@ public class CompileKotlinOperation extends AbstractOperation compileTestClasspath() { return compileTestClasspath_; @@ -317,7 +294,7 @@ public class CompileKotlinOperation extends AbstractOperation mainSourceDirectories() { return mainSourceDirectories_; @@ -433,6 +423,19 @@ public class CompileKotlinOperation extends AbstractOperation mainSourceFiles() { return mainSourceFiles_; @@ -464,6 +467,15 @@ public class CompileKotlinOperation extends AbstractOperation plugins() { + return plugins_; + } + /** * Provides compiler plugins. * @@ -482,9 +494,22 @@ public class CompileKotlinOperation extends AbstractOperation jars, CompileKotlinPlugin... plugins) { + public CompileKotlinOperation plugins(Collection jars, CompilerPlugin... plugins) { jars.forEach(jar -> { for (var plugin : plugins) { - if (jar.getName().matches(plugin.label)) { + if (jar.getName().matches(plugin.regex)) { plugins_.add(jar.getAbsolutePath()); break; } @@ -512,10 +537,7 @@ public class CompileKotlinOperation extends AbstractOperation sources(Collection files, Collection directories) { var sources = new ArrayList<>(files); - for (var directory : directories) { - sources.addAll(getKotlinFileList(directory)); - } - + sources.addAll(directories); return sources; } @@ -530,6 +552,19 @@ public class CompileKotlinOperation extends AbstractOperation testSourceDirectories() { return testSourceDirectories_; @@ -561,6 +596,19 @@ public class CompileKotlinOperation extends AbstractOperation new File[files.length])); + return this; + } + /** * Provides a list of test files that should be compiled. * @@ -573,9 +621,9 @@ public class CompileKotlinOperation extends AbstractOperation testSourceFiles() { return testSourceFiles_; From c901065b3a0a00e5b5e4f86940153bda32140909 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Jun 2024 08:19:34 -0700 Subject: [PATCH 039/126] Improved code and tests Bumped Exec extension to 1.0.1 Bumped PMD extension to 1.1.0 --- .idea/misc.xml | 11 ++ lib/bld/bld-wrapper.properties | 6 +- .../CompileKotlinOperationBuild.java | 1 + .../bld/extension/CompileKotlinOperation.java | 101 ++++++------ .../bld/extension/kotlin/CompileOptions.java | 59 ++++--- .../extension/CompileKotlinOperationTest.java | 46 ++++++ .../CompileOptionsTest.java} | 148 ++++++++++++------ 7 files changed, 235 insertions(+), 137 deletions(-) rename src/test/java/rife/bld/extension/{CompileKotlinOptionsTest.java => kotlin/CompileOptionsTest.java} (56%) diff --git a/.idea/misc.xml b/.idea/misc.xml index b386dc0..4e456d4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,18 @@ + + + + + + + + + + +

    * The classpath can contain file and directory paths, ZIP, or JAR files. * - * @param paths the list of paths + * @param paths the search paths * @return this operation instance */ public CompileOptions classpath(Collection paths) { @@ -378,7 +377,7 @@ public class CompileOptions { /** * Retrieves the class files classpath. * - * @return the list of classpath + * @return the class files classpath */ public Collection classpath() { return classpath_; @@ -493,23 +492,23 @@ public class CompileOptions { * @return this operation instance */ public CompileOptions jvmOptions(String... jvmOptions) { - Collections.addAll(jvmOptions_, jvmOptions); + jvmOptions_.addAll(List.of(jvmOptions)); return this; } /** - * Retrieves the JVM options. + * Retrieves the Java Virtual Machine options. * - * @return the list of options + * @return the JVM options */ public Collection jvmOptions() { return jvmOptions_; } /** - * Pass an option directly to JVM + * Pass an option directly to Java Virtual Machine * - * @param jvmOptions the list JVM options + * @param jvmOptions the JVM options * @return this operation instance */ public CompileOptions jvmOptions(Collection jvmOptions) { @@ -638,14 +637,14 @@ public class CompileOptions { * @return this operation instance */ public CompileOptions optIn(String... annotations) { - Collections.addAll(optIn_, annotations); + optIn_.addAll(List.of(annotations)); return this; } /** * Retrieves the opt-in fully qualified names. * - * @return the list of fully qualified names + * @return the fully qualified names */ public Collection optIn() { return optIn_; @@ -654,7 +653,7 @@ public class CompileOptions { /** * Enable usages of API that requires opt-in with a requirement annotation with the given fully qualified name. * - * @param annotations list of annotation names + * @param annotations the annotation names * @return this operation instance */ public CompileOptions optIn(Collection annotations) { @@ -669,14 +668,14 @@ public class CompileOptions { * @return this operation instance */ public CompileOptions options(String... options) { - Collections.addAll(options_, options); + options_.addAll(List.of(options)); return this; } /** * Retrieves additional compiler options. * - * @return the list of options + * @return the compiler options */ public Collection options() { return options_; @@ -685,7 +684,7 @@ public class CompileOptions { /** * Specify additional compiler options. * - * @param options list of compiler options + * @param options the compiler options * @return this operation instance */ public CompileOptions options(Collection options) { @@ -735,7 +734,7 @@ public class CompileOptions { /** * Retrieves the plugin options. * - * @return the list ofoptions. + * @return the plugin ofoptions. */ public Collection plugin() { return plugin_; @@ -761,14 +760,14 @@ public class CompileOptions { * @return this operation instance */ public CompileOptions scriptTemplates(String... classNames) { - Collections.addAll(scriptTemplates_, classNames); + scriptTemplates_.addAll(List.of(classNames)); return this; } /** * Retrieves the script templates. * - * @return the list of templates. + * @return the script templates. */ public Collection scriptTemplates() { return scriptTemplates_; @@ -779,7 +778,7 @@ public class CompileOptions { *

    * Use fully qualified class names. * - * @param classNames the list class names + * @param classNames the class names * @return this operation instance */ public CompileOptions scriptTemplates(Collection classNames) { diff --git a/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java b/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java index f64e6d3..45c8580 100644 --- a/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java +++ b/src/test/java/rife/bld/extension/CompileKotlinOperationTest.java @@ -18,7 +18,10 @@ package rife.bld.extension; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import rife.bld.Project; import rife.bld.blueprints.BaseProjectBlueprint; +import rife.bld.extension.kotlin.CompileOptions; +import rife.bld.extension.kotlin.CompilerPlugin; import rife.tools.FileUtils; import java.io.File; @@ -26,6 +29,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.logging.ConsoleHandler; @@ -46,6 +50,48 @@ class CompileKotlinOperationTest { logger.setUseParentHandlers(false); } + @Test + void testCollections() { + var op = new CompileKotlinOperation() + .fromProject(new Project()) + .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) + .plugins(new File("lib/compile"), CompilerPlugin.LOMBOK, CompilerPlugin.POWER_ASSERT) + .plugins(List.of("plugin3", "plugin4")) + .plugins(Arrays.stream(Objects.requireNonNull(new File("lib/compile").listFiles())).toList(), + CompilerPlugin.ALL_OPEN, CompilerPlugin.SAM_WITH_RECEIVER); + + assertThat(op.compileMainClasspath()).as("compileMainClassPath") + .containsAll(List.of("path1", "path2")); + assertThat(op.compileOptions().hasRelease()).as("hasRelease").isTrue(); + assertThat(op.compileOptions().isVerbose()).as("isVerbose").isTrue(); + assertThat(op.mainSourceDirectories()).as("mainSourceDirectories").containsExactly( + Path.of("src", "main", "kotlin").toFile().getAbsoluteFile(), new File("dir1"), + new File("dir2"), new File("dir3"), new File("dir4")); + assertThat(op.testSourceDirectories()).as("testSourceDirectories").containsOnly( + Path.of("src", "test", "kotlin").toFile().getAbsoluteFile(), new File("tdir1"), + new File("tdir2"), new File("tdir3"), new File("tdir4")); + assertThat(op.mainSourceFiles()).as("mainSourceFiles").containsOnly( + new File("file1"), new File("file2"), new File("file3"), + new File("file4"), new File("file5"), new File("file6")); + assertThat(op.testSourceFiles()).as("testSourceFiles").containsOnly( + new File("tfile1"), new File("tfile2"), new File("tfile3"), + new File("tfile4"), new File("tfile5"), new File("tfile6")); + assertThat(op.plugins()).hasSize(10); + } + @Test void testExecute() throws IOException { var tmpDir = Files.createTempDirectory("bld-kotlin").toFile(); diff --git a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java b/src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java similarity index 56% rename from src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java rename to src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java index 5c075fb..25df90b 100644 --- a/src/test/java/rife/bld/extension/CompileKotlinOptionsTest.java +++ b/src/test/java/rife/bld/extension/kotlin/CompileOptionsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package rife.bld.extension; +package rife.bld.extension.kotlin; import org.junit.jupiter.api.Test; @@ -23,61 +23,39 @@ import java.io.IOException; import java.nio.file.Files; 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 CompileKotlinOptionsTest { - @Test - void argsCollectionTest() { - var args = new CompileKotlinOptions() - .advancedOptions(List.of("Xoption1", "Xoption2")) - .argFile(List.of("arg1.txt", "arg2.txt")) - .classpath(List.of("path1", "path2")) - .jvmOptions(List.of("option1", "option2")) - .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", - "-Joption1", "-Joption2", - "-opt-in", "opt1", - "-opt-in", "opt2", - "-foo", "-bar", - "-script-templates", - "temp1,temp2", - "-XXoption1", "-XXoption2"); - - for (var arg : args) { - var found = false; - for (var match : matches) { - if (match.equals(arg)) { - found = true; - break; - } - } - assertThat(found).as(arg).isTrue(); - } +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 - void argsTest() { - var options = new CompileKotlinOptions() + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") + void testArgs() { + var options = new CompileOptions() .apiVersion("11") - .argFile("file.txt", "file2.txt") - .classpath("path1", "path2") + .argFile(new File("file.txt"), new File("file2.txt")) + .classpath(new File("path1"), new File("path2")) .javaParameters(true) .jvmTarget("11") .includeRuntime(true) - .jdkHome("path") + .jdkHome(new File("path")) .jdkRelease("11") - .kotlinHome("path") + .kotlinHome(new File("path")) .languageVersion("1.0") .moduleName("module") .noJdk(true) @@ -94,14 +72,14 @@ class CompileKotlinOptionsTest { var matches = List.of( "-api-version", "11", - "@file.txt", "@file2.txt", - "-classpath", "path1" + File.pathSeparator + "path2", + "@" + localPath("file.txt"), "@" + localPath("file2.txt"), + "-classpath", localPath("path1", "path2"), "-java-parameters", "-jvm-target", "11", "-include-runtime", - "-jdk-home", "path", + "-jdk-home", localPath("path"), "-Xjdk-release=11", - "-kotlin-home", "path", + "-kotlin-home", localPath("path"), "-language-version", "1.0", "-module-name", "module", "-no-jdk", @@ -111,7 +89,7 @@ class CompileKotlinOptionsTest { "-opt-in", "opt2", "-foo", "-bar", - "-d", "path", + "-d", localPath("path"), "-P", "plugin:id:name:value", "-progressive", "-script-templates", "name,name2", @@ -123,18 +101,86 @@ class CompileKotlinOptionsTest { args.add(options.apiVersion(11).jvmTarget(11).args()); for (var a : args) { - assertThat(a).hasSize(matches.size()); IntStream.range(0, a.size()).forEach(i -> assertThat(a.get(i)).isEqualTo(matches.get(i))); } } @Test - void checkAllParamsTest() throws IOException { + void testArgsCollections() { + var advanceOptions = List.of("Xoption1", "Xoption2"); + var argFile = List.of(new File("arg1.txt"), new File("arg2.txt")); + var classpath = List.of(new File("path1"), new File("path2")); + var jvmOptions = List.of("option1", "option2"); + 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) + .jvmOptions(jvmOptions) + .noStdLib(false) + .optIn(optIn) + .options(options) + .scriptTemplates(scriptTemplates); + + plugin.forEach(it -> { + var p = it.split(":"); + op.plugin(p[0], p[1], p[2]); + }); + + assertThat(op.advancedOptions()).as("advancedOptions") + .hasSize(advanceOptions.size()).containsAll(advanceOptions); + assertThat(op.argFile()).as("argFile") + .hasSize(argFile.size()).containsAll(argFile); + assertThat(op.classpath()).as("classpath") + .hasSize(classpath.size()).containsAll(classpath); + assertThat(op.jvmOptions()).as("jvmOptions") + .hasSize(jvmOptions.size()).containsAll(jvmOptions); + assertThat(op.optIn()).as("optIn") + .hasSize(optIn.size()).containsAll(optIn); + assertThat(op.options()).as("options") + .hasSize(options.size()).containsAll(options); + assertThat(op.plugin()).as("plugin") + .hasSize(plugin.size()).containsAll(plugin); + 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", + "-XXoption1", "-XXoption2", + "-P", "plugin:id:name:value", + "-P", "plugin:id2:name2:value2"); + + var args = op.args(); + for (var arg : args) { + var found = false; + for (var match : matches) { + if (match.equals(arg)) { + found = true; + break; + } + } + assertThat(found).as(arg).isTrue(); + } + } + + @Test + void testCheckAllParams() throws IOException { var args = Files.readAllLines(Paths.get("src", "test", "resources", "kotlinc-args.txt")); assertThat(args).isNotEmpty(); - var params = new CompileKotlinOptions() + var params = new CompileOptions() .advancedOptions("Xoption") .argFile("file") .classpath("classpath") @@ -152,7 +198,7 @@ class CompileKotlinOptionsTest { .noWarn(true) .optIn("annotation") .options("option") - .path("path") + .path(new File("path")) .plugin("id", "option", "value") .progressive(true) .scriptTemplates("template") From c952b980bba1d5b20afdbd0c36ecc5b3a4cd38b6 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 24 Jun 2024 20:13:27 -0700 Subject: [PATCH 040/126] Ensured exit status is set on failure --- README.md | 2 +- .../bld/java/com/example/ExampleBuild.java | 2 +- .../bld/extension/CompileKotlinOperation.java | 25 ++++++++++--------- .../extension/CompileKotlinOperationTest.java | 3 +-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 8c1d080..e1c974a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ To compile the source code located in `src/main/kotlin` and `src/test/kotlin` fr ```java @BuildCommand(summary = "Compiles the Kotlin project") -public void compile() throws IOException { +public void compile() throws Exception { new CompileKotlinOperation() .fromProject(this) .execute(); diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 352cb20..7461aff 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -57,7 +57,7 @@ public class ExampleBuild extends Project { @BuildCommand(summary = "Compiles the Kotlin project") @Override - public void compile() throws IOException { + public void compile() throws Exception { // The source code located in src/main/kotlin and src/test/kotlin will be compiled new CompileKotlinOperation() .fromProject(this) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index 45aa507..0a69592 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -21,6 +21,7 @@ import rife.bld.BaseProject; import rife.bld.extension.kotlin.CompileOptions; import rife.bld.extension.kotlin.CompilerPlugin; import rife.bld.operations.AbstractOperation; +import rife.bld.operations.exceptions.ExitStatusException; import rife.tools.FileUtils; import java.io.File; @@ -214,10 +215,12 @@ public class CompileKotlinOperation extends AbstractOperation classpath, Collection sources, File destination, File friendPaths) - throws IOException { + throws ExitStatusException { if (sources.isEmpty() || destination == null) { return; } @@ -299,18 +301,17 @@ public class CompileKotlinOperation extends AbstractOperation Date: Wed, 10 Jul 2024 12:38:45 -0700 Subject: [PATCH 041/126] Bumped JUnit to version 5.10.3 --- examples/src/bld/java/com/example/ExampleBuild.java | 4 ++-- .../rife/bld/extension/CompileKotlinOperationBuild.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/src/bld/java/com/example/ExampleBuild.java b/examples/src/bld/java/com/example/ExampleBuild.java index 7461aff..da2b49a 100644 --- a/examples/src/bld/java/com/example/ExampleBuild.java +++ b/examples/src/bld/java/com/example/ExampleBuild.java @@ -34,8 +34,8 @@ public class ExampleBuild extends Project { .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin)); scope(test) .include(dependency("org.jetbrains.kotlin", "kotlin-test-junit5", kotlin)) - .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) - .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))); + .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) + .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3))); // Include the Kotlin source directory when creating or publishing sources Java Archives jarSourcesOperation().sourceDirectories(new File(srcMainDirectory(), "kotlin")); diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index a8a594f..5d0d354 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -61,9 +61,9 @@ public class CompileKotlinOperationBuild extends Project { .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1))); scope(test) - .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) - .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) - .include(dependency("org.assertj", "assertj-core", version(3, 26, 0))); + .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) + .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3))) + .include(dependency("org.assertj", "assertj-core", version(3, 26, 3))); javadocOperation() .javadocOptions() From 1ad14d56c707281ca84575cf8ef2d67693f6a6c7 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 10 Jul 2024 12:39:04 -0700 Subject: [PATCH 042/126] Bumped PMD extension to version 1.1.2 --- lib/bld/bld-wrapper.properties | 2 +- .../java/rife/bld/extension/CompileKotlinOperationBuild.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 80d6f54..34f73c9 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -2,7 +2,7 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.downloadLocation= bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.1 -bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.1.0 +bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.1.2 bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= bld.version=1.9.1 diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 5d0d354..465a49e 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -105,7 +105,7 @@ public class CompileKotlinOperationBuild extends Project { } @BuildCommand(summary = "Runs PMD analysis") - public void pmd() { + public void pmd() throws Exception { new PmdOperation() .fromProject(this) .failOnViolation(true) From c84019de2c43683f1f5e4b4f56d58bb136b268e5 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Thu, 11 Jul 2024 22:01:28 -0700 Subject: [PATCH 043/126] Bumped bld to version 2.0.0-SNAPSHOT --- .idea/libraries/bld.xml | 4 ++-- .vscode/settings.json | 2 +- examples/.idea/libraries/bld.xml | 4 ++-- examples/.vscode/settings.json | 2 +- examples/lib/bld/bld-wrapper.jar | Bin 27319 -> 29229 bytes examples/lib/bld/bld-wrapper.properties | 2 +- lib/bld/bld-wrapper.jar | Bin 27319 -> 29229 bytes lib/bld/bld-wrapper.properties | 2 +- .../CompileKotlinOperationBuild.java | 4 ++-- .../bld/extension/CompileKotlinOperation.java | 1 + 10 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml index cde67cb..b04ed47 100644 --- a/.idea/libraries/bld.xml +++ b/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/.vscode/settings.json b/.vscode/settings.json index d136e4d..33a9922 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.1.jar", + "${HOME}/.bld/dist/bld-2.0.0-SNAPSHOT.jar", "lib/**/*.jar" ] } diff --git a/examples/.idea/libraries/bld.xml b/examples/.idea/libraries/bld.xml index a2969be..2fb5ff0 100644 --- a/examples/.idea/libraries/bld.xml +++ b/examples/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json index d136e4d..33a9922 100644 --- a/examples/.vscode/settings.json +++ b/examples/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.1.jar", + "${HOME}/.bld/dist/bld-2.0.0-SNAPSHOT.jar", "lib/**/*.jar" ] } diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index 0bfc526f16abc52e5fc1af85df2d99b021f2d72d..68884a0fad13e97ddc4787b6d29941839ba2d0e2 100644 GIT binary patch delta 27205 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 Mr@H80GZfVS1KhUang9R* delta 25278 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 diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index edf4d9d..413d8f5 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -4,4 +4,4 @@ bld.downloadLocation= bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.0-SNAPSHOT bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= -bld.version=1.9.1 +bld.version=2.0.0-SNAPSHOT diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar index 902333e6903601a3a5df9347730d4dd420d94e44..5c9583c3adc45115b2f15bffc3eb0c6ab7686599 100644 GIT binary patch delta 27205 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 Mr@H80GZfVS150V+$^ZZW delta 25278 zcmV(}K+wOf$U0S!<~0|XQR2nYxO8;qlo4SoX~jH8i`Fn@drd|Xxa|2g-)cBxyt1LYOAgc4#t_&P+EsGy+YE-Ij+sDO$;ClKCJ)x7DPU{{dnMKNgHuc836NB#p9Yv`u5EAOl?Mu2?+S z%ap$*7+({OVCwiTrdcHoo-XldD7>X+&d@49<<&wsq=uO}?GsY3eZ2Y1GU;aDgVj&(|Xl}*RfT&AM#$hqO3NT9ne+1?uIk9KKz zyk2_Fx9NoJJy&D4?nsx0x6q~&=_Dp=Q~&18K|!k8u*{DJa83FF*0@bu!SYQQKTjFV59_i`9 z2rLo#Y#&CgPl_^EW6sK)2M;T4DJkJMP^C8 z1FFfUW?BQPbwz`Lc(8piU72Q-WU^N_-V{hJHnmb47L@^Mbs)+#W)O%u>wL71DX%BA zDSsLe>RWV1rYLE^K3Xpn>FKWA+1ry(8|h4o&a$bK&Iae|&S5~@42V^00!MK&|l zWRac?!^&U=gc_M-lTBUJ4T+COoURb2l3^rvvyf|zd~LNUMCX9!z;7%b)4F86pL(d* zqOeU7>H`?9qT-QAPfX)sEog+Ee&DM+Ie*pk!KfNKvG8lurWk>aqn0(S=v-af(z&L# zt*x%537q4he>AuyxKnl(4@SdS@D4iHqMbJFqVqE3G@~C--W!N_Z4H8O^S!uSzBLeS z4Q}rbhP#3p-0KW)bOzNFKq+5f(}kiPC-erk1(!#{U4eLeD83b6;MZ^*is)kcgnvbs z*z`%=Z5UV@H+?;Uu3&9Xk8Jxgn=Y4aPmpc5Hm_}2Uf1f~egXPiARRwt(^b-OOiTUB zx_RC%(t3?e*Gg-V)0zd4Q0~(oM z_7J`<8jVEjk_{H!oK!P_Q{S9w@PE@ybgQu0XJO;KbGL1cM$Qdva>eO(=+js*9>;QG zmFL7FVIO@CdK$u0;p*zjzLZe==q|L$`sP(8)nY>gL<-5c&x2D%=mxj=sh#ez>0bIG zSj43Z(~4nP3$)~F+$rlEzN7{TG~1~*VVPO);Bk$39K9fe}BcM2c-A0 z4he_r@1qBqp7ri#u=-!TInWae`m=U%ZOP(zwBPBGwnB?_*=xZTH`cDJYwBEH*VNWh z+feSTtEH}?uC}$V)t?Qa4vd(d1eP2s-T|bmcLbv{(c+osyI&Xjee`umgr@>}=V6;3 zp*>Ipa5`!?#UefZ@u096)PHGGX(jnmx<6*q`ptE&o}Q3(zB%hHdKTD8E2eV-QGckVFl0td|1*>$ zkMG*_J$eBf0g4&}p>S#;0DMe|S4Yb5bSoJC`}6~gerVH6^fJ?w;X2N23iJvs8*7`u zPpxf9{$`pwEO0%h#z#Mf5t>_hyq{jBpIG!$n|?;GL5B=C488mMAyFrl4E0rp^0zp=I+vVYJ}+uADr_pfdG4gD526?j_S6NtscQSpM%l_1pX^m~i`VACJP z0*@Nh4z+{vvOA039D+1>8qNK2YymnY7=YRRQ*yJe0C-z{^cTSQYDa+Z(_8dcQMGM; zdV}7PufH?ROY33?$n3FZikdT@zH-_(nQC)tR$=b$fl3!5aJ%JR#4?G_Jsdo zu^wOW4Q88_1Y0?qd-`KrrN*>5N7r=qL}EdUt)x!Kv}JzIy z5ePTYSU*qTi53^xJc%bKqe8bER0+&!7%olN@y(egm1IInx7GN03Lk6nRGW)=T2ikJ z>4qs_!`H@w%L8zKV&bN+2SPD+hRrh>!PQ7?raqh^fPbj3w3hcY)L1-wi24Hc>ca8p zE;F8H0x zcEuf1%-OIkk5A(UiyLij;%264Da+9X2M44BM+L&&foS(~r;KqqYui?KBC?#+Fr>5F zsYY1)bU|4Q)H*ghe9t-S^0|%ITD;EYb_q8|W`72IKvpPL*V`B0CH*>VUe6m~?4!Zn z$c~^S7V5L;ZTJOzrp;%G8!=iGbRZlFhq?kiq6sWUur(q*-Eo4+E&HBr?o6<@XaK@l5B$ue}_md{`3hb(^B=0{|GBQg?DAR8=@ ztp8D)ALGa2z63?#=%z6l-kqeY1lC@g2Y4SkLUBa{*uKZX)*b8Jdh|ZPPgwk<%}>dK z3Wj#UDz^q=qL!uaH*EeUe+yd)qkm#>M#4p&#ox|IRW%0sW@;6g&rkC+Ha{x>a>3|8 zzj$R}$?sy*8G(&p=>?l#@t>L2Cn3j*FL>r z@$P*}VMm$u6|RzY+D&lD#+e&E@pZe(wds@m(>!A3vsIqtzQ?SnZ+~rTsb99X4Sqyx z=ZgB4JQ}I;ZDlLCrbaLd$sLzckZZ8Mq~B9Oxo|AiXf?)C1-2>_Ygm}2BP731NByPfcVhT^WGF?k_!O1?na8k{k@wI;`r1gU`F$0 zMQ<=3=nljKl3JBnj(@S$6yb*aq(H2V_P|LJKao|jO%XLM9S;nZ&!q31J-4G~*lMO^ zYbG_;wbgd6sKp~GS?Mt3Vl~TFvqc-4n?vDlshDG{QdI_3u_YSm?;GO4q*Oht3R_hQ z%ZgzX3no#b)E{rFxl%6-;VPeGa{=PJ3w-JX5Up{=0>4_QPJgu2Nwzv!RVQ8CSg@-f zPUxH_xcZW3$8P)*U?|&;evX7|E>EnwOldltr-)gIn zmiS12ynuX;WcS#rSHwC;3ovS!{i;uGw^Y_H-0|4KTWW``&Q&`dS3CuGT1hq#!f(l;mO3vPT4+XTh=jM~Tzts+ z=T{f0i+?Tk30qyFKAFtI3~oc>kjc!nl}$R zoXwKiN+lNZL{r=dx&|d{UqF5--@-IU__R_SiGO4s$>r0OKOw1yo*i-w{l5CFt!`7d z%fS~I*iC62cLWRPB!MjTxr{U2^pRj5zozc8)!hoxYqoW)sRO@eORTATY;~{tqLV_< z2Qkt9F70N{&p4fQlTMzRXmGR4Rpl8}<5TxRXdHEv+Gq5+jM5(R!4s;zni2WmKkEI^9)nn@MB(Ds& z9Vm1NURt5gKFoP-M&zvassT&wv(#1^C?McS9JCH)T?0k3Z1mARzJ1X&(v$;Uv^8z=6^89 z=j$!?iwr`oiALZO#FCDy`nmd*O_us~)|2#g(*9dp{Z73O1`ma|24VN=n?1SyEHGw8|NA-q8u@X{=Ba>wSdcLLpWT`*f>M!c;j4;OS0Ro*H2tm_D^#OCep!ILIdPh=X zW1^0x@rom>f7t4ulCKz}$?8oFh<^|Ao~_=OGy74FjrX+Wsejw*KidBHZtD(3HL(BM z>O=LBlfBR~+ZTv$T^)#O&t=Gc21!8);SI74mNiU_MZ2(qWHL79U5a7YhH2zLo)Nih z3WbAh5pOz1^T&oE1Q~jTqQ|go!)N4yKIcS2VR!7zp|s562O0T>Z5bnMV}GPE%4L$B zZX&%6PtagTs9PMVagYe-wvR-M%Okygut3o?8ze`0TWj)-F-C!96xzmEW85I{nPA2X zcsG$KwyiM`hU6`{bEa3mHFb;*{3VNBxPCbU8-AC@(lm;o#~p)AESsW{ih z1lyP>bRU^=qV)k@zA?#|Y=0TY*v1s&SP8+jYYPxSR&>TJz{1JDo2r z9UOuUuh@OYN-V!(MSn?U+0r?SODap}z{@mN*+#vjbKF}rSoZ@e2Y#_2{2hITnkXeCqs=zf8ta@8RW{%p3$zTMCC>yg zY(qBnZk%Bo9maath?twWn4Dn-oZ6~X`eTH#(KgOB&Vn6;lYiW^E4{x#*w&*r!0Y2Kv(J#9^QfzfzfJvu$h{;(~_-T?6hA(AAjvR2Lj%2ENudqwhHuOEOF{^9W)n@QZ0T_Lw z&)9+BZfz_Wt$(Q95)2~_9R)v`rx?3z<2>VhnB|xpes1p%#ynS2v!&3po#Y}wH!ie| zi;RoGudC|L=v+~MYJFR4XG3#)U5nh1TrLT>96`+|ZR1h{!CIk{;ae5lxgxYB6n7I3 zQ-)5Ml%aY!b;cDCL4Ch=Yos^mGd>0FAu$!a5aViiV}Hi^vXX0U<2uQ|*>a4xwzaNB zQg1%vdWjH0AfIsqgm+Og1L~&8mQ*LJXsB??PZBU+v8Iepxy1nlJ z-NDVG;l5-W_Zjy?#l$1xOX%ya&H?FiDBX-}P}s*%)S^@JCZJaO=+xTW zR4c)2DlORRGah7G^#76qmsD+Yds9Pm?Fz8$@_*VkeQ##ckh;{IE^mpHHPtpEkRI#3 zW|*!XDb>r?*5kRVwsn=yc+_!?oY1LqYaq52740pxYu12E*R<5FtUtqNB%I`A^1=x= zo$jG8uhrMJqD!(8_Q74i;Ja;1#e*)rW!dJj86&fF7?)~nsawVeX7(GHS(ReGG!BLY_y_|s}_jSvY>&CAYWxJAOM;xexbL_<<`E6w=UP)v^R zhs#I`#9n(rp{R`1fzgccJf#&)V2{-u?YEDd+r3V)u& zHYbmk(-rC0o2-Xr5^79Ic@|l2snp0763@MxiNjsok(8fvD`xN-lDBCDMPYqQ&lgQy zGa8whG4`GaWv(J;lVtua`R#$HOS6{%w)r5&*sn; zrkZRW77g{8hSn@Wj0i`3G|X0@zbD?=WW`lXR+g>Jd`gP<2jTyR+9#-cA}mG3^Sy%$DiuxGabWC(GbrQ?}?o zc5q&NQK`t@^uw>(>107K>3>UG<_vfMp2!~>IU4QniwDy6x`I0 zqOgcjeNL3zxyg~4O#BTBq4iO>o7ybQk`ZN^lWm$|6qLU^l?+Jg>!E3a8o76#&Q^5x zheO&}Wy_Svd3ZVl!8C0cn5le|Y$%en$fLc}#C2Ar^ypJB&?JpmS$nQ-4g;DXKMpOm6-S&e;svH+a-B7oDCA*yKS~;=ZNrb-~b9xwh<7 zx-%bl7@74>p6gsp0a7>NKagNTPoQ^GcVK2_o_Xe6rsI$NE5ytWFpFtm8HW`!j|V{) zb@jME`t_%0!baLtKL^+W%RYKp1d(JMb&kG|`OJ+Ve^q8o&3`(GHqT-@W^hZ!1tarp z_qJW~w>|7Lv2lwlwM6<%*cw%Z%FU3*<&plL?(pn*vD}3zPI{Kbvw619+?sLi#|a&Z zy-q-Jik!t<=`+uPpUIVQFnp#M>*QT7V6D2Ciz_QDi+!ftUr)nKx*^3vQ4OPyschKx z;_m*SRM%HE7k`IhvHl11|sG=FR4~9Ubzm zg31(rYKTO(_4j4rq2UIKubid(5e{x$5X%ESJ*}a5uzvX@1Hwud>an&1)c| zLwYx8rp2^@&B+br_j*e&{QuwH(Kk9%9)9fMPy&fd|3*b$v)4cGF|W_KjN2&L+#L7U z38MxXO3S<{=^GviC6;+hhF_GeE4bF_Ow$Oa@=^AfZ`VUFw-+A-3ID2-c6-@$tXQQc^w7$ z12keU6+TYmQJ&PXmyUUyrj+vIG!5mMD9?JFW~V>PNs?9yLy~s>ZfBAko zpC~~WN!6vvsw+}eR}SrU_26DbCSYE-n?_Ze2k54bB6Ba@a_|u>at20SL^qJ3H-9`2 zs3Pj4V`w{CV&Kj=EuwyErX942&c)YG^p_F4=o54vT}>Biq$~l7=1`0AV<5mpi{E&~ zcvb6^Yf^~1CWWYL97JK3i18ED8OBeAJfsc*uxSxnlxI;pp7MD^eg;N=mcpn7dpn9;~-W+qcuYaZ=lP7%Ii`HZlXf1m-6X$^!OYE`A+cTU9=E7 zyq-RfG52EB7pRTyp|j{q)J0#Tt@IFGKo0{F_@5pJv`0aX#{glkCPE7Ya3Y;(yrzlJ zmLkIS?pF>V%r$w^S+Sdn1Df5vW_D1Sth54$?2$Slf9 zu&>C}WU8eI?ciL9{{?h0-VT|np&^M5V9ig^IC>He#6k4@2CbrRf<)hcX zZ{U-24~cU1)}l@~_<#PBp^%mQR@qhkXMo}|>3FUBe>b{vbX9`$_wz{M_74XelNYeT z7d-}Gd}^uV_3~MN{YHI$(0m`$A!j~y3+hC>4hZ?m_wy*s!=sxjo~1D&5~vwV5S?)c zSyN#=NRVSB_!uF>bVwY}>L}mKCDplQMY#!{bAT&E0=cT%Du1#{AEN~cp4YL^hXsr& zlcF)sm*9oF5B;Gm!PP}pf*0?mqH3S}Wmo4F`HJ#{z`lb;<})-C!p=)}(=pXKyJ&1*^P{xqc7L{42oz zBW8LNbG?n(-h$k}4d{QwY;R(|w=v^ekn_Jm>A#~Xv=IV$CaCdS<9FbT)9DoBb>sK& zcjnMm;}6CkLHASWbmI-Q$@nuUK7(#CI*h-NsTuKk zvOlC^izgg{gXYtW_lAf#Pq28Y#ZxSvWpM@3hcpFVaQ!&FTurPf#anaIr9JA=iRa6TG|uytK0M034U{ zJ-m7^uYYMOdxk7jE~$995uc;WG{59Em4ktOz-nk~pO{)#OfLI))q#J(J~ z=9A%+lSs_Tkj+z}s2sH$bGLhT**C02 zKz|rP?L0DN@n*t@e#Q73@R<+m_Kvs_nAb4=uD=?wf2XyXEVr&*kNAhydS3VBMdP1v zzurx`(^B&uYJ?K=3D}XfH&oRKqH&+{!qx0cL+3h$kQf|?QW3sK7yHlLWCVB ze>H?tfEPoBjZbhaM|;VIyrZ?lEaaWqS%2p97-l}Ho^z!?7kd2sVt3I>E-|@q*SK(J zxo~q`xEH!`J8}y7;$fjr@IarHg3kXF^h<_?J~^k%0j*>!Pm4qrEAOdcflPA{ME zd$&`ARQF{-ynW2kH*)3@a3adXru9g@n6y3d}fkK@b!{rl4-oi_)zp( zN^?2=KXNU3Bl$n1rBF}PK7Xc}mhmz3?0-|vhh$rP;1K)-$8u}uoex<2wC+MwatLf~ zdfSLT$aMYW$E>b3JsApCq;QnWkB*^ubuhc1;StzTuATFm=ePL#u23z4NQhAQ$_n{6 z3I5%KgCK462#zl$I6fCAN`Cb0LfVa`iRGJD$bXRZ2fuMUS%v(kMt@mq!QHTKuQpY{ z6@)?G4Hmkca>@}}px<8}PWgAo!nYzmn@kRn&6{X6chh7J!tQUTGTxeU^)X9oE%V&9 zm{e&T(!SPYnqU&XoTzFPfo!9J-4AIZo>;W}Y}Z}%{aCa_{#CNzzri5?Lk#k}@S6+y zJ)q+b$}cj-o&OgCPk(ITzwP45ew<#h_CL4>eAJ88hQY%Tnhx7LhogG6Cph3!tF3ZZ zi!YP)YIA9hvsxNWQ%z+WEQpGI`8nHW(Hle0gn|suBot_ZAmr%#uPX3}CGoebf+lDDHULg(+ zN~$7NQ6&{Q0Drnc#zMolCV`h?@A&`Z{c0Y9FlUb3LN$LtEs*%C$Q)2L3AMB+7x9x? zKA=`6)M}_xfKiR@vVz8TiIXf1_YNv7Ei%(U6RHJWq<&&)QI1nz<i}dNHu&D)$+|$$G6Z1zLkRfS?cB6 zD9(2xw!4dN<$Iv3@1=wMC3=?cqnG%8`YrFKH~7o+Hh-1g;Rom+{1AP>53`^5U^S0n zJ$v~$et(>2^8ud6PjD?irTOPF8UgMt)V?NT7lzAHlpkyuVc)sZqy)Rtla^cCG??S2JJTp&oVJ#b`pXP#FFQl`ynNlX@s*?H zb1vnd4wtm>RPC1{Vru`0szt$kOgnYl>21mMnwpNqNLu^A z9<`->zdA>_c^keHDl9Bj4kl`X(gd$Wga_a1DBDYKJKWkY&OniwH&&gWP#2zoL51p4 zjFz^`B}&hAzicp+a2%ra+=CkS6}zdSNejx=5EOir4XA7PtIudzsyOI0-QaDy$q_R* z4}Vv2u-fMULfkJAeI?w>7DPvF)Il3rqOz^DU42Twuf>*0=hcX|(vuB{~pG9Qy9Qf;bM0wu@9bTZ-{30MfM_Zw6!u&JZ4(k==AJF;yL%Nz@qHFnO zx{iMYKKn7<$FI=W_*HrcefOg8ets<#$$u}Papnkfq+V;aIm#Rj&X`P%<`^B9&!iP* zfmsLwMQM`pia8c_*U@x0ssVXYI_rSW*@@0Npr+_Vz3{^Z@=5kCH=U+KU~G=F=&e*} zZVheA2+ECAJJBjjeM-1y6B_*)obyidxP>1fOPiOMS)~0w%Ez0g-B0EtQZ7_CCx6tf z4P~RPC+YPLqaY7{vOIF+0hM$|Ylo$upyQpb9iwyQl~7-3go6AMRPE~tb$?U2j5a$A z@wqWxRG`eE_3i^ua8w9@P`qCSNbyGjQ#?Ze#jA2aeN6!4bDn%A)Wfi>MJ9klGbNzt zCN)Sv3x)cW#I#O9z9dsP2GIAbCx7(&+01a3e+gszYbdAJ=@|Y!HSr&4J^ztz<2PwH z-VgFyApT!L{6EnF{xe4Zg`VTLp?LnLnPC<1b_{*aoS;50f6tjh=0sBh*7bCzImw(1 zaz9A<<}v0J;QRpDV1{GS?>RS|6~e#lI#utw)=@(3A4yG${Paz@j?=zq(WdZGc5 zY96dxg!{nzVluCCP3G)!H&;+tsJ>Nh>{H)Xq^*Kq5{l~C2leZ_52l=EeVWAoq#}M7 z;r#m^!#X>~q_fRwE|bpI0k`r5+_QDS?X1uwRg|mw%LfQInbYY8C!RKEg4do;E%sxy zicqhY)3Uwl#U^-27bn#B+keX|2GkEK3e}IKApTrTe-x@$GApo!pR^xPKZk>*ekqYi zLj6X(DfN3tm%aI5N-5~WBmOV>7@ixvpmBVNroaW6r4&^vgHBXAv{+ems`62z%A+>r zPdWBjVG0N9Q#e@f-~fAUF^@B6VK1jrp*ht*f8 zD8Y~iKQAQlWBeLC1xJMMhA{lK+{yN|9D**ajT0VB6MXTb1_(r4y<#%Pmt&Ng9;-)9sls`ec)rgrQ#rd8(& zl?sjNdNz)MIz<>cbAK-_tM+3s{E)mNKO=rKW?NL9UzESkC_@Zr%)Ns)7Ud<36I_mL zb_&LcOx1Rg?M9Td;B9?Jt{;W0&hoX>MOmyhQYxf<%%k*Paq7Kl2EOf`n&4`z%}V`-uqM^n`Vnyrec zLQSHDYBDWT$54}+LY-agnWR7iVwQZ7*E$i*1G&OA{LqTt+ZH%~&HNu9jZJbxMHEr+_f+N?Hf5acvdv$+U! zSbPah(emSiqvyy^o|Yfctu6fjXLH%sEj4_rm$ues#1HGy(qudRkD?Wt#DmK+O+#sSRZI(y78S`v# z2cP{6R(}9~`ST2JX#PXAiHE(gREtYvxhpIs<&LaSJ5;7omoQGfoyL?^IO1Kt&sYuK zKlDmEBQjkg9<`J#bqbAEwKPdBqnTeN&mJc%Zn%XRFCc{M5J-$HYR zWLQCnDzna9>8k$XRIm3^z1~apI@L7?euJ0nk)QJ6Z7I+%Gp^3=_BD64t+v$L-K^n@S9=FPYGL(hRni$)3 z%73jjSulDN{9I#sw!B+aw!GWeGVy|nawU=PfYr&jAG#AZmL-h7RPt?sn|!0ZYO}n^ z++%EKAWEaC$lPzly*Ls*w)@a?7&|MR^Gj;)kSxqf=j2EZn4ck^K7U~> z%6Zr+j&%%Dw#8dPS!_Ag0gifPh(vwt+P&t6AC>~*GGg-5^9AUFrB22;+E zebO}2#bUZ4rG-3EK%V?|*v-7G6n`I1q^fj}alz!#qb@o@(p7_woz=NCLhbZqb4IF= zY3Q|&G*35v2dH`SH_%*|kGkGoP3g0g!w*YdY_IW&hSJ9Jrx`%kE-c~#w}2>kJ6Qe#%J}%)rH3G`s2%m#^?0M z_Cn(>{c&lb@p=96r9$JLgz?2kjSGYs*mL3NL@ESkXVA$Ihfb8vrc)?D^@zq>s0)#7 zH(Z-I8Ri*UNIT5+BxmoV&5Mc64f=Vees=0-KtH?mGpL_i^fRQN+gtRrS3e{Axm`bF z=H-~7-`rvDa=*^Qm$Y1HUQ5m`zwg6+xsLMqY4g+OXL9q5a$}5nLvEgVqj|G=D;518 zP)i30a`WO**)jkC&}skxP)h>@6aWYa2ml+5qmvFeDYO4NVgdsjjH8oeJu!d1_y2$H zOzvcIvyhOGVKXd3RyNs81Op*~U;-G{0E&}jfPrKt&P)Jtsa9O;UaLZ@w!TtaXhpOk zKn0gpUv2Bt_PxGtw)M5IwRW?+D}29m?wvb#mIVC1_OtcQJ?EbDKj-}Z`#C4Ra_ZO# zBATb|^O7JQW5MnyQ_hw^Ocq;$Q4m;N-lC`m!>Uc)2D8|Qwo@a4 zErDHASNLPGKqNH8m-Q8nPm*k%PI*it25Fx|1vE^jLW7EEI8$D7UnYM&7G4mE_^)6p zFSiDDthuftL!C|~Od|)Mp-!btMTxJ9z8uXpKP7=y;rIZTEV5a1PzE(%64 zN;qG=a(0t>#=@o;0nMu}CnqrA{_H*Pux>nJFKzFX)JdyZd4ROlvFn zQ(lqYB^zBT4639mrtE)cpw}PqV_>Gj^rnRnk{W}i&{SaE{UD68FONCJ=_L{^+v6u9$2)&!G8qAutc2A{9Sd5*8#WiaCEZsTmChEuu!K%;sP> z$TKx(Si=8}_?rT;*q|kn&pPL(?js|xJlSYEkrxhrpsYJ3l z!#ccFPi+RRq*aiE&TtO|A+Rbu2=0pN8iUr-I#Bg@bxFvZGpNoQ*>JsVxFLm9yoFlJ zB?et8Ig%BON*#ajQZ8L)ke@oRydHn7bE|~!JZJZYt^UZ$z~y~`P-md7A`PlmvlCX; zMFE{Q8?;5zPqPrMapKl6QJsQJ;}hdFcXtQ2_`4TGw)FJ`Lb1kOoq^t1FdXvGb}T3w z?u&E=$~yg_$+5DIKv}4-yL*b4w$gMDh44M*j{x$t@1uXH*PzSQf&;st&KMPnQ{yn7 zf%rHMOWGKTgd_F@3W=#tD&r2ONtt+*Nu44zT}tK^2JNORAts&SUYMA3QcQAk$u#p< z8*~kQg2~$z=nljJrllHIp4zk!4x~>m@RJ5zuNK&|y(<`rW`o2H2Hi+E!7NVnN27s= zTHT^x)Zc&69f17sdYx`zDoxCKLA;e(xR-90hSNj08Fagxd~Q#8N5D3e^2?nD-6g+x zhG^3VfJqr!c$!5VmJAAMG* z&l&U}JruY2fTKA<5-{TjD|DA{SSU5;^YjIs9x;FD-{_05De)f59fP3l&Iqg-#1eg) zn=97n^d%?t zgm+55)X9;*9OsI~X6H=3bda8uL_Z;6eoD&KVWuewxo`lHkSiwzC0_^W8H2tmLk@Rm zcQ}6vjXe@yZt{e@)K5nZI!4DK0I)kN`+9pL0SF54EiE5p35DdMKAld)_1{{DV`^S{ zmY$T4X9}^FzCy~P7o~1}ooVh_xw8z~=AoA`C(}Ye;L;@P-|^M759wdM^a_1Tr*BKU z{hc@xA*ZO}CrZLGMBqnQu(O_)3k}NO1PT$q(dj|a{ z{a4x?WMj<1wbS1XL%6&=(;ypKh8!TtY@1R#)sl%q(&@hq`T_kA7R28vWu585K{;XD z9|ytBeW6Y{%2XMez;;XT|6}@zPH!0WQ~FtwFGw03O1Bwy*58SUsjPfRic+*Z^rC-G z|HCxaVZEC}p+Kae8)nYdQ!l+qzclE7rN{Py=dBQ0|CWHP{ z=zH|OP9GTbA$`O&&X$@^IQeKG2FCb9UH(W{gIR{$xmT}h+B6royCto$)u>J``82W; zWsG2l~Npsgl}Z&-gx8IRL>yulNABI3x*%`gNwv^pAS@XIhw%J%w-H6ES> z5kzgIX2BM$&dcRop>w6dRZ`IklukB;BY`!6NK{dgx@Q#%$t%}U##0QQ%F~b!V1zaq zQ$}MeB3MBrhTv%O+1dX!lF$r;&*Pa`J_bpO0Bn6u(F|x3&o+1t&rN@5l9JMjAvGyE zsPk~GBvF^}2pRqE8H2-mo@elUM!uu(@OSqGmTyjpEaM@2rpz!$1zNmN&ZL29X2y{6 zj8pJ%qa@IjAYci?*%El0ml)j4OOZv#!nU=M(o(Tup`_npa4RoEiX+jM4IoOsLBQUy zu#gPu^YFzGOG|%J-8g@*gm8C3VuB&Rl+!dvevnrq)Z;Z){3nAQUT1K-3U)Sk_eHlB zBHQWHd1E{wwJ=*NBS6@Z4KgyR=S>D*CR4kt?m%cuY%A)yLlW+k(v=Q{3>sydb&|j{ z9)?U6Nhh41i*V53Z7NhZgJYe$llDj!`C|buZlUAcbSE!Tb2LSbikX+wJcR zNI)AJGHD2ijxMBOGR7@bnHqoI;4j4Y5oFjVJ=b*UUN(Qp$9{vqBtwa8*v1x9^3dl| zgCCRFc_2+nP7A3>Qaeb~3u(Cd_Ju+!mcx|D#|XtH8D5u~hT<86zbaE#xjDGd9}UPI z3=bpfA0eewmeM4(o{t)Qj1l?gAhd#k?F#IYHcCc0&GPfJ2A|-Qa;|+HQOl5)lxOmy z%G5k>@C$!(3I?XoxC_c1RdHH9e_hh~M%qS+!%)6#@V`sUU}RdtI}z()1zvuIzoqlH z4gL3|5;n2Ea|$iwuDIhX((Me++*G?D6*|lAA#~3>Bb{@EJ#65eak!J7GiA@NXKlh!HKHpK;(s+rdYcRDNmj|MIV3PNFJ8L5f~Jcn1%^ z1vT+{`ECBK&c8GG_Y8R+mDb$iQaA!8>D$7=kdmL-XSL~+N^+B3(YiA`)V!4MPWZgYPY zWH=34El#bfLVXWma(ql-$2bz*8u{84CM%quEL%N8|aiY}%aVw#xF zRF!P1fode!0lk^JA{-6wlJr&tB0a&Vm4_@}yR5NoQ(NPLMUcgokI}bI4!&LvKGP7h zZqs!`fhM2DinbkI- zdP6Kwgv?!?Wl$V2xA$@P;_mJa1qwwAv_N5z#c6RCcU#zixw^J z^77m}^WHl*nao7y{F4v)kU9CC#238~O`cmY(xkbh9#s0Va+o02^1J!mN=Y_uy-wgz zql|vj?-PYs24KHnrNW=>3(f~(HXp+e9Yf|OF7-C>epUHuBA9svwW!8PXQo7^F9Q>$&D4*66)Lxj8bgFI$(w$%|JtLAg;$%W4173Rf zS!UXq+W4_|3F)-_QkS=c;mNy?c&p+oQCWHy#LD`^=S=+M+itMjwzv%)2n{_5h5JP7 zX%fWR^S&Ecv_{T3+8a$b6ciGE6RR_t>v9m--Eb{)1bevV(#nTz)8FBa>NPoqXgS%N zV0719&Kwpk6s#c)%lZwh^)xOKy5oqF!xU!;1omUiJjWXg#rpAV(>(KCsNU8)p>3h~ zwEraNWEo)@S_r`qIYLIOmYyfO!eC}xS1Z?X%w@Dyzx-U=Hb4L+Sm2~vhr_7N#((=y zn(0Vyf*}}p+}X*|GX^IDeYi6Qq};|+>6=_vX*t;|x^)inT{Ac}v2<0n$xCfYVRmz0 zd9n*s7P9+2bnDj{zqNtFxzi2eYb=827CC*Z2Q-xp++UkT-zW_gBOXP=I=|gNrkk;U ztF9|&A~0Y<#_;(>eRAnlccvWD-~i~bFbtgn|42z!7ehKAdZ^0Etvi>-(CiGEYVX?i z>~*zt#uhy8R-q4oFr=JHLJ2is93DRU&tnOpe>SHh-a^Q{TEJITNTRx$jsgb)|!W3tzTneh{M0ivBN0 z^1Og#41^YhNdYPY7HPAS&H^{(jooqZj8H5t_B01kkO2nhvtPz)%`) zCnSLqEvB;kx$ew{7Gi3WT~qyP(Wma;kTtln!tAv`#i6cI zG5mmOUA4v!4=Ivtb$oiXL~k7_cQVzNW?><94e5pWO(i@n_+n>{be18`Bli>FdbZ@d zNAww}euVbQ$;CJ>j>@XGj-FtW1yw+8zFiTGxSu}-(SdB@cL{JMz# z(PE|22h6ww{E`SZ4`DB;0K^>p``|$H^jxMH(af%)25KDW^Wn#S!nR{QaeVibqZ>4R z7?d?K^W*v*p{_nr;}R|7pcXQ&ORA_xzv6tuct6Fv5g5uJnRXj|w8p=2D$o!TJ@FoK zvDj(pZieUuJn(Eb^euZU9bs8TjyVek{#ycy8r2cABEiAcBnuv)JGUFKmD_@uKJZIr zBt;DNHg8Xx=vB_i7m7YhZbPDyrf00|M20n&>+rIex-TEKMK;k ztjbD1l^2vESB{LQcY|}*3Wo#WeFC~KHKQ_CHsFCY>E{;~>KC?}^*22hNz6S_*N)F* zP7#4|5~Nql4>r?fDsANe%jWQ5Ha0HgnbQv6S+Uk524h%pa5FYIN(mcoU$d0EW0gPK zg=+f?>`%!nWS0Y>cqJ*(zhsNelGHZ-eJADSk=#7W^5c_3{{Gv|8v!Z8&W5Iy4fym9 zG}FS5EkDE24LuKFQEZm`k*5)!CBB$WIYY;=qjDgwVk6dR*hEVvqy&bxEkn*6Yzw>__Q<9%e|YF%3PJ@SE8*QzmxxnbCA{% zN}R`We9I@)@6=Fc^qwm={5U%JT2UP?bk(qzuv=iJ6mtglbD*suk&@CD^Gihn-O+n3 zE^J%dlKBl6H&ZO%0YSknoGu(pX&_qM+_!x2g5fr^?GmgpPa625cS_MR%E#>^95fL9 zcV9y{?X5ULepe=Vg*w@D2X$nws|*OylBnpDbA%NT zRxggpW#lru*wNsj_#VSntTb*LofA7IxjWyIQG-9EWt})*R!2nPPP?c?d6fvxOcVOM zSA>(JpJkApHm^m9D(4s$7_+>j9B}h|K?KQq`2-ks&QDp{HDWaxRJ57s9tkv2Ec>7? z$IH{U_Kh?9t{u%ePCL#uYfuO)cJc&5wXQHDJi}Vit7~`Zct!4NQnwJm6!XSyeDP1p~43|R7^BvMxMKh+kaF%#RG(7Smv9v=6$J7meozyc?h105i$( zbq7r*R*1fo{rzg-u3Pv$tfpk6ueagdf(F`=h3I!4P1xVl!9ojd@&TMrYN z$(U6^uTJ*-GH|dBYf$|~pv+-9<)&kF%-uIQOZ}xqe1N-gko#9=V%0xO@(ZoFvrKB! zKWshHj$psl{K+?VGA#4{+0}R6oM2d$P>sj;FGh*dwaWg4#hDc+8CwQT_#s{ry@u1I z|3cJdasp1CE~_Sub9P201q>Ig{9>g0 z@0r|JGXO_fS~&r^O3lSPeZO>0MrD-d6qId%H4A$+RrCDE%haY5TJMQX?7_Ej#ln%c ze8=fdWc&m*b>lRR8Cd@9fH~wQXSy_M@uxQg_9=a?B=yTiP#84Zde64;BK9@Y77okk zxdgszE^6g#h4KbQomt-+DY07UYvZ6B9SSbWbyNiYYHR;IhRuS+Gx&I4m3N3p0=}kMy zJ>eIe>2)N0nr2&4^jnk{b7oi@`tp}lCc{xrY9lnc=RII^RC62buUSoI`ooZRV1+Zk zgwx+x<0eKv3F8huuJyerE$Tn2znEvl-Bw>}>)_rlnXBaHxd(sJ8|d>zEis(ZasGgM zI2yhE(Cnux!m#`G6yHrnjW$aBB#bi)r0Q)gzV+nW*~u>(KG*0{-q(qHY5c_G?t=4T zP4Moc8@t$+Sl$5u91#4;En24JL&eZbR6`b9x5mkh&7v*NTX6%ic1X9}`nwW0xvhX1 z9*{WRS5mEF+aqt>As0!}gn3D&{1sny2 zvC92!u$n!Pd19eFfio!Q+*i8QElK%lkoFx#62P#lOpDsVbJlAHZtgNRhFO+6VSCd0 z^W`7PA9{PfS1c))UP`oOq3`?qMv>0^(x2S36*vIyt2JfQhL1_3N%-Z;AY!&B;Jvq_ zEj8TdV3E5pmoNK88HhWtsXTg1#ZNH#o>t|1KhH2Io%k#KYBMYqseeQ8+i&?1^97D` z)e;}1>Jbi3aMQ+Xh_p(J?f6OL5r)S&0{I?odChV7N`mIihuRo2zpsR5VK>vKTf|zT zJLJM>yI=Q)N2(B)0TQx$(w19-y5l#@!oMZDdSv%zVuh)E0m^k#;g>wkpWy5Bv5<6+ zYO={c@pF%BB|CfZ1e0oW1A|=R9`z3X|Y5@V<%tr&iTDzf-q0psk`IK0H4l z)%2-BxJB&O(7JDfufcfq5-+HwbJ6(7H*9{ExYK&pN+RAi9i;AIV4SA=Dm9|Hckd3h z4wCT*>e^kQ@mnP*8caE}D>Cnyi~fvhw~v4!dakmkKWq?9Zuv1%3?Utf2!Taw#u*W&G^% zOkRdaD7;NN-xbCIHFIpc_Kn8j8uw+|}vQf=Mc=WzyS@`iF%i4|PUm>>BEY*0ac->Q+ z@Im$J0LFO24FWznAGT@svxcOEa>7FJbWf}kXLz@M7h`v+!lA_(=!^zCi;*63L+Bsl zowiZ@2is#A3W*E7#aHuHD*p7o%SDqq)t9b3^cbN0m#ZcX0}s!9UxTh-({k78Qw>ZB zjRIMO4PP_*XOSxA>O!x;8zKy(OfT9dYgTFln!rH|3N?o)&OhN%d?*T6K^2H#3*>7z zrjSxJ*@m!m=Qko37Ev0FJe&~QYVVI-c;wlYQ)pj{afg&5!*f37KX$=|jh>Yat~v4~ zRgy-Y;ZxKZ#^G21SdTKd0GIlYqt4JTEj*z|)aBMI$-=n~HMN2QeiJ{B+T${_RPP@L z`y6oj4Y9}OksEP)9hmqH@yA5Lh>dDNOQpR>4a{TRY|lctjcozTe+d}btYr5tB&84g z#;PQdty-ws-+0WBuJboh)eFR8uQnV|2I&=})DRa`k`>Q`luD3g7KRyuXl#+~v9_^A z+Z?l%8vi1x2g;}iG6k~1`bh%X-%%f;_+}#)pWD3_$@By$QYGGDTa`L4s~m zJRzcDkK46@x0R6(?0s(u8crInyeWUGaa5;N;*w&2{YGg016LH=(K+haSCAQdK;Jv@ zv-cp&!WUF8T~IDz{*8(-OTDcQnrNE%67%z@6~wU=xI*M`uOygb(&9hbr<;X8k3S`L zc5#64UDwznu3N)BHIVr)7y(c!`{IV}3&7QVLV9@~*$zjTzc3fLfo*s=|76|OCQx~^ zfiUKTvfDa^(w#Q3r!nonj_&6}$Fuzqe1|+c;m0uqZLZHpP`eB8#zUMKAapE8>UwJZ z>6>#K9DXHwCQo%}!uQaOkI~-{+Wzj;SxGO^K7P-io3vkS|(VV?(f5d}-^SN@w1A|g|FNQ9f zF0?Aip?vj2KPEX7TIIrKpjCnLP#7>PJUj0m-g@nZz z+Cy9B^{}sFQ7j9}Ic@z`@lU)(T1k=>0eClz91Yb+ewu&ZqllNvhR$h07`d_LnrnQl zEDj@)ZIl7Wd1prG>HW}ate>xzbiTitdonWnY0?+&vWgAf2IsN&*FI-r-IimR2ck{; zz2SWTSA>8Oy`I#nc1+>nkEG5o@$nv*0E9!a)I&P9K+eDj%TFljWE_#k8WHgxvA6Bs zLctzCI5=neU;Z9#Zo*xMB}0mE^cM^WR=@6B`=C|V5B!N#zwwJx;|b8V5D8Ij?*ryP zCVCSTh4_P?37YAW6E&7r*j_0_1#n?g$*O0`&Su6GtG1du(Vdz*?}scCh^5RmQ1`i` zNk28<8`+cpCl5mC+g?Z_!%1OaE#kW}KFENj_c+32$Z=q_``T(WSCzp+8R&Q*l{!t$w8Mgl~`+L+be96bGgRDpV1ekyTA-^f9+C>D}uJ+hji z=*E13EP=Q>zwpZaXtv~+`$7%Php3pxCp*IGGj}7WPY_v&Lv=J~WP()|Eob-{F6q{uK7*DY))olN z>yxX8OUw1n*sTKSy5OtfwH6&TG(7d065r;blDbyzdE)&5IN0JZv!&Q5q21_4mbWNN zo4G z)Fs}}8;ch-yF)Ky!QQ#bx!#i5(`yk(A3EQv^P#3rb>3IMYQKgcA~qc$-w8|OORWQk z&#AW3giNKBES3H6lxwwOAK=qOtS1fv{yh(zZLTy`exzsA*QOKpK^OL6Bk#t}_D3b} z&apf5LmUBZsscG`8?sE0**HY>WZm|-#w~%i^`=Ec-{>;-$qsC zns_XvN(lNuV$Lp$RLnXG%#8Un@h(1hHuXV)sE{SH%<&DOcfXE8-@m?pJX$&6uhGCr zCKP=_e9anH!_Pl~xEw~PVvW~FDZ0!W(J0kOuAVYwdazA+VD$}Sg-(Ni0AlhE)A=nD zLvMx|FP>}*ZRv$pw~Cb9Xy2D6BdJe;E>r1sSebM}F2*PPoHU#G81pLMpQf|gND;a| z2eFuZR5RKF$g`TCYl!k(R&if~TXG4d*AXsni3-XQd(>hCFNGD-G!hQ2b8De=M+rBRwJ*uh3z8BM(9Y2r&) z4*MS*^_(ZB^C;-zwsg=I-)0@VWo%D>qvV3}Z(rJFQEQd%Jco?@Epb!am7h=>z@6vM zC?mCPw-2=;cMCk)nE1C~aH^Bp^617MP;9}&2$#<6*EiwoGlhTsth;iF!6nK6#=st+rnzit>K>HM#ibi00GHuwHxt zve3p|f_kZ?X{`xvywlRKHg&Ft^y=nahvF7RySn5Mt z8F#sPyCqDrvSRLHQ6l>D8eapewmW8aP`G)NN6jSLak$bp2>R)jASBT#XqGtgw#}x= zcmcD}#@>!sr1;!3qn`yTc9k}mslLM>qk1wp*R?BtxU=U0L>DTJTpDx|%Nr|&1JUoA zK2a8XOe=t5w^DvFOI7LczN5BCL_x{&t7Y9LP0Yq)H993E*+19FYP<_?G(LB$R7PLK7u0xg4oR0 zW7h1#wF3mRGTdJ8zg?KU6~YJu90-onM&D4gv4XIwFOEIZ_#iU98*!$WHkD(}q`Pi8 zts)Kn2J@i!>GO|k^W*@S-muVM^lm^5G{@Q;5WPYO*)FW~q-$?_7%o2U_q`5|2185H zj@@Rfq*b^yO^T%*l!bA(0lyD0#$kl?GF3>;9>8?g$!jc|=-W!!u%Z)66&xL|#a3^a zL+4x&$&EU5t1@SS;X>EBNzkr{#$ZIw0_J-0*}1#=8q$=j83n)-^Dt^kZnRMh<0SO~ z;}(=ei%{Ju`&<=o`iyVCTa33HXkpD zxXgKz;&?WDs3ph1^2@i5Aq<@K@J~SuYyv0Pc$K_UF$iKDHg80fiCj;>^_r9k46(<4 z#(D;Ow*VJ|kgwpy&mQD&CSU9@sikYAQNqP zRCkX619;=-RF8t@1&RqVF0h(EYj@a+1SPMza%Mq`H>(h}k}y<0#y?B=G>g$NZR;}) zi9tnYi1^>28VHR9d-qX--J2-g<3wz5xRNF8?wgykakhFw0nfvvzLyPy8lBl?-6ImV z2@+`)61KK(l(1d*1d(#T>MoxOYzGRfNZ!4+MS)I1KTq3?#o2|vqs@%<&$W#PHG<=9 z>J#L_$+nqYx9K%F+JLJdaz{$qj7dw1e6%|&<2OQ+e+eU_31@`CxKYW?zVRCGI0x8y zUiuxwjkQItl%D(3*|Fe4_L8ki2l zRD`GYzL8~W!|$p=yDc5|Y1v;*XWkd|2)PNrt49RoTuSDbGA!r&>(u|)bJ8ssR8WhE zT*y;kjy(lsuSdFqOBqEF?ZmX+E{vE*8lvsjZWR?hMOD~QM9ZFJe@{gohn&;Boc`<5~k^m+>-tW4FI}3r3M((e=`gL}DEFUX7v#TwXTC zuOZ?F2;wH~aCXk~i&G6p$J%fmmfTlQ3rJ$yhxGH(0WsdSq$S;S^N@hM=i>xbFK>z- zH*qCp>?~ufj@*ux3*oO!o=BHbS(oro3&eX3En;l$n5E@e@21|2!uU%EIY*Am%UF`M zCyS5vSEFIzOJ_tu{EY_6b|-!KB)pUo=d_v>ddT8qu5QWmW#^=)OK7(N54pkLF>4Cv zc9ji3$=+a2?R+G8agkBT=(~zT3PS{1bWITR4Kl^W*n+HN&&Yb5K09AXhiH;Bi20WX z2T40G^2?*}z#JlIzXVHph@zjpeSSM-g5b%1f zPU!hX&B&nCa9M`5*uZrbEv8tO-OtiVT8tEytQN~IhTu~=tubMT+Ba`5*tvE>zaPKw zVp5Pp2DN{uc|G$ykGD#N>MbR3W+o6%*lxHvPr!2HAJGM(b6IW1XRQpHNP%QUZa)NH zWM;s|2u5l~GeX1CJEwK+%MR^!hgDfal^K`2Hf}t=Jn3{iHL64NDku?=ck3aQPmi(( z>i7~?z^V|W&rYA0nRhOlfocN{)AIRBs8u9dZcK;$mLhiRAlFXB+Ny42n1O`sMzsgv z!RW+VQLoce-@#<*M3TEh4=?I;8Clq1c@-?SBFFO6^&j!TqOZ0dRtd+6_DvwGT*Cpx zOY2T_WNW1|^PeoQGuil-1{3S|9MW^?*?wq!T@sJNkad|M#HRa}DV_02LpJXV#8;bb z?%tQz>qan!~aVah*}_E!h( zn$l#I)(~G_t;y1ZrJ}Wj_0cAhWmSMlO}_nHqp`GD#U9H+`v>W#gQd!R#H-b!e7URD z+I;B)3f;-kIiafj0K2ZdW!_`eD^HPT&v?%~z|Dtav||$z%x~8e$AMu--7m=h!N>=p zBI7@KUNLgp|AUb?n%hqz{s$p%6aoqSH%o5qM8h)MI4gwm3Y?>3@Yx>Qqaz?7puQGO zHAEz0g#Z811Ej%89`Dsu|9>EL2(q)xe*x(^&QwTcLJ)IjO2~^OA@~2W)c@b>p?p>T zpCl{_!FOT*FAYf-DkPb&5NCT4$hr&8f6Kmh5m-UmTm~JObr=ER{{hioI*9-P diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 34f73c9..3037315 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -5,4 +5,4 @@ bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.1 bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.1.2 bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= -bld.version=1.9.1 +bld.version=2.0.0-SNAPSHOT diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 465a49e..56752e5 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -40,7 +40,7 @@ public class CompileKotlinOperationBuild extends Project { downloadSources = true; autoDownloadPurge = true; - repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES); + repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS); var kotlin = version(2, 0, 0); scope(compile) @@ -59,7 +59,7 @@ public class CompileKotlinOperationBuild extends Project { .include(dependency("org.jetbrains.kotlin", "kotlin-noarg-compiler-plugin", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-power-assert-compiler-plugin", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) - .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1))); + .include(dependency("com.uwyn.rife2", "bld", version(2, 0, 0, "SNAPSHOT"))); scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3))) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index 0a69592..7ee13b5 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -26,6 +26,7 @@ import rife.tools.FileUtils; import java.io.File; import java.io.IOException; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; From 6fa3bdefdb133634a75fd93b6a7e4808c1f6f85c Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Fri, 12 Jul 2024 02:13:13 -0700 Subject: [PATCH 044/126] BREAKING CHANGE: Kotlin must be installed. Location is deducted from KOTLIN_HOME, if set. --- .github/workflows/bld.yml | 1 + README.md | 20 +- scripts/checkcliargs.sh | 9 +- scripts/cliargs.sh | 2 +- .../CompileKotlinOperationBuild.java | 16 -- .../bld/extension/CompileKotlinOperation.java | 206 ++++++++++++------ .../bld/extension/kotlin/CompilerPlugin.java | 23 +- .../extension/CompileKotlinOperationTest.java | 9 +- 8 files changed, 190 insertions(+), 96 deletions(-) diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index ceddff2..769db33 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -9,6 +9,7 @@ jobs: strategy: matrix: java-version: [17, 21, 22] + kotlin-version: [1.9.24, 2.0.0] steps: - name: Checkout source repository diff --git a/README.md b/README.md index e1c974a..8d39dc5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![Kotlin](https://img.shields.io/badge/kotlin-2.0.0-7f52ff.svg)](https://kotlinlang.org) +[![Kotlin](https://img.shields.io/badge/kotlin-1.9%2B-7f52ff.svg)](https://kotlinlang.org) [![bld](https://img.shields.io/badge/1.9.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-kotlin) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-kotlin/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-kotlin) @@ -33,6 +33,24 @@ public void compile() throws Exception { Please check the [Compile Operation documentation](https://rife2.github.io/bld-kotlin/rife/bld/extension/CompileKotlinOperation.html#method-summary) for all available configuration options. +## Kotlin Compiler Requirement + +Please make sure Kotlin is installed and that the `KOTLIN_HOME` environment variable is set. + +You can also manually configure the Kotlin home location as follows: + +```java +@BuildCommand(summary = "Compiles the Kotlin project") +public void compile() throws Exception { + new CompileKotlinOperation() + .fromProject(this) + .kotlinHome("path/to/kotlin") + .execute(); +} +``` + +While older version of Kotlin are likely working with the extension, only version 1.9 or higher are officially supported. + ## Template Project There is also a [Template Project](https://github.com/rife2/kotlin-bld-example) with support for the [Dokka](https://github.com/rife2/bld-dokka) and [Detekt](https://github.com/rife2/bld-detekt) extensions. diff --git a/scripts/checkcliargs.sh b/scripts/checkcliargs.sh index 7855fdc..ef320da 100755 --- a/scripts/checkcliargs.sh +++ b/scripts/checkcliargs.sh @@ -1,10 +1,11 @@ #!/bin/bash -main=org.jetbrains.kotlin.cli.jvm.K2JVMCompiler +new=/tmp/checkcliargs-new +old=/tmp/checkcliargs-old -java -cp "lib/compile/*" $main -h 2>$new -java -cp "examples/lib/bld/*" $main -h 2>$old +kotlinc -h 2>$new +~/.sdkman/candidates/kotlin/2.0.0/bin/kotlinc -h 2>$old -diff $old $new +code --diff --wait $old $new rm -rf $new $old diff --git a/scripts/cliargs.sh b/scripts/cliargs.sh index ebc70f7..0427d9f 100755 --- a/scripts/cliargs.sh +++ b/scripts/cliargs.sh @@ -1,5 +1,5 @@ #!/bin/bash -java -cp "lib/compile/*" org.jetbrains.kotlin.cli.jvm.K2JVMCompiler -h 2> >(grep "^ ") |\ +kotlinc -h 2> >(grep "^ ") |\ sed -e "s/^ //" -e "s/ .*//" -e "s/<.*//" -e '/-help/d' -e '/-version/d' -e '/^$/d'|\ sort > "src/test/resources/kotlinc-args.txt" diff --git a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java index 56752e5..655089f 100644 --- a/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java +++ b/src/bld/java/rife/bld/extension/CompileKotlinOperationBuild.java @@ -42,23 +42,7 @@ public class CompileKotlinOperationBuild extends Project { repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS); - var kotlin = version(2, 0, 0); scope(compile) - .include(dependency("org.jetbrains.kotlin", "kotlin-compiler", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-annotation-processing", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-scripting-compiler", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-reflect", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin)) - .include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core-jvm", version(1, 9, 0, "RC"))) - // Compiler Plugins - .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-assignment-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-serialization-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-lombok-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-allopen-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-noarg-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-power-assert-compiler-plugin", kotlin)) - .include(dependency("org.jetbrains.kotlin", "kotlin-sam-with-receiver-compiler-plugin", kotlin)) .include(dependency("com.uwyn.rife2", "bld", version(2, 0, 0, "SNAPSHOT"))); scope(test) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) diff --git a/src/main/java/rife/bld/extension/CompileKotlinOperation.java b/src/main/java/rife/bld/extension/CompileKotlinOperation.java index 7ee13b5..3b184ee 100644 --- a/src/main/java/rife/bld/extension/CompileKotlinOperation.java +++ b/src/main/java/rife/bld/extension/CompileKotlinOperation.java @@ -16,7 +16,6 @@ package rife.bld.extension; -import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import rife.bld.BaseProject; import rife.bld.extension.kotlin.CompileOptions; import rife.bld.extension.kotlin.CompilerPlugin; @@ -26,7 +25,7 @@ import rife.tools.FileUtils; import java.io.File; import java.io.IOException; -import java.time.format.DateTimeFormatter; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -52,32 +51,9 @@ public class CompileKotlinOperation extends AbstractOperation getJarList(File directory, String regex) { - var jars = new ArrayList(); - - if (directory.isDirectory()) { - var files = directory.listFiles(); - if (files != null) { - for (var f : files) { - if (!f.getName().endsWith("-sources.jar") && (!f.getName().endsWith("-javadoc.jar")) && - f.getName().matches(regex)) { - jars.add(f.getAbsolutePath()); - } - } - } - } - - return jars; - } + private File workDir_; /** * Determines if the given string is not blank. @@ -222,6 +198,18 @@ public class CompileKotlinOperation extends AbstractOperation classpath, Collection sources, File destination, File friendPaths) - throws ExitStatusException { + throws ExitStatusException, InterruptedException, IOException { if (sources.isEmpty() || destination == null) { return; } - var k2 = new K2JVMCompiler(); - var args = new ArrayList(); + var kotlinc = Path.of(kotlinHome_.getAbsolutePath(), "bin", "kotlinc").toFile(); - // classpath - args.add("-cp"); - args.add(FileUtils.joinPaths(classpath.stream().toList())); + if (kotlinc.exists() && kotlinc.canExecute()) { + var args = new ArrayList(); - // destination - args.add("-d"); - args.add(destination.getAbsolutePath()); + // kotlinc + args.add(kotlinc.getAbsolutePath()); - // friend-path - if (friendPaths != null && friendPaths.exists()) { - args.add("-Xfriend-paths=" + friendPaths.getAbsolutePath()); - } + // classpath + args.add("-cp"); + args.add(FileUtils.joinPaths(classpath.stream().toList())); - // options - if (compileOptions_ != null) { - args.addAll(compileOptions_.args()); - } + // destination + args.add("-d"); + args.add(destination.getAbsolutePath()); - // plugins - if (!plugins_.isEmpty()) { - plugins_.forEach(p -> args.add("-Xplugin=" + p)); - } + // friend-path + if (friendPaths != null && friendPaths.exists()) { + args.add("-Xfriend-paths=" + friendPaths.getAbsolutePath()); + } - // sources - sources.forEach(f -> args.add(f.getAbsolutePath())); + // options + if (compileOptions_ != null) { + args.addAll(compileOptions_.args()); + } - if (LOGGER.isLoggable(Level.FINE) && !silent()) { - LOGGER.fine("kotlinc " + String.join(" ", args)); - } + // plugins + if (!plugins_.isEmpty()) { + plugins_.forEach(p -> args.add("-Xplugin=" + p)); + } - var exitCode = k2.exec(System.err, args.toArray(String[]::new)); - if (exitCode.getCode() != 0) { - throw new ExitStatusException(exitCode.getCode()); + // sources + sources.forEach(f -> args.add(f.getAbsolutePath())); + + if (LOGGER.isLoggable(Level.FINE) && !silent()) { + LOGGER.fine(String.join(" ", args)); + } + + var pb = new ProcessBuilder(); + pb.inheritIO(); + pb.command(args); + pb.directory(workDir_); + + var proc = pb.start(); + proc.waitFor(); + ExitStatusException.throwOnFailure(proc.exitValue()); + } else { + if (LOGGER.isLoggable(Level.SEVERE) && !silent()) { + LOGGER.severe("The Kotlin compiler could not be found or executed: " + kotlinc.getAbsolutePath()); + } + throw new ExitStatusException(ExitStatusException.EXIT_FAILURE); } } @@ -312,7 +315,7 @@ public class CompileKotlinOperation extends AbstractOperation * Sets the following from the project: *