Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tlinkowski/tlinkowski-superpom
Gradle Settings & Gradle SuperPOM plugins for all projects of Tomasz Linkowski.
https://github.com/tlinkowski/tlinkowski-superpom
configuration gradle gradle-plugin sharing
Last synced: 3 months ago
JSON representation
Gradle Settings & Gradle SuperPOM plugins for all projects of Tomasz Linkowski.
- Host: GitHub
- URL: https://github.com/tlinkowski/tlinkowski-superpom
- Owner: tlinkowski
- License: apache-2.0
- Created: 2019-04-06T11:00:52.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-09-16T03:03:41.000Z (over 5 years ago)
- Last Synced: 2024-01-29T06:16:04.712Z (about 1 year ago)
- Topics: configuration, gradle, gradle-plugin, sharing
- Language: Kotlin
- Homepage: http://superpom.tlinkowski.pl/
- Size: 503 KB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Gradle SuperPOM of Tomasz Linkowski
[![Build (Linux)](https://img.shields.io/travis/com/tlinkowski/tlinkowski-superpom/master.svg?logo=linux)](https://travis-ci.com/tlinkowski/tlinkowski-superpom)
[![Build (Windows)](https://img.shields.io/appveyor/ci/tlinkowski/tlinkowski-superpom/master.svg?logo=windows)](https://ci.appveyor.com/project/tlinkowski/tlinkowski-superpom/branch/master)
[![Code coverage](https://img.shields.io/codecov/c/github/tlinkowski/tlinkowski-superpom.svg)](https://codecov.io/gh/tlinkowski/tlinkowski-superpom)
[![Codacy grade](https://img.shields.io/codacy/grade/81a0cef956a34083accd2f8e401a66de.svg)](https://app.codacy.com/project/tlinkowski/tlinkowski-superpom/dashboard)[![Maven Central](https://img.shields.io/maven-central/v/pl.tlinkowski.gradle.my/pl.tlinkowski.gradle.my.superpom?label=Maven%20Central)](https://search.maven.org/search?q=g:pl.tlinkowski.gradle.my)
[![Javadocs](https://javadoc.io/badge/pl.tlinkowski.gradle.my/pl.tlinkowski.gradle.my.superpom.svg?color=blue)](https://javadoc.io/doc/pl.tlinkowski.gradle.my/pl.tlinkowski.gradle.my.superpom)
[![Semantic Versioning](https://img.shields.io/badge/-semantic%20versioning-333333)](https://semver.org/)
[![Automated Release Notes by gren](https://img.shields.io/badge/%F0%9F%A4%96-release%20notes-00B2EE.svg)](https://github-tools.github.io/github-release-notes/)This project is inspired by [The Gradle SuperPOM](http://andresalmiray.com/the-gradle-superpom/) post by
[Andres Almiray](https://twitter.com/aalmiray).This projects provides two plugins:
1. A Gradle [`Project`](https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html)
plugin (id: [`pl.tlinkowski.gradle.my.superpom`](subprojects/pl.tlinkowski.gradle.my.superpom))2. A Gradle [`Settings`](https://docs.gradle.org/current/javadoc/org/gradle/api/initialization/Settings.html)
plugin (id: [`pl.tlinkowski.gradle.my.settings`](subprojects/pl.tlinkowski.gradle.my.settings))Together, those two plugins preconfigure Gradle builds for each of my projects.
## Usage
### by Tomasz Linkowski
`gradle.properties`:
```properties
# Release scopes: [major, minor, patch]
reckon.scope=minor
# Dependencies
mySuperpomVersion=x.y.z
````settings.gradle.kts`:
```kotlin
buildscript {
repositories {
mavenCentral()
}
dependencies {
val mySuperpomVersion: String by settings
classpath(group = "pl.tlinkowski.gradle.my", name = "pl.tlinkowski.gradle.my.settings", version = mySuperpomVersion)
}
}
apply(plugin = "pl.tlinkowski.gradle.my.settings")
````build.gradle.kts`:
```kotlin
plugins {
id("pl.tlinkowski.gradle.my.superpom")
}
```For a complete usage example, see [sample-project](test-data/sample-project).
### by others
If you like what this plugin does, you can:
1. [Fork](https://github.com/tlinkowski/tlinkowski-superpom/fork) this project.
2. Change data related to Tomasz Linkowski to match your person / organization (especially classes with `My` prefix).
3. Set up your Bintray and Maven Central accounts.
4. Release **your own** version of the Gradle Settings & SuperPOM plugin.## Features
### Settings Plugin (id: `pl.tlinkowski.gradle.my.settings`)
Configures:
1. plugin management:
- Maven Central repository for `pl.tlinkowski.gradle.my.superpom` (this plugin is not deployed to Gradle Plugin
Portal as it's not a general-use plugin)- automatic version resolution for `pl.tlinkowski.gradle.my.superpom`
(using `mySuperpomVersion` property in `gradle.properties`)2. project structure (inspired by [Kordamp project structure](https://aalmiray.github.io/kordamp-gradle-plugins/#_project_structure)):
- subprojects in `subprojects` directory
- build file names changed from `build.gradle.kts` to `.gradle.kts`
- build files required for all subprojects
- subprojects optionally grouped under subdirectories (e.g. `subprojects/sample/pl.tlinkowski.xyz.sample`)### Project Plugin (id: `pl.tlinkowski.gradle.my.superpom`)
#### Project Preconfiguration
This is the basic feature described by Andres Almiray in [his post](http://andresalmiray.com/the-gradle-superpom/).
This SuperPOM plugin can be applied to the **root** project only, and it does the following:
1. for all projects:
- applies: [`idea`](https://docs.gradle.org/current/userguide/idea_plugin.html) plugin
- configures: Maven Central repository
2. for the root project:
- applies:
- [`org.kordamp.gradle.project`](https://aalmiray.github.io/kordamp-gradle-plugins/#_org_kordamp_gradle_project) plugin
- [`org.kordamp.gradle.bintray`](https://aalmiray.github.io/kordamp-gradle-plugins/#_org_kordamp_gradle_bintray) plugin
- [`org.ajoberstar.grgit`](https://github.com/ajoberstar/grgit) plugin
- [`org.ajoberstar.reckon`](https://github.com/ajoberstar/reckon) plugin
- [`com.github.ben-manes.versions`](https://github.com/ben-manes/gradle-versions-plugin) plugin- configures:
- main project properties using
[Kordamp DSL](https://aalmiray.github.io/kordamp-gradle-plugins/#_org_kordamp_gradle_base_dsl)
([`MyCoreConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/MyCoreConfigPlugin.kt))- shared file import tasks (see [direct file sharing](#direct-file-sharing))
- `SNAPSHOT`/`FINAL` release stages for [reckon](https://github.com/ajoberstar/reckon)
([`VersionConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/VersionConfigPlugin.kt))- a [comprehensive release process](#comprehensive-release-process)
- [dependency updates](https://github.com/ben-manes/gradle-versions-plugin): skipping Release Candidates
([`DependencyUpdatesConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/DependencyUpdatesConfigPlugin.kt))- [project Lombok usage](#lombok) (opt-in)
([`LombokConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/LombokConfigPlugin.kt))3. for subprojects:
- applies:
- [`org.javamodularity.moduleplugin`](https://github.com/java9-modularity/gradle-modules-plugin) plugin
(for JPMS support)- [`groovy`](https://docs.gradle.org/current/userguide/groovy_plugin.html) plugin
(for test code: [Spock](http://spockframework.org/))- [`kotlin("jvm")`](https://kotlinlang.org/docs/reference/using-gradle.html) plugin
(for test code: custom helpers)- configures:
- logging of test events
([`TestConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/TestConfigPlugin.kt))- test dependencies on Kotlin, Groovy, and [Spock](http://spockframework.org/)
([`TestConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/TestConfigPlugin.kt))- at `testImplementaton` scope (if
[`superpom.isTestProject`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/extension/MySuperpomExtension.kt)
is `false` — default)- at `api` scope (if `superpom.isTestProject` is `true` — opt-in)
- `compileTestGroovy` dependency on `compileTestKotlin` (so that Spock can access Kotlin helpers)
([`TestConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/TestConfigPlugin.kt))- [running tests on classpath](https://github.com/java9-modularity/gradle-modules-plugin#fall-back-to-classpath-mode)
(necessary as Groovy isn't JPMS-compatible)
([`ModularityConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/ModularityConfigPlugin.kt))- minimum line code coverage = **95%** ([JaCoCo](https://www.jacoco.org/jacoco/))
([`JacocoConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/JacocoConfigPlugin.kt))- project name and module name validation (see [Naming Convention](#naming-convention))
([`NamingConventionEnforcementPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/NamingConventionEnforcementPlugin.kt))- [`Automatic-Module-Name`](https://docs.oracle.com/en/java/javase/12/docs/specs/jar/jar.html#modular-jar-files)
equal to `project.name` (if `module-info.java` is absent)
([`ModularityConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/ModularityConfigPlugin.kt))- publishing to JCenter and Maven Central
([`MyCentralPublishConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/MyCentralPublishConfigPlugin.kt))#### Comprehensive Release Process
This plugin configures a comprehensive release process by:
- exposing `release` Gradle task (which serves as the root of a complex task chain)- providing [shared](#direct-file-sharing) [`release.bat`](release.bat) script
(which simply calls `gradle clean` followed by `gradle release -Preckon.stage=final`)The comprehensive release process is configured by
[`MyComprehensiveReleaseConfigurator`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/configurator/MyComprehensiveReleaseConfigurator.kt)
and includes:1. Release validation (requirements: clean repo, pushed `master` branch, `reckon.stage=final` property)
2. Full clean build (to make 100% sure we can release)
3. Confirmations to make sure the release is going fine
4. Changelog generation (by [gren](https://github.com/github-tools/github-release-notes), requires Node.js)
5. Tagging the release in Git
6. Publishing to GitHub (by [gren](https://github.com/github-tools/github-release-notes), requires Node.js)
7. Publishing to central repos (JCenter & Maven Central)
8. Post-release reset of the release scope for [reckon](https://github.com/ajoberstar/reckon) in `gradle.properties`This is how a Gradle build log of such a release process looks:
```text
> Task :validateReleasePossible // 1> Task ::[...] // 2
> Task ::build // 2> Task ::[...] // 2
> Task ::build // 2> Task :confirmReleaseProcessLaunch // 3
=== Do you want to begin the release process for version 0.1.0 of 'sample-project'? [y/N] ===
y> Task :addTemporaryVersionTag // 4 (required by gren)
> Task :generateChangelog // 4 (gren)
> Task :removeTemporaryVersionTag // 4 (no longer needed)> Task :confirmChangelogPush // 3
=== Do you want to push the updated CHANGELOG.md and continue with the release process? [y/N] ===
y> Task :pushUpdatedChangelog // 4
> Task :addFinalVersionTag // 5> Task :confirmFinalPublication // 3
=== Are you SURE you want to publish the code at 0.1.0 tag to GitHub, JCenter & MavenCentral? [y/N] ===
y> Task :releaseToGitHub // 6 (gren)
> Task ::[...] // 7
> Task ::publishMainPublicationToMavenLocal // 7> Task ::[...] // 7
> Task ::publishMainPublicationToMavenLocal // 7> Task :injectReleasePasswords // 7
> Task ::[...] // 7
> Task ::bintrayUpload // 7> Task ::[...] // 7
> Task ::bintrayUpload // 7> Task :bintrayPublish // 7
> Task :releaseToCentralRepos // 7
> Task :release
> Task :resetScopeInGradleProperties // 8
> Task :pushUpdatedGradleProperties // 8
```Note the
[`injectReleasePasswords`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/task/InjectReleasePasswordsTask.kt)
task, which obtains the following passwords for performing a release:- `bintrayApiKey`: from Gradle properties (i.e. `~/.gradle/gradle.properties`),
- `gnupgPassphrase`, `sonatypePassword`: by requesting them in a Swing dialog (not suitable for CI)Also, note that thanks to [reckon](https://github.com/ajoberstar/reckon) plugin, we don't need to do the classic
"pre-release version bumps". Instead, we:- automatically reset the version scope after a release to `patch` (= "post-release version bump")
- manually change the scope to `minor` or `major` whenever we commit any changes that are in such scope#### Gradle Configuration Sharing
A large part of the build configuration for:
- this (*source*) project
(defined mostly in the included [`buildSrc`](buildSrc) build), and- *target* projects
(defined in [`pl.tlinkowski.gradle.my.superpom`](subprojects/pl.tlinkowski.gradle.my.superpom) plugin project)is *shared* as [`pl.tlinkowski.gradle.my.superpom.shared`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared)
package (see [`MyCompleteSharedConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/MyCompleteSharedConfigPlugin.kt)).Thanks to this, we don't have to:
- duplicate large portions of configuration between the *source* and *target* projects, nor
- apply the previous version of this plugin to itself to avoid the duplication mentioned above
(as Andres Almiray suggests in [his post](http://andresalmiray.com/the-gradle-superpom/))- such approach would be problematic for [direct file sharing](#direct-file-sharing)
This is achieved by synchronizing the contents of the SuperPOM plugin's
[`shared`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared)
package with a corresponding `shared` package in `buildSrc`
(see [`buildSrc/build.gradle.kts`](buildSrc/build.gradle.kts) for details).#### Gradle Property Sharing
Gradle properties at [`gradle/shared-gradle.properties`](gradle/shared-gradle.properties) are shared by
[`SuperpomSharedFileExportPlugin`](buildSrc/src/main/kotlin/pl/tlinkowski/gradle/my/buildsrc/plugin/SuperpomSharedFileExportPlugin.kt)
(a part of [direct file sharing](#direct-file-sharing) mechanism). Then, these properties are imported by:- by [`shared-gradle-properties.gradle.kts`](gradle/shared-gradle-properties.gradle.kts),
for [`buildSrc`](buildSrc), root [`settings.gradle.kts`](settings.gradle.kts),
and root [`build.gradle.kts`](build.gradle.kts)- by [`SuperpomSharedGradlePropertyImportPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/internal/plugin/SuperpomSharedGradlePropertyImportPlugin.kt),
for all *target* projectsIf a shared property to be imported already exists, it's ignored with a warning.
#### Direct File Sharing
Selected files in this project can be directly exported to projects that apply this SuperPOM plugin. It can be viewed
as a "sync" operation between this (*source*) project and all *target* projects.The files to be shared are specified in
[`SuperpomFileSharing`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/SuperpomFileSharing.kt)
(usually, it's a good idea to git-ignore them in *target* projects). Currently, the following files are shared *directly*:- `idea`: parts of IntelliJ configuration from [`.idea`](.idea) directory
(subdirectories `codeStyles`, `copyright`, `inspectionProfiles`)- `release`: files related to releasing, like [`release.bat`](release.bat) script and Node.js configuration for
[gren](https://github.com/github-tools/github-release-notes)- `ci`: configuration for Continuous Integration environments, i.e. [`.appveyor.yml`](.appveyor.yml) and
[`.travis.yml`](.travis.yml) files (these files should *not* be git-ignored in *target* projects)- `lombok`: [Lombok configuration](https://projectlombok.org/features/configuration),
i.e. [`lombok.config`](lombok.config) fileThis feature is implemented:
- in [`SuperpomSharedFileExportPlugin`](buildSrc/src/main/kotlin/pl/tlinkowski/gradle/my/buildsrc/plugin/SuperpomSharedFileExportPlugin.kt),
by registering a special `exportSharedFiles` task for this (*source*) project- the task zips files to be exported and places the resulting archive in the
[resources](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/resources) of the SuperPOM plugin- in [`SuperpomSharedFileImportPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/internal/plugin/SuperpomSharedFileImportPlugin.kt),
by registering a special `importSharedFiles` task for a *target* project- the task reads the archive as a resource and unzips it in the corresponding location
#### Lombok
If [`superpom.useLombok`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/extension/MySuperpomExtension.kt)
is `true`, this plugin (through [`LombokConfigPlugin`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/LombokConfigPlugin.kt)):- adds `compileOnly` and `annotationProcessor` dependencies on [Project Lombok](https://projectlombok.org/)
(like [`gradle-lombok`](https://github.com/franzbecker/gradle-lombok) plugin)- configures [`delombokJava`](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/task/DelombokJavaTask.kt)
task, which generates [delomboked](https://projectlombok.org/features/delombok) version of the main Java source code
(like [`gradle-delombok`](https://github.com/lukoerfer/gradle-delombok) plugin, but in a JPMS-compatible way)- configures `javadoc` task to use the delomboked source code as its source
(otherwise, JavaDoc wouldn't reflect code generated by Lombok at all)## Naming Convention
This project applies a
[naming convention for Maven & JPMS by Christian Stein](https://sormuras.github.io/blog/2019-08-04-maven-coordinates-and-java-module-names).
In short:
> Gradle project name = JPMS module nameThe SuperPOM plugin [enforces this convention](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/plugin/NamingConventionEnforcementPlugin.kt)
by ensuring that the Gradle project name (i.e. Maven `artifactId`):- starts with Maven `groupId`
- is a prefix of every package in the project
- equals JPMS module name (only if `module-info.java` is present)
- is [valid](subprojects/pl.tlinkowski.gradle.my.superpom/src/main/kotlin/pl/tlinkowski/gradle/my/superpom/shared/internal/ModuleNameValidator.kt)
automatic JPMS module name (only if `module-info.java` is absent)## Requirements
Gradle 5+, JDK 11+.
## About the Author
See my webpage ([tlinkowski.pl](https://tlinkowski.pl/)) or
find me on Twitter ([@t_linkowski](https://twitter.com/t_linkowski)).