Skip to content

Commit 9c779d2

Browse files
authored
refactor: add gradle plugin (#887)
1 parent f119a39 commit 9c779d2

File tree

9 files changed

+534
-1
lines changed

9 files changed

+534
-1
lines changed

.github/workflows/release.yml

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,39 @@ jobs:
540540
FLAMINGOCK_JRELEASER_GPG_SECRET_KEY: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_SECRET_KEY }}
541541
FLAMINGOCK_JRELEASER_GPG_PASSPHRASE: ${{ secrets.FLAMINGOCK_JRELEASER_GPG_PASSPHRASE }}
542542

543+
flamingock-gradle-plugin:
544+
needs: [ build ]
545+
runs-on: ubuntu-latest
546+
steps:
547+
- name: Checkout project
548+
uses: actions/checkout@v4
549+
550+
- name: Cache Gradle packages
551+
uses: actions/cache@v4
552+
with:
553+
path: |
554+
~/.gradle/caches
555+
~/.gradle/wrapper
556+
~/.gradle/build-cache
557+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
558+
restore-keys: |
559+
${{ runner.os }}-gradle-
560+
561+
- name: Set up JDK 17
562+
uses: actions/setup-java@v4
563+
with:
564+
java-version: '17'
565+
distribution: 'temurin'
566+
567+
- name: Setup Gradle
568+
uses: gradle/actions/setup-gradle@v3
569+
570+
- name: Publish to Gradle Plugin Portal
571+
run: ./gradlew :flamingock-gradle-plugin:publishPlugins
572+
env:
573+
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
574+
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
575+
543576
github-release:
544577
needs: [
545578
flamingock-core,
@@ -580,7 +613,8 @@ jobs:
580613
mongock-importer-couchbase,
581614
flamingock-test-support,
582615
flamingock-springboot-test-support,
583-
flamingock-sql-auditstore
616+
flamingock-sql-auditstore,
617+
flamingock-gradle-plugin
584618
]
585619
uses: ./.github/workflows/github-release.yml
586620
secrets:

buildSrc/src/main/kotlin/flamingock.project-structure.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ val testKitsProjects = setOf(
7373
"couchbase-test-kit"
7474
)
7575

76+
val gradlePluginProjects = setOf(
77+
"flamingock-gradle-plugin"
78+
)
79+
7680
val allProjects = coreProjects + cloudProjects + communityProjects + pluginProjects + targetSystemProjects + externalSystemProjects + utilProjects + legacyProjects + testKitsProjects
7781

7882
// Project classification utilities
@@ -118,11 +122,16 @@ extra["externalSystemProjects"] = externalSystemProjects
118122
extra["utilProjects"] = utilProjects
119123
extra["legacyProjects"] = legacyProjects
120124
extra["testKitsProjects"] = testKitsProjects
125+
extra["gradlePluginProjects"] = gradlePluginProjects
121126
extra["allProjects"] = allProjects
122127

123128
// Apply appropriate plugins based on project type
124129
when {
125130
project == rootProject -> { /* Do not publish root project */ }
131+
name in gradlePluginProjects -> {
132+
// Gradle plugin handles its own publishing via com.gradle.plugin-publish
133+
apply(plugin = "flamingock.license")
134+
}
126135
isBomModule() -> {
127136
apply(plugin = "java-platform")
128137
apply(plugin = "flamingock.license")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
plugins {
2+
`java-gradle-plugin`
3+
`kotlin-dsl`
4+
id("com.gradle.plugin-publish") version "1.2.1"
5+
}
6+
7+
dependencies {
8+
implementation(gradleApi())
9+
testImplementation(kotlin("test"))
10+
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
11+
}
12+
13+
gradlePlugin {
14+
website.set("https://www.flamingock.io/")
15+
vcsUrl.set("https://github.com/flamingock/flamingock-java")
16+
17+
plugins {
18+
create("flamingock") {
19+
id = "io.flamingock"
20+
implementationClass = "io.flamingock.gradle.FlamingockPlugin"
21+
displayName = "Flamingock Gradle Plugin"
22+
description = "Gradle plugin to configure Flamingock with zero boilerplate"
23+
tags.set(listOf(
24+
"flamingock", "change-as-code", "external-systems",
25+
"application-evolution", "gradle-plugin"
26+
))
27+
}
28+
}
29+
}
30+
31+
tasks.processResources {
32+
filesMatching("flamingock-plugin.properties") {
33+
expand("pluginVersion" to project.version)
34+
}
35+
}
36+
37+
java {
38+
toolchain {
39+
languageVersion.set(JavaLanguageVersion.of(8))
40+
}
41+
}
42+
43+
tasks.test {
44+
useJUnitPlatform()
45+
}
46+
47+
publishing {
48+
publications {
49+
withType<MavenPublication> {
50+
pom {
51+
name.set("Flamingock Gradle Plugin")
52+
description.set("Gradle plugin to configure Flamingock with zero boilerplate")
53+
url.set("https://www.flamingock.io/")
54+
licenses {
55+
license {
56+
name.set("Apache License, Version 2.0")
57+
url.set("https://www.apache.org/licenses/LICENSE-2.0")
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright 2024 Flamingock (https://www.flamingock.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.flamingock.gradle
17+
18+
/**
19+
* Extension for configuring Flamingock in a Gradle project.
20+
*
21+
* Usage:
22+
* ```
23+
* flamingock {
24+
* community()
25+
* sql()
26+
* mongodb()
27+
* dynamodb()
28+
* couchbase()
29+
* mongock()
30+
* springboot()
31+
* graalvm()
32+
* }
33+
* ```
34+
*/
35+
open class FlamingockExtension {
36+
37+
internal var isCloudEnabled: Boolean = false
38+
private set
39+
40+
internal var isCommunityEnabled: Boolean = false
41+
private set
42+
43+
internal var isMongockEnabled: Boolean = false
44+
private set
45+
46+
internal var isSpringbootEnabled: Boolean = false
47+
private set
48+
49+
internal var isGraalvmEnabled: Boolean = false
50+
private set
51+
52+
internal var isSqlEnabled: Boolean = false
53+
private set
54+
55+
internal var isMongodbEnabled: Boolean = false
56+
private set
57+
58+
internal var isDynamodbEnabled: Boolean = false
59+
private set
60+
61+
internal var isCouchbaseEnabled: Boolean = false
62+
private set
63+
64+
/**
65+
* Enables the Cloud edition of Flamingock.
66+
*
67+
* This is the default edition. If neither [cloud] nor [community] is called,
68+
* cloud is activated automatically.
69+
*
70+
* Adds:
71+
* - `implementation("io.flamingock:flamingock-cloud")`
72+
*/
73+
fun cloud() {
74+
isCloudEnabled = true
75+
}
76+
77+
/**
78+
* Enables the Community edition of Flamingock.
79+
*
80+
* Adds:
81+
* - `implementation("io.flamingock:flamingock-community")`
82+
*/
83+
fun community() {
84+
isCommunityEnabled = true
85+
}
86+
87+
/**
88+
* Enables Mongock compatibility for migrating from Mongock to Flamingock.
89+
*
90+
* Adds:
91+
* - `implementation("io.flamingock:mongock-support")`
92+
* - `annotationProcessor("io.flamingock:mongock-support")`
93+
*/
94+
fun mongock() {
95+
isMongockEnabled = true
96+
}
97+
98+
/**
99+
* Enables Spring Boot integration.
100+
*
101+
* Adds:
102+
* - `implementation("io.flamingock:flamingock-springboot-integration")`
103+
*
104+
* Also switches test support from `flamingock-test-support` to
105+
* `flamingock-springboot-test-support` (which transitively includes the basic one).
106+
*/
107+
fun springboot() {
108+
isSpringbootEnabled = true
109+
}
110+
111+
/**
112+
* Enables GraalVM native image support.
113+
*
114+
* Adds:
115+
* - `implementation("io.flamingock:flamingock-graalvm")`
116+
*/
117+
fun graalvm() {
118+
isGraalvmEnabled = true
119+
}
120+
121+
/**
122+
* Enables SQL support.
123+
*
124+
* Adds:
125+
* - `implementation("io.flamingock:flamingock-sql-template")`
126+
* - `implementation("io.flamingock:flamingock-sql-targetsystem")`
127+
*/
128+
fun sql() {
129+
isSqlEnabled = true
130+
}
131+
132+
/**
133+
* Enables MongoDB support.
134+
*
135+
* Adds:
136+
* - `implementation("io.flamingock:flamingock-mongodb-sync-template")`
137+
* - `implementation("io.flamingock:flamingock-mongodb-sync-targetsystem")`
138+
*
139+
* If [springboot] is also enabled, additionally adds:
140+
* - `implementation("io.flamingock:flamingock-mongodb-springdata-targetsystem")`
141+
*/
142+
fun mongodb() {
143+
isMongodbEnabled = true
144+
}
145+
146+
/**
147+
* Enables DynamoDB support.
148+
*
149+
* Adds:
150+
* - `implementation("io.flamingock:flamingock-dynamodb-targetsystem")`
151+
*/
152+
fun dynamodb() {
153+
isDynamodbEnabled = true
154+
}
155+
156+
/**
157+
* Enables Couchbase support.
158+
*
159+
* Adds:
160+
* - `implementation("io.flamingock:flamingock-couchbase-targetsystem")`
161+
*/
162+
fun couchbase() {
163+
isCouchbaseEnabled = true
164+
}
165+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2024 Flamingock (https://www.flamingock.io)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.flamingock.gradle
17+
18+
import io.flamingock.gradle.internal.DependencyConfigurator
19+
import io.flamingock.gradle.internal.FlamingockConstants
20+
import org.gradle.api.GradleException
21+
import org.gradle.api.Plugin
22+
import org.gradle.api.Project
23+
24+
/**
25+
* Flamingock Gradle Plugin.
26+
*
27+
* Simplifies Flamingock setup by automatically configuring dependencies
28+
* and annotation processors.
29+
*
30+
* Usage:
31+
* ```
32+
* plugins {
33+
* id("io.flamingock") version "1.0.0"
34+
* }
35+
*
36+
* flamingock {
37+
* community()
38+
* mongock() // optional
39+
* springboot() // optional
40+
* graalvm() // optional
41+
* }
42+
* ```
43+
*/
44+
class FlamingockPlugin : Plugin<Project> {
45+
46+
override fun apply(project: Project) {
47+
// Apply java plugin if not already applied
48+
if (!project.plugins.hasPlugin("java")) {
49+
project.plugins.apply("java")
50+
}
51+
52+
// Create and register the extension
53+
val extension = project.extensions.create(
54+
FlamingockConstants.EXTENSION_NAME,
55+
FlamingockExtension::class.java
56+
)
57+
58+
// Configure dependencies after project evaluation
59+
project.afterEvaluate {
60+
validateConfiguration(extension)
61+
DependencyConfigurator.configure(project, extension, FlamingockConstants.FLAMINGOCK_VERSION)
62+
}
63+
}
64+
65+
private fun validateConfiguration(extension: FlamingockExtension) {
66+
if (extension.isCommunityEnabled && extension.isCloudEnabled) {
67+
throw GradleException(
68+
"""
69+
|
70+
|FLAMINGOCK CONFIGURATION ERROR
71+
|
72+
|Both community() and cloud() editions are selected.
73+
|
74+
|Please choose only one:
75+
|
76+
|flamingock {
77+
| community() // OR cloud() (default)
78+
|}
79+
|
80+
""".trimMargin()
81+
)
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)