How to know which project is running in gradle - android

I have multiple projects and one trunk...
Some times I need to run via cmd:
gradlew Proj1:assembleRelease
And other times:
gradlew Proj2:assembleRelease
How can I in gradle file know what is building Proj1 or Proj2?

You can access this information via the gradle property on any instance of Project. From the docs:
getGradle()
Returns the Gradle invocation which this project belongs to.
The instance of Gradle provides the startParameter property, which contains the information you want. For example, in the root scope:
print project.gradle.startParameter
For my particular invocation, I could print the name of the first task request via
print project.gradle.startParameter.taskRequests[0].args[0]
However, the above is probably quite fragile and will surely fail in a number of important cases.
There are also many other things you may find useful in the Gradle instance, if the above doesn't do exactly what you want, such as the task execution graph and root project for this build. Note that all the above information is available by following links from the documentation for the Project class, which I linked above. I strongly recommend that you peruse this documentation.
On the other hand, why do you want to do this? Usually you would just add configuration to the individual projects themselves and let the task runner take care of running your specific implementations, rather than saying if task1 is running then x else y

Related

Turn android lintVitalAnazlyzeRelease of for jar projects we bring in from gradle?

We ran into some bug in linVitalAnaylzeRelease
* What went wrong:
Execution failed for task ':app:lintVitalAnalyzeRelease'.
> java.lang.NullPointerException (no error message)
We narrowed it down to the fact we are using gradle composite builds and
Our android build brings in ../../java/libraries/apis/orders-api project
../../java/libraries/apis/orders-api project bring in ../common project via an api dependency so android project can use it.
orders-api is a simple interface and many simple POJO DTOs, nothing else, no business logic, nothing. common project was only Orders.java file simple DTO and nothing else.
I am wondering if we can turn off lintVitalAnalyzeRelease for downstream jar files somehow and only run that on the android project class files?
NOTE: I even deleted ALL *.java files from common project and then references to those objects in orders-api project as well and I still get the NullPointerException.
If I have orders-api stop depending on common, this also fixes the nullpointer but we ideally have a few things like Order.java we re-use in different apis so in microservices this then allows us to pass that Order form one api to another api.

Multi-module gradle project - Executing all Unit tests

Our current set-up looks like this: One root-project with nine sub-modules, which are mixed between pure Java libraries and Android libraries.
Each of the modules contains features, one of the modules is the main module which builds the Android app by merging all required modules.
Each of the modules contains a lot of unit tests, and I'd like to execute them all in one gradle step. Right now I'm using gradlew test for this, but since (for example) the main module has multiple product flavors it is executing the unit tests in this module multiple times (for each flavor).
Ideally, I'd like to only execute the main module unit tests once, for a certain flavor and signing configuration, but since the testFlavorDebug tasks are created while evaluating the project (as far as I know) I cannot define this before actually executing the evaluation.
I've tried to find the tasks in afterEvaluate blocks, I've tried to loop over all modules, different combinations and ways, but I can't seem to figure out how to properly set this up.
I'd be glad if someone has some pointers or experience with a set-up like this and could help me out. If you require additional information, let me know and I'll supply them, but as far as the project set-up it's pretty straight forward in regards to the multi-module setting.
You can override the test method in your main module's build.gradle to only run the one time

How can I view the CLI command executed by a Gradle task in Android Studio?

I'm trying to get a better picture of what happens behind the scenes in Android Studio when building an Android application. I've been reading up on Gradle, but one thing I cannot figure out is how to see the respective CLI command and arguments that is being invoked by Gradle. It seems to be abstracted and not logged to the Gradle Console or Event Log.
The closest I've gotten to seeing what's going on inside Gradle is the AOSP code.
2.2.2 Source:
https://android.googlesource.com/platform/tools/base/+/gradle_2.2.2/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks
Goals
I want to be able to see the respective CLI command that is generated by the Gradle tasks inside Android Studio.
Use Case Example
I want to view the Legacy Android Build Process in depth. This includes going through the following:
Source Code / Library Code -> javac -> Java bytecode (.class) -> proguard -> minimized bytecode (.class) -> dex -> DEX bytecode (.dex)
For example I would want to see the respective javac command invoked by AndroidJavaCompile. https://android.googlesource.com/platform/tools/base/+/gradle_2.2.2/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/factory/AndroidJavaCompile.java
I fear that the only way to do this is to look directly through source code or even build directly from source.
Due Diligence
I've done quite a bit of searching on Google, Android blogs, Google I/O talks, Android books, and much more. I haven't been able to find a straight-forward answer.
That's not possible. Simply, because most of the Gradle tasks do not invoke CLI commands.
Every Gradle build file is a piece of Groovy code that gets executed in a JVM along with the Gradle API (written in Java). Therefor, you can implement any task or configuration functionality directly in any JVM language, from which most plugins make use of instead of executing command line tools. Nevertheless, this is possible by using or extending the Exec task.
The compilation step is handled by a AndroidJavaCompile task, which extends the common JavaCompile Gradle task by some version checks and the Instant Run feature. However, you don't know how Gradle actually compiles the .java files. In the internal source files for the JavaCompile task of the Gradle API, there seem to be various implementations (DaemonJavaCompiler, JdkJavaCompiler and even CommandLineJavaCompiler). Since you can specify CompilerOptions with your task, Gradle seems to choose the real compiler based on these options. Please note, that even if a CommandLineJavaCompiler exists, it is also possible (and highly likely), that Gradle prefers to use the javax.tools package and its JavaCompiler implementation to compile the source files instead of invoking a command line tool.
I also took a look on the ProGuard step in your example build process: ProGuard can be used as command line tool, where you can specify arguments to define how it'll work. But ProGuard also provides a Gradle task (ProGuardTask), that executes without invoking ProGuard from command line. The ProGuard Java code will be executed in the Gradle JVM.
As you can see, even if each Gradle task may be replaced by one (or multiple) CLI command(s), Gradle does not execute these commands. Instead, the functionality is called directly in the Gradle JVM. If you want to get a better insight, you can increase the Gradle log level. Good implementations of Gradle tasks should provide all necessary information in logs.

what exactly is "configuration on demand" in Gradle?

I recently changed some settings in Gradle to speed up its process and one of them was changing this: org.gradle.configureondemand=true property in gradle.properties file.
I know you can guess a lot from the words "configuration on demand", but I wanna know the exact impact of this feature? Do I have to do something to trigger configuration if I set this argument as true?
Can something go wrong if I set it as true ?
What configuration phase exactly is?
This setting is relevant only for multiple modules projects. Basically, it tells Gradle to configure modules that only are relevant to the requested tasks instead of configuring all of them, which is a default behaviour.
To answer more precisely to your questions:
No, you don't have to trigger configuration manually.
Yes, something could go wrong as stated in the documentation. The
feature should work very well for multi-project builds that have
decoupled projects.
In “configuration on demand” mode, projects are configured as follows:
The root project is always configured. This way the typical common configuration is supported (allprojects or subprojects script blocks).
The project in the directory where the build is executed is also configured, but only when Gradle is executed without any tasks. This way the default tasks behave correctly when projects are configured on demand.
The standard project dependencies are supported and makes relevant projects configured. If project A has a compile dependency on project B then building A causes configuration of both projects.
The task dependencies declared via task path are supported and cause relevant projects to be configured. Example: someTask.dependsOn(:someOtherProject:someOtherTask)
A task requested via task path from the command line (or Tooling API) causes the relevant project to be configured. For example, building projectA:projectB:someTask causes configuration of projectB.
Here is the full documentation.

android gradle run assemble after tests pass

I'm trying to fire off various android based gradle tasks e.g. assemble, after 'gradle clean test' is run.
Some background...
My company has jenkins and it is managed by a separate team so I don't have access to configure it myself. On any changes to the remote repo (git) a jenkins job will fire, running gradle clean test and using a build.gradle file that we have inside our repo.
I'm told that this is the only command that the build team will provide and if I want any further actions running, I'll have to configure them inside the build.gradle script.
I am imagining that I can possibly do something like afterTest(:assemble) or maybe addTestListener() but I can't seem to find any examples on google.
Can anyone here help me? Is this even possible or should I ask my build team to allow me to run a diff gradle task depending on what I want?
Configuring CI jobs uniformly is a good idea. However, there is no good way to have additional independent tasks executed when gradle clean test is run. They'd have to at least run gradle clean build so that you can add tasks with build.dependsOn(myTask). (However, keep in mind that build already depends on assemble.) Or they run a custom task such as gradle (clean) ciBuild which by default only depends on test, and to which further task dependencies can be added as necessary.

Categories

Resources