I've the following gradle project structure:
SUPER/
|______A/
| |______A1/
| | |______build.gradle
| |______A2/
| | |______build.gradle
| |______build.gradle
| |______settings.gradle
|
|______B/
| |______build.gradle
| |______settings.gradle
|
|______build.gradle
|______settings.gradle
My build.gradle from the A-Project contains somethings like that:
...
project(":A1") {
apply plugin: "java-library"
dependencies {
api project(":A2")
}
}
project(":A2") {
apply plugin: "java-library"
dependencies {
...
}
}
...
My "Super"-settings.gradle file contains something like that:
rootProject.name = 'SUPER'
include 'A'
include 'B'
In my sub-project "A" the settings.gradle looks like that:
include 'A1', 'A2'
When calling the gradlewrapper like that "./gradlew SUPER:A1:sometask" on the command line from the SUPER-folder, it fails with the message:
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\Users\<somepath>\SUPER\A\build.gradle' line: 44
* What went wrong:
A problem occurred evaluating project ':A'.
> Project with path ':A1' could not be found in project ':A'.
But when doing something like that "./gradlew A1:sometask" from the A-sub-project-folder, it works successfully.
can you explain me what am I'm doing here wrong?
Related
I have a multi-module project that ends up outputting a directory called logs at the root of each module - including the root project.
I have extended the clean task like this but it only deletes the logs dir in the root project and not in the sub-modules.
allprojects {
clean {
delete 'logs'
}
}
I thought that this meant "add the clean task to all the projects and delete the logs dir in each project".
It seems like even though the delete is being called in each sub-module, it is using the root directory as the relative path to find the logs dir.
However, if I change it to the following it deletes the directory in each module.
allprojects {
clean {
delete file('./logs')
}
}
This looks functionally identical to me since if the path of each clean task is relative to the root then file('./logs') should also be relative to the root.
However, the file object seems to be relative to the module dir and not the root.
Why does the file object resolve correctly but the string passed to the clean task does not?
How are paths resolved for each module when running a multi-module project?
Is there a better way to do this than using a file object?
Could not replicate - gradle 6.7 / jdk 11
Dir structure
.
|____a
| |____b
| |____c
common delete task
allprojects {
apply plugin: 'java'
task deleteLogs(type: Delete) {
delete 'logs'
}
clean {
delete 'logs'
}
task printcd {
println 'project : ' + project.name
println 'rootDir : ' + project.rootDir
println 'prjDir : ' + project.projectDir
println '-------------'
println 'file : ' + file('logs').absolutePath
println 'file ./ : ' + file('./logs').absolutePath
println '-------------'
print 'deletePath : '
project.tasks.getByName('deleteLogs').targetFiles.each {file -> println file.absolutePath }
println '-------------'
print 'clean : '
project.tasks.getByName('clean').targetFiles.each {file -> print file.absolutePath + " , " }
println ''
println '============='
}
repositories {
mavenCentral()
}
}
output
-bash$ gradle printcd
> Configure project :
project : a
rootDir : /Users/xyz/a
prjDir : /Users/xyz/a
-------------
file : /Users/xyz/a/logs
file ./ : /Users/xyz/a/logs
-------------
deletePath : /Users/xyz/a/logs
-------------
clean : /Users/xyz/a/build , /Users/xyz/a/logs ,
=============
project : b
rootDir : /Users/xyz/a
prjDir : /Users/xyz/a/b
-------------
file : /Users/xyz/a/b/logs
file ./ : /Users/xyz/a/b/logs
-------------
deletePath : /Users/xyz/a/b/logs
-------------
clean : /Users/xyz/a/b/build , /Users/xyz/a/b/logs ,
=============
project : c
rootDir : /Users/xyz/a
prjDir : /Users/xyz/a/c
-------------
file : /Users/xyz/a/c/logs
file ./ : /Users/xyz/a/c/logs
-------------
deletePath : /Users/xyz/a/c/logs
-------------
clean : /Users/xyz/a/c/build , /Users/xyz/a/c/logs ,
=============
BUILD SUCCESSFUL in 578ms
-bash$ gradle --version
------------------------------------------------------------
Gradle 6.7
------------------------------------------------------------
JVM: 11.0.8 (Oracle Corporation 11.0.8+10-LTS)
I have the next project structure.
\rootProj
|
+--\moduleA
| |
| +--\build
| |--build.gradle
| ...
|
+--\moduleB
|
+--\main
| |
| +--\resources
| ...
|
|-build.gradle
...
I'm searching an approach to put everything from moduleA\build to moduleB\main\resources.
Could someone help me with this task?
I've googled about it but found nothing - I'm new in Gradle and it may be a cause I can't ask in the right way.
Thanks in advance!
As an answer to my question I've made the next solution:
buildscript{
ext{
generatedResOutDir = file("$buildDir/generated-resources")
}
}
sourceSets {
main{
output.dir(generatedResOutDir, builtBy: 'copyRes')
}
}
task copyRes(type: Copy){
//for to be certain a directory
//we are going to copy from
dependsOn ':moduleA:build'
from project(':moduleA').buildDir
into '${generatedResOutDir}/static'
}
This solution is inspiried by Gradle DSL SourceSetOutput doc.
I am trying read a project property from command line interface. There is a task gradle properties, which prints all of them. Therefore, I can write: gradle properties | grep "rootProject: root project" | awk '{print $NF}' | tr -d "'" and get what I want. The returned result is correct. I would like to use a proper gradle command to achieve the same result. What is a gradle command to get the project name?
this is my build.gradle:
plugins {
id 'java'
}
tasks.register("rootProjectName") {
doLast {
println(rootProject.name)
}
}
build {
println 'hi'
}
Looks like you're just after the rootProject.name property. There is no built-in Gradle task that will give you that property. You can write a simple task that prints that value to the console which will simplify your command.
tasks.register("rootProjectName") {
doLast {
println(rootProject.name)
}
}
Then simply call that task with -q:
$ ./gradlew rootProjectName -q
demo
You can see demo is simply printed out for this example.
So far the closest I got is the following build.gradle:
plugins {
id 'java'
}
task printRootProjectName {
doLast {
println('root project: ' + rootProject.name)
}
}
build {
println 'unwanted output'
}
and then:
gradle printRootProjectName -q | grep "root project:" | awk '{print $NF}' | head -n 1
I have a Gradle project that I want to import to Versioneye to check if my dependencies are up to date, but it's a complex config file (with external variables etc.) and Versioneye does not manage to handle the dependencies properly.
I don't want to install the Versioneye gradle plugin.
How can I export the dependencies from my repo to Versioneye?
You can list all the dependencies gradle app:dependencies.
With a bit of string manipulation, you can export a "clean" dependencies file and manually upload it to Versioneye.
#!/bin/bash
OUT_DIR='versioneye'
OUT_FILE="${OUT_DIR}/build.gradle"
mkdir -p "${OUT_DIR}"
touch "${OUT_FILE}"
# copy your maven repositories closure below from build.gradle
tee "${OUT_FILE}" <<EOF >/dev/null
allprojects {
repositories {
maven {
url 'https://maven.google.com/maven-google-remote'
}
maven {
url "https://jitpack.io"
}
}
}
EOF
echo 'dependencies {' >> "${OUT_FILE}"
./gradlew app:dependencies | grep '^+---' | sed 's|+--- |compile "|' | sed 's| (\*)||g' | sed 's|$|"|' | sort -u >> "${OUT_FILE}"
echo '}' >> "${OUT_FILE}"
cat "${OUT_FILE}"
cd "${OUT_DIR}"
start .
cd -
echo 'Now, open versioneye.com and manually upload the genreated build.gradle file.'
This will generate a file that looks like this:
allprojects {
repositories {
maven {
url 'https://maven.google.com/maven-google-remote'
}
maven {
url "https://jitpack.io"
}
...
}
}
dependencies {
compile "com.android.support.test.espresso:espresso-contrib:2.2.2"
compile "com.android.support.test.espresso:espresso-core:2.2.2"
compile "com.android.support.test.espresso:espresso-intents:2.2.2"
compile "com.facebook.android:facebook-android-sdk:4.17.0"
compile "com.facebook.fresco:fresco:1.5.0"
compile "com.facebook.fresco:imagepipeline-okhttp3:1.5.0"
...
}
This file can be imported to Versioneye with a file upload and will be processed correctly.
I know that Gradle has the excellent dependencies task that lists out all dependencies for a project. However, it returns them in a tree listing.
I would like to get a list of all my dependencies as they are resolved in just a flat list. Similar to how the Maven dependency plugin list goal behaves.
Here is a short task that meets that need:
task('dependenciesList') << {
println "Compile dependencies"
def selectedDeps = project.configurations.compile.incoming.resolutionResult.allDependencies.collect { dep ->
"${dep.selected}"
}
selectedDeps.unique().sort().each { println it}
}
The third line is the interesting part. You need to get the configuration you care about (compile) then instead of getting dependencies there, the incoming.resolutionResult will provide the resolved values and versions.
<< was removed in Gradle 5. To make the task work in Gradle 5 and later versions, remove << and use doLast { } instead. Also, use runtimeClasspath or compileClasspath for the configuration instead of compile:
task('dependenciesList') {
doLast {
println "Compile dependencies"
def selectedDeps = project.configurations.compileClasspath.incoming.resolutionResult.allDependencies.collect { dep ->
"${dep.selected}"
}
selectedDeps.unique().sort().each { println it}
}
}
Without modifying the build, flatten the tree using sed, sort, and uniq as follows:
$ gradle dependencies | sed 's/^.* //' | sort | uniq
Alternatively, with slightly tighter sed matching:
./gradlew dependencies \
| sed -n 's/.*--- \([^ ]*\).*/\1/p' \
| grep -v "^project$" \
| sort \
| uniq
Thanks for the answers already supplied.
Finally I complete it by a more standard way:
project.gradle.addListener(new DependencyResolutionListener() {
#Override
void beforeResolve(ResolvableDependencies dependencies) {}
#Override
void afterResolve(ResolvableDependencies dependencies) {
dependencies.resolutionResult.allComponents.each { select ->
println "selected component: ${select} " + select.selectionReason
}
}
})
Project implementation will also be resolved in this way, and the final selected component version will be resolved correctly.