I've been researching and trying to find examples for the above and found the following:
For Android Projects:
Hosting a Private Maven Repo on Amazon S3
gradle maven push project
These plugin however expects certain Android properties specified and throws errors like Could not find property 'android' on task ':androidJavadocs'.
For Remote repositories over SFTP, there is maven-publish.
Besides, it seems to be possible to do this in Maven.
Would be great if anyone can point me to an example of how to do this.
Gradle has a plugin to do this now however it is in incubating state and yet to be released.
https://docs.gradle.org/current/userguide/publishing_maven.html
I've slightly modified the code from your second link (here) for Java-based projects. The only problematic sections are at the bottom of the file, where the source and javadoc jars are being created since he is directly referencing Android. If you replace the final tasks (line 95 onwards) with the following it should resolve your problem:
task sourcesJar(type: Jar) {
classifier = 'sources'
from sourceSets.main.allSource
}
// Makes the Javadocs
task javadocs(type: Javadoc) {
// I set this to false here since I reference third party classes in my Javadocs
// which fails the Javadoc generation, but this can be removed
failOnError false
source = sourceSets.main.java.srcDirs
}
task javadocJar(type: Jar, dependsOn: javadocs) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
Related
I'm using gradle plugin as
plugins {
id 'net.ltgt.errorprone' version '2.0.2' apply false
}
Now, I forked net.ltgt.errorprone on Github, did some changes in branch changes. How can I tell Gradle to use the fork instead of upstream?
I've found this 'Fork' git repository as dependency in gradle for dependencies, looking for something similar for plugins.
I solved it using jitpack.io to distribute the forked code into my app as a dep.
You can go to https://jitpack.io/ and enter your git url, it will give you available refs to use.
Also, don't forget to check ref's log so you know jitpack can actually build your dep.
The log is available via icon in Log column.
If the icon is not visible, you can access it via url.
E.g. for commit hash 384433165eba475b113189d05786d4daf17c465c it is located on https://jitpack.io/com/github/johnrengelman/shadow/384433165eba475b113189d05786d4daf17c465c/build.log
There you can see the build is actually broken as the plugins needs at least jdk 11 but jitpack runs it with v1.8.
You can force jitpack tu use another jdk version by creating jitpack.yml in project's root with following content:
jdk: openjdk11
See https://jitpack.io/docs/BUILDING/#java-version for more info.
I've found few ways how to use the fork but I liked this one the most:
Let's say you use these
plugins {
// in my opinion, removing `version` makes it more obvious that we're using JitPack, but it can stay too
id 'com.eriwen.gradle.css' version '2.14.0'
id 'com.eriwen.gradle.js' version '2.14.1'
}
So you can replace them with your fork via adding this (jitpack repository and replacement resolution) to your settings.gradle:
pluginManagement {
repositories {
gradlePluginPortal()
maven {
url 'https://jitpack.io'
}
}
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'com.eriwen.gradle.css') {
useModule('com.github.eriwen:gradle-css-plugin:9fe88d7') // can also be a branch, i.e. `master-SNAPSHOT`
}
if (requested.id.id == 'com.eriwen.gradle.js') {
useModule('com.github.eriwen:gradle-js-plugin:d15f4ae') // can also be a branch, i.e. `master-SNAPSHOT`
}
}
}
}
We have lots of libraries for which we have the following snippets to configure the respective plugins. We would want to avoid code duplication and rather want to pull these definitions from a base repository which can be shared across all projects. How should this be configured?
checkstyle {
showViolations = false
ignoreFailures = true
..
}
pmd {
..
}
license {
..
}
spotless {
..
}
artifactory {
..
}
With an easy approach you can import build script plugins into other build scripts even if they are located in a different location / different repository. The only requirement that I think is necessary that on the machine where you will build the project at the end you have access to those repositories.
Imagine you have GitHub repository that contains main configuration.
https://github.com/user/shared-gradle-config/blob/master/scriptPlugin.gradle
That contains:
checkstyle {
showViolations = false
ignoreFailures = true
..
}
pmd {
..
}
...
Now be sure that you use raw resources in other scripts. Every repository service will have different kind of link. Below example for GitHub:
https://raw.githubusercontent.com/user/shared-gradle-config/master/scriptPlugin.gradle
At the beginning of the Gradle build script for the actual projects you have to include application of the remote script plugin:
// Application of shared remote Gradle script plguin with common configuration
// With this line all the checkStyle, PMD configuration and whatever you have declared in the script will be applied to current project
apply from: "https://raw.githubusercontent.com/user/shared-gradle-config/master/scriptPlugin.gradle"
// Whatever custom logic below
wrapper {
version = "7.0.0"
distributionType = Wrapper.DistributionType.ALL
}
...
I made a prototype project miself as I tried to understand how to share build configuration this way. Maybe it can help you, https://github.com/rivancic/gradle/tree/master/script-plugin. Note its not in final version, still improving it..
I have a multi-module build with approx 100 modules. Is there a way to create jar files for only the changed modules and copy them to somewhere?
The task should be a standalone task without modifying existing jar tasks
So, assuming all your modules are simple java modules, all your modules will have a jar task (of type Jar) that build the JAR file of the respective module. Each jar task will only be executed, if the contents changed in any way (e.g. new files were compiled), thanks to Gradle incremental build feature.
You can simply add a doLast closure to each of these tasks, which copies the created file to your directory, because the closure will only be executed if and only if the task was executed:
Example for a single task:
jar {
doLast {
project.copy {
from archivePath
into 'path/to/my/location'
}
}
}
If this works for a single module, we can try a similar approach as what #lance-java did:
allprojects { project ->
project.tasks.withType(Jar).all { jar ->
jar.doLast {
project.copy {
from jar.archivePath
into 'path/to/my/location'
}
}
}
}
Assuming you have all your task inputs and outputs setup correctly, gradle supports up to date checking and task skipping out of the box. See up to date checks (aka incremental build)
For the copying, you could use a Sync task which will only copy (or delete) jars that are different from the target directory.
Eg
task syncJars(type: Sync) {
allprojects { p ->
from p.tasks.withType(Jar)
}
into 'path/to/target/dir'
}
I'm asking you about a very basic question but I hope you can find the time to help me:
I'm trying to realise a java-project, that can spit out several different programs which partially have dependencies on other projects of mine.
In order to keep it simple, I want to have all the code in one project, run by Gradle, so if I make changes to a central library (the database connector for example) all the child-programs automatically recieve the changes.
An example could look like this:
project:
program_A
central_library
program_B
output:
program_A.jar (including central library)
program_B.jar (including central library)
Now I'm having serious troubles finding a correct buildscript for this and was wondering if someone here could help me out.
P.S. : Since I'm new to this, if I should realize this through different modules within the Gradleproject instead of different packages in the Gradleprojects sourcefile, feel free to tell me :)
One way to approach this is to have a root project, that holds the three other projects inside of it.
Specify the sub-projects inside its settings.gradle file:
rootProject.name = 'RootProject'
include 'program_A'
include 'central_library'
include 'program_B'
With this in place, program_a can depend on central_library by adding a dependency in its build.gradle:
dependencies {
compile project(':central_library')
}
I have a similar setup in one of my projects, although the "central library" is the root project and the submodules are test environments.
Create a root directory and put each library or program into its own sub-directory.
Create a gradle project in each subproject.
You can for example create a skeleton gradle project by running
gradle init --type=java-library
or
gradle init --type=java-application
Then in the root directory create a gradle multi-module project. Basically
run only
gradle init
and then create a settings.gradle and list all sub-projects there.
This is actually described very well in the gradle documentation:
https://guides.gradle.org/creating-multi-project-builds/
If I understand correctly, what you want to do is, when you change your local projects, you want other projects to see those details. For this you need to publish your projects to some kind of repo, like maven repo. You can do this from command line gradle publishToMavenLocal, or gradle build pTMl. You can also do this in build.gradle file with something like the following:
task sourceJar (type : Jar) {
classifier = constants.extSources
from sourceSets.main.allSource
}
publications {
mavenJava(MavenPublication) {
from components.java
artifact(sourceJar) {
classifier "sources" //classifier = constants.extSources
}
}
}
Currently, my build.gradle has a dependency on an external library built with Ant. To accomplish building the library, I followed the advice here and created a task which builds the external library, and copies it to the libs/ folder.
The task is called as part of a dependency:
build.gradle
dependencies {
compile fileTree('libs') {
include '*.jar'
builtBy 'myTask'
}
}
task myTask (type: GradleBuild) { GradleBuild antBuild ->
antBuild.buildFile('external-stub.gradle')
antBuild.tasks = ['clean', 'ivy.check', 'ivy.download', 'ivy.task', 'ivy',
'init', 'mergeCode', 'compile', 'jar', 'copyJarsToProject']
}
However, when the compile actually runs, the library I just built and copied in is not included in the dependencies, as evidenced by a whole lot of compilation errors.
Am I including the library the wrong way?
The full build.gradle and associated files are over at Github, and I've linked to the specific commit I'm having issues with: Source Repository
Alright, took me a while to get a build I was happy with. But, here's what was changed.
The actual build of the JAR was built using the same style, but moved to the external project (so that the main build project wasn't reaching across to it). I'll give an in-depth explanation below, but the commits are here and here. These are in order.
Basically, we export the jar as an artifact that other projects can depend on, rather than copying over the Jar ourselves. This way, the Ant build runs and other projects can see the Jar we just created. This is the end of the first commit. In the second commit, the task outputs are marked as needing to be regenerated only if the Jar does not exist. This was due to the fact that whenever I tried to build the app, it would take minutes to regen the Jar, and then have to repackage everything else as well. The code is below:
build.gradle External Project
configurations {
buildJSword
}
task doBuildJSword (type: GradleBuild) {
buildFile = 'jsword-stub.gradle'
tasks = ['clean', 'ivy.check', 'ivy.download', 'ivy.task', 'ivy',
'init', 'mergeCode', 'compile', 'jar'] //, 'copyJarsToMinimalBible']
ext.outputJar = file('distribution/jsword.jar')
outputs.upToDateWhen {
ext.outputJar.exists()
}
}
artifacts {
buildJSword(doBuildJSword.ext.outputJar) {
builtBy doBuildJSword
}
}
Then, the main project just has to add this project as a compile-time dependency:
build.gradle Main Project
compile project(path: ':jsword-minimalbible', configuration: 'buildJSword')
Hope this is helpful for anyone with a similar issue, let me know if you have questions!
Note: The build currently does not clean itself properly, so if you change any code in the external project, you need to delete the external Jar for everything to regenerate itself correctly.