gradle-resolution-rules-plugin icon indicating copy to clipboard operation
gradle-resolution-rules-plugin copied to clipboard

Android Project Support - Fix manifest merge task being skipped

Open jkasten2 opened this issue 8 years ago • 1 comments

Issue

This plugin is not compatible with Android projects as the com.android.application gradle plugin adds tasks and steps up it's depencies on the project.afterEvaluate event as well. The existing logic on whether to apply rules or not is done by checking config.allDependencies.isEmpty(). This will be empty for the processDebugResources task for example. processReleaseResources is executed when calling the standard build task on an Android project.

Note that ./gradlew app:dependencies --configuration compile works fine, however tasks that do manifest merging fail. For example if we use mismatched versions of the com.android.support group in the main app's build.gradle but try to create an alignment rule to sync them it won't be applied to the processReleaseResources task and following error will throw:

Caused by: java.lang.RuntimeException: Manifest merger failed : Attribute meta-data#android.support.VERSION@value value=(26.0.0) from [com.android.support:appcompat-v7:26.0.0] AndroidManifest.xml:28:13-35
	is also present at [com.android.support:support-v4:26.1.0] AndroidManifest.xml:28:13-35 value=(26.1.0).
	Suggestion: add 'tools:replace="android:value"' to <meta-data> element at AndroidManifest.xml to override.
	at com.android.builder.core.AndroidBuilder.mergeManifestsForApplication(AndroidBuilder.java:509)
	at com.android.build.gradle.tasks.MergeManifests.doFullTaskAction(MergeManifests.java:150)
	at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:106)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$IncrementalTaskAction.doExecute(DefaultTaskClassInfoStore.java:179)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:135)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:122)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
	... 28 more

The following test reproduces this issue. https://github.com/nebula-plugins/gradle-resolution-rules-plugin/pull/58/files#diff-c71d74290a4498733d4ad203fc844abaR393

Solutions

Solution 1

This is the one that is implemented in this pull. Add a delay fallback on the project.gradle.taskGraph.afterTask when the rules are applied. In my testing I found that this is run after the Android plugin sets up the dependencies on it's tasks. Since this doesn't pass all existing tests with the delayed event on it's own we need to keep the project.onExecute event.

Solution 2

Another solution would be to simply remove the config.allDependencies.isEmpty() check. However it looks like this was put into place due to performance reasons.

TODO

  • [x] Investigate if project.onExecute can be delayed so config.allDependencies are fully resolved by any other gradle plugins.
  • [x] Add a unit test reproducing the issue
  • [x] Fix failing "Skipping dependency rules for configuration \':compile\' - No dependencies are configured" test

jkasten2 avatar Oct 13 '17 09:10 jkasten2

@DanielThomas I just completed this pull request, could you give it a review?

This plugin solves a number of common gradle dependency issues and would be a great help to Android developers if they could use it as well! Specifically around having group alignment for the Android Support Library and Google Play Services Library since each includes a number of modules per group.

jkasten2 avatar Oct 16 '17 10:10 jkasten2