Skip to content

Commit eddeda4

Browse files
committed
Set Java toolchain to version 17 in library plugin
Configured the ProcessingLibraryPlugin to use Java toolchain version 17 via JavaPluginExtension. Also marked the 'createLibrary' task in dxf library build script as deprecated, recommending use of the 'bundleLibrary' task from the plugin. Add custom Gradle plugin for Processing libraries Introduces a new Gradle plugin module for Processing libraries, including plugin implementation, extension, and configuration classes. Updates the DXF library to use the new plugin and configuration DSL, and adjusts project settings to include and manage the plugin build. Add bundleLibrary task and update library plugin Introduces BundleLibraryFilesTask to handle bundling of Processing library files, replacing the removed CollectLibraryFilesTask. Updates ProcessingLibraryPlugin to register the new bundleLibrary task, which collects the jar, runtime dependencies, examples, javadoc, and generates library.properties. Also adds a 'name' property to ProcessingLibraryConfiguration and comments out the old createLibrary Copy task in dxf's build script. Refactor library bundling logic into task class Moved the logic for bundling Processing library files from the plugin registration into the BundleLibraryFilesTask class. The task now takes a ProcessingLibraryConfiguration and handles copying jars, dependencies, examples, javadocs, and generating library.properties internally. Also made ProcessingLibraryConfiguration serializable for safer Gradle usage. Update library version handling and add zip task Changed ProcessingLibraryConfiguration.version from String to Int for stricter versioning. Added a zipLibrary Gradle task to package the library folder as .zip and .pdex archives. Updated dxf library build script to use new version format and incremented version to 1. Add installLibrary task and update DXF build config Introduces an installLibrary Gradle task to automate Processing library installation using user preferences. Also re-enables the createLibrary copy task in the DXF library build script and removes minRevision/maxRevision constraints from the library configuration. Only run when actually running the task -.- Refactor library author metadata handling Changed the authors field in ProcessingLibraryConfiguration from a list of names to a map of author names to URLs, updating related code to format authors as markdown links. Updated the DXF library build configuration to use the new authors map structure. Added documentation comments to ProcessingLibraryConfiguration properties for clarity.
1 parent 023bfd2 commit eddeda4

File tree

7 files changed

+330
-12
lines changed

7 files changed

+330
-12
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
plugins {
2+
`java-gradle-plugin`
3+
kotlin("jvm") version "2.2.20"
4+
}
5+
6+
gradlePlugin {
7+
plugins {
8+
create("processing.library") {
9+
id = "org.processing.library"
10+
implementationClass = "ProcessingLibraryPlugin"
11+
}
12+
}
13+
}
14+
15+
repositories {
16+
mavenCentral()
17+
}
18+
19+
dependencies {
20+
testImplementation(kotlin("test"))
21+
}
22+
23+
tasks.test {
24+
useJUnitPlatform()
25+
}
26+
kotlin {
27+
jvmToolchain(17)
28+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import org.gradle.api.DefaultTask
2+
import org.gradle.api.GradleException
3+
import org.gradle.api.tasks.Input
4+
import org.gradle.api.tasks.OutputDirectory
5+
import org.gradle.api.tasks.TaskAction
6+
import org.gradle.api.tasks.bundling.Jar
7+
import org.gradle.api.tasks.javadoc.Javadoc
8+
9+
abstract class BundleLibraryFilesTask : DefaultTask() {
10+
@Input
11+
var configuration: ProcessingLibraryConfiguration? = null
12+
13+
@OutputDirectory
14+
val outputDir = project.objects.directoryProperty()
15+
16+
init {
17+
outputDir.convention(project.layout.buildDirectory.dir("library"))
18+
}
19+
20+
@TaskAction
21+
fun bundle() {
22+
val configuration = configuration
23+
?: throw GradleException("Processing library configuration must be provided.")
24+
val libraryName = configuration.name ?: project.name
25+
26+
val buildDir = project.layout.buildDirectory.dir("library/$libraryName").get().asFile
27+
buildDir.mkdirs()
28+
29+
val libDir = buildDir.resolve("library")
30+
libDir.mkdirs()
31+
32+
// Copy the jar file
33+
val jarFile = project.tasks.named("jar", Jar::class.java).get().archiveFile.get().asFile
34+
jarFile.copyTo(libDir.resolve("$libraryName.jar"), overwrite = true)
35+
36+
// Copy all runtime dependencies
37+
val runtimeClasspath = project.configurations.getByName("runtimeClasspath")
38+
runtimeClasspath.resolvedConfiguration.resolvedArtifacts.forEach { artifact ->
39+
val depFile = artifact.file
40+
depFile.copyTo(libDir.resolve(depFile.name), overwrite = true)
41+
}
42+
43+
// Copy Examples folder
44+
val examplesDir = project.projectDir.resolve("examples")
45+
if (!examplesDir.exists() || !examplesDir.isDirectory) {
46+
throw GradleException("Examples folder not found in project directory.")
47+
}
48+
examplesDir.copyRecursively(buildDir.resolve("examples"), overwrite = true)
49+
50+
// Copy javadoc to reference folder
51+
val docsDir = project.tasks.named("javadoc", Javadoc::class.java).get().destinationDir
52+
docsDir?.copyRecursively(buildDir.resolve("reference"), overwrite = true)
53+
54+
// Create library.properties file
55+
val propertiesFile = buildDir.resolve("library.properties")
56+
propertiesFile.bufferedWriter().use { writer ->
57+
val properties = mapOf(
58+
"name" to libraryName,
59+
"version" to (configuration.version ?: "1.0.0"),
60+
"prettyVersion" to (configuration.prettyVersion ?: configuration.version ?: "1.0.0"),
61+
"authors" to (configuration.authors.entries.joinToString(", ") { "[${it.key}](${it.value})" }),
62+
"url" to configuration.url,
63+
"category" to configuration.categories.joinToString(", "),
64+
"sentence" to configuration.sentence,
65+
"paragraph" to configuration.paragraph,
66+
"minRevision" to configuration.minRevision,
67+
"maxRevision" to configuration.maxRevision
68+
)
69+
properties
70+
.filter { it.value != null && it.value.toString().isNotEmpty() }
71+
.forEach { (key, value) ->
72+
writer.write("$key=$value\n")
73+
}
74+
}
75+
propertiesFile.copyTo(buildDir.resolve("../$libraryName.txt"), overwrite = true)
76+
}
77+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import org.gradle.api.Action
2+
import org.gradle.api.model.ObjectFactory
3+
import java.io.Serializable
4+
import javax.inject.Inject
5+
6+
open class ProcessingLibraryExtension @Inject constructor(objects: ObjectFactory) {
7+
var version: String? = null
8+
val library = objects.newInstance(ProcessingLibraryConfiguration::class.java)
9+
fun library(action: Action<ProcessingLibraryConfiguration>) {
10+
action.execute(library)
11+
}
12+
}
13+
14+
open class ProcessingLibraryConfiguration @Inject constructor() : Serializable {
15+
/**
16+
* Name of the library. If not set, the project name will be used.
17+
*/
18+
var name: String? = null
19+
20+
/**
21+
* Version number of the library.
22+
*/
23+
var version: Int? = null
24+
25+
/**
26+
* Pretty version string of the library.
27+
*/
28+
var prettyVersion: String? = null
29+
30+
/**
31+
* Map of author URLs to author names.
32+
*/
33+
var authors: Map<String, String> = emptyMap()
34+
35+
/**
36+
* URL of the library where more information can be found.
37+
*/
38+
var url: String? = null
39+
40+
/**
41+
* List of categories the library belongs to.
42+
*/
43+
var categories: List<String> = emptyList()
44+
45+
/**
46+
* A one-line sentence describing the library.
47+
*/
48+
var sentence: String? = null
49+
50+
/**
51+
* A longer paragraph describing the library.
52+
*/
53+
var paragraph: String? = null
54+
55+
/**
56+
* Minimum Processing revision required.
57+
*/
58+
var minRevision: Int? = null
59+
60+
/**
61+
* Maximum Processing revision supported.
62+
*/
63+
var maxRevision: Int? = null
64+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import org.gradle.api.GradleException
2+
import org.gradle.api.Plugin
3+
import org.gradle.api.Project
4+
import org.gradle.api.plugins.JavaPlugin
5+
import org.gradle.api.plugins.JavaPluginExtension
6+
import org.gradle.api.tasks.bundling.Jar
7+
import org.gradle.api.tasks.bundling.Zip
8+
import org.gradle.api.tasks.javadoc.Javadoc
9+
import org.gradle.jvm.toolchain.JavaLanguageVersion
10+
import java.util.prefs.Preferences
11+
12+
class ProcessingLibraryPlugin : Plugin<Project> {
13+
14+
override fun apply(target: Project) {
15+
val extension = target.extensions.create("processing", ProcessingLibraryExtension::class.java)
16+
target.plugins.apply(JavaPlugin::class.java)
17+
18+
target.repositories.mavenCentral()
19+
target.repositories.maven { it.setUrl("https://jogamp.org/deployment/maven/") }
20+
21+
// Grab processing core if available, otherwise use the published version
22+
val hasCore = try {
23+
val core = target.project(":core")
24+
target.dependencies.add("compileOnly", core)
25+
true
26+
} catch (_: Exception) {
27+
false
28+
}
29+
30+
target.afterEvaluate {
31+
if (!hasCore) {
32+
if (extension.version == null) {
33+
throw GradleException("Processing library version must be specified, please set processing.version in your build.gradle.kts")
34+
}
35+
val processingVersion = extension.version
36+
target.dependencies.add("compileOnly", "org.processing:core:$processingVersion")
37+
}
38+
}
39+
target.extensions.configure(JavaPluginExtension::class.java) { extension ->
40+
extension.toolchain.languageVersion.set(JavaLanguageVersion.of(17))
41+
}
42+
43+
target.plugins.withType(JavaPlugin::class.java) {
44+
val jarTask = target.tasks.named("jar", Jar::class.java)
45+
val javaDocTask = target.tasks.named("javadoc", Javadoc::class.java)
46+
47+
val bundleTask = target.tasks.register("bundleLibrary", BundleLibraryFilesTask::class.java) { task ->
48+
task.configuration = extension.library
49+
task.group = "processing"
50+
task.description = "Creates the Processing library folder with jar, library.properties, and examples."
51+
task.dependsOn(jarTask, javaDocTask)
52+
}
53+
54+
val zipTask = target.tasks.register("zipLibrary", Zip::class.java) { task ->
55+
task.apply {
56+
val libraryName = extension.library.name ?: target.name
57+
val sourceDir = bundleTask.get().outputDir.get().asFile
58+
59+
group = "processing"
60+
description = "Creates a zip & pdex archive of the Processing library folder."
61+
dependsOn(bundleTask)
62+
include("${libraryName}/**")
63+
64+
archiveFileName.set("$libraryName.zip")
65+
from(sourceDir)
66+
destinationDirectory.set(sourceDir)
67+
doLast {
68+
val zip = task.outputs.files.files.first()
69+
zip.copyTo(sourceDir.resolve("$libraryName.pdex"), overwrite = true)
70+
}
71+
}
72+
}
73+
74+
target.tasks.register("installLibrary") { task ->
75+
task.apply {
76+
group = "processing"
77+
dependsOn(zipTask)
78+
doLast {
79+
val preferences = Preferences.userRoot().node("org/processing/app")
80+
81+
val semverRe = Regex("""^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?""")
82+
fun semverKey(v: String): Triple<Long, Boolean, String> {
83+
val m = semverRe.find(v)
84+
val maj = m?.groupValues?.getOrNull(1)?.toLongOrNull() ?: 0L
85+
val min = m?.groupValues?.getOrNull(2)?.toLongOrNull() ?: 0L
86+
val pat = m?.groupValues?.getOrNull(3)?.toLongOrNull() ?: 0L
87+
val pre = m?.groupValues?.getOrNull(4)
88+
val packed = (maj shl 40) or (min shl 20) or pat
89+
return Triple(packed, pre == null, pre ?: "")
90+
}
91+
92+
val installLocations = preferences.get("installLocations", "")
93+
.split(",")
94+
.filter { it.isNotEmpty() }
95+
.mapNotNull {
96+
val parts = it.split("^")
97+
if (parts.size < 2) null else parts[1] to parts[0] // version to path
98+
}
99+
.sortedWith(Comparator { a, b ->
100+
val ka = semverKey(a.first)
101+
val kb = semverKey(b.first)
102+
when {
103+
ka.first != kb.first -> kb.first.compareTo(ka.first)
104+
ka.second != kb.second -> kb.second.compareTo(ka.second)
105+
else -> kb.third.compareTo(ka.third)
106+
}
107+
})
108+
109+
val installPath = installLocations.firstOrNull()?.second
110+
?: throw GradleException("Could not find Processing install location in preferences.")
111+
112+
val libraryName = extension.library.name ?: target.name
113+
val sourceDir = bundleTask.get().outputDir.get().asFile.resolve("$libraryName.pdex")
114+
115+
ProcessBuilder()
116+
.command(installPath, sourceDir.absolutePath)
117+
.inheritIO()
118+
.start()
119+
}
120+
}
121+
}
122+
123+
}
124+
}
125+
}

gradle/plugins/settings.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
plugins {
2+
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
3+
}
4+
5+
include("library")

java/libraries/dxf/build.gradle.kts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
plugins{
2-
java
2+
id("org.processing.library")
3+
}
4+
5+
processing {
6+
library {
7+
version = 1
8+
prettyVersion = "1.0.0"
9+
10+
authors = mapOf(
11+
"The Processing Foundation" to "https://processing.org"
12+
)
13+
url = "https://processing.org/"
14+
categories = listOf("file", "exporter", "dxf")
15+
16+
sentence = "DXF export library for Processing"
17+
paragraph =
18+
"This library allows you to export your Processing drawings as DXF files, which can be opened in CAD applications."
19+
20+
}
321
}
422

523
sourceSets {
@@ -9,27 +27,23 @@ sourceSets {
927
}
1028
}
1129
}
12-
repositories{
13-
mavenCentral()
14-
maven("https://jogamp.org/deployment/maven/")
15-
}
16-
1730
dependencies{
18-
compileOnly(project(":core"))
19-
2031
implementation("com.lowagie:itext:2.1.7")
2132
}
2233

23-
tasks.register<Copy>("createLibrary"){
34+
/**
35+
* @deprecated Legacy task, use 'bundleLibrary' task provided by 'org.processing.library' plugin
36+
*/
37+
tasks.register<Copy>("createLibrary") {
2438
dependsOn("jar")
2539
into(layout.buildDirectory.dir("library"))
2640

27-
from(layout.projectDirectory){
28-
include ("library.properties")
41+
from(layout.projectDirectory) {
42+
include("library.properties")
2943
include("examples/**")
3044
}
3145

32-
from(configurations.runtimeClasspath){
46+
from(configurations.runtimeClasspath) {
3347
into("library")
3448
}
3549

settings.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
rootProject.name = "processing"
2+
3+
pluginManagement {
4+
includeBuild("gradle/plugins")
5+
}
6+
27
include(
38
"core",
49
"core:examples",

0 commit comments

Comments
 (0)