This message was deleted.
# community-support
s
This message was deleted.
v
As this sounds highly Android-specific you might consider moving your question to #CJYS1DAP5 eventually
v
well yes and no, yes ommiting release variatn might be a android need, but could apply to any project as well, where code optimizers are ran
solution afaik should be generic, sounds like just getting all
test
tasks for jvm and
testDebugUnitTest
for android but, it feels rather low level, and wondering if there is more idiomatic approach
n
The fact that all variants are built during the
check
lifecycle task is highly specific to the android plugin, no? Gradle just provides the
check
task as a hook, nothing more, nothing less. So even if you consider this a generic need, the solution to your specific build is very much android-specific.
v
fair
I'll move my business there
n
I don't really find an easy reference for the AGP extension, but perhaps the
beforeVariant
callback can help you select which variants to build under what circumstances (this is a guess on my end though): https://developer.android.com/reference/tools/gradle-api/7.1/com/android/build/api/extension/AndroidComponentsExtension#beforevariant%0As
v
what I think I want is, at a root build.gradle, iterate all projects, collect all tasks which name is either "test" or "testDebugUnitTest" .. that's all
n
That's generally not advisable anymore, as you'll introduce coupling between modules. I think you should find a way in the android plugin to exclude variants based on whatever rules you set, instead of working around the problem by introducing extra tasks and/or complexity. If you insist (again, best not to):
Copy code
projects.all {
    tasks.named("test").configureEach {}
    tasks.withType(Test).configureEach {}
}
v
what I think I want is, at a root build.gradle, iterate all projects, collect all tasks which name is either "test" or "testDebugUnitTest" .. that's all
You could simply do
./gradlew test testDebugUnitTest
v
hmm plural? doesn't exist .. was that a typo?
v
Yes, sorry, fixed 🙂
v
test
has the same issue as check on android, it runs every variant
v
Well, then
what I think I want is, at a root build.gradle, iterate all projects, collect all tasks which name is either "test" or "testDebugUnitTest" .. that's all
wouldn't help either as that is exactly what that commandline is triggering. If for whatever reason
test
is configured to depend on those other variants - which sounds like a bad idea - then triggering
test
will trigger them, unless you prevent it for example by changing the dependency configuration, disabling the unintended tasks, or excluding them from the commandline using
-x
.
v
hm why not, essentially in this demo app I have
:app
and
:base
.. app is android application, base is a kotlin jvm module essentially what I want is
Copy code
tasks.register("testDebug") {
	dependsOn ":app:testDebugUnitTest", ":base:test"
}
now just to find a way to generalize this over all modules
Copy code
./gradlew :app:testDebugUnitTest :base:test
this does what I want and is what I'd expect to be already provided but whatever
also, there seems to be
testDebug
already, although I don't see it in
gradlew tasks
but it seems to be just running the app module tests, excluding the base tests
Copy code
tasks.register("testDebug") {
    List<Task> testTasks = []
    allprojects { project ->
        def task = project.tasks.findByName("test")
        if (task != null) { testTasks += task }
    }
    testTasks.each { println it.path }

    dependsOn testTasks
}
does this seem idiomatic way to find a certain task over all modules?
the lookup is I presume done in configuration phase .. is that correct?
v
also, there seems to be
testDebug
already, although I don't see it in
gradlew tasks
It might not have a group assigned, e.g. because it is not intended for manual triggering. Look at
gw tasks --all
to see all tasks.
does this seem idiomatic way to find a certain task over all modules?
Practically all usage of
allprojects
or
subprojects
is non-idiomatic. And it will probably also not work properly. It would require the other projects to be configured first or you will not find the tasks in question. Besides that your
allprojects { ... }
iirc will be a delayed action so directly using the "result" of the closure will also not work. And even if it would work, it would not do what you want, because it would produce the same result as calling
gw test
and you said that this is not what you want to do.
v
yea. I changed it like this
Copy code
tasks.register("testDebug") {
    List<Task> testTasks = []
    allprojects { project ->
        def androidTestTask = project.tasks.findByName("testDebugUnitTest")
        if (androidTestTask != null) {
            testTasks += androidTestTask
        } else {
            def testTask = project.tasks.findByName("test")
            if (testTask != null) {
                testTasks += testTask
            }
        }
    }
    testTasks.each { println it.path }

    dependsOn testTasks
}
now if testDebugUnitTest is available, then it takes it over the "test" which would do all variants yea
this seems to do what I want when ran, but then again I dont know what Im doing 😄
what the issue with
allProjects
? should I rather look for a "subgraph"? i.e. app+all it's dependencies?
v
Any form of cross-project configuration is bad. It introduces project coupling which works against more sophisticated Gradle features like configure-on-demand or
--parallel
or configuration cache, ...
v
Copy code
The following practices should be avoided:

Explicitly depending on a task from another project via Task.dependsOn(java.lang.Object...).
so I read that as exactly this
Copy code
tasks.register("testDebug") {
	dependsOn ":app:testDebugUnitTest", ":base:test"
}
...huh really? isn't that just a plain composition?
v
Well, composition by manually depending on tasks is the problem. 🙂 You usually compose things by publishing things in one project and consuming them from another project. In your case a possible solution might be to just have a
testDebug
task in all projects that depends on
test
in non-android projects and on
testDebugUnitTest
in android projects. Then you could safely run
gw testDebug
and get the tests run you intend. This configuration is optimally done in a "my.android" convention plugin and in a "my.java" convention plugin that you apply to the according projects. 🙂