Changing default dependency handling of project dependencies


(Igor Berman) #1

Hi, I have multiproject build. I want to change behavior of project dependency for all project dependencies in all subprojects I want to change from :

dependencies {

compile project(’:baseLibrary’) // which is essentially compile project(path: ‘:baseLibrary’, configuration:‘runtime’) } into dependencies {

compile project(path: ‘:baseLibrary’, configuration:‘compile’)

runtime project(path: ‘:baseLibrary’, configuration:‘runtime’) }

but I’ll prefer more precise way to do it instead of replicating each project dependency in two lines

think of base library as having different compile and runtime configurations, e.g. in runtime of projectLibrary there are some dependencies that I don’t want to be present in compile configuration of this project, so I could enforce strict rules regarding what projects can use what dependent projects

Thanks in advace.


(Peter Niederwieser) #2

What exactly is your question?


(davidmichaelkarr) #3

Perhaps Igor will provide more information, but I’ll add an additional question taking his original question at face value.

Is it possible and reasonable to simply have a “post-config” process that looks for all dependencies of project “baseLibrary” and replaces them with two dependencies, in the form he’s looking for above? If so, what would that look like?


(Igor Berman) #4

Hi Peter, can I set somehow in common configuration that if I put compile project(’:baseLibrary’) it somehow will convert into

compile project(path: ‘:baseLibrary’, configuration:‘compile’)

runtime project(path: ‘:baseLibrary’, configuration:‘runtime’)

i.e. compile dependencies of baseLibrary will be in compile configuration and runtime of baseLibrary will be in runtime configuration

and I mean for all project dependencies(baseLibrary is only an example)


(Peter Niederwieser) #5

Typically, you’d do it the other way around - introduce your own dependency notation, and translate that into the notation that Gradle understands.


(Igor Berman) #6

thanks Peter, can you point to some links/examples how to do this kind of translation?

to give some real life scenario: my example is very common in our multiproject, I want to do it as generic as possible usually we have api project and impl project and “some project” that depends on api in compile time and depends on impl at runtime(spring beans that implement some interfaces) due to default behavior any project that depends on “some project” gets at compile configuration impl which is not desirable at all since it breaks encapsulation(might be not intentionally, but anyway)

thanks in advance


(Peter Niederwieser) #7

No, this isn’t possible.


(Peter Niederwieser) #8

First concepts to understand is extensions and ‘NamedDomainObjectContainer’. Information on these can be found in the Gradle User Guide, Gradle Build Language Reference, and the samples in the full Gradle distribution.


(Igor Berman) #9

Peter, am I in a right direction? allprojects { configurations{

service } afterEvaluate { p ->

p.configurations.each { c ->

if(c.name == ‘service’) {

c.dependencies.withType(org.gradle.api.artifacts.ProjectDependency.class).each{ d ->

println d

//p.configurations.compile.dependencies.add(‘compile’, d.dependencyProject)

//p.configurations.runtime.dependencies.add(‘runtime’, d.dependencyProject)

}

}

}

} } and usage: dependencies {

service project(’:baseLibrary’) }

the only problem with this - I don’t know how to construct Project dependency at runtime


(Igor Berman) #10

this one works

allprojects {
 apply plugin: ServicePlugin
   configurations {
  service
 }
}
  class ServicePlugin implements Plugin<Project> {
    void apply(Project theProject) {
  theProject.configurations.whenObjectAdded{o ->
   if (o.name.contains('service')){
    o.dependencies.whenObjectAdded{ d ->
     theProject.dependencies {
      println "adding dependency"
      compile
project(path: ":"+d.dependencyProject.name, configuration: 'compile')
      compile
project(path: ":"+d.dependencyProject.name, configuration: 'archives')
      runtime
project(path: ":"+d.dependencyProject.name, configuration: 'runtime')
      runtime
project(path: ":"+d.dependencyProject.name, configuration: 'archives')
     }
    }
   }
  }
    }
}

settings.gradle include ‘app’ include ‘library’ include ‘baseLibrary’ include ‘util’

app:build.gradle apply plugin: ‘java’ apply plugin: ‘application’

mainClassName=“com.example.android.multiproject.MainActivity” dependencies {

service project(’:library’) } library:build.gradle apply plugin: ‘java’

dependencies {

service project(’:baseLibrary’) } baseLibrary:build.gradle apply plugin: ‘java’

dependencies {

runtime project(’:util’) }

gradle :app:dependencies :app:dependencies

------------------------------------------------------------ Project :app ------------------------------------------------------------

archives - Configuration for archive artifacts. No dependencies

compile - Compile classpath for source set ‘main’. — project :library

— project :baseLibrary

default - Configuration for default artifacts. — project :library

— project :baseLibrary

— project :util

runtime - Runtime classpath for source set ‘main’. — project :library

— project :baseLibrary

— project :util

service — project :library

— project :baseLibrary

— project :util

testCompile - Compile classpath for source set ‘test’. — project :library

— project :baseLibrary

testRuntime - Runtime classpath for source set ‘test’. — project :library

— project :baseLibrary

— project :util

gradle :app:distZip also works - puts into jars(runtime and compile time)


(Igor Berman) #11

this topic is connected to my quesiton http://forums.gradle.org/gradle/topics/why_does_a_compile_project_dependency_use_the_default_configuration_by_default