Search code examples
mavengradleandroid-studiopom.xmlandroid-gradle-plugin

Optional Gradle dependencies for Maven libraries


I'm working on an Android library and would like to use a dependency only if the project using my library includes that dependency as well. Similar to what Picasso does with OkHttp.

I already took care of this on the main code by checking for ClassNotFoundExceptions but it still includes the dependencies upon deploying it to Maven Central. How do I generate something such as Maven's <optional>true</optional> tag?

I'm using gradle-mvn-push to deploy my artifacts via Gradle.


Solution

  • Vote for GRADLE-1749.

    In the mean time you can use pom.withXml approach to modify the generated pom file, for example to add <optional> tags or change <scope>values:

    apply plugin: 'java'
    apply plugin: 'maven-publish'
    
    configurations {
      optional
      compile.extendsFrom optional
    }
    
    dependencies {
      compile 'com.some.group:artifact:1.0';
      optional 'com.another.group:optional-artifact:1.0'
    }
    
    publishing {
      publications {
        maven( MavenPublication ) {
          from components.java
    
          pom.withXml {
            asNode().dependencies.dependency.findAll { xmlDep ->
              // mark optional dependencies
              if ( project.configurations.optional.allDependencies.findAll { dep ->
                xmlDep.groupId.text() == dep.group && xmlDep.artifactId.text() == dep.name
              } ) {
                def xmlOptional = xmlDep.optional[ 0 ];
                if ( !xmlOptional ) {
                  xmlOptional = xmlDep.appendNode( 'optional' )
                }
                xmlOptional.value = 'true';
              }
    
              // fix maven-publish issue when all maven dependencies are placed into runtime scope
              if ( project.configurations.compile.allDependencies.findAll { dep ->
                xmlDep.groupId.text() == dep.group && xmlDep.artifactId.text() == dep.name
              } ) {
                def xmlScope = xmlDep.scope[ 0 ];
                if ( !xmlScope ) {
                  xmlScope = xmlDep.appendNode( 'scope' )
                }
                xmlScope.value = 'compile';
              }
            }
          }
        }
      }
    }