How can I invoke Gradle's repository search manually? - gradle

As a precondition for building a release version, say acme-widgets-1.0, I would like to search the configured repositories (or a specific repository) to make sure acme-widgets-1.0.jar hasn't already been published. How can I do this with Gradle? Alternatively, is there a way to configure a not-exists dependency for a specific version?
group = 'com.acme'
version = '1.0'
repositories {
jcenter()
}
if (gradle.startParameter.taskNames.contains("release")) {
def taskNames = gradle.startParameter.taskNames
taskNames.add(0, "checkReleaseDoesntExist")
gradle.startParameter.taskNames = taskNames
}
task checkReleaseDoesntExist() {
}
task release() {
println "Building release"
}
checkReleaseDoesntExist.doLast {
println "Checking repositories to make sure release hasn't already been built"
// TODO What do I do here?
}

You could declare a configuration with only the artifacts for which you are trying to see if they are already published.
Upon resolving this configuration, you would have an empty fileset or not.
So something along the lines of:
configurations {
checkRelease { transitive = false }
}
dependency {
checkRelease "$group:$name:$version"
}
task ('checkReleaseDoesntExist') {
doLast {
println "Checking repositories to make sure release hasn't already been built"
try {
if (!configurations.checkRelease.files.isEmpty()) {
// already exists
}
}
catch (ResolveException e) {
// doesn't exist
}
}

Related

Build and publish test classes with gradle.kts

We have a multiproject gradle repository with several subprojects. One of the subprojects is supposed to generate separate testJar and publish it to the local maven repository:
// build a repositories-testJar.jar with test classes for services tests
tasks.register<Jar>("testJar") {
archiveClassifier.set("testJar")
from(sourceSets["test"].output)
}
// the testJar must be built within the build phase
tasks.build {
dependsOn(tasks.withType<Jar>())
}
// needed for publishing plugin to be aware of the testJar
configurations.create("testJar") {
extendsFrom(configurations["testCompile"])
}
artifacts {
add("testJar", tasks.named<Jar>("testJar"))
}
This works and I can see -testJar.jar is generated within the /build/libs.
Then, within the rootProject gradle.kts we set up a publishing extension:
allprojects {
configure<PublishingExtension> {
publications {
create<MavenPublication>(project.name) {
groupId = "foo.bar"
artifactId = project.name.toLowerCase().replace(":", "-")
version = "ci"
from(components["kotlin"])
}
}
repositories {
maven {
url = uri("file://${rootProject.rootDir}/../m2")
}
}
}
}
This also normally works and I can see modules being published in the m2 directory. However the testJar is not published. I couldn't find a way how to attach the testJar artifact to the publication defined in root project.
Solved with addition of:
publishing {
publications {
create<MavenPublication>(project.name + "-" + testArtifact.name) {
groupId = "my.group"
artifactId = project.name.toLowerCase().replace(":", "-")
version = "version"
artifact(testArtifact)
}
}
}

Gradle list dependency without resolving configuration

I have a custom task which unpacks all tar/zip dependencies for all configurations.
How do I define an up-to-date check that checks if any of the dependencies have changed, without resolving the configurations.
If I resolve the configuration I can't add dependencies to it later.
Current code:
def dependencyList() {
Set ret = []
configurations.each { conf ->
if (conf.canBeResolved) {
conf.resolvedConfiguration.resolvedArtifacts.each {
if (isArchive(it)) {
ret.add(it.toString())
}
}
}
return ret
}
task extractDeps {
inputs.property 'deps', dependencyList()
....
}
// This block will fail since the compile configuration is already resolved.
dependencies {
compile 'group:name:version#tar'
}

Gradle dependency resolution strategy with maven deployer

I am working on an android project. We are using the DependencyResoultionStrategy to swap some dependency versions. The code looks like this:
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
final version = getVersionForDependency(project, details.requested.group, details.requested.name)
if (version != null) {
details.useVersion(version)
}
}
So for example, the project requests the dependency group:name:1.1.2 but it is swapped so the dependency group:name:1.2.0 is used. This works perfectly and the project is built with the right dependency (the second one).
We also have a publish task, which deploys the project to a local maven repository. We use the maven plugin for this, the code looks like this:
apply plugin: 'maven'
task publish(dependsOn: uploadArchives)
uploadArchives {
configurations {
deployerFTP
}
repositories {
mavenDeployer {
configuration = configurations.deployerFTP
repository(URL) {
authentication(USERNAME, PASSWORD)
}
}
}
dependencies {
deployerFTP "org.apache.maven.wagon:wagon-ftp:2.4"
}
}
The problem is, if I publish the library, in the resulting .pom file, the dependency group:name:1.1.2 is entered, not the one which is actually used. How can I change this behavior, so the pom contains the right dependency?
I have found an answer, simply add this code block:
mavenDeployer {
// ...
pom.whenConfigured { pom ->
pom.dependencies = pom.dependencies.collect { dep ->
def version = getVersionForDependency(project, dep.groupId, dep.artifactId)
if (version != null) {
dep.version = version
}
return dep
}
}
}

Set repositories and version/revison dynamically in gradle

I have a gradle buildscript. In this script I set some publications.
Later in the script I have a task which reads the Buildnumber from a file and increases it. Than the version of the project will be changed.
Now my question: Is it possible to change the revision/version after initialising the "Publishing"-PlugIn? If I doesn't set the new version, the "Publishing"-PlugIn will throw n error. If I change the version by editing the descriptor, the Plugin says, that it's not allowed to edit the descriptor directly.
I also want to change the repository-url, based on the build number.
Does anybody know a fix or had the same problem?
publishing {
publications {
ivy(IvyPublication) {
organisation project.group
module project.name
revision project.version
descriptor.status = 'milestone'
from components.java
artifact(sourceJar) {
type "source"
conf "runtime"
}
}
maven(MavenPublication) {
groupId project.group
artifactId project.name
version project.version
from components.java
}
}
repositories {
ivy {
// change to point to your repo, e.g. http://my.org/repo
url "P:/Java/Repo/ivy"
}
maven {
// change to point to your repo, e.g. http://my.org/repo
url "P:/Java/Repo/maven"
}
}
}
Here is my script for increasing the build number
def incVersion(project) {
project.versionInced = true
def versionPropsFile = file("${project.rootDir}/version.properties")
if (!versionPropsFile.canRead()) {
versionPropsFile.createNewFile();
}
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
if(versionProps['build_version'] == null)
{
versionProps['build_version'] = 0;
}
def code = versionProps['build_version'].toInteger()+1;
versionProps['build_version']=code.toString()
versionProps.store(versionPropsFile.newWriter(), null)
project.projectInfos.version = project.version + "." + code.toString()
project.version = project.projectInfos.version
println "Version: "+project.version
return project.version
}
If I understood well, yes it can be done dynamically. You can pass a version while running gradle via project property (-P) or via system property (-D).
It will be:
gradle <some_task> -PsomeVersion=<version>
You need to alter the gradle script to read the property, so:
publishing {
publications {
ivy(IvyPublication) {
revision project.hasProperty('someVersion') ? project.someVersion : '<HERE YOU NEED TO PUT DEFAULT VERSION OR MAYBE THROW EXCEPTION IF EMPTY>'
//...
}
}
}
If you won't check if project has the property (using hasProperty method on project instance), MissingPropertyException will be thrown.

whenReady not setting gradle property before task runs

I have a a version property in my gradle.properties file that gives the version I am building. I have a task in the build called release that if present in the task graph will upload to the snapshot repo. However what is happening is that even though I include the release task in the build tasks, snapshot is not appended to my version property when uploadArchives runs so it attempts to upload to the wrong repository and fails. The when ready runs, but it does not seem to run before uploadArchives. Can anyone explain what is happening here?
uploadArchives {
repositories {
ivy {
credentials {
username nexusUser
password nexusPassword
}
if (version.endsWith("-SNAPSHOT")) {
url nexusSnapshotRepository
} else {
url nexusReleaseRepository
}
}
}
}
gradle.taskGraph.whenReady {taskGraph ->
if (!taskGraph.hasTask(release)) {
version = version + '-SNAPSHOT'
}
println "release task not included - version set to $version"
}
task release(){
doLast{
println "Releasing"
}
}
This is very similar to the example on the gradle site so I don't see what is going wrong.
http://www.gradle.org/docs/current/userguide/tutorial_using_tasks.html
The script is checking the project.version value in the configuration phase (not when the task executes), but only modifying it after the task execution graph has been built. One way to fix this is to override the repository url from inside the taskGraph.whenReady callback:
uploadArchives {
repositories {
ivy {
name "nexus"
url nexusReleaseRepository
...
}
}
}
gradle.taskGraph.whenReady { taskGraph ->
if (!taskGraph.hasTask(release)) {
version += '-SNAPSHOT'
uploadArchives.repositories.nexus.url nexusSnapshotRepository
// ps: println has to go inside here
}
}

Resources