├── .appveyor.yml
├── .github
├── dependabot.yml
└── workflows
│ └── CI.yml
├── .gitignore
├── .yo-rc.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
├── main
└── groovy
│ └── ru
│ └── vyarus
│ └── gradle
│ └── plugin
│ └── lib
│ ├── JavaLibExtension.groovy
│ └── JavaLibPlugin.groovy
└── test
├── groovy
└── ru
│ └── vyarus
│ └── gradle
│ └── plugin
│ └── lib
│ ├── AbstractKitTest.groovy
│ ├── AbstractTest.groovy
│ ├── ConfigurationCacheSupportKitTest.groovy
│ ├── EncodingConfigurationTest.groovy
│ ├── GradleMetadataDisableKitTest.groovy
│ ├── GradlePluginCompatibilityKitTest.groovy
│ ├── GradlePluginCompatibilityTest.groovy
│ ├── JarModificationKitTest.groovy
│ ├── JavaLibPluginKitTest.groovy
│ ├── JavaLibPluginTest.groovy
│ ├── JavaPlatformKitTest.groovy
│ ├── LegacyModeKitTest.groovy
│ ├── OpenDepsReportTasksTest.groovy
│ ├── PomConfigurationTest.groovy
│ ├── PomCorrectnessKitTest.groovy
│ ├── PublicationOverrideKitTest.groovy
│ ├── ReportsAggregationKitTest.groovy
│ ├── ReportsAggregationTest.groovy
│ ├── SigningKitTest.groovy
│ └── UpstreamKitTest.groovy
└── resources
├── cert
└── test.gpg
└── sample
├── Sample.java
├── Sample2.java
├── SampleTest.groovy
├── SampleTest2.groovy
└── TestPlugin.java
/.appveyor.yml:
--------------------------------------------------------------------------------
1 | version: '{build}'
2 |
3 | environment:
4 | matrix:
5 | - job_name: Java 8
6 | JAVA_HOME: C:\Program Files\Java\jdk1.8.0
7 | - job_name: Java 11
8 | JAVA_HOME: C:\Program Files\Java\jdk11
9 | - job_name: Java 17
10 | appveyor_build_worker_image: Visual Studio 2019
11 | JAVA_HOME: C:\Program Files\Java\jdk17
12 |
13 | build_script:
14 | - ./gradlew assemble --no-daemon
15 | test_script:
16 | - ./gradlew check --no-daemon
17 |
18 | on_success:
19 | - ./gradlew jacocoTestReport --no-daemon
20 | - ps: |
21 | $ProgressPreference = 'SilentlyContinue'
22 | Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile codecov.exe
23 | .\codecov.exe -f build\reports\jacoco\test\jacocoTestReport.xml -F windows
24 |
25 | cache:
26 | - C:\Users\appveyor\.gradle\caches
27 | - C:\Users\appveyor\.gradle\wrapper
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gradle
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "23:00"
8 | open-pull-requests-limit: 10
9 |
--------------------------------------------------------------------------------
/.github/workflows/CI.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | name: Java ${{ matrix.java }}
11 | strategy:
12 | matrix:
13 | java: [8, 11, 17]
14 |
15 | steps:
16 | - uses: actions/checkout@v4
17 |
18 | - name: Set up JDK ${{ matrix.java }}
19 | uses: actions/setup-java@v4
20 | with:
21 | distribution: 'zulu'
22 | java-version: ${{ matrix.java }}
23 |
24 | - name: Setup Gradle
25 | uses: gradle/actions/setup-gradle@v3
26 |
27 | - name: Build
28 | run: |
29 | chmod +x gradlew
30 | ./gradlew assemble --no-daemon
31 |
32 | - name: Test
33 | env:
34 | GH_ACTIONS: true
35 | run: ./gradlew check --no-daemon
36 |
37 | - name: Build coverage report
38 | if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
39 | run: ./gradlew jacocoTestReport --no-daemon
40 |
41 | - uses: codecov/codecov-action@v4
42 | if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
43 | with:
44 | files: build/reports/jacoco/test/jacocoTestReport.xml
45 | flags: LINUX
46 | fail_ci_if_error: true
47 | token: ${{ secrets.CODECOV_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created with https://www.gitignore.io
2 |
3 | ### Gradle ###
4 | .gradle/
5 | build/
6 |
7 | # Ignore Gradle GUI config
8 | gradle-app.setting
9 |
10 | ### JetBrains ###
11 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
12 |
13 | /*.iml
14 |
15 | ## Directory-based project format:
16 | .idea/
17 |
18 | ## File-based project format:
19 | *.ipr
20 | *.iws
21 |
22 | ## Plugin-specific files:
23 |
24 | # IntelliJ
25 | out/
26 |
27 | # mpeltonen/sbt-idea plugin
28 | .idea_modules/
29 |
30 | # JIRA plugin
31 | atlassian-ide-plugin.xml
32 |
33 | # Crashlytics plugin (for Android Studio and IntelliJ)
34 | com_crashlytics_export_strings.xml
35 |
36 |
37 | ### Eclipse ###
38 | *.pydevproject
39 | .metadata
40 | bin/
41 | tmp/
42 | *.tmp
43 | *.bak
44 | *.swp
45 | *~.nib
46 | local.properties
47 | .settings/
48 | .loadpath
49 |
50 | # External tool builders
51 | .externalToolBuilders/
52 |
53 | # Locally stored "Eclipse launch configurations"
54 | *.launch
55 |
56 | # CDT-specific
57 | .cproject
58 |
59 | # PDT-specific
60 | .buildpath
61 |
62 | # sbteclipse plugin
63 | .target
64 |
65 | # TeXlipse plugin
66 | .texlipse
67 |
68 | ### Java ###
69 | *.class
70 |
71 | # Mobile Tools for Java (J2ME)
72 | .mtj.tmp/
73 |
74 | # Package Files #
75 | *.war
76 | *.ear
77 |
78 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
79 | hs_err_pid*
80 |
81 |
82 | ### NetBeans ###
83 | nbproject/private/
84 | nbbuild/
85 | dist/
86 | nbdist/
87 | nbactions.xml
88 | nb-configuration.xml
89 |
90 |
91 | ### OSX ###
92 | .DS_Store
93 | .AppleDouble
94 | .LSOverride
95 |
96 | # Icon must end with two \r
97 | Icon
98 |
99 |
100 | # Thumbnails
101 | ._*
102 |
103 | # Files that might appear on external disk
104 | .Spotlight-V100
105 | .Trashes
106 |
107 | # Directories potentially created on remote AFP share
108 | .AppleDB
109 | .AppleDesktop
110 | Network Trash Folder
111 | Temporary Items
112 | .apdisk
113 |
114 |
115 | ### Windows ###
116 | # Windows image file caches
117 | Thumbs.db
118 | ehthumbs.db
119 |
120 | # Folder config file
121 | Desktop.ini
122 |
123 | # Recycle Bin used on file shares
124 | $RECYCLE.BIN/
125 |
126 | # Windows Installer files
127 | *.cab
128 | *.msi
129 | *.msm
130 | *.msp
131 |
132 | # Windows shortcuts
133 | *.lnk
134 |
135 |
136 | ### Linux ###
137 | *~
138 |
139 | # KDE directory preferences
140 | .directory
141 |
142 | ### JEnv ###
143 | # JEnv local Java version configuration file
144 | .java-version
145 |
146 | # Used by previous versions of JEnv
147 | .jenv-version
148 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-gradle-plugin": {
3 | "githubUser": "xvik",
4 | "authorName": "Vyacheslav Rusakov",
5 | "authorEmail": "vyarus@gmail.com",
6 | "projectName": "gradle-java-lib-plugin",
7 | "projectGroup": "ru.vyarus",
8 | "projectPackage": "ru.vyarus.gradle.plugin.lib",
9 | "projectVersion": "0.1.0",
10 | "projectDesc": "Gradle Java-lib plugin",
11 | "pluginPortalDesc": "Common gradle configuration for Java or Groovy library",
12 | "pluginPortalTags": "java, groovy, lib",
13 | "pluginPortalUseCustomGroup": true,
14 | "usedGeneratorVersion": "2.0.0",
15 | "centralPublish": true
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 3.0.0 (2024-03-10)
2 | * (BREAKING) Drop gradle 5 and 6 support
3 | * (BREAKING) Always use native javadoc and source jars tasks (withJavadocJar() and withSourcesJar())
4 | (before, custom legacy tasks were used for gradle 7.6 and older)
5 | * Cleanup deprecated gradle api usages
6 | * Update pom plugin to 3.0.0 (drops pom convention in favor of type-safe maven.pom)
7 | - (BREAKING) Remove pom plugin configuration shortcut (javaLib.pom) to avoid confusion (use maven extension directly)
8 | * Fix signing error when used with plugin-publish plugin
9 | * Configuration cache compatibility
10 |
11 | ### 2.4.0 (2023-02-16)
12 | * Gradle 8 compatibility
13 | * Fix plugin-publish 1.0 compatibility for gradle 7.6 and above
14 | (older gradle versions should use plugin-publish 0.21)
15 | * (breaking) For gradle 7.6 and above use native gradle registration of javadoc sources tasks
16 | (withJavadocJar() and withSourcesJar()).
17 | Related changes:
18 | - javadoc jar always created (even if no sources)
19 | - groovydoc artifact not created (always javadoc)
20 | For gradle older 7.6 legacy behaviour preserved
21 |
22 | ### 2.3.1 (2022-11-09)
23 | * Updated pom plugin (2.2.2): support repositories declaration in settings file only
24 |
25 | ### 2.3.0 (2021-11-01)
26 | * Updated pom plugin (2.2.1): automatic detection of incorrect pom closure usage
27 | * Fix gradle 7 warnings
28 | * Remove jacocoMerge task (used for jacoco executions data merge during reports aggregation):
29 | jacocoTestReport (JacocoReport) merges coverage data directly now
30 |
31 | ### 2.2.2 (2021-10-03)
32 | * Add disable publication option: javaLib.withoutPublication() (disables all declared publications)
33 | Useful for disabling bom publication in the root project (use platform for deps management only)
34 | * Fix aggregated coverage report for case when not all submodules produce coverage
35 |
36 | ### 2.2.1 (2021-07-13)
37 | * Fix multi-module projects configuration with allprojects closure
38 | (configuration extension always created on plugin activation to avoid mis-references)
39 |
40 | ### 2.2.0 (2021-06-22)
41 | * Updated pom plugin (2.2.0): java-platform compatibility
42 | * Add java-platform plugin support (assuming declared platform published as BOM):
43 | - activates platform dependencies (javaPlatform.allowDependencies())
44 | - register pom plugin
45 | - add install task
46 | - registers "bom" publication (intentionally different name)
47 | - configures signing if signing plugin enabled
48 | - allows overriding default artifact name with javaLib.bom configuration
49 | (by default it's a root project name)
50 | * Add automatic signing configuration when 'signing' plugin applied
51 | (for snapshots signing not required - for release, not configured signing would fail)
52 | * Add openDependencyReport task when project-report plugin enabled
53 | (task opens htmlDependencyReport directly in the browser)
54 | * Enable jacoco xml report by default (required for coverage services)
55 | * Multi-module projects support: test and coverage reports aggregation
56 | (at least "base" plugin must be applied to trigger minimal java-lib plugin activation )
57 | * Add `javaLib` configuration closure:
58 | - withoutGradleMetadata() - disables gradle metadata publishing
59 | - withoutJavadoc() and withoutSources() - disable javadoc and sources publish
60 | - bom.artifactId and bom.description properties - updates artifact declared with java-platform
61 | - pom - shortcut for the new pom plugin configuration closure (to use instead of pomGeneration)
62 | - autoModuleName - shortcut for defining Automatic-Module-Name manifest property
63 | - aggregateReports() - supposed to be used in the root project to aggregate
64 | test reports and jacoco coverage (adds test and jacocoTestReport tasks)
65 | Also, aggregates dependency report id project-report plugin enabled
66 |
67 | ### 2.1.0 (2020-01-19)
68 | * Updated pom plugin (2.1.0):
69 | - Brings back `provided` and `optional` scopes, because gradle native features can't completely replace them
70 | - `compileOnly` dependencies no more added to pom (default behaviour reverted)
71 |
72 | Versions 2.0.0 and 2.0.1 are not recommended for usage because of referenced pom plugin
73 | (there was an attempt to replace optional and provided configurations with native gradle features,
74 | but it failed: custom configurations still required).
75 |
76 | ### 2.0.1 (2020-01-19) DON'T USE
77 | * Updated pom plugin (2.0.1) containing fix for provided dependencies declared with BOM
78 | * Revert to old behaviour: in case of gradle plugin project use "maven" publication because its not possible
79 | to differentiate gralde plugin from usual project. In any case, artifacts will be exactly the same everywhere
80 | (plugin-publish javadoc and sources tasks will be disabled).
81 |
82 | ### 2.0.0 (2020-01-17) DON'T USE
83 | * (breaking) Requires gradle 5.1 and above
84 | - Remove legacy (lazy, without strict publishing) publication configuration
85 | * (breaking) Drop java 7 support
86 | * (breaking) Updated pom plugin ([2.0.0](https://github.com/xvik/gradle-pom-plugin/releases/tag/2.0.0)) removes provided and optional scopes
87 | - provided scope replaced with standard compileOnly configuration support
88 | * Use gradle configuration avoidance to prevent not used tasks creation
89 | * Set UTF-8 encoding for JavaCompile and GroovyCompile tasks
90 | * Set file.encoding=UTF-8 system property for Test tasks
91 | * Set UTF-8 encoding for javadoc task (encoding, charSet, docencoding)
92 | * Gradle plugin projects compatibility fixes:
93 | - When used with java-gardle-plugin, re-use pluginMaven publication instead of creating
94 | new one (because java-gardle-plugin hardcode publication name and it has to init it because of alias publications )
95 | - Plugin-publish will not create his own javadoc and sources tasks (so java-lib tasks will be used)
96 |
97 | ### 1.1.2 (2018-07-22)
98 | * Fix missed pom dependencies
99 | * Unify stable/lazy behaviours
100 |
101 | ### 1.1.1 (2018-07-13)
102 | * Fix stable publishing detection
103 |
104 | ### 1.1.0 (2018-07-13)
105 | * Gradle 4.8 [STABLE_PUBLISHING](https://docs.gradle.org/4.8/userguide/publishing_maven.html#publishing_maven:deferred_configuration) support
106 | - Plugin requires gradle 4.6 or above (will fail on earlier gradle).
107 | - Gradle 4.6, 4.7 - legacy mode (as before)
108 | - (breaking) Gradle 4.8, <5.0 - updated pom plugin (1.3.0) will automatically enable STABLE_PUBLISHING mode
109 | - Gradle 5.0 and above - assumed stable publishing enabled by default
110 |
111 | Important: when STABLE_PUBLISHING is enabled (gradle 4.8 and above) publishing configurations will NOT work
112 | in a lazy way as before. Use `afterEvaluate {}` INSIDE publication configuration in order to configure lazy properties
113 |
114 | ### 1.0.5 (2017-08-15)
115 | * Update pom plugin (support gradle java-library plugin)
116 |
117 | ### 1.0.4 (2016-09-05)
118 | * Update pom plugin (fix non string values support, add clashing tag names workaround, add manual xml configuration shortcut)
119 |
120 | ### 1.0.3 (2016-07-29)
121 | * Update pom plugin (fix pom closure merge for repeatable tags like developers)
122 |
123 | ### 1.0.2 (2016-05-20)
124 | * Update pom plugin (fix pom dependencies scopes update)
125 |
126 | ### 1.0.1 (2015-12-05)
127 | * groovydocJar use javadoc classifier if no java sources available (because maven central requires javadoc for publication)
128 | * Generate pom.properties inside jar's META-INF (like maven)
129 |
130 | ### 1.0.0 (2015-11-23)
131 | * Initial release
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2023 Vyacheslav Rusakov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Gradle Java-lib plugin
2 | [](http://www.opensource.org/licenses/MIT)
3 | [](https://github.com/xvik/gradle-java-lib-plugin/actions/workflows/CI.yml)
4 | [](https://ci.appveyor.com/project/xvik/gradle-java-lib-plugin)
5 | [](https://codecov.io/gh/xvik/gradle-java-lib-plugin)
6 |
7 |
8 | ### About
9 |
10 | Plugin do all boilerplate of maven publication configuration (using [maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html))
11 | for java (or groovy) library or gradle plugin. Simplifies POM configuration and dependencies management (BOM).
12 | Also, changes some defaults common for java projects (like UTF-8 usage).
13 |
14 | Makes gradle more "maven" (in sense of simplicity, some behaviours and for [multi-module projects](#maven-like-multi-module-project)).
15 |
16 | Features:
17 |
18 | * Maven-like `jar` configuration
19 | - put `pom.xml` and `pom.properties` inside jar
20 | - fill manifest properties
21 | * Configure javadoc and sources artifacts (required for maven central publish)
22 | (with native gradle integrations)
23 | * Prepare maven publication (`maven-publish` plugin configuration)
24 | - `maven` publication configured with all jars (jar, sources javadoc)
25 | * Applies [pom plugin](https://github.com/xvik/gradle-pom-plugin) which:
26 | - Fix [dependencies scopes](https://github.com/xvik/gradle-pom-plugin/#dependencies)
27 | in generated pom
28 | - Add `maven.pom` configuration to [simplify pom definition](https://github.com/xvik/gradle-pom-plugin#pom-configuration).
29 | - Add `maven.withPomXml` configuration closure to use if you [need manual xml configuration](https://github.com/xvik/gradle-pom-plugin#manual-pom-modification)
30 | * Add `install` task as shortcut for `publishToMavenLocal` (simpler to use)
31 | * Apply `UTF-8` encoding for:
32 | - compile tasks: `JavaCompile` and `GroovyCompile`
33 | - javadoc (encoding, charSet, docEncoding)
34 | - test tasks: set `file.encoding=UTF-8` system property (only for test tasks)
35 | * Prepares BOM publication for [java-platform](https://docs.gradle.org/current/userguide/java_platform_plugin.html) plugin
36 | * Test and coverage reports aggregation for multi-module projects
37 | * Simplifies gradle platforms usage in multi-module projects (avoid "platform" leaking in published poms)
38 |
39 | If you need [multiple publications](https://docs.gradle.org/current/userguide/publishing_maven.html#N17EB8) from the same project,
40 | then you will have to perform additional configuration or, maybe (depends on case), use only [pom plugin](https://github.com/xvik/gradle-pom-plugin).
41 |
42 | **Confusion point**: plugin named almost the same as gradle's own [java-library](https://docs.gradle.org/current/userguide/java_library_plugin.html) plugin,
43 | but plugins do *different things* (gradle plugin only provides `api` and `implementation` configurations) and plugins *could* be used together.
44 |
45 | ##### Summary
46 |
47 | * Configuration closures: `maven` (from pom plugin), `javaLib`
48 | * Tasks: `sourcesJar`, `javadocJar`, `install`, `openDependencyReport`
49 | * [Publication](https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:publications): `maven`, `bom`
50 | * Enable plugins: [maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html),
51 | [ru.vyarus.pom](https://github.com/xvik/gradle-pom-plugin)
52 |
53 | ### Setup
54 |
55 | [](https://maven-badges.herokuapp.com/maven-central/ru.vyarus/gradle-java-lib-plugin)
56 | [](https://plugins.gradle.org/plugin/ru.vyarus.java-lib)
57 |
58 | ```groovy
59 | buildscript {
60 | repositories {
61 | gradlePluginPortal()
62 | }
63 | dependencies {
64 | classpath 'ru.vyarus:gradle-java-lib-plugin:3.0.0'
65 | }
66 | }
67 | apply plugin: 'ru.vyarus.java-lib'
68 | ```
69 |
70 | OR
71 |
72 | ```groovy
73 | plugins {
74 | id 'ru.vyarus.java-lib' version '3.0.0'
75 | }
76 | ```
77 |
78 | #### Compatibility
79 |
80 | Plugin compiled for java 8, compatible with java 17
81 |
82 | Gradle | Version
83 | --------|-------
84 | 7 | 3.0.0
85 | 5.1 | [2.4.0](https://github.com/xvik/gradle-java-lib-plugin/tree/2.4.0)
86 | 4.6 | [1.1.2](https://github.com/xvik/gradle-java-lib-plugin/tree/1.1.2)
87 | older | [1.0.5](https://github.com/xvik/gradle-java-lib-plugin/tree/1.0.5)
88 |
89 | NOTE: plugin-publish 1.x would work properly only with gradle 7.6 or above
90 |
91 | #### Snapshots
92 |
93 |
94 | Snapshots may be used through JitPack
95 |
96 | * Go to [JitPack project page](https://jitpack.io/#ru.vyarus/gradle-java-lib-plugin)
97 | * Select `Commits` section and click `Get it` on commit you want to use
98 | or use `master-SNAPSHOT` to use the most recent snapshot
99 |
100 | * Add to `settings.gradle` (top most!) (exact commit hash might be used as version):
101 |
102 | ```groovy
103 | pluginManagement {
104 | resolutionStrategy {
105 | eachPlugin {
106 | if (requested.id.id == 'ru.vyarus.java-lib') {
107 | useModule('ru.vyarus:gradle-java-lib-plugin:master-SNAPSHOT')
108 | }
109 | }
110 | }
111 | repositories {
112 | gradlePluginPortal()
113 | maven { url 'https://jitpack.io' }
114 | }
115 | }
116 | ```
117 | * Use plugin without declaring version:
118 |
119 | ```groovy
120 | plugins {
121 | id 'ru.vyarus.java-lib'
122 | }
123 | ```
124 |
125 |
126 |
127 | ### Usage
128 |
129 | Plugin activate features based on registered plugins. Plugin support several usage scenarios.
130 |
131 | In case of multi-module projects, plugin activate features only in applied module, ignoring submodules or root module
132 | (so to apply it in all submodules use `allprojects` or `subprojects` section)
133 |
134 | Example projects:
135 |
136 | * [Java library](https://github.com/xvik/dropwizard-guicey), published to maven central
137 | * [Multi-module java library](https://github.com/xvik/dropwizard-guicey-ext) (with BOM), published to maven central
138 | * [Simple multi-module library](https://github.com/xvik/yaml-updater) (without BOM), published to maven central
139 | * [This project](https://github.com/xvik/gradle-java-lib-plugin/blob/master/build.gradle) is an example of gradle plugin publication to maven central and plugins portal
140 |
141 |
142 | #### Java module
143 |
144 | ```groovy
145 | plugins {
146 | id 'java' // groovy or java-library
147 | // id 'signing'
148 | // id 'project-report'
149 | id 'ru.vyarus.java-lib'
150 | }
151 |
152 | group = 'your.group'
153 | version = '1.0.0'
154 | description = 'My project description'
155 |
156 | // configure target pom
157 | maven.pom {
158 | name = 'Project Name'
159 | description = 'My awesome project'
160 | ...
161 | }
162 |
163 | repositories { mavenLocal(); mavenCentral() }
164 | dependencies {
165 | ...
166 | }
167 |
168 | javaLib {
169 | // withoutJavadoc()
170 | // withoutSources()
171 | withoutGradleMetadata()
172 |
173 | // autoModuleName = 'project-module-name'
174 |
175 | pom {
176 | // removeDependencyManagement()
177 | // forceVersions()
178 | // disableScopesCorrection()
179 | // disableBomsReorder()
180 | }
181 | }
182 |
183 | ```
184 |
185 | Activates with [java](https://docs.gradle.org/current/userguide/java_plugin.html),
186 | [groovy](https://docs.gradle.org/current/userguide/groovy_plugin.html) or
187 | [java-library](https://docs.gradle.org/current/userguide/java_library_plugin.html) plugin.
188 | Typical usage: single-module gradle project which must be published to maven central (or any other maven repo)
189 |
190 | * Adds `javadoc` and `sources` for publication
191 | * Registers `maven` publication for pom, jar, javadoc and sources artifacts
192 | * Applies UTF-8 encoding for java/groovy compile, javadoc/groovydoc and test executions
193 | * If [signing](https://docs.gradle.org/current/userguide/signing_plugin.html) plugin active, [configures publication signing](#signing) (required for maven central publication)
194 | * Adds `install` task for installation into local repository (like maven; simply shortcut for `publishToMavenLocal` task)
195 | * Enables xml jacoco reports (if jacoco enabled; required for coverage services)
196 | * Register [ru.vyarus.pom](https://github.com/xvik/gradle-pom-plugin) plugin which:
197 | - adds `optional` and `provided` configurations (in maven sense)
198 | - fixes dependency scopes in the generated pom
199 | - moves up dependencyManagement section in the generated pom (if platforms used)
200 | - adds `maven.pom` extension for pom declaration (`maven.withPomXml` might be used for low-level modification)
201 | * Utilities:
202 | - simple Auto-Module-Name declaration (java 9 modules)
203 | - option to disable gradle metadata publication (maven central fails on it sometimes)
204 | - option to remove dependencyManagement section in the generated pom (appears if platforms used): use resolved dependencies versions instead (pom plugin feature)
205 | * Adds [openDependencyReport](#dependency-report) task added if [project-report](https://docs.gradle.org/current/userguide/project_report_plugin.html) plugin enabled
206 | (opens `htmlDependencyReport` directly in browser)
207 |
208 | #### BOM module
209 |
210 | ```groovy
211 | plugins {
212 | id 'java-platform'
213 | // id 'signing'
214 | // id 'project-report'
215 | id 'ru.vyarus.java-lib'
216 | }
217 |
218 | group = 'your.group'
219 | version = '1.0.0'
220 | description = 'My project description'
221 |
222 | maven.pom {
223 | ...
224 | }
225 |
226 | repositories { mavenLocal(); mavenCentral() }
227 | dependencies {
228 | api platform('ru.vyarus.guicey:guicey-bom:5.2.0-1')
229 | constraints {
230 | api 'org.webjars:webjars-locator:0.40'
231 | }
232 | // add subprojects to published BOM
233 | project.subprojects.each { api it }
234 | }
235 |
236 | javaLib {
237 | bom {
238 | // change artifact from project name, if required
239 | artifactId = 'something-bom'
240 | description = 'Different from project description'
241 | }
242 | withoutGradleMetadata()
243 | }
244 | ```
245 |
246 | Activates with [java-platform](https://docs.gradle.org/current/userguide/java_platform_plugin.html) plugin.
247 | Typical usage: BOM module (might be root project) in multi-module project
248 |
249 | * Activates platform dependencies (javaPlatform.allowDependencies()) to allow single dependencies declaration
250 | * Registers `bom` publication for bom artifact (produced from declared platform)
251 | * Register [ru.vyarus.pom](https://github.com/xvik/gradle-pom-plugin) plugin (with the same features as above)
252 | * If [signing](https://docs.gradle.org/current/userguide/signing_plugin.html) plugin active, [configures publication signing](#signing) (required for maven central publication)
253 | * Adds `install` task for installation into local repository (like maven; simply shortcut for `publishToMavenLocal` task)
254 | * Utilities:
255 | - option to disable gradle metadata publication (maven central fails on it sometimes)
256 | - option to change bom artifact id (useful when platform declared in the root module)
257 | * Adds [openDependencyReport](#dependency-report) task added if [project-report](https://docs.gradle.org/current/userguide/project_report_plugin.html) plugin enabled
258 | (opens `htmlDependencyReport` directly in browser)
259 |
260 | #### Root project reports aggregation
261 |
262 | ```groovy
263 | plugins {
264 | id 'base'
265 | id 'jacoco'
266 | //id 'project-report'
267 | id 'ru.vyarus.java-lib'
268 | }
269 |
270 | javaLib {
271 | aggregateReports()
272 | }
273 |
274 | // sub modules - simple java projects
275 | subprojects {
276 | apply plugin: 'java'
277 |
278 | ...
279 | }
280 | ```
281 |
282 | Activates with [base](https://docs.gradle.org/current/userguide/base_plugin.html) plugin.
283 | Used to aggregate test and coverage reports from java submodules.
284 |
285 | By default, will only register `openDependencyReport` task added if [project-report](https://docs.gradle.org/current/userguide/project_report_plugin.html) plugin enabled.
286 | Reports aggregation must be explicitly triggered:
287 | - Adds `test` task which would simply aggregate (run if required) java submodules test reports
288 | - If jacoco plugin active, add `jacocoMerge` (not for direct usage) and
289 | `jacocoTestReport` tasks to aggregate jacoco xml and html reports from java submodules
290 | - If project-report plugin active, will aggregate dependency reports for submodules
291 |
292 | In short: it adds absolutely the same tasks as in java modules and generates
293 | reports exactly into the same locations so there would be no difference in paths
294 | when configuring external services (e.g. coveralls).
295 |
296 | NOTE: aggregation will work with `java-platform` plugin too if it used in the root module (see [complete multi-module example](#maven-like-multi-module-project)).
297 |
298 | ### Options
299 |
300 | ```groovy
301 | javaLib {
302 |
303 | /**
304 | * Do not publish javadoc (groovydoc) with `maven` publication.
305 | */
306 | withoutJavadoc()
307 |
308 | /**
309 | * Do not publish sources with `maven` publication.
310 | */
311 | withoutSources()
312 |
313 | /**
314 | * Do not publish gradle metadata artifact.
315 | * Affects all publications (not just registered by plugin).
316 | */
317 | withoutGradleMetadata()
318 |
319 | /**
320 | * Disable all publications. Might be used to disable configured BOM publication or any sub-module publication.
321 | */
322 | withoutPublication()
323 |
324 | /**
325 | * Shortcut for Auto-Module-Name meta-inf header declaration
326 | */
327 | autoModuleName = 'project-module-name'
328 |
329 | /**
330 | * Used ONLY with java-platform plugin if published artifact must differ from
331 | * project name (for example, when declared in the root project).
332 | */
333 | bom {
334 | // when not declared, project.name used
335 | artifactId = 'name'
336 | // when not declared, project.description used
337 | description = 'desc'
338 | }
339 |
340 | /**
341 | * Used in the root project (project with child projects) to aggregate
342 | * test, coverage (jacoco) and dependency (project-report) reports.
343 | * Requires at least `base` plugin. Will work java-platform plugin
344 | * (will not work with java plugin because such module can't aggregate).
345 | */
346 | aggregateReports()
347 | }
348 | ```
349 |
350 | ### POM
351 |
352 | You need to specify general project info:
353 |
354 | ```groovy
355 | group = 'your.group' // maven group
356 | version = '1.0.0' // project version
357 | description = 'My project description' // optional (affects jar manifest)
358 | ```
359 |
360 | Note: maven `artifactId` will be the same as project name, and the default for project name
361 | is current directory name. If you need to change name, add in `settings.gradle`:
362 |
363 | ```
364 | rootProject.name = 'the-name-you-want'
365 | ```
366 |
367 | For maven-central publication you need to fill all required pom sections:
368 |
369 | ```groovy
370 | maven.pom {
371 | // name and desciption set automatically from project, but you can override them here
372 | //name 'Project Name'
373 | //description 'My awesome project'
374 | licenses {
375 | license {
376 | name = "The MIT License"
377 | url = "http://www.opensource.org/licenses/MIT"
378 | distribution = 'repo'
379 | }
380 | }
381 | scm {
382 | url = 'https://github.com/me/my-repo'
383 | connection = 'scm:git@github.com:me/my-repo.git'
384 | developerConnection = 'scm:git@github.com:me/my-repo.git'
385 | }
386 | developers {
387 | developer {
388 | id = "dev1"
389 | name = "Dev1 Name"
390 | email = "dev1@email.com"
391 | }
392 | }
393 | }
394 | ```
395 |
396 | Read more about pom configuration in the [pom plugin's docs](https://github.com/xvik/gradle-pom-plugin#pom-configuration).
397 |
398 | If your project hosted on github you may use [github-info](https://github.com/xvik/gradle-github-info-plugin) plugin,
399 | which fills most github-related pom sections for you automatically.
400 |
401 | Use the following configurations to get correct scopes in the resulted pom:
402 |
403 | Maven scope | Gradle configuration
404 | ------------| ----------------
405 | compile | implementation, api
406 | runtime | runtimeOnly
407 | provided | provided (**not** compileOnly!)
408 | optional | optional, [feature variants](https://github.com/xvik/gradle-pom-plugin#feature-variants)
409 |
410 | See [pom plugin doc](https://github.com/xvik/gradle-pom-plugin#dependencies) for more details about dependencies scopes in the generated pom
411 |
412 | #### Using BOMs
413 |
414 | When you use BOMs (for dependencies versions management) with spring plugin or gradle platform you'll have
415 | `dependencyManagement` section generated in the target pom. Often it is not desired:to use only resolved
416 | versions and avoid `dependencyManagent` use:
417 |
418 | ```groovy
419 | maven.pom.removeDependencyManagement()
420 | ```
421 |
422 | Read more in the [pom plugin's docs](https://github.com/xvik/gradle-pom-plugin#improving-boms-usage)
423 |
424 | #### BOM declaration
425 |
426 | The simplest way to declare BOM is using [java-platform](https://docs.gradle.org/current/userguide/java_platform_plugin.html)
427 |
428 | ```groovy
429 | plugins {
430 | id 'java-platform'
431 | id 'ru.vyarus.java-lib'
432 | }
433 |
434 | repositories { mavenLocal(); mavenCentral() }
435 | dependencies {
436 | api platform('ru.vyarus.guicey:guicey-bom:5.2.0-1')
437 | constraints {
438 | api 'org.webjars:webjars-locator:0.40'
439 | }
440 | // add subprojects to published BOM
441 | project.subprojects.each { api it }
442 | }
443 | ```
444 |
445 | Java-lib plugin would automatically activate dependencies declaration (`constraints` block).
446 |
447 | I propose to mix dependencies and modules into single BOM declaration, but you can always split
448 | dependencies management and modules BOM by declaring two platforms in two different modules.
449 |
450 | If you use `java-platform` in the root project, then you might want to change name of published artifact
451 | (by default it would be root project name in this case). To change it use:
452 |
453 | ```groovy
454 | javaLib {
455 | bom {
456 | artifactId = 'some-bom'
457 | description = 'overridden description'
458 | }
459 | }
460 | ```
461 |
462 | ### Publication
463 |
464 | [maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html) plugin used for publication.
465 |
466 | By default, plugin configures `maven` publication with javadoc or (and) groovydoc and sources jars for `java`
467 | (`groovy` or `java-library`) plugins and `bom` publication for `java-platform` plugin.
468 |
469 | Use `install` task to deploy everything into local maven repository.
470 |
471 | ```bash
472 | $ gradlew install
473 | ```
474 |
475 | If you don't want to publish everything (jar, sources, javadoc) then you can:
476 |
477 | ```groovy
478 | javaLib {
479 | withtouSources()
480 | withoutJavadoc()
481 | }
482 | ```
483 |
484 | OR override list of publishing artifacts:
485 |
486 | ```groovy
487 | publishing.publications.maven.artifacts = [jar, javadocJar]
488 | ```
489 |
490 | NOTE that for maven central publication sources and javadocs are required
491 |
492 | To ADD artifacts for publication, configure them directly for publication:
493 |
494 | ```groovy
495 | publishing {
496 | publications.maven {
497 | artifact buildDelivery { archiveClassifier.set('zip') }
498 | }
499 | }
500 | ```
501 |
502 | Here the result of `buildDelivery` task (of type `Zip`) **added** to `maven` publication with `zip` classifier.
503 |
504 | #### Gradle metadata
505 |
506 | Since gradle 6, gradle would always publish its [metadata](https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html):
507 |
508 | ```
509 | Gradle Module Metadata is a unique format aimed at improving dependency resolution by making it multi-platform and variant-aware.
510 | ```
511 |
512 | Essentially, it's an additional `.module` file containing json representation of dependencies.
513 | This is really necessary only when advanced gradle features used (constraints (not in platform), variants).
514 |
515 | But this would mean that gradle and maven projects would use *different* dependencies
516 | after publication: maven use pom, gradle would load .module file with additional dependencies info.
517 |
518 | It would be more honest to publish only pom (especially for public projects) and disable metadata publishing:
519 |
520 | ```groovy
521 | javaLib {
522 | withoutMavenMetadata()
523 | }
524 | ```
525 |
526 | Also note, that maven central could complain about metadata file (if published).
527 |
528 | #### Publish to repository
529 |
530 | You must configure repository for actual publication [repository](https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:repositories) must be configured:
531 |
532 | ```groovy
533 | publishing {
534 | repositories {
535 | maven {
536 | // change to point to your repo, e.g. http://my.org/repo
537 | url "$buildDir/repo"
538 | }
539 | }
540 | }
541 | ```
542 |
543 | Then [publish task](https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:publishing) may be used to perform publish.
544 |
545 | #### Publish to maven-central
546 |
547 | For maven-central publication use [nexus publish plugin](https://github.com/gradle-nexus/publish-plugin)
548 | which automates full maven central release cycle.
549 |
550 | ```groovy
551 | plugins {
552 | ...
553 | id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
554 | }
555 |
556 | nexusPublishing {
557 | repositories {
558 | sonatype {
559 | username = findProperty('sonatypeUser')
560 | password = findProperty('sonatypePassword')
561 | }
562 | }
563 | }
564 | ```
565 |
566 | For release, you would need to call two tasks: `publishToSonatype`, `closeAndReleaseSonatypeStagingRepository`
567 |
568 | You'll need to configure `sonatypeUser` and `sonatypePassword` properties in global gradle file:
569 | `~/.gradle/gradle.properties`
570 |
571 | IMPORTANT artifacts must be [signed](#signing)!
572 |
573 | #### Gradle plugin
574 |
575 | Gradle plugin project will have [java-gradle-plugin](https://docs.gradle.org/current/userguide/java_gradle_plugin.html),
576 | which declares its own maven publication `pluginMaven` (with main jar as artifact). Also, plugin creates one more
577 | publication per declared plugin to publish [plugin marker artifact](https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_markers)
578 | (required by gradle plugins dsl).
579 |
580 | Java-lib plugin will still create separate publication `maven` and you should use it for publishing with bintray
581 | (same way as for usual library)
582 |
583 | ##### Publishing to gradle plugin repository
584 |
585 | For publishing in gradle plugin repository you will use [com.gradle.plugin-publish](https://plugins.gradle.org/docs/publish-plugin)
586 | plugin.
587 |
588 | **IMPORTANT**: plugin-publish 1.x is supported for gradle 7.6 and above, for lower gradle use 0.x
589 |
590 | Use `maven` publication for publishing into maven central or other repo (optional). Plugin-publish
591 | will use it's `plugin-maven` publication for plugins portal publication. Both publications
592 | would contain the same artifacts.
593 |
594 | Example for publishing in maven central and plugin portal (gradle 7.6 or above):
595 |
596 | ```groovy
597 | plugins {
598 | id 'com.gradle.plugin-publish' version '1.2.1'
599 | id 'java-gradle-plugin'
600 | id 'ru.vyarus.java-lib' version '3.0.0'
601 | }
602 |
603 | repositories { mavenLocal(); mavenCentral(); gradlePluginPortal() }
604 |
605 | group = 'com.foo'
606 | description = 'Short description'
607 |
608 | gradlePlugin {
609 | plugins {
610 | myPlugin {
611 | id = 'com.foo.plugin'
612 | displayName = project.description
613 | description = 'Long description'
614 | tags.set(['something'])
615 | implementationClass = 'com.foo.MyPlugin'
616 | }
617 | }
618 | }
619 | ```
620 |
621 | Here `publishMavenPublicationToMavenRepository` would publish to repository and `publishPlugins` publish into plugins portal.
622 |
623 | Assuming custom `maven` (name!) repository is configured:
624 |
625 | ```groovy
626 | publishing {
627 | repositories { maven { url "http://some.repo/"} }
628 | }
629 | ```
630 |
631 | ##### Publishing only to custom repo
632 |
633 | This is in-house plugin case, when plugin is published only into corporate repository.
634 |
635 | The simplest solution is to disable `pluginMaven` publication tasks (but marker artifact publications should remain!)
636 | and publish only remaining `maven` publication:
637 |
638 | ```groovy
639 | tasks.withType(AbstractPublishToMaven) { Task task ->
640 | if (task.name.startsWith("publishPluginMaven")) {
641 | task.enabled(false)
642 | }
643 | }
644 | ```
645 |
646 | This will disable: `publishPluginMavenPublicationToMavenLocal` and `publishPluginMavenPublicationToMavenRepository`
647 |
648 | And you can simply use `publish` task to trigger all required publications without duplicates.
649 |
650 | The same way, `install` will install all required artifacts locally (including markers) and so it is possible
651 | to use plugins from local maven repository too (with plugin syntax):
652 |
653 | add to settings.gradle:
654 |
655 | ```groovy
656 | pluginManagement {
657 | repositories {
658 | mavenLocal()
659 | gradlePluginPortal()
660 | }
661 | }
662 | ```
663 |
664 | ### Encodings
665 |
666 | UTF-8 applied to:
667 |
668 | * (all `CompileJava` tasks).options.encoding
669 | * (all `CompileGrovy` tasks).options.encoding
670 | * (all `Javadoc`).options.\[encoding, charSet, docEncoding]
671 | * (all `Test`).systemProperty 'file.encoding'
672 |
673 | Note that groovydoc task does not have encoding configuration, but it should use UTF-8 by defautl.
674 |
675 | For tests, encoding is important (especially on windows) because test forked process will not inherit root gradle encoding configuration.
676 |
677 | ### Tasks
678 |
679 | NOTE: for gradle 7.6 and above [native javadoc and sources registration used](https://docs.gradle.org/current/userguide/java_plugin.html#packaging)
680 |
681 | - `sourcesJar`
682 | - `javadocJar`
683 | - `openDependencyReport` if `project-report` plugin active - opens html dependency report in browser
684 |
685 | `install` task added to simplify publication to local maven repository: this is simply shortcut for
686 | gradle's [publishToMavenLocal](https://docs.gradle.org/current/userguide/publishing_maven.html#publishing_maven:tasks) task
687 | (simply shorter to type and more common name after maven).
688 |
689 | ### Main Jar
690 |
691 | Plugin applies default manifest properties:
692 |
693 | ```groovy
694 | 'Implementation-Title': project.description ?: project.name,
695 | 'Implementation-Version': project.version,
696 | 'Built-By': System.getProperty('user.name'),
697 | 'Built-Date': new Date(),
698 | 'Built-JDK': System.getProperty('java.version'),
699 | 'Built-Gradle': gradle.gradleVersion,
700 | 'Target-JDK': project.targetCompatibility
701 | ```
702 |
703 | You can override it:
704 |
705 | ```groovy
706 | jar {
707 | manifest {
708 | attributes 'Implementation-Title': 'My Custom value',
709 | 'Built-By': 'Me'
710 | }
711 | }
712 | ```
713 |
714 | For all not specified properties default values will be used.
715 |
716 | Plugin will include additional files inside jar (like maven do) into `META-INF/maven/group/artifact/`
717 |
718 | * pom.xml
719 | * pom.properties
720 |
721 | pom.properties contains:
722 |
723 | * version
724 | * groupId
725 | * artifactId
726 |
727 | ### Signing
728 |
729 | Plugin will configure signing automatically for *configured publications*: `maven` and `bom`
730 | (note that in case of gradle plugin, gradle use its own publication for portal publication
731 | and it would not be signed (no need)).
732 |
733 | You only need to apply [signing](https://docs.gradle.org/current/userguide/signing_plugin.html) plugin:
734 |
735 | ```groovy
736 | plugins {
737 | id 'java'
738 | id 'signing'
739 | id 'ru.vyarus.java-lib'
740 | }
741 | ```
742 |
743 | No additional configuration required, except properties in the global gradle config `~/.gradle/gradle.properties`:
744 |
745 | ```properties
746 | signing.keyId = 78065050
747 | signing.password =
748 | signing.secretKeyRingFile = /path/to/certs.gpg
749 | ```
750 |
751 | IMPORTANT: password property (empty) required even if no password used!
752 |
753 | Note that project build will not complain while building snapshot versions
754 | (version ending with `-SNAPSHOT`) - signing task would be simply ignored.
755 | But, on release gradle would fail if signing not configured properly.
756 |
757 | #### Signing certificate
758 |
759 | Certificate generation described in many articles around the web, for example, sonatype
760 | [gpg guide](https://central.sonatype.org/publish/requirements/gpg/).
761 |
762 | I will just show required commands for generation and obtaining keyring file:
763 |
764 | Certificate generation:
765 |
766 | ```
767 | gpg --gen-key
768 | ```
769 |
770 | (if you want, you can leave passphrase blank - just hit enter several times)
771 |
772 | Alternatively, `gpg --full-gen-key` may be used to set exact algorithm and expiration (by default generated key would expire in few years)
773 |
774 | List keys:
775 |
776 | ```
777 | gpg --list-keys
778 | gpg --list-secret-keys
779 | ```
780 |
781 | You can always edit key if required (for example change expiration):
782 |
783 | ```
784 | gpg --edit-key (key id)
785 | gpg> key 1
786 | gpg> expire
787 | (follow prompts)
788 | gpg> save
789 | ```
790 |
791 | Create keyring file:
792 |
793 | ```
794 | gpg --export-secret-keys (key id) > cert.gpg
795 | ```
796 |
797 | Put `cert.gpg` somewhere and set full path to it in `signing.secretKeyRingFile`
798 |
799 | You also need short key id:
800 |
801 | ```
802 | gpg --list-secret-keys --keyid-format SHORT
803 |
804 | Example output:
805 | sec rsa3072/78065050 2021-06-06 [SC]
806 | ```
807 |
808 | Here `78065050` is your keyid which should be set as `signing.keyId`
809 |
810 | If you set passphrase, set it in `signing.password`, otherwise leave it blank
811 |
812 | IMPORTANT: for maven central, you'll need to register your public key with
813 |
814 | ```
815 | gpg --keyserver keyserver.ubuntu.com --send-keys (short key id)
816 | ```
817 |
818 | That's all.
819 |
820 | ### Dependency report
821 |
822 | When [project-report](https://docs.gradle.org/current/userguide/project_report_plugin.html) plugin active,
823 | `openDependencyReport` task created.
824 |
825 | This is pure utility task: it calls `htmlDependencyReport` and opens it directly
826 | in the browser (directly on page with dependencies, instead of index).
827 |
828 | This simply faster: manual `htmlDependencyReport` requires several clicks to open required report.
829 |
830 | ### Maven-like multi-module project
831 |
832 | Here is an example of how plugin could be used in multi-module project to apply
833 | maven configuration style: root project manage all dependency versions.
834 |
835 | ```groovy
836 | plugins {
837 | id 'jacoco'
838 | id 'java-platform'
839 | id 'ru.vyarus.java-lib'
840 | }
841 |
842 | description = 'Maven-like project'
843 |
844 | // dependency versions management
845 | dependencies {
846 | api platform("ru.vyarus:dropwizard-guicey:$guicey")
847 | constraints {
848 | api 'com.h2database:h2:1.4.200'
849 |
850 | // add subprojects to BOM
851 | project.subprojects.each { api it }
852 | }
853 | }
854 |
855 | javaLib {
856 | aggregateReports()
857 | // publish root BOM as custom artifact
858 | bom {
859 | artifactId = 'sample-bom'
860 | description = 'Sample project BOM'
861 | }
862 |
863 | // OR disable BOM publication
864 | // withoutPublication()
865 | }
866 |
867 | // maven publication related configuration applied to all projects
868 | allprojects {
869 | //apply plugin: 'project-report'
870 | //apply plugin: 'signing'
871 |
872 | repositories { mavenCentral(); mavenLocal() }
873 |
874 | group = 'com.test'
875 |
876 | // such delay is required because java-lib (and java) plugin would be applied only
877 | // in the subprojects section and so this would configure root project configuration
878 | // without delay
879 | plugins.withId('java') {
880 | maven.pom {
881 | licenses {
882 | license {
883 | name = "The MIT License"
884 | url = "http://www.opensource.org/licenses/MIT"
885 | distribution = 'repo'
886 | }
887 | }
888 | scm {
889 | url = 'https://github.com/me/my-repo.git'
890 | connection = 'scm:git@github.com:me/my-repo.git'
891 | developerConnection = 'scm:git@github.com:me/my-repo.git'
892 | }
893 | //...
894 | }
895 | }
896 |
897 | javaLib.withoutGradleMetadata()
898 | }
899 |
900 | // all sub-modules are normal java modules, using root BOM (like maven)
901 | subprojects {
902 | apply plugin: 'groovy'
903 | apply plugin: 'jacoco'
904 | apply plugin: 'ru.vyarus.java-lib'
905 |
906 | sourceCompatibility = 1.8
907 |
908 | // common dependencies for all modules
909 | dependencies {
910 | implementation platform(project(':'))
911 |
912 | compileOnly 'com.github.spotbugs:spotbugs-annotations:4.2.3'
913 | implementation 'ru.vyarus:dropwizard-guicey'
914 |
915 | testImplementation 'org.spockframework:spock-core'
916 | testImplementation 'io.dropwizard:dropwizard-testing'
917 | }
918 |
919 | javaLib {
920 | // java 9 auto module name
921 | autoModuleName = "com.sample.module"
922 | }
923 |
924 | maven {
925 | // use only direct dependencies in the generated pom, removing BOM
926 | removeDependencyManagement()
927 | }
928 | }
929 | ```
930 |
931 | Here required dependency versions declared in the root project using gradle platform.
932 | Platform published as BOM with custom artifact name (dual BOM: both project modules and dependencies).
933 |
934 | Sub-projects are java modules which use platform declared in the root project for dependency management.
935 | `maven.removeDependencyManagement()` prevents "leaking" platform into module poms
936 | (generated poms would contain just required dependencies with resolved versions)
937 |
938 | `groovy` plugin used just as an example (used for spock tests, main sources might be java-only): it could be `java` or `java-library` plugin.
939 |
940 | The complete multi-module project example could be generated with [java-library generator](https://github.com/xvik/generator-lib-java).
941 |
942 | * [dropwizard-guicey-ext](https://github.com/xvik/dropwizard-guicey-ext) - multi-module project with (published) bom
943 | * [yaml-updater](https://github.com/xvik/yaml-updater) - simple multi-module without bom (simple case)
944 |
945 | ### APPENDIX: boilerplate plugin removes
946 |
947 | Section briefly shows what plugin configures so if plugin defaults didn't fit your needs, you can
948 | easily reproduce parts of it in your custom build.
949 |
950 | #### Java module boilerplate
951 |
952 | ```groovy
953 | plugins { id 'java' }
954 |
955 | apply plugin: 'ru.vyarus.pom'
956 |
957 | jar {
958 | manifest {
959 | attributes 'Implementation-Title': project.description ?: project.name,
960 | 'Implementation-Version': project.version,
961 | 'Built-By': System.getProperty('user.name'),
962 | 'Built-Date': new Date(),
963 | 'Built-JDK': System.getProperty('java.version'),
964 | 'Built-Gradle': gradle.gradleVersion,
965 | 'Target-JDK': project.targetCompatibility
966 | }
967 | }
968 |
969 | java {
970 | withJavadocJar()
971 | withSourcesJar()
972 | }
973 |
974 | task generatePomPropertiesFile {
975 | inputs.properties ([
976 | 'version': "${ -> project.version }",
977 | 'groupId': "${ -> project.group }",
978 | 'artifactId': "${ -> project.name }"
979 | ])
980 | outputs.file "$project.buildDir/generatePomPropertiesFile/pom.properties"
981 | doLast {
982 | File file = outputs.files.singleFile
983 | file.parentFile.mkdirs()
984 | file << inputs.properties.collect{ key, value -> "$key: $value" }.join('\n')
985 | }
986 | }
987 |
988 | model {
989 | tasks.jar {
990 | into("META-INF/maven/$project.group/$project.name") {
991 | from generatePomFileForMavenPublication
992 | rename ".*.xml", "pom.xml"
993 | from generatePomPropertiesFile
994 | }
995 | }
996 | }
997 |
998 | tasks.withType(JavaCompile).configureEach {
999 | it.options.encoding = StandardCharsets.UTF_8
1000 | }
1001 |
1002 | tasks.withType(GroovyCompile).configureEach {
1003 | it.options.encoding = StandardCharsets.UTF_8
1004 | }
1005 |
1006 | tasks.withType(Test).configureEach {
1007 | it.systemProperty JvmOptions.FILE_ENCODING_KEY, StandardCharsets.UTF_8
1008 | }
1009 |
1010 | tasks.withType(Javadoc).configureEach {
1011 | it.with {
1012 | options.encoding = StandardCharsets.UTF_8
1013 | // StandardJavadocDocletOptions
1014 | options.charSet = StandardCharsets.UTF_8
1015 | options.docEncoding = StandardCharsets.UTF_8
1016 | }
1017 | }
1018 |
1019 | jar.manifest {
1020 | attributes 'Automatic-Module-Name': 'module-name'
1021 | }
1022 |
1023 | publishing.publications {
1024 | maven(MavenPublication) {
1025 | from components.java
1026 | }
1027 | }
1028 |
1029 | task.jacocoTestReport.xml.required.set(true)
1030 |
1031 | tasks.register('install') {
1032 | dependsOn: publishToMavenLocal
1033 | group: 'publishing'
1034 | doLast {
1035 | logger.warn "INSTALLED $project.group:$project.name:$project.version"
1036 | }
1037 | }
1038 | ```
1039 |
1040 | #### Java platform boilerplate
1041 |
1042 | ```groovy
1043 | plugins { id 'java-platform' }
1044 |
1045 | apply plugin: 'ru.vyarus.pom'
1046 |
1047 | javaPlatform.allowDependencies()
1048 |
1049 | maven.pom {
1050 | name = 'custom-name' // if differs from project name
1051 | description = 'custom description'
1052 | }
1053 |
1054 | publishing.publications {
1055 | bom(MavenPublication) {
1056 | from components.javaPlatform
1057 | artifactId = 'custom-name' // if differs from project name
1058 | }
1059 | }
1060 |
1061 | jacocoTestReport.reports.xml.required.set(true)
1062 |
1063 | tasks.register('install') {
1064 | dependsOn: publishToMavenLocal
1065 | group: 'publishing'
1066 | doLast {
1067 | logger.warn "INSTALLED $project.group:custom-name:$project.version"
1068 | }
1069 | }
1070 | ```
1071 |
1072 | #### Reports aggregation boilerplate
1073 |
1074 | ```groovy
1075 | task test (type: TestReport, description: 'Generates aggregated test report') {
1076 | group = 'verification'
1077 | destinationDir = project.file("${project.buildDir}/reports/tests/test")
1078 | reportOn project.subprojects.findAll { it.plugins.hasPlugin(JavaPlugin) }.test
1079 | }
1080 |
1081 | def projectsWithCoverage = project.subprojects.findAll { it.plugins.hasPlugin(JacocoPlugin) }
1082 |
1083 | task jacocoTestReport (type: JacocoReport, description: 'Generates aggregated jacoco coverage report') {
1084 | dependsOn 'test'
1085 | group = 'verification'
1086 | executionData project.files(projectsWithCoverage
1087 | .collect { it.file("${it.buildDir}/jacoco/test.exec") })
1088 | .filter { it.exists() }
1089 | sourceDirectories.from = project.files(projectsWithCoverage.sourceSets.main.allSource.srcDirs)
1090 | classDirectories.from = project.files(projectsWithCoverage.sourceSets.main.output)
1091 | reports.xml.destination = project.file("$project.buildDir/reports/jacoco/test/jacocoTestReport.xml")
1092 | reports.xml.required.set(true)
1093 | reports.html.destination = project.file("$project.buildDir/reports/jacoco/test/html/")
1094 | }
1095 |
1096 | htmlDependencyReport.projects = project.allprojects
1097 | ```
1098 |
1099 | #### Utility boilerplate
1100 |
1101 | Signing:
1102 |
1103 | ```groovy
1104 | signing {
1105 | sign publishing.publications.maven // or bom
1106 | required = { !project.version.toString().endsWith('SNAPSHOT') }
1107 | }
1108 | ```
1109 |
1110 | Gradle metadata disabling
1111 |
1112 | ```groovy
1113 | tasks.withType(GenerateModuleMetadata).configureEach {
1114 | enabled = false
1115 | }
1116 | ```
1117 |
1118 | Open report:
1119 |
1120 | ```groovy
1121 | task openDependencyReport(description: 'Opens gradle htmlDependencyReport in browser', group: 'help') {
1122 | dependsOn 'htmlDependencyReport'
1123 | doLast {
1124 | java.awt.Desktop.desktop.open(file("build/reports/project/dependencies/root.${project.name}.html))
1125 | }
1126 | }
1127 | ```
1128 |
1129 | ### Might also like
1130 |
1131 | * [quality-plugin](https://github.com/xvik/gradle-quality-plugin) - java and groovy source quality checks
1132 | * [github-info-plugin](https://github.com/xvik/gradle-github-info-plugin) - pre-configure common plugins with github related info
1133 | * [animalsniffer-plugin](https://github.com/xvik/gradle-animalsniffer-plugin) - java compatibility checks
1134 | * [mkdocs-plugin](https://github.com/xvik/gradle-mkdocs-plugin) - project documentation generator
1135 | * [java-library generator](https://github.com/xvik/generator-lib-java) - java library project generator
1136 |
1137 | ---
1138 | [](https://github.com/xvik/generator-gradle-plugin)
1139 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.gradle.plugin-publish' version '1.3.1'
3 | id 'java-gradle-plugin'
4 | id 'groovy'
5 | id 'jacoco'
6 | id 'signing'
7 | id 'net.researchgate.release' version '3.1.0'
8 | id 'ru.vyarus.quality' version '5.0.0'
9 | id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
10 | id 'ru.vyarus.java-lib' version '3.0.0'
11 | id 'ru.vyarus.github-info' version '2.0.0'
12 | id 'com.github.ben-manes.versions' version '0.52.0'
13 | id "pl.droidsonroids.jacoco.testkit" version "1.0.12"
14 | }
15 |
16 | java {
17 | sourceCompatibility = 1.8
18 | }
19 |
20 | wrapper {
21 | gradleVersion = '8.6'
22 | distributionType = Wrapper.DistributionType.BIN
23 | }
24 |
25 | repositories { mavenLocal(); mavenCentral(); gradlePluginPortal() }
26 | dependencies {
27 | implementation 'ru.vyarus:gradle-pom-plugin:3.0.0'
28 |
29 | testImplementation('org.spockframework:spock-core:2.3-groovy-3.0') {
30 | exclude group: 'org.codehaus.groovy'
31 | }
32 | testImplementation 'com.gradle.publish:plugin-publish-plugin:1.3.1'
33 | }
34 |
35 | group = 'ru.vyarus'
36 | description = 'Gradle Java-lib plugin'
37 |
38 | github {
39 | user 'xvik'
40 | license 'MIT'
41 | }
42 |
43 | maven.pom {
44 | developers {
45 | developer {
46 | id = 'xvik'
47 | name = 'Vyacheslav Rusakov'
48 | email = 'vyarus@gmail.com'
49 | }
50 | }
51 | }
52 |
53 | nexusPublishing {
54 | repositories {
55 | sonatype {
56 | username = findProperty('sonatypeUser')
57 | password = findProperty('sonatypePassword')
58 | }
59 | }
60 | }
61 |
62 | // skip signing for jitpack (snapshots)
63 | tasks.withType(Sign) {onlyIf { !System.getenv('JITPACK') }}
64 |
65 | // Required signing properties for release: signing.keyId, signing.password and signing.secretKeyRingFile
66 | // (https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials)
67 |
68 | javaLib {
69 | // don't publish gradle metadata artifact
70 | withoutGradleMetadata()
71 | }
72 |
73 |
74 | gradlePlugin {
75 | plugins {
76 | javaLibPlugin {
77 | id = 'ru.vyarus.java-lib'
78 | displayName = project.description
79 | description = 'Common gradle configuration for Java or Groovy library'
80 | tags.set(['java', 'groovy', 'lib'])
81 | implementationClass = 'ru.vyarus.gradle.plugin.lib.JavaLibPlugin'
82 | }
83 | }
84 | }
85 |
86 | release.git.requireBranch.set('master')
87 |
88 | afterReleaseBuild {
89 | dependsOn = [
90 | 'publishMavenPublicationToSonatypeRepository',
91 | 'closeAndReleaseSonatypeStagingRepository',
92 | publishPlugins
93 | ]
94 | doLast {
95 | logger.warn "RELEASED $project.group:$project.name:$project.version"
96 | }
97 | }
98 |
99 | test {
100 | useJUnitPlatform()
101 | testLogging {
102 | events 'skipped', 'failed'
103 | exceptionFormat 'full'
104 | }
105 | maxHeapSize = '512m'
106 | doLast {
107 | sleep(1000)
108 | }
109 | }
110 |
111 | dependencyUpdates.revision = 'release'
112 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | version=3.0.1-SNAPSHOT
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xvik/gradle-java-lib-plugin/59ad479c9e74ae110d3686d401511b8b45781835/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo. 1>&2
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
48 | echo. 1>&2
49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
50 | echo location of your Java installation. 1>&2
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo. 1>&2
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
62 | echo. 1>&2
63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
64 | echo location of your Java installation. 1>&2
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenLocal()
4 | gradlePluginPortal()
5 | }
6 | }
7 |
8 | rootProject.name = 'gradle-java-lib-plugin'
9 |
--------------------------------------------------------------------------------
/src/main/groovy/ru/vyarus/gradle/plugin/lib/JavaLibExtension.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import groovy.transform.CompileStatic
4 | import org.gradle.api.Action
5 | import org.gradle.api.Project
6 |
7 | /**
8 | * Java-lib plugin extension. Accessible as `javaLib` closure.
9 | *
10 | * @author Vyacheslav Rusakov
11 | * @since 06.06.2021
12 | */
13 | @CompileStatic
14 | @SuppressWarnings('ConfusingMethodName')
15 | class JavaLibExtension {
16 |
17 | private final Project project
18 |
19 | JavaLibExtension(Project project) {
20 | this.project = project
21 | }
22 |
23 | /**
24 | * Java-platform plugin related configurations.
25 | */
26 | JavaPlatform bom = new JavaPlatform()
27 |
28 | /**
29 | * Automatic-Module-Name meta-inf property value (java 9 modules).
30 | * Object used as type to allow lazy-evaluated GStrings.
31 | */
32 | Object autoModuleName
33 |
34 | // ----------------------------------- method-based configuration
35 | // (properties accessible, but not supposed to be used)
36 |
37 | boolean gradleMetadata = true
38 | boolean addJavadoc = true
39 | boolean addSources = true
40 | boolean publication = true
41 | boolean aggregatedReports = false
42 |
43 | /**
44 | * Disable gradle metadata publishing. Metadata files contains additional gradle dependencies semantic which
45 | * is impossible to express in pom file. In majority of cases this file is not required and may be excluded
46 | * to avoid publishing additional artifact (besides, some repos might complain about it).
47 | */
48 | void withoutGradleMetadata() {
49 | gradleMetadata = false
50 | }
51 |
52 | /**
53 | * Disable javadoc (groovydoc) publication.
54 | * Ignored with java-publish plugin.
55 | */
56 | void withoutJavadoc() {
57 | addJavadoc = false
58 | }
59 |
60 | /**
61 | * Disable sources publication.
62 | * Ignored with java-publish plugin.
63 | */
64 | void withoutSources() {
65 | addSources = false
66 | }
67 |
68 | /**
69 | * Disable all publications. Might be used to disable configured BOM publication or any sub-module publication.
70 | */
71 | void withoutPublication() {
72 | publication = false
73 | }
74 |
75 | /**
76 | * Aggregate test, jacoco coverage and dependency reports for subprojects (assuming 1 level hierarchy).
77 | * This option will work with "base" plugin (often used in root project to allow grouping).
78 | *
79 | * IMPORTANT: must be used in the root project or any subproject containing other subprojects.
80 | *
81 | * Aggregates only direct subprojects (ignoring lower levels).
82 | *
83 | * For jacoco reports aggregation jacoco plugin must be active. Jacoco report aggregation is important for
84 | * coverage services integration (they require single aggregated report; when aggregation enabled, report
85 | * path would be the same as with single module: build/reports/jacoco/test/jacocoTestReport.xml)
86 | *
87 | * Dependencies html report grouping activated if report-plugin is applied.
88 | */
89 | void aggregateReports() {
90 | aggregatedReports = true
91 | }
92 |
93 | // ----------------------------------- Utility methods required for sub objects configuration
94 |
95 | /**
96 | * Bom sub-object configuration. Used only with java-platform plugin when platform declared in the root project.
97 | *
98 | * @param config configuration action
99 | */
100 | void bom(Action config) {
101 | config.execute(bom)
102 | }
103 |
104 | /**
105 | * Configuration for java-platform plugin. Required for case when java-platform is declared in the root project,
106 | * but published bom maven coordinates must differ from root project name.
107 | */
108 | static class JavaPlatform {
109 | /**
110 | * Used with java-platform plugin when platform is declared in the root module to rename artifact (which is by
111 | * default equal to project name)
112 | */
113 | String artifactId
114 |
115 | /**
116 | * Used with java-platform plugin when platform is declared in the root module to specify custom description in
117 | * the generated pom (otherwise it would be root project description).
118 | */
119 | String description
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/groovy/ru/vyarus/gradle/plugin/lib/JavaLibPlugin.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import groovy.transform.CompileStatic
4 | import groovy.transform.TypeCheckingMode
5 | import org.gradle.api.Action
6 | import org.gradle.api.DefaultTask
7 | import org.gradle.api.GradleException
8 | import org.gradle.api.Plugin
9 | import org.gradle.api.Project
10 | import org.gradle.api.Task
11 | import org.gradle.api.java.archives.Attributes
12 | import org.gradle.api.plugins.*
13 | import org.gradle.api.provider.Provider
14 | import org.gradle.api.publish.PublishingExtension
15 | import org.gradle.api.publish.maven.MavenPublication
16 | import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
17 | import org.gradle.api.publish.maven.tasks.PublishToMavenLocal
18 | import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
19 | import org.gradle.api.publish.tasks.GenerateModuleMetadata
20 | import org.gradle.api.reporting.ConfigurableReport
21 | import org.gradle.api.reporting.SingleFileReport
22 | import org.gradle.api.reporting.dependencies.HtmlDependencyReportTask
23 | import org.gradle.api.tasks.Copy
24 | import org.gradle.api.tasks.SourceSetContainer
25 | import org.gradle.api.tasks.TaskCollection
26 | import org.gradle.api.tasks.compile.GroovyCompile
27 | import org.gradle.api.tasks.compile.JavaCompile
28 | import org.gradle.api.tasks.javadoc.Javadoc
29 | import org.gradle.api.tasks.testing.Test
30 | import org.gradle.api.tasks.testing.TestReport
31 | import org.gradle.jvm.tasks.Jar
32 | import org.gradle.plugins.signing.Sign
33 | import org.gradle.plugins.signing.SigningExtension
34 | import org.gradle.plugins.signing.SigningPlugin
35 | import org.gradle.process.internal.JvmOptions
36 | import org.gradle.testing.jacoco.plugins.JacocoPlugin
37 | import org.gradle.testing.jacoco.tasks.JacocoReport
38 | import org.gradle.util.GradleVersion
39 | import ru.vyarus.gradle.plugin.pom.PomExtension
40 | import ru.vyarus.gradle.plugin.pom.PomPlugin
41 |
42 | import java.nio.charset.StandardCharsets
43 |
44 | /**
45 | * Plugin performs common configuration for java or groovy library:
46 | *
47 | * - Fills manifest for main jar, add pom and generated pom.properties inside jar (as maven do)
48 | *
- Add sourcesJar and javadocJar tasks (gradle native way)
49 | *
- Configures maven publication named 'maven' (with all jars)
50 | *
- Applies 'ru.vyarus.pom' plugin which fixes pom dependencies, adds 'pom' closure for simpler pom
51 | * configuration
52 | *
- Configure signing if "signing" plugin applied
53 | *
- Add 'install' task as shortcut for publishToMavenLocal
54 | *
55 | *
56 | * When used with java-platform plugin:
57 | *
58 | * - Applies 'ru.vyarus.pom' plugin
59 | *
- Configure `bom` maven publication
60 | *
- Configure signing if "signing" plugin applied
61 | *
- Add 'install' task as shortcut for publishToMavenLocal
62 | *
- Activates platform dependencies (javaPlatform.allowDependencies())
63 | *
64 | * Java-publish might be used in the root project (for multi-module project) and in this case custom artifact name
65 | * would be required (most likely, BOM artifact should not be called the same as project name. For this case
66 | * special extension must be used: {@code libJava.bom.artifactId = 'something-bom'}. Name in the generated pom would be
67 | * changed accordingly. Also, {@code libJava.bom.description} may be used to specify custom description instead
68 | * of root project description.
69 | *
70 | * Also, in the root project reports aggregation might be enabled with {@code javaLib.aggregateReports()}.
71 | * When enabled aggregates test reports, coverage report (jacoco plugin) and dependency report (project-report plugin).
72 | * Aggregation might be used with at least "base" plugin (but may be also with java-platform).
73 | *
74 | * In case of gradle plugin (java-gradle-plugin + plugin-publish) "pluginMaven" publication will be created for
75 | * plugins portal publication, but java-lib plugin will still use "maven" publication (for maven central
76 | * publication).
77 | * Overall, in case of gradle plugin, 2 maven publications should be used, but exactly the same artifacts would
78 | * be published everywhere (plugin portal will additionally receive alias publications).
79 | *
80 | * @author Vyacheslav Rusakov
81 | * @since 07.11.2015
82 | * @see JavaLibExtension for options (javaLib closure in gradle)
83 | */
84 | @SuppressWarnings('DuplicateStringLiteral')
85 | @CompileStatic(TypeCheckingMode.SKIP)
86 | class JavaLibPlugin implements Plugin {
87 |
88 | @Override
89 | void apply(Project project) {
90 | // always creating extension to avoid hard to track mis-references in multi-module projects
91 | JavaLibExtension extension = project.extensions.create('javaLib', JavaLibExtension, project)
92 |
93 | // partial activation for java-platform plugin (when root module is a BOM)
94 | project.plugins.withType(JavaPlatformPlugin) {
95 | project.plugins.apply(PomPlugin)
96 | // different name used for publication
97 | MavenPublication bom = configureBomPublication(project)
98 | configurePlatform(project, extension, bom)
99 | configureGradleMetadata(project, extension)
100 | disablePublication(project, extension)
101 | configureSigning(project, bom)
102 |
103 | Provider name = project.provider { "$project.group:$bom.artifactId:$project.version" }
104 | addInstallTask(project, extension) {
105 | it.logger.warn "INSTALLED ${name.get()}"
106 | }
107 | }
108 |
109 | // full activation when java plugin is enabled
110 | project.plugins.withType(JavaPlugin) {
111 | project.plugins.apply(PomPlugin)
112 | // assume gradle 5.0 and above - stable publishing enabled
113 | MavenPublication publication = configureMavenPublication(project)
114 | configureEncoding(project)
115 | configureJar(project, publication)
116 | addJavadocAndSourceJars(project, extension)
117 | configureGradleMetadata(project, extension)
118 | disablePublication(project, extension)
119 | configureSigning(project, publication)
120 | applyAutoModuleName(project, extension)
121 | enableJacocoXmlReport(project)
122 |
123 | Provider name = project.provider { "$project.group:$project.name:$project.version" }
124 | addInstallTask(project, extension) {
125 | it.logger.warn "INSTALLED ${name.get()}"
126 | }
127 | }
128 |
129 | // extension applied with base plugin because it's often used in the root project for grouping
130 | project.plugins.withType(BasePlugin) {
131 | aggregateReports(project, extension)
132 | }
133 |
134 | // helper task to open dependency report in browser
135 | addOpenDependencyReportTask(project)
136 | }
137 |
138 | private void configurePlatform(Project project, JavaLibExtension extension, MavenPublication bom) {
139 | project.configure(project) {
140 | // allow dependencies declaration in BOM
141 | javaPlatform.allowDependencies()
142 |
143 | // for configuration cache support it must be direct link to simle pojo
144 | JavaLibExtension.JavaPlatform model = extension.bom
145 | // actual processing would be delayed by xml processing time in pom plugin
146 | project.extensions.getByType(PomExtension).pom {
147 | if (model?.artifactId) {
148 | // by default artifact name is project name and if root bom would be published it should
149 | // have a different name
150 | bom.artifactId = model.artifactId
151 | name = model.artifactId
152 | }
153 | if (model?.description) {
154 | description = model.description
155 | }
156 | }
157 | }
158 | }
159 |
160 | private void configureEncoding(Project project) {
161 | project.tasks.withType(JavaCompile).configureEach {
162 | it.options.encoding = StandardCharsets.UTF_8
163 | }
164 |
165 | project.tasks.withType(GroovyCompile).configureEach {
166 | it.options.encoding = StandardCharsets.UTF_8
167 | }
168 |
169 | project.tasks.withType(Test).configureEach {
170 | it.systemProperty JvmOptions.FILE_ENCODING_KEY, StandardCharsets.UTF_8
171 | }
172 |
173 | project.tasks.withType(Javadoc).configureEach {
174 | it.with {
175 | options.encoding = StandardCharsets.UTF_8
176 | // StandardJavadocDocletOptions
177 | options.charSet = StandardCharsets.UTF_8
178 | options.docEncoding = StandardCharsets.UTF_8
179 | }
180 | }
181 | }
182 |
183 | private void configureJar(Project project, MavenPublication publication) {
184 | project.tasks.register('generatePomPropertiesFile') {
185 | it.with {
186 | inputs.properties([
187 | 'version': "${ -> project.version }",
188 | 'groupId': "${ -> project.group }",
189 | 'artifactId': "${ -> project.name }",
190 | ])
191 | outputs.file project.layout.buildDirectory.file('generatePomPropertiesFile/pom.properties')
192 | doLast {
193 | File file = outputs.files.singleFile
194 | file.parentFile.mkdirs()
195 | file << inputs.properties.collect { key, value -> "$key: $value" }.join('\n')
196 | }
197 | }
198 | }
199 | project.configure(project) {
200 | // delayed to be able to use version
201 | afterEvaluate {
202 | // do not override user attributes
203 | tasks.named('jar').configure {
204 | Attributes attributes = it.manifest.attributes
205 | putIfAbsent(attributes, 'Implementation-Title', project.description ?: project.name)
206 | putIfAbsent(attributes, 'Implementation-Version', project.version)
207 | putIfAbsent(attributes, 'Built-By', System.getProperty('user.name'))
208 | putIfAbsent(attributes, 'Built-Date', new Date())
209 | putIfAbsent(attributes, 'Built-JDK', System.getProperty('java.version'))
210 | putIfAbsent(attributes, 'Built-Gradle', project.gradle.gradleVersion)
211 | putIfAbsent(attributes, 'Target-JDK', project.extensions
212 | .getByType(JavaPluginExtension).targetCompatibility)
213 | }
214 | }
215 |
216 | project.tasks.named('processResources', Copy).configure {
217 | it.with {
218 | into("META-INF/maven/$project.group/$project.name") {
219 | from project.tasks.named("generatePomFileFor${publication.name.capitalize()}Publication")
220 | rename '.*.xml', 'pom.xml'
221 | from project.tasks.named('generatePomPropertiesFile')
222 | }
223 | }
224 | }
225 | }
226 | }
227 |
228 | @SuppressWarnings('Indentation')
229 | private void addJavadocAndSourceJars(Project project, JavaLibExtension extension) {
230 | // use gradle native configuration method to aovid clashes with plugin-publish 1.0
231 | JavaPluginExtension javaExt = project.extensions.getByType(JavaPluginExtension)
232 | javaExt.withJavadocJar()
233 | javaExt.withSourcesJar()
234 | project.afterEvaluate {
235 | if (!extension.addJavadoc || !extension.addSources) {
236 | project.extensions.getByType(SourceSetContainer)
237 | .named('main').configure { sourceSet ->
238 | if (!extension.addJavadoc) {
239 | project.tasks.named(sourceSet.javadocJarTaskName).configure {
240 | it.enabled = false
241 | }
242 | }
243 | if (!extension.addSources) {
244 | project.tasks.named(sourceSet.sourcesJarTaskName).configure {
245 | it.enabled = false
246 | }
247 | }
248 | }
249 | }
250 | }
251 | }
252 |
253 | private MavenPublication configureMavenPublication(Project project) {
254 | // Configure publication:
255 | // java-gradle-plugin will create its own publication pluginMaven, but still plugin configures separate
256 | // maven publication because java-gradle-plugin most likely will be applied after java-lib and so
257 | // it's not possible to detect it for sure. But it's not a problem: pom will be corrected for both
258 | // (and in any case portal does not use this pom).
259 | // NOTE: java-gradle-plugin will also create alias publications for each plugin, but we will simply don't
260 | // use them
261 | MavenPublication publication = project.extensions
262 | .findByType(PublishingExtension)
263 | .publications
264 | .maybeCreate('maven', MavenPublication)
265 | publication.from(project.components.getByName('java'))
266 | // in stable publication mode extra jars added directly after tasks registration
267 | return publication
268 | }
269 |
270 | private MavenPublication configureBomPublication(Project project) {
271 | MavenPublication publication = project.extensions
272 | .findByType(PublishingExtension)
273 | .publications
274 | .maybeCreate('bom', MavenPublication)
275 | publication.from(project.components.getByName('javaPlatform'))
276 | // in stable publication mode extra jars added directly after tasks registration
277 | return publication
278 | }
279 |
280 | private void addInstallTask(Project project, JavaLibExtension extension, Action last) {
281 | Provider publication = project.provider { extension.publication }
282 | project.tasks.register('install') {
283 | it.with {
284 | dependsOn 'publishToMavenLocal'
285 | group = 'publishing'
286 | description = 'Publish to local maven repository (alias for publishToMavenLocal)'
287 | doLast {
288 | // show message only if publication not disabled
289 | if (publication.get()) {
290 | last.execute(it)
291 | }
292 | }
293 | }
294 | }
295 | }
296 |
297 | private void configureGradleMetadata(Project project, JavaLibExtension extension) {
298 | project.afterEvaluate {
299 | // disable gradle metadata publishing (usually it confuse a lot)
300 | if (!extension.gradleMetadata) {
301 | project.tasks.withType(GenerateModuleMetadata).configureEach {
302 | enabled = false
303 | }
304 | }
305 | }
306 | }
307 |
308 | private void disablePublication(Project project, JavaLibExtension extension) {
309 | project.afterEvaluate {
310 | if (!extension.publication) {
311 | project.tasks.withType(PublishToMavenRepository).configureEach {
312 | enabled = extension.publication
313 | }
314 | project.tasks.withType(PublishToMavenLocal).configureEach {
315 | enabled = false
316 | }
317 | }
318 | }
319 | }
320 |
321 | private void configureSigning(Project project, MavenPublication publication) {
322 | project.plugins.withType(SigningPlugin) {
323 | // https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials
324 | SigningExtension ext = project.extensions.getByType(SigningExtension)
325 | ext.sign publication
326 | ext.required = { !project.version.toString().endsWith('SNAPSHOT') }
327 |
328 | // Fix Gradle warning about signing tasks using publishing task outputs without explicit dependencies
329 | // https://github.com/gradle/gradle/issues/26091
330 | project.tasks.withType(AbstractPublishToMaven).configureEach {
331 | TaskCollection signingTasks = project.tasks.withType(Sign)
332 | mustRunAfter(signingTasks)
333 | }
334 | }
335 | }
336 |
337 | private void applyAutoModuleName(Project project, JavaLibExtension extension) {
338 | project.afterEvaluate {
339 | if (extension.autoModuleName) {
340 | // java 11 auto module name
341 | (project.tasks.jar as Jar).manifest {
342 | attributes 'Automatic-Module-Name': extension.autoModuleName
343 | }
344 | }
345 | }
346 | }
347 |
348 | private void addOpenDependencyReportTask(Project project) {
349 | project.plugins.withType(ProjectReportsPlugin) {
350 | project.tasks.register('openDependencyReport').configure {
351 | (it as DefaultTask).with {
352 | group = 'help'
353 | dependsOn 'htmlDependencyReport'
354 | description = 'Opens gradle htmlDependencyReport in browser'
355 | // prevent calling task on all subprojects
356 | impliesSubProjects = true
357 | doLast {
358 | File report = project.file("build/reports/project/dependencies/root.${project.name}.html")
359 | if (!report.exists()) {
360 | // for multi-module project root, if reports aggregation enabled name would be different
361 | report = project.file('build/reports/project/dependencies/root.html')
362 | }
363 | java.awt.Desktop.desktop.open(report)
364 | }
365 | }
366 | }
367 | }
368 | }
369 |
370 | private void enableJacocoXmlReport(Project project) {
371 | // by default jacoco xml report is disabled, but its required for coverage services
372 | project.plugins.withType(JacocoPlugin) {
373 | project.tasks.named('jacocoTestReport').configure {
374 | (it as JacocoReport).reports.xml.required.set(true)
375 | }
376 | }
377 | }
378 |
379 | @SuppressWarnings(['AbcMetric', 'MethodSize'])
380 | private void aggregateReports(Project project, JavaLibExtension extension) {
381 | project.afterEvaluate {
382 | if (!extension.aggregatedReports) {
383 | return
384 | }
385 | // makes no sense otherwise
386 | if (project.subprojects.empty) {
387 | throw new GradleException('javaLib.aggregateReports() could not be used on project ' +
388 | "'$project.name' because does not contain subprojects")
389 | }
390 | if (project.plugins.hasPlugin(JavaPlugin)) {
391 | throw new GradleException('javaLib.aggregateReports() could not be used on project ' +
392 | "'$project.name' because it contains java sources. If this is a root project use 'base' " +
393 | 'plugin instead.')
394 | }
395 |
396 | // aggregate test reports from subprojects
397 | project.tasks.register('test', TestReport) {
398 | it.with {
399 | description = 'Generates aggregated test report'
400 | // show task in common place
401 | group = 'verification'
402 | if (GradleVersion.current() < GradleVersion.version('8.0')) {
403 | destinationDir = project.file("${project.buildDir}/reports/tests/test")
404 | reportOn project.subprojects
405 | .findAll { it.plugins.hasPlugin(JavaPlugin) }.test
406 | } else {
407 | destinationDirectory.set(project.layout.buildDirectory.dir('reports/tests/test'))
408 | testResults.from(project.subprojects
409 | .findAll { it.plugins.hasPlugin(JavaPlugin) }.test)
410 | }
411 | }
412 | }
413 |
414 | // aggregate jacoco coverage from subprojects
415 | project.plugins.withType(JacocoPlugin) {
416 | Set projectsWithCoverage = project.subprojects
417 | .findAll { it.plugins.hasPlugin(JacocoPlugin) }
418 |
419 | project.tasks.register('jacocoTestReport', JacocoReport) {
420 | it.with {
421 | description = 'Generates aggregated jacoco coverage report'
422 | dependsOn 'test'
423 | // show task in common place
424 | group = 'verification'
425 | executionData project.files(projectsWithCoverage
426 | .collect { it.layout.buildDirectory.file('jacoco/test.exec') })
427 | .filter { it.exists() }
428 | sourceDirectories.from = selectFiles(projectsWithCoverage) { SourceSetContainer sourceSets ->
429 | sourceSets.main.allSource.srcDirs
430 | }
431 | classDirectories.from = selectFiles(projectsWithCoverage) { SourceSetContainer sourceSets ->
432 | sourceSets.main.output.files
433 | }
434 | // use same location as in single-module case
435 | reportDestination(reports.xml, project, 'reports/jacoco/test/jacocoTestReport.xml')
436 | reportDestination(reports.html, project, 'reports/jacoco/test/html/')
437 | reports.xml.required.set(true)
438 | }
439 | }
440 | }
441 |
442 | // aggregated html dependency report
443 | project.plugins.withType(ProjectReportsPlugin) {
444 | project.tasks.named('htmlDependencyReport').configure {
445 | (it as HtmlDependencyReportTask).projects = project.allprojects
446 | }
447 | }
448 | }
449 | }
450 |
451 | private Set selectFiles(Set projects, Closure> extractor) {
452 | Set res = []
453 | projects.forEach {
454 | res.addAll(extractor.call(it.extensions.getByType(SourceSetContainer)))
455 | }
456 | res
457 | }
458 |
459 | private void putIfAbsent(Attributes attributes, String name, Object value) {
460 | if (!attributes.containsKey(name)) {
461 | attributes.put(name, value)
462 | }
463 | }
464 |
465 | @SuppressWarnings('Instanceof')
466 | private void reportDestination(ConfigurableReport report, Project project, String path) {
467 | if (GradleVersion.current() < GradleVersion.version('8.0')) {
468 | report.destination = project.file("$project.buildDir/$path")
469 | } else {
470 | if (report instanceof SingleFileReport) {
471 | report.outputLocation.set(project.layout.buildDirectory.get().file(path))
472 | } else {
473 | report.outputLocation.set(project.layout.buildDirectory.dir(path))
474 | }
475 | }
476 | }
477 | }
478 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/AbstractKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.BuildResult
4 | import org.gradle.testkit.runner.GradleRunner
5 | import spock.lang.Specification
6 | import spock.lang.TempDir
7 |
8 | /**
9 | * @author Vyacheslav Rusakov
10 | * @since 18.11.2015
11 | */
12 | abstract class AbstractKitTest extends Specification {
13 |
14 | boolean debug
15 | @TempDir File testProjectDir
16 | File buildFile
17 |
18 | def setup() {
19 | buildFile = file('build.gradle')
20 | // jacoco coverage support
21 | fileFromClasspath('gradle.properties', 'testkit-gradle.properties')
22 | // override maven local repository
23 | // (see org.gradle.api.internal.artifacts.mvnsettings.DefaultLocalMavenRepositoryLocator.getLocalMavenRepository)
24 | System.setProperty("maven.repo.local", new File(testProjectDir, "build/repo").getAbsolutePath())
25 | }
26 |
27 | def build(String file) {
28 | buildFile << file
29 | }
30 |
31 | File file(String path) {
32 | new File(testProjectDir, path)
33 | }
34 |
35 | File fileFromClasspath(String toFile, String source) {
36 | File target = file(toFile)
37 | target.parentFile.mkdirs()
38 | target.withOutputStream {
39 | it.write((getClass().getResourceAsStream(source) ?: getClass().classLoader.getResourceAsStream(source)).bytes)
40 | }
41 | target
42 | }
43 |
44 | /**
45 | * Enable it and run test with debugger (no manual attach required). Not always enabled to speed up tests during
46 | * normal execution.
47 | */
48 | def debug() {
49 | debug = true
50 | }
51 |
52 | String projectName() {
53 | return testProjectDir.getName()
54 | }
55 |
56 | GradleRunner gradle(File root, String... commands) {
57 | GradleRunner.create()
58 | .withProjectDir(root)
59 | .withArguments((commands + ['--stacktrace']) as String[])
60 | .withPluginClasspath()
61 | .withDebug(debug)
62 | .forwardOutput()
63 | }
64 |
65 | GradleRunner gradle(String... commands) {
66 | gradle(testProjectDir, commands)
67 | }
68 |
69 | BuildResult run(String... commands) {
70 | return gradle(commands).build()
71 | }
72 |
73 | BuildResult runFailed(String... commands) {
74 | return gradle(commands).buildAndFail()
75 | }
76 |
77 | BuildResult runVer(String gradleVersion, String... commands) {
78 | return gradle(commands).withGradleVersion(gradleVersion).build()
79 | }
80 |
81 | BuildResult runFailedVer(String gradleVersion, String... commands) {
82 | return gradle(commands).withGradleVersion(gradleVersion).buildAndFail()
83 | }
84 |
85 | protected String unifyString(String input) {
86 | return input
87 | // cleanup win line break for simpler comparisons
88 | .replace("\r", '')
89 | }
90 |
91 | Set withoutModuleFile(File deployDir) {
92 | // gradle 6 publish additional module file (for extended dependencies model)
93 | (deployDir.list() as Set).findAll {!it.endsWith('.module')}
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/AbstractTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.Project
4 | import org.gradle.testfixtures.ProjectBuilder
5 | import spock.lang.Specification
6 | import spock.lang.TempDir
7 |
8 | /**
9 | * @author Vyacheslav Rusakov
10 | * @since 18.11.2015
11 | */
12 | abstract class AbstractTest extends Specification {
13 |
14 | @TempDir File testProjectDir
15 |
16 | Project project(Closure config = null) {
17 | projectBuilder(config).build()
18 | }
19 |
20 | ExtendedProjectBuilder projectBuilder(Closure root = null) {
21 | new ExtendedProjectBuilder().root(testProjectDir, root)
22 | }
23 |
24 | File file(String path) {
25 | new File(testProjectDir, path)
26 | }
27 |
28 | File fileFromClasspath(String toFile, String source) {
29 | File target = file(toFile)
30 | target.parentFile.mkdirs()
31 | target << getClass().getResourceAsStream(source).text
32 | }
33 |
34 | static class ExtendedProjectBuilder {
35 | Project root
36 |
37 | ExtendedProjectBuilder root(File dir, Closure config = null) {
38 | assert root == null, "Root project already declared"
39 | Project project = ProjectBuilder.builder()
40 | .withProjectDir(dir).build()
41 | if (config) {
42 | project.configure(project, config)
43 | }
44 | root = project
45 | return this
46 | }
47 |
48 | /**
49 | * Direct child of parent project
50 | *
51 | * @param name child project name
52 | * @param config optional configuration closure
53 | * @return builder
54 | */
55 | ExtendedProjectBuilder child(String name, Closure config = null) {
56 | return childOf(null, name, config)
57 | }
58 |
59 | /**
60 | * Direct child of any registered child project
61 | *
62 | * @param projectRef name of required parent module (gradle project reference format: `:some:deep:module`)
63 | * @param name child project name
64 | * @param config optional configuration closure
65 | * @return builder
66 | */
67 | ExtendedProjectBuilder childOf(String projectRef, String name, Closure config = null) {
68 | assert root != null, "Root project not declared"
69 | Project parent = projectRef == null ? root : root.project(projectRef)
70 | File folder = parent.file(name)
71 | if (!folder.exists()) {
72 | folder.mkdir()
73 | }
74 | Project project = ProjectBuilder.builder()
75 | .withName(name)
76 | .withProjectDir(folder)
77 | .withParent(parent)
78 | .build()
79 | if (config) {
80 | project.configure(project, config)
81 | }
82 | return this
83 | }
84 |
85 | /**
86 | * Evaluate configuration.
87 | *
88 | * @return root project
89 | */
90 | Project build() {
91 | if (root.subprojects) {
92 | linkSubprojectsEvaluation(root)
93 | }
94 | root.evaluate()
95 | return root
96 | }
97 |
98 | private void linkSubprojectsEvaluation(Project project) {
99 | project.evaluationDependsOnChildren()
100 | project.subprojects.each { linkSubprojectsEvaluation(it) }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/ConfigurationCacheSupportKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.BuildResult
4 | import org.gradle.testkit.runner.TaskOutcome
5 |
6 | import java.util.zip.ZipFile
7 |
8 | /**
9 | * @author Vyacheslav Rusakov
10 | * @since 02.03.2024
11 | */
12 | class ConfigurationCacheSupportKitTest extends AbstractKitTest {
13 |
14 | def "Check install task"() {
15 | setup:
16 | file('src/main/java').mkdirs()
17 | build """
18 | plugins {
19 | id 'java'
20 | id 'ru.vyarus.java-lib'
21 | }
22 |
23 | group 'ru.vyarus'
24 | version 1.0
25 | """
26 |
27 | when: "run pom task"
28 | BuildResult result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
29 |
30 |
31 | String artifactId = projectName()
32 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
33 |
34 | then: "no configuration cache incompatibilities"
35 | result.output.contains("1 problem was found storing the configuration cache")
36 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
37 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
38 |
39 | then: "task done"
40 | result.task(":install").outcome == TaskOutcome.SUCCESS
41 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
42 |
43 | then: "artifacts deployed"
44 | deploy.exists()
45 | def baseName = artifactId + '-1.0'
46 | withoutModuleFile(deploy) ==
47 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
48 |
49 |
50 | when: "run from cache"
51 | println '\n\n------------------- FROM CACHE ----------------------------------------'
52 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
53 |
54 | then: "cache used"
55 | result.output.contains('Reusing configuration cache.')
56 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
57 | }
58 |
59 |
60 |
61 | def "Check reports aggregation"() {
62 | setup:
63 | build """
64 | plugins {
65 | id 'base'
66 | id 'jacoco'
67 | id 'project-report'
68 | id 'ru.vyarus.java-lib'
69 | }
70 |
71 | javaLib {
72 | aggregateReports()
73 | }
74 |
75 | allprojects {
76 | repositories { mavenCentral() }
77 | }
78 |
79 | subprojects {
80 | apply plugin: 'groovy'
81 | apply plugin: 'jacoco'
82 | apply plugin: 'project-report'
83 | apply plugin: 'ru.vyarus.java-lib'
84 |
85 | dependencies {
86 | testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
87 | }
88 |
89 | test {
90 | useJUnitPlatform()
91 | }
92 | }
93 | """
94 | file('settings.gradle') << "include 'sub1', 'sub2'"
95 |
96 | fileFromClasspath('sub1/src/main/java/sample/Sample.java', '/sample/Sample.java')
97 | fileFromClasspath('sub1/src/test/groovy/sample/SampleTest.groovy', '/sample/SampleTest.groovy')
98 |
99 | fileFromClasspath('sub2/src/main/java/sample/Sample2.java', '/sample/Sample2.java')
100 | fileFromClasspath('sub2/src/test/groovy/sample/SampleTest2.groovy', '/sample/SampleTest2.groovy')
101 |
102 | when: "run test task"
103 | def result = run('--configuration-cache', '--configuration-cache-problems=warn', 'test')
104 |
105 | then: "no configuration cache incompatibilities"
106 | result.output.contains("1 problem was found storing the configuration cache")
107 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
108 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
109 |
110 | then: "task done"
111 | result.task(":test").outcome == TaskOutcome.SUCCESS
112 |
113 | then: "test report created"
114 | def test = file('build/reports/tests/test/index.html')
115 | test.exists()
116 |
117 | when: "run coverage task"
118 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'clean', 'jacocoTestReport')
119 |
120 | then: "no configuration cache incompatibilities"
121 | result.output.contains("1 problem was found storing the configuration cache")
122 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
123 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
124 |
125 | then: "task done"
126 | result.task(":jacocoTestReport").outcome == TaskOutcome.SUCCESS
127 |
128 | then: "coverage aggregated"
129 | def cov = file('build/reports/jacoco/test/jacocoTestReport.xml')
130 | cov.exists()
131 | cov.length() > 0
132 |
133 | when: "run dependencies task"
134 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'htmlDependencyReport')
135 |
136 | then: "no configuration cache incompatibilities"
137 | result.output.contains("1 problem was found storing the configuration cache")
138 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
139 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
140 |
141 | then: "task done"
142 | result.task(":htmlDependencyReport").outcome == TaskOutcome.SUCCESS
143 |
144 | then: "aggregated dependency report"
145 | file('build/reports/project/dependencies/root.sub1.html').exists()
146 | file('build/reports/project/dependencies/root.sub2.html').exists()
147 | file('build/reports/project/dependencies/root.html').exists()
148 |
149 |
150 |
151 | when: "run test task from cache"
152 | println '\n\n------------------- FROM CACHE ----------------------------------------'
153 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'test')
154 |
155 | then: "cache used"
156 | result.output.contains('Reusing configuration cache.')
157 |
158 | then: "task done"
159 | result.task(":test").outcome == TaskOutcome.UP_TO_DATE
160 |
161 | then: "test report created"
162 | test.exists()
163 |
164 | when: "run coverage task"
165 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'clean', 'jacocoTestReport')
166 |
167 | then: "cache used"
168 | result.output.contains('Reusing configuration cache.')
169 |
170 | then: "task done"
171 | result.task(":jacocoTestReport").outcome == TaskOutcome.SUCCESS
172 |
173 | then: "coverage aggregated"
174 | cov.exists()
175 | cov.length() > 0
176 |
177 | when: "run dependencies task"
178 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'htmlDependencyReport')
179 |
180 | then: "cache used"
181 | result.output.contains('Reusing configuration cache.')
182 |
183 | then: "task done"
184 | result.task(":htmlDependencyReport").outcome == TaskOutcome.SUCCESS
185 |
186 | then: "aggregated dependency report"
187 | file('build/reports/project/dependencies/root.sub1.html').exists()
188 | file('build/reports/project/dependencies/root.sub2.html').exists()
189 | file('build/reports/project/dependencies/root.html').exists()
190 | }
191 |
192 |
193 | def "Check automatic signing"() {
194 | setup:
195 | file('src/main/java').mkdirs()
196 | build """
197 | plugins {
198 | id 'java'
199 | id 'signing'
200 | id 'ru.vyarus.java-lib'
201 | }
202 |
203 | javaLib {
204 | withoutGradleMetadata()
205 | withoutJavadoc()
206 | withoutSources()
207 | }
208 |
209 | group 'ru.vyarus'
210 | version 1.0
211 |
212 | ext['signing.keyId']='78065050'
213 | ext['signing.password']=
214 | ext['signing.secretKeyRingFile']='test.gpg'
215 | """
216 | fileFromClasspath('test.gpg', '/cert/test.gpg')
217 | file('settings.gradle') << """
218 | rootProject.name = "test"
219 | """
220 |
221 | when: "run pom task"
222 | BuildResult result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
223 |
224 |
225 | String artifactId = 'test'
226 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
227 |
228 | then: "no configuration cache incompatibilities"
229 | result.output.contains("1 problem was found storing the configuration cache")
230 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
231 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
232 |
233 | then: "task done"
234 | result.task(":install").outcome == TaskOutcome.SUCCESS
235 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
236 |
237 | then: "artifacts deployed"
238 | deploy.exists()
239 | def baseName = artifactId + '-1.0'
240 | withoutModuleFile(deploy) ==
241 | ["${baseName}.jar", "${baseName}.pom", "${baseName}.jar.asc", "${baseName}.pom.asc"] as Set
242 |
243 |
244 | when: "run from cache"
245 | println '\n\n------------------- FROM CACHE ----------------------------------------'
246 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
247 |
248 | then: "cache used"
249 | result.output.contains('Reusing configuration cache.')
250 | }
251 |
252 |
253 |
254 | def "Check current publish plugin with signing integration correctness"() {
255 | setup:
256 | fileFromClasspath('src/main/java/ru/vyarus/TestPlugin.java', '/sample/TestPlugin.java')
257 |
258 | build """
259 | plugins {
260 | id 'com.gradle.plugin-publish' version '1.2.1'
261 | id 'java-gradle-plugin'
262 | id 'ru.vyarus.java-lib'
263 | id 'java'
264 | id 'signing'
265 | }
266 |
267 | gradlePlugin {
268 | plugins {
269 | testPlugin {
270 | description = 'Test plugin'
271 | tags.set(['java'])
272 | id = 'ru.vyarus.test'
273 | implementationClass = 'ru.vyarus.TestPlugin'
274 | }
275 | }
276 | }
277 |
278 | maven.pom {
279 | name = 'customName'
280 | }
281 |
282 | group 'ru.vyarus'
283 | version 1.0
284 |
285 | ext['signing.keyId']='78065050'
286 | ext['signing.password']=
287 | ext['signing.secretKeyRingFile']='test.gpg'
288 | """
289 | fileFromClasspath('test.gpg', '/cert/test.gpg')
290 | file('settings.gradle') << """
291 | rootProject.name = "test"
292 | """
293 |
294 | when: "run pom task"
295 | def result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
296 |
297 |
298 | String artifactId = 'test'
299 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
300 |
301 | then: "no configuration cache incompatibilities"
302 | result.output.contains("1 problem was found storing the configuration cache")
303 | result.output.contains('Gradle runtime: support for using a Java agent with TestKit')
304 | result.output.contains('Calculating task graph as no cached configuration is available for tasks:')
305 |
306 | then: "task done"
307 | result.task(":install").outcome == TaskOutcome.SUCCESS
308 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
309 |
310 | then: "alias publication created"
311 | result.task(":publishMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
312 | result.task(":publishTestPluginPluginMarkerMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
313 |
314 | then: "custom jar tasks used"
315 | result.task(":sourcesJar").outcome == TaskOutcome.SUCCESS
316 | result.task(":javadocJar").outcome == TaskOutcome.SUCCESS
317 |
318 | then: "plugin descriptors generation executed"
319 | result.task(":pluginDescriptors").outcome == TaskOutcome.SUCCESS
320 |
321 | then: "artifacts deployed"
322 | deploy.exists()
323 | def baseName = artifactId + '-1.0'
324 | withoutModuleFile(deploy) ==
325 | ["${baseName}.jar", "${baseName}.jar.asc",
326 | "${baseName}.pom", "${baseName}.pom.asc",
327 | "${baseName}-sources.jar", "${baseName}-sources.jar.asc",
328 | "${baseName}-javadoc.jar", "${baseName}-javadoc.jar.asc",
329 | "${baseName}.module.asc"] as Set
330 |
331 | then: "jar modifiers applied"
332 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
333 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
334 | println manifest
335 | manifest.contains("Implementation-Title: $artifactId")
336 | manifest.contains("Implementation-Version: 1.0")
337 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
338 | manifest.contains("Built-Date:")
339 | manifest.contains("Built-JDK:")
340 | manifest.contains("Built-Gradle:")
341 | manifest.contains("Target-JDK:")
342 |
343 | then: "jar contains pom"
344 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
345 | println jarPom
346 | jarPom != null
347 | jarPom.contains("ru.vyarus")
348 | jarPom.contains("$artifactId")
349 |
350 | then: "pom closure applied"
351 | jarPom.contains("customName")
352 |
353 | then: "jar contains pom.properties"
354 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
355 | println props
356 | props != null
357 | props.contains('groupId: ru.vyarus')
358 | props.contains("artifactId: $artifactId")
359 | props.contains('version: 1.0')
360 |
361 | then: "jar contains plugin desriptor"
362 | String gradleDesc = jar.getInputStream(jar.getEntry("META-INF/gradle-plugins/ru.vyarus.test.properties")).text
363 | println gradleDesc
364 | gradleDesc.trim() == 'implementation-class=ru.vyarus.TestPlugin'
365 |
366 |
367 | when: "run from cache"
368 | println '\n\n------------------- FROM CACHE ----------------------------------------'
369 | result = run('--configuration-cache', '--configuration-cache-problems=warn', 'install')
370 |
371 | then: "cache used"
372 | result.output.contains('Reusing configuration cache.')
373 |
374 | cleanup:
375 | jar?.close()
376 | }
377 | }
378 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/EncodingConfigurationTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.Project
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 09.11.2019
8 | */
9 | class EncodingConfigurationTest extends AbstractTest {
10 |
11 | def "Check encoding set for java tasks"() {
12 |
13 | when: "activating plugin"
14 | file('src/main/java').mkdirs()
15 | Project project = project {
16 | apply plugin: 'java'
17 | apply plugin: "ru.vyarus.java-lib"
18 | }
19 |
20 | then: "compile tasks affected"
21 | project.tasks.compileJava.options.encoding == 'UTF-8'
22 | project.tasks.compileTestJava.options.encoding == 'UTF-8'
23 |
24 | then: "javadoc affected"
25 | project.tasks.javadoc.options.encoding == 'UTF-8'
26 | project.tasks.javadoc.options.charSet == 'UTF-8'
27 | project.tasks.javadoc.options.docEncoding == 'UTF-8'
28 |
29 | then: "test sys property set"
30 | project.tasks.test.allJvmArgs.contains('-Dfile.encoding=UTF-8')
31 | }
32 |
33 | def "Check encoding set for groovy tasks"() {
34 |
35 | when: "activating plugin"
36 | file('src/main/java').mkdirs()
37 | file('src/main/groovy').mkdirs()
38 | Project project = project {
39 | apply plugin: 'groovy'
40 | apply plugin: "ru.vyarus.java-lib"
41 | }
42 |
43 | then: "compile tasks affected"
44 | project.tasks.compileJava.options.encoding == 'UTF-8'
45 | project.tasks.compileGroovy.options.encoding == 'UTF-8'
46 | project.tasks.compileGroovy.groovyOptions.encoding == 'UTF-8'
47 | project.tasks.compileTestJava.options.encoding == 'UTF-8'
48 | project.tasks.compileTestGroovy.options.encoding == 'UTF-8'
49 | project.tasks.compileTestGroovy.groovyOptions.encoding == 'UTF-8'
50 |
51 | then: "javadoc affected"
52 | project.tasks.javadoc.options.encoding == 'UTF-8'
53 | project.tasks.javadoc.options.charSet == 'UTF-8'
54 | project.tasks.javadoc.options.docEncoding == 'UTF-8'
55 |
56 | then: "test sys property set"
57 | project.tasks.test.allJvmArgs.contains('-Dfile.encoding=UTF-8')
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/GradleMetadataDisableKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 06.06.2021
8 | */
9 | class GradleMetadataDisableKitTest extends AbstractKitTest {
10 |
11 | def "Check metadata disable"() {
12 | setup:
13 | file('src/main/java').mkdirs()
14 | build """
15 | plugins {
16 | id 'java'
17 | id 'ru.vyarus.java-lib'
18 | }
19 |
20 | group 'ru.vyarus'
21 | version 1.0
22 |
23 | dependencies {
24 | implementation 'ru.vyarus:guice-validator:2.0.0'
25 | }
26 |
27 | javaLib {
28 | withoutGradleMetadata()
29 | }
30 | """
31 |
32 | when: "run install task"
33 | def result = run('install')
34 |
35 | String artifactId = projectName()
36 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
37 |
38 | then: "task done"
39 | result.task(":install").outcome == TaskOutcome.SUCCESS
40 |
41 | then: "artifacts deployed"
42 | deploy.exists()
43 | def baseName = artifactId + '-1.0'
44 | deploy.list().size() == 4
45 | withoutModuleFile(deploy) ==
46 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
47 | }
48 |
49 | def "Check metadata disable for bom"() {
50 | setup:
51 | file('src/main/java').mkdirs()
52 | build """
53 | plugins {
54 | id 'java-platform'
55 | id 'ru.vyarus.java-lib'
56 | }
57 |
58 | group 'ru.vyarus'
59 | version 1.0
60 |
61 | dependencies {
62 | constraints {
63 | api 'ru.vyarus:guice-validator:2.0.0'
64 | }
65 | }
66 |
67 | javaLib {
68 | withoutGradleMetadata()
69 | }
70 | """
71 |
72 | when: "run install task"
73 | def result = run('install')
74 |
75 | String artifactId = projectName()
76 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
77 |
78 | then: "task done"
79 | result.task(":install").outcome == TaskOutcome.SUCCESS
80 |
81 | then: "artifacts deployed"
82 | deploy.exists()
83 | def baseName = artifactId + '-1.0'
84 | deploy.list().size() == 1
85 | withoutModuleFile(deploy) == ["${baseName}.pom"] as Set
86 | }
87 |
88 | def "Check metadata disable in allprojects"() {
89 | setup:
90 | build """
91 | plugins {
92 | id 'base'
93 | id 'ru.vyarus.java-lib'
94 | }
95 |
96 | allprojects {
97 | println '!!!!!!!!'+it.name
98 |
99 | apply plugin: 'ru.vyarus.java-lib'
100 |
101 | group 'ru.vyarus'
102 | version 1.0
103 |
104 | repositories { mavenCentral() }
105 |
106 | javaLib.withoutGradleMetadata()
107 | }
108 |
109 | subprojects {
110 | apply plugin: 'groovy'
111 | }
112 | """
113 | file('settings.gradle') << "include 'sub'"
114 | file('sub').mkdirs()
115 |
116 | when: "run install task"
117 | def result = run('install')
118 |
119 | String artifactId = 'sub'
120 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
121 |
122 | then: "task done"
123 | result.task(":sub:install").outcome == TaskOutcome.SUCCESS
124 |
125 | then: "artifacts deployed"
126 | deploy.exists()
127 | def baseName = artifactId + '-1.0'
128 |
129 | then: "pom does not have metadata comment"
130 | def pom = new File(deploy, "${baseName}.pom").text
131 | !pom.contains('')
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/GradlePluginCompatibilityKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | import java.util.zip.ZipFile
6 |
7 | /**
8 | * @author Vyacheslav Rusakov
9 | * @since 13.11.2019
10 | */
11 | class GradlePluginCompatibilityKitTest extends AbstractKitTest {
12 |
13 | def "Check legacy publish plugin integration correctness"() {
14 | setup:
15 | fileFromClasspath('src/main/java/ru/vyarus/TestPlugin.java', '/sample/TestPlugin.java')
16 |
17 | build """
18 | plugins {
19 | id 'com.gradle.plugin-publish' version '0.21.0'
20 | id 'java-gradle-plugin'
21 | id 'ru.vyarus.java-lib'
22 | id 'java'
23 | id 'signing'
24 | }
25 |
26 | gradlePlugin {
27 | plugins {
28 | testPlugin {
29 | id = 'ru.vyarus.test'
30 | implementationClass = 'ru.vyarus.TestPlugin'
31 | }
32 | }
33 | }
34 | pluginBundle {
35 | description = 'Test plugin'
36 | tags = ['java']
37 |
38 | mavenCoordinates {
39 | groupId = project.group
40 | artifactId = project.name
41 | }
42 | }
43 |
44 | maven.pom {
45 | name = 'customName'
46 | }
47 |
48 | group 'ru.vyarus'
49 | version 1.0
50 |
51 | ext['signing.keyId']='78065050'
52 | ext['signing.password']=
53 | ext['signing.secretKeyRingFile']='test.gpg'
54 | """
55 | fileFromClasspath('test.gpg', '/cert/test.gpg')
56 | file('settings.gradle') << """
57 | rootProject.name = "test"
58 | """
59 |
60 | when: "run pom task"
61 | def result = run('install')
62 |
63 |
64 | String artifactId = 'test'
65 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
66 |
67 | then: "task done"
68 | result.task(":install").outcome == TaskOutcome.SUCCESS
69 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
70 |
71 | then: "alias publication created"
72 | result.task(":publishMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
73 | result.task(":publishTestPluginPluginMarkerMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
74 |
75 | then: "custom jar tasks used"
76 | result.task(":sourcesJar").outcome == TaskOutcome.SUCCESS
77 | result.task(":javadocJar").outcome == TaskOutcome.SUCCESS
78 |
79 | then: "plugin-publish did not register custom tasks"
80 | result.task(":publishPluginJar") == null
81 | result.task(":publishPluginJavaDocsJar") == null
82 | result.task(":publishPluginGroovyDocsJar") == null
83 |
84 | then: "plugin descriptors generation executed"
85 | result.task(":pluginDescriptors").outcome == TaskOutcome.SUCCESS
86 |
87 | then: "artifacts deployed"
88 | deploy.exists()
89 | def baseName = artifactId + '-1.0'
90 | withoutModuleFile(deploy) ==
91 | ["${baseName}.jar", "${baseName}.jar.asc",
92 | "${baseName}.pom", "${baseName}.pom.asc",
93 | "${baseName}-sources.jar", "${baseName}-sources.jar.asc",
94 | "${baseName}-javadoc.jar", "${baseName}-javadoc.jar.asc",
95 | "${baseName}.module.asc"] as Set
96 |
97 | then: "jar modifiers applied"
98 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
99 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
100 | println manifest
101 | manifest.contains("Implementation-Title: $artifactId")
102 | manifest.contains("Implementation-Version: 1.0")
103 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
104 | manifest.contains("Built-Date:")
105 | manifest.contains("Built-JDK:")
106 | manifest.contains("Built-Gradle:")
107 | manifest.contains("Target-JDK:")
108 |
109 | then: "jar contains pom"
110 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
111 | println jarPom
112 | jarPom != null
113 | jarPom.contains("ru.vyarus")
114 | jarPom.contains("$artifactId")
115 |
116 | then: "pom closure applied"
117 | jarPom.contains("customName")
118 |
119 | then: "jar contains pom.properties"
120 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
121 | println props
122 | props != null
123 | props.contains('groupId: ru.vyarus')
124 | props.contains("artifactId: $artifactId")
125 | props.contains('version: 1.0')
126 |
127 | then: "jar contains plugin desriptor"
128 | String gradleDesc = jar.getInputStream(jar.getEntry("META-INF/gradle-plugins/ru.vyarus.test.properties")).text
129 | println gradleDesc
130 | gradleDesc.trim() == 'implementation-class=ru.vyarus.TestPlugin'
131 |
132 | cleanup:
133 | jar?.close()
134 | }
135 |
136 |
137 | def "Check current publish plugin integration correctness"() {
138 | setup:
139 | fileFromClasspath('src/main/java/ru/vyarus/TestPlugin.java', '/sample/TestPlugin.java')
140 |
141 | build """
142 | plugins {
143 | id 'com.gradle.plugin-publish' version '1.2.1'
144 | id 'java-gradle-plugin'
145 | id 'ru.vyarus.java-lib'
146 | id 'java'
147 | }
148 |
149 | gradlePlugin {
150 | plugins {
151 | testPlugin {
152 | description = 'Test plugin'
153 | tags.set(['java'])
154 | id = 'ru.vyarus.test'
155 | implementationClass = 'ru.vyarus.TestPlugin'
156 | }
157 | }
158 | }
159 |
160 | maven.pom {
161 | name = 'customName'
162 | }
163 |
164 | group 'ru.vyarus'
165 | version 1.0
166 | """
167 | file('settings.gradle') << """
168 | rootProject.name = "test"
169 | """
170 |
171 | when: "run pom task"
172 | def result = run('install')
173 |
174 |
175 | String artifactId = 'test'
176 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
177 |
178 | then: "task done"
179 | result.task(":install").outcome == TaskOutcome.SUCCESS
180 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
181 |
182 | then: "alias publication created"
183 | result.task(":publishMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
184 | result.task(":publishTestPluginPluginMarkerMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
185 |
186 | then: "custom jar tasks used"
187 | result.task(":sourcesJar").outcome == TaskOutcome.SUCCESS
188 | result.task(":javadocJar").outcome == TaskOutcome.SUCCESS
189 |
190 | then: "plugin descriptors generation executed"
191 | result.task(":pluginDescriptors").outcome == TaskOutcome.SUCCESS
192 |
193 | then: "artifacts deployed"
194 | deploy.exists()
195 | def baseName = artifactId + '-1.0'
196 | withoutModuleFile(deploy) ==
197 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
198 |
199 | then: "jar modifiers applied"
200 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
201 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
202 | println manifest
203 | manifest.contains("Implementation-Title: $artifactId")
204 | manifest.contains("Implementation-Version: 1.0")
205 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
206 | manifest.contains("Built-Date:")
207 | manifest.contains("Built-JDK:")
208 | manifest.contains("Built-Gradle:")
209 | manifest.contains("Target-JDK:")
210 |
211 | then: "jar contains pom"
212 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
213 | println jarPom
214 | jarPom != null
215 | jarPom.contains("ru.vyarus")
216 | jarPom.contains("$artifactId")
217 |
218 | then: "pom closure applied"
219 | jarPom.contains("customName")
220 |
221 | then: "jar contains pom.properties"
222 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
223 | println props
224 | props != null
225 | props.contains('groupId: ru.vyarus')
226 | props.contains("artifactId: $artifactId")
227 | props.contains('version: 1.0')
228 |
229 | then: "jar contains plugin desriptor"
230 | String gradleDesc = jar.getInputStream(jar.getEntry("META-INF/gradle-plugins/ru.vyarus.test.properties")).text
231 | println gradleDesc
232 | gradleDesc.trim() == 'implementation-class=ru.vyarus.TestPlugin'
233 |
234 | cleanup:
235 | jar?.close()
236 | }
237 |
238 |
239 | def "Check current publish plugin with signing integration correctness"() {
240 | setup:
241 | fileFromClasspath('src/main/java/ru/vyarus/TestPlugin.java', '/sample/TestPlugin.java')
242 |
243 | build """
244 | plugins {
245 | id 'com.gradle.plugin-publish' version '1.2.1'
246 | id 'java-gradle-plugin'
247 | id 'ru.vyarus.java-lib'
248 | id 'java'
249 | id 'signing'
250 | }
251 |
252 | gradlePlugin {
253 | plugins {
254 | testPlugin {
255 | description = 'Test plugin'
256 | tags.set(['java'])
257 | id = 'ru.vyarus.test'
258 | implementationClass = 'ru.vyarus.TestPlugin'
259 | }
260 | }
261 | }
262 |
263 | maven.pom {
264 | name = 'customName'
265 | }
266 |
267 | group 'ru.vyarus'
268 | version 1.0
269 |
270 | ext['signing.keyId']='78065050'
271 | ext['signing.password']=
272 | ext['signing.secretKeyRingFile']='test.gpg'
273 | """
274 | fileFromClasspath('test.gpg', '/cert/test.gpg')
275 | file('settings.gradle') << """
276 | rootProject.name = "test"
277 | """
278 |
279 | when: "run pom task"
280 | def result = run('install')
281 |
282 |
283 | String artifactId = 'test'
284 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
285 |
286 | then: "task done"
287 | result.task(":install").outcome == TaskOutcome.SUCCESS
288 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
289 |
290 | then: "alias publication created"
291 | result.task(":publishMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
292 | result.task(":publishTestPluginPluginMarkerMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
293 |
294 | then: "custom jar tasks used"
295 | result.task(":sourcesJar").outcome == TaskOutcome.SUCCESS
296 | result.task(":javadocJar").outcome == TaskOutcome.SUCCESS
297 |
298 | then: "plugin descriptors generation executed"
299 | result.task(":pluginDescriptors").outcome == TaskOutcome.SUCCESS
300 |
301 | then: "artifacts deployed"
302 | deploy.exists()
303 | def baseName = artifactId + '-1.0'
304 | withoutModuleFile(deploy) ==
305 | ["${baseName}.jar", "${baseName}.jar.asc",
306 | "${baseName}.pom", "${baseName}.pom.asc",
307 | "${baseName}-sources.jar", "${baseName}-sources.jar.asc",
308 | "${baseName}-javadoc.jar", "${baseName}-javadoc.jar.asc",
309 | "${baseName}.module.asc"] as Set
310 |
311 | then: "jar modifiers applied"
312 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
313 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
314 | println manifest
315 | manifest.contains("Implementation-Title: $artifactId")
316 | manifest.contains("Implementation-Version: 1.0")
317 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
318 | manifest.contains("Built-Date:")
319 | manifest.contains("Built-JDK:")
320 | manifest.contains("Built-Gradle:")
321 | manifest.contains("Target-JDK:")
322 |
323 | then: "jar contains pom"
324 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
325 | println jarPom
326 | jarPom != null
327 | jarPom.contains("ru.vyarus")
328 | jarPom.contains("$artifactId")
329 |
330 | then: "pom closure applied"
331 | jarPom.contains("customName")
332 |
333 | then: "jar contains pom.properties"
334 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
335 | println props
336 | props != null
337 | props.contains('groupId: ru.vyarus')
338 | props.contains("artifactId: $artifactId")
339 | props.contains('version: 1.0')
340 |
341 | then: "jar contains plugin desriptor"
342 | String gradleDesc = jar.getInputStream(jar.getEntry("META-INF/gradle-plugins/ru.vyarus.test.properties")).text
343 | println gradleDesc
344 | gradleDesc.trim() == 'implementation-class=ru.vyarus.TestPlugin'
345 |
346 | cleanup:
347 | jar?.close()
348 | }
349 |
350 |
351 | def "Check publishing only maven publication (with signing)"() {
352 | setup:
353 | fileFromClasspath('src/main/java/ru/vyarus/TestPlugin.java', '/sample/TestPlugin.java')
354 |
355 | build """
356 | plugins {
357 | id 'com.gradle.plugin-publish' version '1.2.1'
358 | id 'java-gradle-plugin'
359 | id 'ru.vyarus.java-lib'
360 | id 'java'
361 | id 'signing'
362 | }
363 |
364 | gradlePlugin {
365 | plugins {
366 | testPlugin {
367 | description = 'Test plugin'
368 | tags.set(['java'])
369 | id = 'ru.vyarus.test'
370 | implementationClass = 'ru.vyarus.TestPlugin'
371 | }
372 | }
373 | }
374 |
375 | maven.pom {
376 | name = 'customName'
377 | }
378 |
379 | group 'ru.vyarus'
380 | version 1.0
381 |
382 | ext['signing.keyId']='78065050'
383 | ext['signing.password']=
384 | ext['signing.secretKeyRingFile']='test.gpg'
385 | """
386 | fileFromClasspath('test.gpg', '/cert/test.gpg')
387 | file('settings.gradle') << """
388 | rootProject.name = "test"
389 | """
390 |
391 | when: "run pom task"
392 | def result = run('publishMavenPublicationToMavenLocal')
393 |
394 |
395 | String artifactId = 'test'
396 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
397 |
398 | then: "task done"
399 | result.task(":publishMavenPublicationToMavenLocal").outcome == TaskOutcome.SUCCESS
400 |
401 | then: "custom jar tasks used"
402 | result.task(":sourcesJar").outcome == TaskOutcome.SUCCESS
403 | result.task(":javadocJar").outcome == TaskOutcome.SUCCESS
404 |
405 | then: "plugin descriptors generation executed"
406 | result.task(":pluginDescriptors").outcome == TaskOutcome.SUCCESS
407 |
408 | then: "artifacts deployed"
409 | deploy.exists()
410 | def baseName = artifactId + '-1.0'
411 | withoutModuleFile(deploy) ==
412 | ["${baseName}.jar", "${baseName}.jar.asc",
413 | "${baseName}.pom", "${baseName}.pom.asc",
414 | "${baseName}-sources.jar", "${baseName}-sources.jar.asc",
415 | "${baseName}-javadoc.jar", "${baseName}-javadoc.jar.asc",
416 | "${baseName}.module.asc"] as Set
417 |
418 | then: "jar modifiers applied"
419 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
420 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
421 | println manifest
422 | manifest.contains("Implementation-Title: $artifactId")
423 | manifest.contains("Implementation-Version: 1.0")
424 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
425 | manifest.contains("Built-Date:")
426 | manifest.contains("Built-JDK:")
427 | manifest.contains("Built-Gradle:")
428 | manifest.contains("Target-JDK:")
429 |
430 | then: "jar contains pom"
431 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
432 | println jarPom
433 | jarPom != null
434 | jarPom.contains("ru.vyarus")
435 | jarPom.contains("$artifactId")
436 |
437 | then: "pom closure applied"
438 | jarPom.contains("customName")
439 |
440 | then: "jar contains pom.properties"
441 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
442 | println props
443 | props != null
444 | props.contains('groupId: ru.vyarus')
445 | props.contains("artifactId: $artifactId")
446 | props.contains('version: 1.0')
447 |
448 | then: "jar contains plugin desriptor"
449 | String gradleDesc = jar.getInputStream(jar.getEntry("META-INF/gradle-plugins/ru.vyarus.test.properties")).text
450 | println gradleDesc
451 | gradleDesc.trim() == 'implementation-class=ru.vyarus.TestPlugin'
452 |
453 | cleanup:
454 | jar?.close()
455 | }
456 | }
457 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/GradlePluginCompatibilityTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.Project
4 | import ru.vyarus.gradle.plugin.pom.PomPlugin
5 |
6 | /**
7 | * java-gradle-plugin crete separate pluginMaven publication + publication-link for each plugin (alias for plugin).
8 | * plugin-publish creates source and javadoc tasks but avoid this if project.archives already contains them
9 | *
10 | * @author Vyacheslav Rusakov
11 | * @since 13.11.2019
12 | */
13 | class GradlePluginCompatibilityTest extends AbstractTest {
14 |
15 | def "Check default plugins behaviour"() {
16 |
17 | when: "activating plugin"
18 | file('src/main/java').mkdirs()
19 | Project project = project {
20 | apply plugin: 'com.gradle.plugin-publish'
21 | apply plugin: 'java-gradle-plugin'
22 | apply plugin: 'groovy'
23 | apply plugin: 'maven-publish'
24 | }
25 |
26 | then: "mavenJava publication registered"
27 | project.publishing.publications.names == ["pluginMaven"] as Set
28 |
29 | then: "artifacts initialized"
30 | project.publishing.publications.pluginMaven.artifacts.collect {it.file.name} as Set == ['test.jar', 'test-sources.jar', 'test-javadoc.jar'] as Set
31 | }
32 |
33 | def "Check plugin registration"() {
34 |
35 | when: "activating plugin"
36 | file('src/main/java').mkdirs()
37 | Project project = project {
38 | apply plugin: 'com.gradle.plugin-publish'
39 | apply plugin: 'java-gradle-plugin'
40 | apply plugin: 'ru.vyarus.java-lib'
41 | apply plugin: 'groovy'
42 | }
43 |
44 | then: "java and pom plugins activated"
45 | project.plugins.findPlugin(PomPlugin)
46 |
47 | then: "mavenJava publication used"
48 | project.publishing.publications.names == ['maven', 'pluginMaven'] as Set
49 |
50 | then: "javadoc and sources tasks created"
51 | project.tasks.javadocJar
52 | project.tasks.sourcesJar
53 |
54 | then: "install task created"
55 | project.tasks.install
56 |
57 | then: "artifacts initialized"
58 | project.publishing.publications.maven.artifacts.collect {it.file.name} as Set == ['test.jar', 'test-sources.jar', 'test-javadoc.jar'] as Set
59 | project.publishing.publications.pluginMaven.artifacts.collect {it.file.name} as Set == ['test.jar', 'test-sources.jar', 'test-javadoc.jar'] as Set
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/JarModificationKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import java.util.zip.ZipFile
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 23.11.2015
8 | */
9 | class JarModificationKitTest extends AbstractKitTest {
10 |
11 | def "Check jar modification"() {
12 |
13 | setup:
14 | file('src/main/java').mkdirs()
15 | build """
16 | plugins {
17 | id 'java'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | group 'ru.vyarus'
22 | version 1.0
23 | """
24 | file('settings.gradle') << """
25 | rootProject.name = "test"
26 | """
27 |
28 | when: "run pom task"
29 | def result = run('install')
30 |
31 |
32 | String artifactId = 'test'
33 | String baseName = artifactId + '-1.0'
34 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
35 |
36 | then: "jar manifest correct"
37 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
38 | println manifest
39 | manifest.contains("Implementation-Title: $artifactId")
40 | manifest.contains("Implementation-Version: 1.0")
41 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
42 | manifest.contains("Built-Date:")
43 | manifest.contains("Built-JDK:")
44 | manifest.contains("Built-Gradle:")
45 | manifest.contains("Target-JDK:")
46 |
47 | then: "jar contains pom"
48 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
49 | jarPom != null
50 | println jarPom
51 |
52 | then: "jar contains pom.properties"
53 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
54 | props != null
55 | println props
56 | props.contains('groupId: ru.vyarus')
57 | props.contains("artifactId: $artifactId")
58 | props.contains('version: 1.0')
59 |
60 | cleanup:
61 | jar?.close()
62 | }
63 |
64 | def "Check jar manifest override"() {
65 |
66 | setup:
67 | file('src/main/java').mkdirs()
68 | build """
69 | plugins {
70 | id 'java'
71 | id 'ru.vyarus.java-lib'
72 | }
73 |
74 | group 'ru.vyarus'
75 | version 1.0
76 |
77 | jar {
78 | manifest {
79 | attributes 'Implementation-Title': 'Custom',
80 | 'Target-JDK': '1.0'
81 | }
82 | }
83 | """
84 |
85 | when: "run pom task"
86 | def result = run('install')
87 | String artifactId = projectName()
88 | String baseName = artifactId + '-1.0'
89 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
90 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
91 | println manifest
92 |
93 | then: "user attributes preserved"
94 | manifest.contains("Implementation-Title: Custom")
95 | manifest.contains("Target-JDK: 1.0")
96 |
97 | then: "default attributes added"
98 | manifest.contains("Implementation-Version: 1.0")
99 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
100 | manifest.contains("Built-Date:")
101 | manifest.contains("Built-JDK:")
102 | manifest.contains("Built-Gradle:")
103 |
104 | cleanup:
105 | jar?.close()
106 | }
107 |
108 | def "Check auto module name appliance"() {
109 |
110 | setup:
111 | file('src/main/java').mkdirs()
112 | build """
113 | plugins {
114 | id 'java'
115 | id 'ru.vyarus.java-lib'
116 | }
117 |
118 | group 'ru.vyarus'
119 | version 1.0
120 |
121 | javaLib.autoModuleName = "\$project.group-test"
122 | """
123 |
124 | when: "run pom task"
125 | def result = run('install')
126 | String artifactId = projectName()
127 | String baseName = artifactId + '-1.0'
128 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
129 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
130 | println manifest
131 |
132 | then: "module name applied"
133 | manifest.contains("Automatic-Module-Name: ru.vyarus-test")
134 |
135 | cleanup:
136 | jar?.close()
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/JavaLibPluginKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 10.11.2015
8 | */
9 | class JavaLibPluginKitTest extends AbstractKitTest {
10 |
11 | def "Check install task"() {
12 | setup:
13 | file('src/main/java').mkdirs()
14 | build """
15 | plugins {
16 | id 'java'
17 | id 'ru.vyarus.java-lib'
18 | }
19 |
20 | group 'ru.vyarus'
21 | version 1.0
22 | """
23 |
24 | when: "run pom task"
25 | def result = run('install')
26 |
27 |
28 | String artifactId = projectName()
29 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
30 |
31 | then: "task done"
32 | result.task(":install").outcome == TaskOutcome.SUCCESS
33 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
34 |
35 | then: "artifacts deployed"
36 | deploy.exists()
37 | def baseName = artifactId + '-1.0'
38 | withoutModuleFile(deploy) ==
39 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
40 | }
41 |
42 | def "Check jar only publish"() {
43 | setup:
44 | file('src/main/java').mkdirs()
45 | build """
46 | plugins {
47 | id 'java'
48 | id 'ru.vyarus.java-lib'
49 | }
50 |
51 | javaLib {
52 | withoutJavadoc()
53 | withoutSources()
54 | }
55 |
56 | group 'ru.vyarus'
57 | version 1.0
58 | """
59 |
60 | when: "run pom task"
61 | def result = run('install')
62 |
63 |
64 | String artifactId = projectName()
65 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
66 |
67 | then: "task done"
68 | result.task(":install").outcome == TaskOutcome.SUCCESS
69 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
70 |
71 | then: "artifacts deployed"
72 | deploy.exists()
73 | def baseName = artifactId + '-1.0'
74 | withoutModuleFile(deploy) ==
75 | ["${baseName}.jar", "${baseName}.pom"] as Set
76 | }
77 |
78 | def "Check install task for groovy"() {
79 | setup:
80 | file('src/main/groovy').mkdirs()
81 | build """
82 | plugins {
83 | id 'groovy'
84 | id 'ru.vyarus.java-lib'
85 | }
86 |
87 | group 'ru.vyarus'
88 | version 1.0
89 | """
90 |
91 | when: "run pom task"
92 | def result = run('install')
93 |
94 |
95 | String artifactId = projectName()
96 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
97 |
98 | then: "task done"
99 | result.task(":install").outcome == TaskOutcome.SUCCESS
100 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
101 |
102 | then: "artifacts deployed"
103 | deploy.exists()
104 | def baseName = artifactId + '-1.0'
105 | // javadoc will be produced instead of groovydoc! important for maven central
106 | withoutModuleFile(deploy) ==
107 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
108 | }
109 |
110 | def "Check install for both sources"() {
111 | setup:
112 | file('src/main/java').mkdirs()
113 | file('src/main/groovy').mkdirs()
114 | build """
115 | plugins {
116 | id 'groovy'
117 | id 'ru.vyarus.java-lib'
118 | }
119 |
120 | group 'ru.vyarus'
121 | version 1.0
122 | """
123 |
124 | when: "run pom task"
125 | def result = run('install')
126 |
127 |
128 | String artifactId = projectName()
129 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
130 |
131 | then: "task done"
132 | result.task(":install").outcome == TaskOutcome.SUCCESS
133 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
134 |
135 | then: "artifacts deployed"
136 | deploy.exists()
137 | def baseName = artifactId + '-1.0'
138 | withoutModuleFile(deploy) ==
139 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
140 | }
141 |
142 | def "Check install for no sources"() {
143 | setup:
144 | build """
145 | plugins {
146 | id 'groovy'
147 | id 'ru.vyarus.java-lib'
148 | }
149 |
150 | group 'ru.vyarus'
151 | version 1.0
152 | """
153 |
154 | when: "run pom task"
155 | def result = run('install')
156 |
157 |
158 | String artifactId = projectName()
159 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
160 |
161 | then: "task done"
162 | result.task(":install").outcome == TaskOutcome.SUCCESS
163 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
164 |
165 | then: "artifacts deployed"
166 | deploy.exists()
167 | def baseName = artifactId + '-1.0'
168 | withoutModuleFile(deploy) ==
169 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
170 | }
171 |
172 | def "Check behaviour on test sources"() {
173 | setup:
174 | file('src/test/java').mkdirs()
175 | file('src/test/groovy').mkdirs()
176 | build """
177 | plugins {
178 | id 'groovy'
179 | id 'ru.vyarus.java-lib'
180 | }
181 |
182 | group 'ru.vyarus'
183 | version 1.0
184 | """
185 |
186 | when: "run pom task"
187 | def result = run('install')
188 |
189 |
190 | String artifactId = projectName()
191 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
192 |
193 | then: "task done"
194 | result.task(":install").outcome == TaskOutcome.SUCCESS
195 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
196 |
197 | then: "artifacts deployed"
198 | deploy.exists()
199 | def baseName = artifactId + '-1.0'
200 | withoutModuleFile(deploy) ==
201 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
202 | }
203 | }
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/JavaLibPluginTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.Project
4 | import org.gradle.testing.jacoco.tasks.JacocoReport
5 | import ru.vyarus.gradle.plugin.pom.PomPlugin
6 |
7 | /**
8 | * @author Vyacheslav Rusakov
9 | * @since 07.11.2015
10 | */
11 | class JavaLibPluginTest extends AbstractTest {
12 |
13 | def "Check plugin registration"() {
14 |
15 | when: "activating plugin"
16 | file('src/main/java').mkdirs()
17 | Project project = project {
18 | apply plugin: 'java'
19 | apply plugin: "ru.vyarus.java-lib"
20 | }
21 |
22 | then: "java and pom plugins activated"
23 | project.plugins.findPlugin(PomPlugin)
24 |
25 | then: "mavenJava publication registered"
26 | project.publishing.publications.maven
27 |
28 | then: "javadoc and sources tasks created"
29 | project.tasks.javadocJar
30 | project.tasks.sourcesJar
31 |
32 | then: "install task created"
33 | project.tasks.install
34 | }
35 |
36 | def "Check plugin registration for groovy"() {
37 |
38 | when: "activating plugin"
39 | file('src/main/groovy').mkdirs()
40 | Project project = project {
41 | apply plugin: 'groovy'
42 | apply plugin: "ru.vyarus.java-lib"
43 | }
44 |
45 | then: "java and pom plugins activated"
46 | project.plugins.findPlugin(PomPlugin)
47 |
48 | then: "mavenJava publication registered"
49 | project.publishing.publications.maven
50 |
51 | then: "javadoc and sources tasks created"
52 | project.tasks.javadocJar
53 | project.tasks.sourcesJar
54 |
55 | then: "install task created"
56 | project.tasks.install
57 | }
58 |
59 | def "Check plugin registration for java-library"() {
60 |
61 | when: "activating plugin"
62 | file('src/main/java').mkdirs()
63 | Project project = project {
64 | apply plugin: 'java-library'
65 | apply plugin: "ru.vyarus.java-lib"
66 | }
67 |
68 | then: "java and pom plugins activated"
69 | project.plugins.findPlugin(PomPlugin)
70 |
71 | then: "mavenJava publication registered"
72 | project.publishing.publications.maven
73 |
74 | then: "javadoc and sources tasks created"
75 | project.tasks.javadocJar
76 | project.tasks.sourcesJar
77 |
78 | then: "install task created"
79 | project.tasks.install
80 | }
81 |
82 | def "Check plugin registration for java-platform"() {
83 |
84 | when: "activating plugin"
85 | file('src/main/java').mkdirs()
86 | Project project = project {
87 | apply plugin: 'java-platform'
88 | apply plugin: "ru.vyarus.java-lib"
89 | }
90 |
91 | then: "pom plugin activated"
92 | project.plugins.findPlugin(PomPlugin)
93 |
94 | then: "bom publication registered"
95 | project.publishing.publications.bom
96 |
97 | then: "install task created"
98 | project.tasks.install
99 | }
100 |
101 | def "Check jacoco xml report active"() {
102 |
103 | when: "activating plugin"
104 | file('src/main/java').mkdirs()
105 | Project project = project {
106 | apply plugin: 'java'
107 | apply plugin: 'jacoco'
108 | apply plugin: "ru.vyarus.java-lib"
109 | }
110 |
111 | then: "xml report active"
112 | (project.tasks.findByName('jacocoTestReport') as JacocoReport).reports.xml.required.get()
113 | }
114 | }
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/JavaPlatformKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import groovy.xml.XmlParser
4 | import org.gradle.testkit.runner.TaskOutcome
5 |
6 | /**
7 | * @author Vyacheslav Rusakov
8 | * @since 06.06.2021
9 | */
10 | class JavaPlatformKitTest extends AbstractKitTest {
11 |
12 | def "Check install task for BOM"() {
13 | setup:
14 | file('src/main/java').mkdirs()
15 | build """
16 | plugins {
17 | id 'java-platform'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | group 'ru.vyarus'
22 | version 1.0
23 |
24 | dependencies {
25 | constraints {
26 | api 'ru.vyarus:guice-validator:2.0.0'
27 | }
28 | }
29 | """
30 |
31 | when: "run install task"
32 | def result = run('install')
33 |
34 |
35 | String artifactId = projectName()
36 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
37 |
38 | then: "task done"
39 | result.task(":install").outcome == TaskOutcome.SUCCESS
40 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
41 |
42 | then: "artifacts deployed"
43 | deploy.exists()
44 | def baseName = artifactId + '-1.0'
45 | withoutModuleFile(deploy) ==
46 | ["${baseName}.pom"] as Set
47 | }
48 |
49 | def "Check custom BOM artifact name"() {
50 | setup:
51 | file('src/main/java').mkdirs()
52 | build """
53 | plugins {
54 | id 'java-platform'
55 | id 'ru.vyarus.java-lib'
56 | }
57 |
58 | javaLib.bom {
59 | artifactId = 'bom'
60 | description = 'Sample BOM'
61 | }
62 |
63 | group 'ru.vyarus'
64 | version 1.0
65 |
66 | dependencies {
67 | constraints {
68 | api 'ru.vyarus:guice-validator:2.0.0'
69 | }
70 | }
71 | """
72 |
73 | when: "run install task"
74 | def result = run('install')
75 |
76 |
77 | String artifactId = 'bom'
78 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
79 |
80 | then: "task done"
81 | result.task(":install").outcome == TaskOutcome.SUCCESS
82 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
83 |
84 | then: "artifacts deployed"
85 | deploy.exists()
86 | def baseName = artifactId + '-1.0'
87 | withoutModuleFile(deploy) ==
88 | ["${baseName}.pom"] as Set
89 |
90 | when: "get pom"
91 | def pomFile = new File(deploy, "${baseName}.pom")
92 | def pom = new XmlParser().parse(pomFile)
93 | // for debug
94 | println pomFile.getText()
95 |
96 | then: "pom is correct"
97 | pom.dependencyManagement.dependencies.'*'.find { it.artifactId.text() == 'guice-validator' }
98 | pom.name.text() == 'bom'
99 | pom.description.text() == 'Sample BOM'
100 | }
101 |
102 | def "Check avoid local bom publishing"() {
103 | setup:
104 | file('src/main/java').mkdirs()
105 | build """
106 | plugins {
107 | id 'java-platform'
108 | id 'ru.vyarus.java-lib'
109 | }
110 |
111 | group 'ru.vyarus'
112 | version 1.0
113 |
114 | javaLib.withoutPublication()
115 |
116 | dependencies {
117 | constraints {
118 | api 'ru.vyarus:guice-validator:2.0.0'
119 | }
120 | }
121 | """
122 |
123 | when: "run install task"
124 | def result = run('install')
125 |
126 |
127 | String artifactId = projectName()
128 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
129 |
130 | then: "task done"
131 | result.task(":install").outcome == TaskOutcome.SUCCESS
132 | !result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
133 |
134 | then: "artifacts not deployed"
135 | !deploy.exists()
136 | }
137 |
138 | def "Check avoid external repo bom publishing"() {
139 | setup:
140 | file('src/main/java').mkdirs()
141 | build """
142 | plugins {
143 | id 'java-platform'
144 | id 'ru.vyarus.java-lib'
145 | }
146 |
147 | group 'ru.vyarus'
148 | version 1.0
149 |
150 | javaLib.withoutPublication()
151 |
152 | publishing {
153 | repositories {
154 | maven {
155 | url = layout.buildDirectory.dir('repo2')
156 | }
157 | }
158 | }
159 |
160 | dependencies {
161 | constraints {
162 | api 'ru.vyarus:guice-validator:2.0.0'
163 | }
164 | }
165 | """
166 |
167 | when: "run install task"
168 | def result = run('publish')
169 |
170 | String artifactId = projectName()
171 | File deploy = file("build/repo2/ru/vyarus/$artifactId/1.0/")
172 |
173 | then: "task done"
174 | result.task(":publish").outcome == TaskOutcome.UP_TO_DATE
175 | !result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
176 |
177 | then: "artifacts not deployed"
178 | !deploy.exists()
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/LegacyModeKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 | import spock.lang.IgnoreIf
5 |
6 | /**
7 | * @author Vyacheslav Rusakov
8 | * @since 11.07.2018
9 | */
10 | @IgnoreIf({jvm.java17Compatible}) // only gradle 7.3 supports java 17
11 | class LegacyModeKitTest extends AbstractKitTest {
12 |
13 | String GRADLE_VERSION = '7.0'
14 |
15 | def "Check install task"() {
16 | setup:
17 | file('src/main/java').mkdirs()
18 | build """
19 | plugins {
20 | id 'java'
21 | id 'ru.vyarus.java-lib'
22 | }
23 |
24 | group 'ru.vyarus'
25 | version 1.0
26 | """
27 |
28 | when: "run pom task"
29 | def result = runVer(GRADLE_VERSION,'install')
30 |
31 |
32 | String artifactId = projectName()
33 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
34 |
35 | then: "task done"
36 | result.task(":install").outcome == TaskOutcome.SUCCESS
37 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
38 |
39 | then: "artifacts deployed"
40 | deploy.exists()
41 | def baseName = artifactId + '-1.0'
42 | withoutModuleFile(deploy) ==
43 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
44 | }
45 |
46 | def "Check install task for groovy"() {
47 | setup:
48 | file('src/main/groovy').mkdirs()
49 | build """
50 | plugins {
51 | id 'groovy'
52 | id 'ru.vyarus.java-lib'
53 | }
54 |
55 | group 'ru.vyarus'
56 | version 1.0
57 | """
58 |
59 | when: "run pom task"
60 | def result = runVer(GRADLE_VERSION, 'install')
61 |
62 |
63 | String artifactId = projectName()
64 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
65 |
66 | then: "task done"
67 | result.task(":install").outcome == TaskOutcome.SUCCESS
68 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
69 |
70 | then: "artifacts deployed"
71 | deploy.exists()
72 | def baseName = artifactId + '-1.0'
73 | // javadoc will be produced instead of groovydoc! important for maven central
74 | withoutModuleFile(deploy) ==
75 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
76 | }
77 |
78 | def "Check install for both sources"() {
79 | setup:
80 | file('src/main/java').mkdirs()
81 | file('src/main/groovy').mkdirs()
82 | build """
83 | plugins {
84 | id 'groovy'
85 | id 'ru.vyarus.java-lib'
86 | }
87 |
88 | group 'ru.vyarus'
89 | version 1.0
90 | """
91 |
92 | when: "run pom task"
93 | def result = runVer(GRADLE_VERSION,'install')
94 |
95 |
96 | String artifactId = projectName()
97 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
98 |
99 | then: "task done"
100 | result.task(":install").outcome == TaskOutcome.SUCCESS
101 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
102 |
103 | then: "artifacts deployed"
104 | deploy.exists()
105 | def baseName = artifactId + '-1.0'
106 | withoutModuleFile(deploy) ==
107 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
108 | }
109 |
110 | def "Check install for no sources"() {
111 | setup:
112 | build """
113 | plugins {
114 | id 'groovy'
115 | id 'ru.vyarus.java-lib'
116 | }
117 |
118 | group 'ru.vyarus'
119 | version 1.0
120 | """
121 |
122 | when: "run pom task"
123 | def result = runVer(GRADLE_VERSION, 'install')
124 |
125 |
126 | String artifactId = projectName()
127 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
128 |
129 | then: "task done"
130 | result.task(":install").outcome == TaskOutcome.SUCCESS
131 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
132 |
133 | then: "artifacts deployed"
134 | deploy.exists()
135 | def baseName = artifactId + '-1.0'
136 | withoutModuleFile(deploy) ==
137 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
138 | }
139 |
140 | def "Check behaviour on test sources"() {
141 | setup:
142 | file('src/test/java').mkdirs()
143 | file('src/test/groovy').mkdirs()
144 | build """
145 | plugins {
146 | id 'groovy'
147 | id 'ru.vyarus.java-lib'
148 | }
149 |
150 | group 'ru.vyarus'
151 | version 1.0
152 | """
153 |
154 | when: "run pom task"
155 | def result = runVer(GRADLE_VERSION, 'install')
156 |
157 |
158 | String artifactId = projectName()
159 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
160 |
161 | then: "task done"
162 | result.task(":install").outcome == TaskOutcome.SUCCESS
163 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
164 |
165 | then: "artifacts deployed"
166 | deploy.exists()
167 | def baseName = artifactId + '-1.0'
168 | withoutModuleFile(deploy) as Set ==
169 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
170 | }
171 |
172 | def "Check publication override"() {
173 | setup:
174 | file('src/main/java').mkdirs()
175 | build """
176 | plugins {
177 | id 'java'
178 | id 'ru.vyarus.java-lib'
179 | }
180 |
181 | group 'ru.vyarus'
182 | version 1.0
183 |
184 | javaLib {
185 | // artifacts could be changed when metadata enabled
186 | withoutGradleMetadata()
187 | }
188 |
189 | publishing.publications.maven.artifacts = [jar, javadocJar]
190 | """
191 |
192 | when: "run pom task"
193 | def result = runVer(GRADLE_VERSION,'install')
194 |
195 |
196 | String artifactId = projectName()
197 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
198 |
199 | then: "task done"
200 | result.task(":install").outcome == TaskOutcome.SUCCESS
201 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
202 |
203 | then: "artifacts deployed, but without sources"
204 | deploy.exists()
205 | def baseName = artifactId + '-1.0'
206 | withoutModuleFile(deploy) as Set ==
207 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-javadoc.jar"] as Set
208 | }
209 |
210 | def "Check reports aggregation"() {
211 | setup:
212 | build """
213 | plugins {
214 | id 'base'
215 | id 'jacoco'
216 | id 'project-report'
217 | id 'ru.vyarus.java-lib'
218 | }
219 |
220 | javaLib {
221 | aggregateReports()
222 | }
223 |
224 | allprojects {
225 | repositories { mavenCentral() }
226 | }
227 |
228 | subprojects {
229 | apply plugin: 'groovy'
230 | apply plugin: 'jacoco'
231 | apply plugin: 'project-report'
232 | apply plugin: 'ru.vyarus.java-lib'
233 |
234 | dependencies {
235 | testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
236 | }
237 |
238 | test {
239 | useJUnitPlatform()
240 | }
241 | }
242 | """
243 | file('settings.gradle') << "include 'sub1', 'sub2'"
244 |
245 | fileFromClasspath('sub1/src/main/java/sample/Sample.java', '/sample/Sample.java')
246 | fileFromClasspath('sub1/src/test/groovy/sample/SampleTest.groovy', '/sample/SampleTest.groovy')
247 |
248 | fileFromClasspath('sub2/src/main/java/sample/Sample2.java', '/sample/Sample2.java')
249 | fileFromClasspath('sub2/src/test/groovy/sample/SampleTest2.groovy', '/sample/SampleTest2.groovy')
250 |
251 | when: "run test task"
252 | def result = runVer(GRADLE_VERSION, 'test')
253 |
254 | then: "task done"
255 | result.task(":test").outcome == TaskOutcome.SUCCESS
256 |
257 | then: "test report created"
258 | def test = file('build/reports/tests/test/index.html')
259 | test.exists()
260 |
261 | when: "run coverage task"
262 | result = runVer(GRADLE_VERSION, 'clean', 'jacocoTestReport')
263 |
264 | then: "task done"
265 | result.task(":jacocoTestReport").outcome == TaskOutcome.SUCCESS
266 |
267 | then: "coverage aggregated"
268 | def cov = file('build/reports/jacoco/test/jacocoTestReport.xml')
269 | cov.exists()
270 | cov.length() > 0
271 |
272 | when: "run dependencies task"
273 | result = runVer(GRADLE_VERSION, 'htmlDependencyReport')
274 |
275 | then: "task done"
276 | result.task(":htmlDependencyReport").outcome == TaskOutcome.SUCCESS
277 |
278 | then: "aggregated dependency report"
279 | file('build/reports/project/dependencies/root.sub1.html').exists()
280 | file('build/reports/project/dependencies/root.sub2.html').exists()
281 | file('build/reports/project/dependencies/root.html').exists()
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/OpenDepsReportTasksTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.Project
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 10.06.2021
8 | */
9 | class OpenDepsReportTasksTest extends AbstractTest {
10 |
11 | def "Check show dependencies task appear"() {
12 |
13 | when: "activating plugin"
14 | file('src/main/java').mkdirs()
15 | Project project = project {
16 | apply plugin: 'project-report'
17 | apply plugin: "ru.vyarus.java-lib"
18 | }
19 |
20 | then: "task applied"
21 | project.tasks.findByName('openDependencyReport')
22 | }
23 |
24 | def "Check show dependencies task appear in multi-module configuration"() {
25 |
26 | when: "activating plugin"
27 | file('src/main/java').mkdirs()
28 | Project project = project {
29 | apply plugin: "ru.vyarus.java-lib"
30 |
31 | allprojects {
32 | apply plugin: 'project-report'
33 | }
34 | }
35 |
36 | then: "task applied"
37 | project.tasks.findByName('openDependencyReport')
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/PomConfigurationTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import groovy.xml.XmlParser
4 | import org.gradle.testkit.runner.TaskOutcome
5 |
6 | /**
7 | * @author Vyacheslav Rusakov
8 | * @since 09.06.2021
9 | */
10 | class PomConfigurationTest extends AbstractKitTest {
11 |
12 | def "Check install task"() {
13 | setup:
14 | file('src/main/java').mkdirs()
15 | build """
16 | plugins {
17 | id 'java'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | repositories {mavenCentral()}
22 | dependencies {
23 | implementation platform('com.google.inject:guice-bom:4.0')
24 | implementation 'com.google.inject:guice'
25 | }
26 |
27 | maven {
28 | removeDependencyManagement()
29 | }
30 |
31 | group 'ru.vyarus'
32 | version 1.0
33 | """
34 |
35 | when: "run pom task"
36 | def result = run('install')
37 |
38 |
39 | String artifactId = projectName()
40 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
41 |
42 | then: "task done"
43 | result.task(":install").outcome == TaskOutcome.SUCCESS
44 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
45 |
46 | when: "find pom"
47 | def pomFile = new File(deploy, "$artifactId-1.0.pom")
48 | // for debug
49 | println pomFile.getText()
50 | def pom = new XmlParser().parse(pomFile)
51 |
52 | then: "no dependency management section"
53 | !pom.dependencyManagement
54 | pom.dependencies.'*'.find { it.artifactId.text() == 'guice' }.version.text() == '4.0'
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/PomCorrectnessKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import groovy.xml.XmlParser
4 | import org.gradle.testkit.runner.TaskOutcome
5 |
6 | /**
7 | * @author Vyacheslav Rusakov
8 | * @since 17.07.2018
9 | */
10 | class PomCorrectnessKitTest extends AbstractKitTest {
11 |
12 | def "Check install task"() {
13 | setup:
14 | file('src/main/java').mkdirs()
15 | build """
16 | plugins {
17 | id 'java'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | dependencies {
22 | provided 'com.google.code.findbugs:annotations:3.0.0'
23 | implementation 'org.javassist:javassist:3.16.1-GA'
24 | }
25 |
26 | maven.pom {
27 | name = 'sample'
28 | }
29 |
30 | group 'ru.vyarus'
31 | version 1.0
32 | """
33 |
34 | when: "run pom task"
35 | def result = run('install')
36 |
37 |
38 | String artifactId = projectName()
39 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
40 |
41 | then: "task done"
42 | result.task(":install").outcome == TaskOutcome.SUCCESS
43 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
44 |
45 | then: "artifacts deployed"
46 | deploy.exists()
47 | def baseName = artifactId + '-1.0'
48 | withoutModuleFile(deploy) ==
49 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
50 |
51 | when: "get pom"
52 | def pomFile = new File(deploy, "${baseName}.pom")
53 | def pom = new XmlParser().parse(pomFile)
54 | // for debug
55 | println pomFile.getText()
56 |
57 | then: "pom is correct"
58 | pom.dependencies.'*'.find { it.artifactId.text() == 'javassist' }.scope.text() == 'compile'
59 | pom.dependencies.'*'.find { it.artifactId.text() == 'annotations' }.scope.text() == 'provided'
60 | pom.name.text() == 'sample'
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/PublicationOverrideKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 05.12.2015
8 | */
9 | class PublicationOverrideKitTest extends AbstractKitTest {
10 |
11 | def "Check publication override"() {
12 | setup:
13 | file('src/main/java').mkdirs()
14 | build """
15 | plugins {
16 | id 'java'
17 | id 'ru.vyarus.java-lib'
18 | }
19 |
20 | group 'ru.vyarus'
21 | version 1.0
22 |
23 | javaLib {
24 | // metadata publishing would fail build with modified artifacts
25 | withoutGradleMetadata()
26 | }
27 |
28 | publishing.publications.maven.artifacts = [jar, javadocJar]
29 | """
30 | file('settings.gradle') << """
31 | rootProject.name = "test"
32 | """
33 |
34 | when: "run pom task"
35 | def result = run('install')
36 |
37 |
38 | String artifactId = 'test'
39 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
40 |
41 | then: "task done"
42 | result.task(":install").outcome == TaskOutcome.SUCCESS
43 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
44 |
45 | then: "artifacts deployed, but without sources"
46 | deploy.exists()
47 | def baseName = artifactId + '-1.0'
48 | withoutModuleFile(deploy) ==
49 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-javadoc.jar"] as Set
50 | }
51 | }
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/ReportsAggregationKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 12.06.2021
8 | */
9 | class ReportsAggregationKitTest extends AbstractKitTest {
10 |
11 | def "Check reports aggregation"() {
12 | setup:
13 | build """
14 | plugins {
15 | id 'base'
16 | id 'jacoco'
17 | id 'project-report'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | javaLib {
22 | aggregateReports()
23 | }
24 |
25 | allprojects {
26 | repositories { mavenCentral() }
27 | }
28 |
29 | subprojects {
30 | apply plugin: 'groovy'
31 | apply plugin: 'jacoco'
32 | apply plugin: 'project-report'
33 | apply plugin: 'ru.vyarus.java-lib'
34 |
35 | dependencies {
36 | testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
37 | }
38 |
39 | test {
40 | useJUnitPlatform()
41 | }
42 | }
43 | """
44 | file('settings.gradle') << "include 'sub1', 'sub2'"
45 |
46 | fileFromClasspath('sub1/src/main/java/sample/Sample.java', '/sample/Sample.java')
47 | fileFromClasspath('sub1/src/test/groovy/sample/SampleTest.groovy', '/sample/SampleTest.groovy')
48 |
49 | fileFromClasspath('sub2/src/main/java/sample/Sample2.java', '/sample/Sample2.java')
50 | fileFromClasspath('sub2/src/test/groovy/sample/SampleTest2.groovy', '/sample/SampleTest2.groovy')
51 |
52 | when: "run test task"
53 | def result = run('test')
54 |
55 | then: "task done"
56 | result.task(":test").outcome == TaskOutcome.SUCCESS
57 |
58 | then: "test report created"
59 | def test = file('build/reports/tests/test/index.html')
60 | test.exists()
61 |
62 | when: "run coverage task"
63 | result = run('clean', 'jacocoTestReport')
64 |
65 | then: "task done"
66 | result.task(":jacocoTestReport").outcome == TaskOutcome.SUCCESS
67 |
68 | then: "coverage aggregated"
69 | def cov = file('build/reports/jacoco/test/jacocoTestReport.xml')
70 | cov.exists()
71 | cov.length() > 0
72 |
73 | when: "run dependencies task"
74 | result = run('htmlDependencyReport')
75 |
76 | then: "task done"
77 | result.task(":htmlDependencyReport").outcome == TaskOutcome.SUCCESS
78 |
79 | then: "aggregated dependency report"
80 | file('build/reports/project/dependencies/root.sub1.html').exists()
81 | file('build/reports/project/dependencies/root.sub2.html').exists()
82 | file('build/reports/project/dependencies/root.html').exists()
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/ReportsAggregationTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.api.GradleException
4 | import org.gradle.api.Project
5 | import org.gradle.api.tasks.testing.TestReport
6 | import org.gradle.testing.jacoco.tasks.JacocoReport
7 |
8 | /**
9 | * @author Vyacheslav Rusakov
10 | * @since 12.06.2021
11 | */
12 | class ReportsAggregationTest extends AbstractTest {
13 |
14 | def "Check aggregated reports"() {
15 |
16 | when: "apply plugin"
17 | file('sub1/src/main/java').mkdirs()
18 | file('sub1/src/test/java').mkdirs()
19 | file('sub2/src/main/java').mkdirs()
20 | file('sub2/src/test/java').mkdirs()
21 |
22 | file('sub1/src/main/java/Sample.java').createNewFile()
23 | file('sub1/src/test/java/SampleTest.java').createNewFile()
24 | file('sub2/src/main/java/Sample.java').createNewFile()
25 | file('sub2/src/test/java/SampleTest.java').createNewFile()
26 |
27 | Project project = projectBuilder {
28 | apply plugin: 'base'
29 | apply plugin: 'jacoco'
30 | apply plugin: 'project-report'
31 | apply plugin: 'ru.vyarus.java-lib'
32 |
33 | javaLib {
34 | aggregateReports()
35 | }
36 | }
37 | .child('sub1') {
38 | apply plugin: 'java'
39 | apply plugin: 'jacoco'
40 | apply plugin: 'project-report'
41 | apply plugin: 'ru.vyarus.java-lib'
42 | }
43 | .child('sub2') {
44 | apply plugin: 'java'
45 | apply plugin: 'jacoco'
46 | apply plugin: 'project-report'
47 | apply plugin: 'ru.vyarus.java-lib'
48 | }
49 | .build()
50 |
51 | then: "aggregation tasks created"
52 | JacocoReport cov = project.tasks.jacocoTestReport
53 | // execution data counts only existing files
54 | cov.executionData.size() == 0
55 |
56 | then: "tests aggregation task"
57 | TestReport test = project.tasks.test
58 | test
59 | // testResults contains not only test reports but also coverage
60 | test.testResults.files.findAll {it.name == 'binary'}.size() == 2
61 |
62 | then: "dependencies reports aggregated"
63 | project.htmlDependencyReport.projects.size() == 3
64 | }
65 |
66 | def "Check not same submodules case"() {
67 |
68 | when: "apply plugin"
69 | file('sub2/src/main/java').mkdirs()
70 | file('sub2/src/test/java').mkdirs()
71 |
72 | file('sub2/src/main/java/Sample.java').createNewFile()
73 | file('sub2/src/test/java/SampleTest.java').createNewFile()
74 |
75 | Project project = projectBuilder {
76 | apply plugin: 'base'
77 | apply plugin: 'jacoco'
78 | apply plugin: 'project-report'
79 | apply plugin: 'ru.vyarus.java-lib'
80 |
81 | javaLib {
82 | aggregateReports()
83 | }
84 | }
85 | .child('sub1')
86 | .child('sub2') {
87 | apply plugin: 'java'
88 | apply plugin: 'jacoco'
89 | apply plugin: 'project-report'
90 | apply plugin: 'ru.vyarus.java-lib'
91 | }
92 | .build()
93 |
94 | then: "aggregation tasks created"
95 | JacocoReport cov = project.tasks.jacocoTestReport
96 | // execution data counts only existing files
97 | cov.executionData.size() == 0
98 |
99 | then: "tests aggregation task"
100 | TestReport test = project.tasks.test
101 | test
102 | test.testResults.files.findAll {it.name == 'binary'}.size() == 1
103 |
104 | then: "dependencies reports aggregated"
105 | project.htmlDependencyReport.projects.size() == 3
106 | }
107 |
108 | def "Check aggregation on simple module"() {
109 |
110 | when: "activating plugin"
111 | file('src/main/java').mkdirs()
112 | project {
113 | apply plugin: 'base'
114 | apply plugin: 'jacoco'
115 | apply plugin: "ru.vyarus.java-lib"
116 |
117 | javaLib {
118 | aggregateReports()
119 | }
120 | }
121 |
122 | then: "xml report active"
123 | def ex = thrown(GradleException)
124 | ex.cause.message == 'javaLib.aggregateReports() could not be used on project \'test\' because does not contain subprojects'
125 | }
126 |
127 | def "Check aggregation on java module"() {
128 |
129 | when: "activating plugin"
130 | file('src/main/java').mkdirs()
131 | projectBuilder {
132 | apply plugin: 'java'
133 | apply plugin: 'jacoco'
134 | apply plugin: "ru.vyarus.java-lib"
135 |
136 | javaLib {
137 | aggregateReports()
138 | }
139 | }.child('sub') {
140 | apply plugin: 'java'
141 | }
142 | .build()
143 |
144 | then: "xml report active"
145 | def ex = thrown(GradleException)
146 | ex.cause.message == 'javaLib.aggregateReports() could not be used on project \'test\' because it contains java sources. If this is a root project use \'base\' plugin instead.'
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/SigningKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | /**
6 | * @author Vyacheslav Rusakov
7 | * @since 07.06.2021
8 | */
9 | class SigningKitTest extends AbstractKitTest {
10 |
11 | def "Check automatic signing"() {
12 | setup:
13 | file('src/main/java').mkdirs()
14 | build """
15 | plugins {
16 | id 'java'
17 | id 'signing'
18 | id 'ru.vyarus.java-lib'
19 | }
20 |
21 | javaLib {
22 | withoutGradleMetadata()
23 | withoutJavadoc()
24 | withoutSources()
25 | }
26 |
27 | group 'ru.vyarus'
28 | version 1.0
29 |
30 | ext['signing.keyId']='78065050'
31 | ext['signing.password']=
32 | ext['signing.secretKeyRingFile']='test.gpg'
33 | """
34 | fileFromClasspath('test.gpg', '/cert/test.gpg')
35 | file('settings.gradle') << """
36 | rootProject.name = "test"
37 | """
38 |
39 | when: "run pom task"
40 | def result = run('install')
41 |
42 |
43 | String artifactId = 'test'
44 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
45 |
46 | then: "task done"
47 | result.task(":install").outcome == TaskOutcome.SUCCESS
48 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
49 |
50 | then: "artifacts deployed"
51 | deploy.exists()
52 | def baseName = artifactId + '-1.0'
53 | withoutModuleFile(deploy) ==
54 | ["${baseName}.jar", "${baseName}.pom", "${baseName}.jar.asc", "${baseName}.pom.asc"] as Set
55 | }
56 |
57 | def "Check automatic BOM signing"() {
58 | setup:
59 | file('src/main/java').mkdirs()
60 | build """
61 | plugins {
62 | id 'java-platform'
63 | id 'signing'
64 | id 'ru.vyarus.java-lib'
65 | }
66 |
67 | javaLib {
68 | withoutGradleMetadata()
69 | }
70 |
71 | group 'ru.vyarus'
72 | version 1.0
73 |
74 | ext['signing.keyId']='78065050'
75 | ext['signing.password']=
76 | ext['signing.secretKeyRingFile']='test.gpg'
77 | """
78 | fileFromClasspath('test.gpg', '/cert/test.gpg')
79 | file('settings.gradle') << """
80 | rootProject.name = "test"
81 | """
82 |
83 | when: "run pom task"
84 | def result = run('install')
85 |
86 |
87 | String artifactId = 'test'
88 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
89 |
90 | then: "task done"
91 | result.task(":install").outcome == TaskOutcome.SUCCESS
92 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
93 |
94 | then: "artifacts deployed"
95 | deploy.exists()
96 | def baseName = artifactId + '-1.0'
97 | withoutModuleFile(deploy) ==
98 | ["${baseName}.pom", "${baseName}.pom.asc"] as Set
99 | }
100 |
101 | def "Check all artifacts signing"() {
102 | setup:
103 | file('src/main/java').mkdirs()
104 | build """
105 | plugins {
106 | id 'java'
107 | id 'signing'
108 | id 'ru.vyarus.java-lib'
109 | }
110 |
111 | group 'ru.vyarus'
112 | version 1.0
113 |
114 | ext['signing.keyId']='78065050'
115 | ext['signing.password']=
116 | ext['signing.secretKeyRingFile']='test.gpg'
117 | """
118 | fileFromClasspath('test.gpg', '/cert/test.gpg')
119 | file('settings.gradle') << """
120 | rootProject.name = "test"
121 | """
122 |
123 | when: "run pom task"
124 | def result = run('install')
125 |
126 |
127 | String artifactId = 'test'
128 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
129 |
130 | then: "task done"
131 | result.task(":install").outcome == TaskOutcome.SUCCESS
132 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
133 |
134 | then: "artifacts deployed"
135 | deploy.exists()
136 | def baseName = artifactId + '-1.0'
137 | withoutModuleFile(deploy) ==
138 | ["${baseName}.jar", "${baseName}.jar.asc",
139 | "${baseName}.pom", "${baseName}.pom.asc",
140 | "${baseName}-sources.jar", "${baseName}-sources.jar.asc",
141 | "${baseName}-javadoc.jar", "${baseName}-javadoc.jar.asc",
142 | "${baseName}.module.asc"] as Set
143 | }
144 |
145 | def "Check snapshots not signed"() {
146 | setup:
147 | file('src/main/java').mkdirs()
148 | build """
149 | plugins {
150 | id 'java'
151 | id 'signing'
152 | id 'ru.vyarus.java-lib'
153 | }
154 |
155 | javaLib {
156 | withoutGradleMetadata()
157 | withoutJavadoc()
158 | withoutSources()
159 | }
160 |
161 | group 'ru.vyarus'
162 | version '1.0-SNAPSHOT'
163 | """
164 | file('settings.gradle') << """
165 | rootProject.name = "test"
166 | """
167 |
168 | when: "run pom task"
169 | def result = run('install')
170 |
171 |
172 | String artifactId = 'test'
173 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0-SNAPSHOT/")
174 |
175 | then: "task done"
176 | result.task(":install").outcome == TaskOutcome.SUCCESS
177 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0-SNAPSHOT")
178 |
179 | then: "artifacts deployed"
180 | deploy.exists()
181 | def baseName = artifactId + '-1.0-SNAPSHOT'
182 | withoutModuleFile(deploy) ==
183 | ["${baseName}.jar", "${baseName}.pom", 'maven-metadata-local.xml'] as Set
184 | }
185 |
186 | def "Check snapshots signed if cert configured"() {
187 | setup:
188 | file('src/main/java').mkdirs()
189 | build """
190 | plugins {
191 | id 'java'
192 | id 'signing'
193 | id 'ru.vyarus.java-lib'
194 | }
195 |
196 | javaLib {
197 | withoutGradleMetadata()
198 | withoutJavadoc()
199 | withoutSources()
200 | }
201 |
202 | group 'ru.vyarus'
203 | version '1.0-SNAPSHOT'
204 |
205 | ext['signing.keyId']='78065050'
206 | ext['signing.password']=
207 | ext['signing.secretKeyRingFile']='test.gpg'
208 | """
209 | fileFromClasspath('test.gpg', '/cert/test.gpg')
210 | file('settings.gradle') << """
211 | rootProject.name = "test"
212 | """
213 |
214 | when: "run pom task"
215 | def result = run('install')
216 |
217 |
218 | String artifactId = 'test'
219 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0-SNAPSHOT/")
220 |
221 | then: "task done"
222 | result.task(":install").outcome == TaskOutcome.SUCCESS
223 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0-SNAPSHOT")
224 |
225 | then: "artifacts deployed"
226 | deploy.exists()
227 | def baseName = artifactId + '-1.0-SNAPSHOT'
228 | withoutModuleFile(deploy) ==
229 | ["${baseName}.jar", "${baseName}.jar.asc", "${baseName}.pom", "${baseName}.pom.asc", 'maven-metadata-local.xml'] as Set
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/src/test/groovy/ru/vyarus/gradle/plugin/lib/UpstreamKitTest.groovy:
--------------------------------------------------------------------------------
1 | package ru.vyarus.gradle.plugin.lib
2 |
3 | import org.gradle.testkit.runner.TaskOutcome
4 |
5 | import java.util.zip.ZipFile
6 |
7 | /**
8 | * @author Vyacheslav Rusakov
9 | * @since 13.11.2019
10 | */
11 | class UpstreamKitTest extends AbstractKitTest {
12 |
13 | String GRADLE_VERSION = '8.6'
14 |
15 | def "Check install task"() {
16 | setup:
17 | file('src/main/java').mkdirs()
18 | build """
19 | plugins {
20 | id 'java'
21 | id 'ru.vyarus.java-lib'
22 | }
23 |
24 | group 'ru.vyarus'
25 | version 1.0
26 | """
27 |
28 | when: "run pom task"
29 | def result = runVer(GRADLE_VERSION, 'install', '--warning-mode', 'all')
30 |
31 |
32 | String artifactId = projectName()
33 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
34 |
35 | then: "task done"
36 | result.task(":install").outcome == TaskOutcome.SUCCESS
37 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
38 |
39 | then: "artifacts deployed"
40 | deploy.exists()
41 | def baseName = artifactId + '-1.0'
42 | withoutModuleFile(deploy) ==
43 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
44 | }
45 |
46 | def "Check install task for groovy"() {
47 | setup:
48 | file('src/main/groovy').mkdirs()
49 | build """
50 | plugins {
51 | id 'groovy'
52 | id 'ru.vyarus.java-lib'
53 | }
54 |
55 | group 'ru.vyarus'
56 | version 1.0
57 | """
58 |
59 | when: "run pom task"
60 | def result = runVer(GRADLE_VERSION, 'install')
61 |
62 |
63 | String artifactId = projectName()
64 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
65 |
66 | then: "task done"
67 | result.task(":install").outcome == TaskOutcome.SUCCESS
68 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
69 |
70 | then: "artifacts deployed"
71 | deploy.exists()
72 | def baseName = artifactId + '-1.0'
73 | // javadoc will be produced instead of groovydoc! important for maven central
74 | withoutModuleFile(deploy) ==
75 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
76 | }
77 |
78 | def "Check install for both sources"() {
79 | setup:
80 | file('src/main/java').mkdirs()
81 | file('src/main/groovy').mkdirs()
82 | build """
83 | plugins {
84 | id 'groovy'
85 | id 'ru.vyarus.java-lib'
86 | }
87 |
88 | group 'ru.vyarus'
89 | version 1.0
90 | """
91 |
92 | when: "run pom task"
93 | def result = runVer(GRADLE_VERSION, 'install')
94 |
95 |
96 | String artifactId = projectName()
97 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
98 |
99 | then: "task done"
100 | result.task(":install").outcome == TaskOutcome.SUCCESS
101 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
102 |
103 | then: "artifacts deployed"
104 | deploy.exists()
105 | def baseName = artifactId + '-1.0'
106 | withoutModuleFile(deploy) ==
107 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
108 | }
109 |
110 | def "Check install for no sources"() {
111 | setup:
112 | build """
113 | plugins {
114 | id 'groovy'
115 | id 'ru.vyarus.java-lib'
116 | }
117 |
118 | group 'ru.vyarus'
119 | version 1.0
120 | """
121 |
122 | when: "run pom task"
123 | def result = runVer(GRADLE_VERSION, 'install')
124 |
125 |
126 | String artifactId = projectName()
127 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
128 |
129 | then: "task done"
130 | result.task(":install").outcome == TaskOutcome.SUCCESS
131 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
132 |
133 | then: "artifacts deployed"
134 | deploy.exists()
135 | def baseName = artifactId + '-1.0'
136 | withoutModuleFile(deploy) ==
137 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
138 | }
139 |
140 | def "Check behaviour on test sources"() {
141 | setup:
142 | file('src/test/java').mkdirs()
143 | file('src/test/groovy').mkdirs()
144 | build """
145 | plugins {
146 | id 'groovy'
147 | id 'ru.vyarus.java-lib'
148 | }
149 |
150 | group 'ru.vyarus'
151 | version 1.0
152 | """
153 |
154 | when: "run pom task"
155 | def result = runVer(GRADLE_VERSION, 'install')
156 |
157 |
158 | String artifactId = projectName()
159 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
160 |
161 | then: "task done"
162 | result.task(":install").outcome == TaskOutcome.SUCCESS
163 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
164 |
165 | then: "artifacts deployed"
166 | deploy.exists()
167 | def baseName = artifactId + '-1.0'
168 | withoutModuleFile(deploy) ==
169 | ["${baseName}.jar", "${baseName}.pom", "${baseName}-sources.jar", "${baseName}-javadoc.jar"] as Set
170 | }
171 |
172 | def "Check jar modification"() {
173 |
174 | setup:
175 | file('src/main/java').mkdirs()
176 | build """
177 | plugins {
178 | id 'java'
179 | id 'ru.vyarus.java-lib'
180 | }
181 |
182 | group 'ru.vyarus'
183 | version 1.0
184 | """
185 | file('settings.gradle') << """
186 | rootProject.name = "test"
187 | """
188 |
189 | when: "run pom task"
190 | def result = runVer(GRADLE_VERSION, 'install')
191 |
192 |
193 | String artifactId = 'test'
194 | String baseName = artifactId + '-1.0'
195 | ZipFile jar = new ZipFile(file("build/repo/ru/vyarus/$artifactId/1.0/${baseName}.jar"))
196 |
197 | then: "jar manifest correct"
198 | String manifest = jar.getInputStream(jar.getEntry('META-INF/MANIFEST.MF')).text
199 | println manifest
200 | manifest.contains("Implementation-Title: $artifactId")
201 | manifest.contains("Implementation-Version: 1.0")
202 | manifest.contains("Built-By: ${System.getProperty('user.name')}")
203 | manifest.contains("Built-Date:")
204 | manifest.contains("Built-JDK:")
205 | manifest.contains("Built-Gradle:")
206 | manifest.contains("Target-JDK:")
207 |
208 | then: "jar contains pom"
209 | String jarPom = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.xml")).text
210 | jarPom != null
211 | println jarPom
212 |
213 | then: "jar contains pom.properties"
214 | String props = jar.getInputStream(jar.getEntry("META-INF/maven/ru.vyarus/$artifactId/pom.properties")).text
215 | props != null
216 | println props
217 | props.contains('groupId: ru.vyarus')
218 | props.contains("artifactId: $artifactId")
219 | props.contains('version: 1.0')
220 |
221 | cleanup:
222 | jar?.close()
223 | }
224 |
225 | def "Check jar only publish"() {
226 | setup:
227 | file('src/main/java').mkdirs()
228 | build """
229 | plugins {
230 | id 'java'
231 | id 'ru.vyarus.java-lib'
232 | }
233 |
234 | javaLib {
235 | withoutJavadoc()
236 | withoutSources()
237 | }
238 |
239 | group 'ru.vyarus'
240 | version 1.0
241 | """
242 |
243 | when: "run pom task"
244 | def result = runVer(GRADLE_VERSION, 'install')
245 |
246 |
247 | String artifactId = projectName()
248 | File deploy = file("build/repo/ru/vyarus/$artifactId/1.0/")
249 |
250 | then: "task done"
251 | result.task(":install").outcome == TaskOutcome.SUCCESS
252 | result.output.contains("INSTALLED ru.vyarus:$artifactId:1.0")
253 |
254 | then: "artifacts deployed"
255 | deploy.exists()
256 | def baseName = artifactId + '-1.0'
257 | withoutModuleFile(deploy) ==
258 | ["${baseName}.jar", "${baseName}.pom"] as Set
259 | }
260 |
261 | def "Check reports aggregation"() {
262 | setup:
263 | build """
264 | plugins {
265 | id 'base'
266 | id 'jacoco'
267 | id 'project-report'
268 | id 'ru.vyarus.java-lib'
269 | }
270 |
271 | javaLib {
272 | aggregateReports()
273 | }
274 |
275 | allprojects {
276 | repositories { mavenCentral() }
277 | }
278 |
279 | subprojects {
280 | apply plugin: 'groovy'
281 | apply plugin: 'jacoco'
282 | apply plugin: 'project-report'
283 | apply plugin: 'ru.vyarus.java-lib'
284 |
285 | dependencies {
286 | testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0'
287 | }
288 |
289 | test {
290 | useJUnitPlatform()
291 | }
292 | }
293 | """
294 | file('settings.gradle') << "include 'sub1', 'sub2'"
295 |
296 | fileFromClasspath('sub1/src/main/java/sample/Sample.java', '/sample/Sample.java')
297 | fileFromClasspath('sub1/src/test/groovy/sample/SampleTest.groovy', '/sample/SampleTest.groovy')
298 |
299 | fileFromClasspath('sub2/src/main/java/sample/Sample2.java', '/sample/Sample2.java')
300 | fileFromClasspath('sub2/src/test/groovy/sample/SampleTest2.groovy', '/sample/SampleTest2.groovy')
301 |
302 | when: "run test task"
303 | def result = runVer(GRADLE_VERSION, 'test', '--warning-mode', 'all')
304 |
305 | then: "task done"
306 | result.task(":test").outcome == TaskOutcome.SUCCESS
307 |
308 | then: "test report created"
309 | def test = file('build/reports/tests/test/index.html')
310 | test.exists()
311 |
312 | when: "run coverage task"
313 | result = runVer(GRADLE_VERSION, 'clean', 'jacocoTestReport', '--warning-mode', 'all')
314 |
315 | then: "task done"
316 | result.task(":jacocoTestReport").outcome == TaskOutcome.SUCCESS
317 |
318 | then: "coverage aggregated"
319 | def cov = file('build/reports/jacoco/test/jacocoTestReport.xml')
320 | cov.exists()
321 | cov.length() > 0
322 |
323 | when: "run dependencies task"
324 | result = runVer(GRADLE_VERSION, 'htmlDependencyReport', '--warning-mode', 'all')
325 |
326 | then: "task done"
327 | result.task(":htmlDependencyReport").outcome == TaskOutcome.SUCCESS
328 |
329 | then: "aggregated dependency report"
330 | file('build/reports/project/dependencies/root.sub1.html').exists()
331 | file('build/reports/project/dependencies/root.sub2.html').exists()
332 | file('build/reports/project/dependencies/root.html').exists()
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/src/test/resources/cert/test.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xvik/gradle-java-lib-plugin/59ad479c9e74ae110d3686d401511b8b45781835/src/test/resources/cert/test.gpg
--------------------------------------------------------------------------------
/src/test/resources/sample/Sample.java:
--------------------------------------------------------------------------------
1 | package sample;
2 |
3 | public class Sample {
4 |
5 | public String foo() {
6 | return "test";
7 | }
8 | }
--------------------------------------------------------------------------------
/src/test/resources/sample/Sample2.java:
--------------------------------------------------------------------------------
1 | package sample;
2 |
3 | public class Sample2 {
4 |
5 | public String foo() {
6 | return "test";
7 | }
8 | }
--------------------------------------------------------------------------------
/src/test/resources/sample/SampleTest.groovy:
--------------------------------------------------------------------------------
1 | package sample
2 |
3 | import spock.lang.Specification
4 |
5 | class SampleTest extends Specification{
6 |
7 | def "Check sample"() {
8 |
9 | expect:
10 | new Sample().foo() == 'test'
11 | }
12 | }
--------------------------------------------------------------------------------
/src/test/resources/sample/SampleTest2.groovy:
--------------------------------------------------------------------------------
1 | package sample
2 |
3 | import spock.lang.Specification
4 |
5 | class SampleTest2 extends Specification{
6 |
7 | def "Check sample"() {
8 |
9 | expect:
10 | new Sample2().foo() == 'test'
11 | }
12 | }
--------------------------------------------------------------------------------
/src/test/resources/sample/TestPlugin.java:
--------------------------------------------------------------------------------
1 | package ru.vyarus;
2 |
3 | import org.gradle.api.Plugin;
4 | import org.gradle.api.Project;
5 |
6 | public class TestPlugin implements Plugin {
7 |
8 | @Override
9 | public void apply(Project target) {
10 |
11 | }
12 | }
--------------------------------------------------------------------------------