Gradle project test depends on another project's test - gradle

This might be a duplicate somewhere but some of the answers were for old Gradle which doesn't work anymore. Please let me know if this is doable. I have a new project named NewProject . NewProject depends on common project which lives in another directory.
- NewProject
- \build.gradle
- \settings.gradle
- \src
- \main\java
- \test\java
- common
- \build.gradle
- \settings.gradle
- \src
- \main\java
- \test\java
In NewProject, my file settings.gradle looks like this
rootProject.anme = 'NewProject'
include ':common'
project(':common').projectDir = file('../common')
and my file build.gradle has below lines in dependencies section
dependencies {
implementation project(':common')
...
testImplementation project(':common')
...
}
The problems I have are two:
Because I don't own the common project code, so I can not change the build file in common.
My test in NewProject couldn't locate the common's test classes. For example BaseTest etc.
I have tried approaches of:
Using testImplementation project(':common:test') doesn't work because ':common:test' is not recognized.
Using testImplementation project(':common').sourceSets.output.classes, but this approach is invalid for Gradle 5.0 and above.
Please let me know if there are other ways of doing this!

What is needed ?
The test-classes and test-resources dir of :common need to be in the classpath of the :newProject test
A way for your setup via Local dir access - in the :newProject build.gradle
testImplementation files('../common/build/classes/java/test')
testImplementation files('../common/build/resources/test')
note: this does not transitively add :common test dependencies to :newProject test, you have to do that manually.

Related

Gradle composite build throwing "Failed to get Gradle name for :module"

We've a collection of libraries developed by different teams and individually pushed to different Git repositories. To minimize the hassle of publishing to local Maven repositories or publishing snapshot versions, we've put together a root project to include all those libraries with Gradle's dependencies substitutions.
The structure is as follows:
- root (Git-root)
...
- modules
- module-a (Git-module-a)
- a-core
- build.gradle.kts
- a-data
- build.gradle.kts
- settings.gradle.kts
- module-b (Git-module-b)
- b-core
- build.gradle.kts
- b-data
- build.gradle.kts
- settings.gradle.kts
- settings.gradle.kts
- settings.gradle.kts
It's a bit confusing but module-a and module-b are included as git submodules inside a modules folder of the root project.
The Gradle files are as follow:
settings.gradle.kts
rootProject.name = "project-root"
includeBuild("modules")
modules/settings.gradle.kts
rootProject.name = "modules"
includeBuild("module-a")
includeBuild("module-b")
modules/module-a/settings.gradle.kts
rootProject.name = "module-a"
include("a-core")
include("a-data")
modules/module-b/settings.gradle.kts
rootProject.name = "module-b"
include("b-core")
include("b-data")
Just to illustrate the reason for this, lets say that the module-b:b-core depends on the module-a:a-core library.
The problem is that when I run this build it comes back with the following message:
Multiple build operations failed.
Failed to get Gradle name for :a-core
Failed to get Gradle name for :a-data
Failed to get Gradle name for :b-core
Failed to get Gradle name for :b-data
I don't know if what I'm trying to achieve is possible, but I couldn't find anything in the documentation. It looks like we're always very close to what we desire, but it's almost impossible to get there.
Do you guys know what I'm missing?
Error messsages come from AGP ModelBuilder.getBuildeName()
The reason is that most "bottom" projects in composite build ("a-core", "a-data", "b-core" and "b-data") have gradle.rootProject.parent set to "topmost" project ("project-root"), instead of their immediate parents ("module-a" and "module-b").
You can check it putting
println("${project.name} parent is ${project.gradle.parent?.rootProject?.name}")
in build.gradle.kts of all the projects and running sync
It whether Gradle or AGP problem, depending on is such a root behavior correct or a gradle bug.
I have created the issue about this case in gradle project. Will look what gradle team answer :)
As temporary solution add includeBuild("a-core") and other bottom level projects in modules/settings.gradle.kts. If still will got error, try add it to the topmost "project-root" settings.gradle.kts instead.

gradle default configuration, what is it and how can I define it

I am having a weird error, for which I found a lot of hits in google but most about android studio or library imports and I don't use android studio nor am I trying to build any app/library so I'll try and ask here and see if I understand the background of it.
I have a project in which I have this plugin:
https://gitlab.com/zkovari/gradle-mermaid-plugin/-/blob/master/examples/single-project/build.gradle
This is a plugin that displays my dependencies as a mermaid graph.
Everything was fine until today I updated some dependencies and created a sub-project to do something else.
I'm trying to generate the graph again and somehow it's failing with this error message.
> Task :generateMermaidDependenciesDiagram FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':generateMermaidDependenciesDiagram'.
> Configuration with name 'default' not found.
I can see in the source code of the plugin that it automatically sets some configurations
#Override
public void apply(Project project) {
GenerateMermaidDependenciesDiagram generateDependencyDiagramsTask = project.getTasks()
.create(GENERATE_MERMAID_DEPENDENCIES_DIAGRAM_TASK_NAME, GenerateMermaidDependenciesDiagram.class);
generateDependencyDiagramsTask.setConfiguration("default");
generateDependencyDiagramsTask
.setOutput(project.getBuildDir().toPath().resolve("mermaid/dependencies.mmd").toFile());
generateDependencyDiagramsTask.setDiagramGenerator(new MermaidDiagramGenerator());
}
So my question is a bit high level but what is the "default" configuration?
And in my project I don't really have any configuration block I simply have my dependencies:
dependencies {
implementation group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: awsVersion, transitive: false
...
testCompile group: 'org.slf4j', name: 'slf4j-simple', version: slf4jVersion
}
My structure looks like this:
project:
-- build.gradle
-- settings.gradle
-- sub-project:
--- build.gradle
I think this stopped working when I added my sub-project but the plugin is applied at the root project level.
I do have a dependency between my sub-project and my root project (one of my sub-project tasks depends on the root project)
I'm trying to understand that this might be very similar but I'm not fully getting it.
Gradle: What Is The Default Configuration and How Do I Change It
I do apply the java plugin on my main project so I expect the configuration.default should exist.
Even if I think I shouldn't do it I tried to re-define a default configuration extending implementation but that did not work
https://docs.gradle.org/current/userguide/declaring_dependencies.html
configurations {
default.extendsFrom implementation
}
build file 'C:\dev\repo\connector-custom\build.gradle': 66: unexpected token: default # line 66, column 5.
default.extendsFrom implementation
I did a quick test and removing my subproject did work so I know the problem is there but no idea why.
It means somehow I must pass to my subproject the default configuration of the main project?

Test runtime classpath does not contain plugin metadata file 'plugin-under-test-metadata.properties'

I am upgrading gradle version to 6.8.1.For testing purpose. I am adding the dependency testCompile gradleTestKit() in build.gradle but my intergation test case are failing with below error.
I tried upgrading to Junit 5, spock 2.0-groovy-2.5 & groovy 2.5.12.
Code:
def runner = GradleRunner.create()
.withProjectDir(this.testDir)
.withPluginClasspath()
withPluginClasspath() method getting the exception.
Test case:
def "Make sure a build runs successfully"() {
when:
def result = build 'compileJava'
Error:
Test runtime classpath does not contain plugin metadata file 'plugin-under-test-metadata.properties'
org.gradle.testkit.runner.InvalidPluginMetadataException: Test runtime classpath does not contain plugin metadata file 'plugin-under-test-metadata.properties'
at org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading.readImplementationClasspath(PluginUnderTestMetadataReading.java:44)
at org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading.readImplementationClasspath(PluginUnderTestMetadataReading.java:37)
at org.gradle.testkit.runner.internal.DefaultGradleRunner.withPluginClasspath(DefaultGradleRunner.java:162)
I fixed this issue by changing integration tests settings in build.gradle:
integTest {
// old code had "configurations.testRuntime" at the end
compileClasspath += sourceSets.main.output + configurations.testRuntimeClasspath
}
I fixed this issue by adding 'plugin-under-test-metadata.properties' file in my src/resources folder as I noticed classpath is reading from src folder.

Gradle - get dependency list for each library/module

I am trying to get the dependencies list for each modules/library in a project.
Here is the structure of the project:
Project
+ --- library1
+ --- library2
+ --- library3
+ --- library4
+ --- library3
The build.gradle of project is
dependencies {
compile project(':library1')
}
library2 and library4 all depend on library3. and the way they compile dependencies are the same with project.
I would want to get the dependencies for each modules/libraries so that i can decide the sequence of bumping version for these libraries and uploading to maven in a script file.
So I would first want to save these dependencies for each module in a variable and the script file can read it and do the automation work.
I have tried using Conifguration.getAllDependencies() in custom gradle build file. But it doesnt work.
Anyone know how would I do that?
Any suggestions would be much appreciated!
====
UPDATE:
I have tried adding a task under project's gradle file
List<ProjectDependency> dependencies =
project.configurations.collectMany {
it.allDependencies
}.findAll {
it instanceof ProjectDependency
}
But the dependencies returns 0 size of list
For a simple project, one can get its dependencies by invoking
project.configurations*.
dependencies*.
findAll { it instanceof ExternalDependency }.
flatten()
Note that ExternalDependency, not ProjectDependency is used.
For dealing with dependencies on a real project, gradle-versions-plugin by Ben Manes offers some nice reports
gradle-dependency-lock plugin by Netflix provides dependency update automation

how to add a local android lib to gradle build?

I have an android library (source) that I have been using in eclipse and i need to port to android studio. I have the library building as its own project. but now i want to use it in another project (somewhere else on the filesystem).
How can i declare this library project to my other project. I don't want to copy the files over but rather use it in place. so it cant be under the other project dir hierarchy.
Hope it make sense. If you need more info let just ask. possibly i have to add stuff to publish it as an artifact? when i was using maven i would declare it as a module with a file path ....
tried
repositories {
flatDir {
dirs 'path'
}
}
but to no avail ...
may get diff results with diff gradle versions but i've done this on 1.10...
gradle.settings
include '..:youLib'
AndroidManifest for your lib...
make sure its minimal and it does not contain "ActivityName" or "launcher" props
build.gradle
dependencies {
compile project(':..:youLib')
You need to declare libraries in dependencies section:
E.g.
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}

Resources