Raymond
Raymond

Reputation: 2372

Gradle transitive repositories and credentials

The Situation

I have multiple Android plugins using JFrog Bintray. These are all located in a different maven Repository. All of there are private repositories and therefor need to be authenticated before resolving these dependencies. There is project A and project B which are being developed internally and also a project C which is developed by a third party, which needs to implement Project B as a dependency, which in turn has a dependency on project A. For project A there will be a bintray user 1 which is granted authority to project A. There will also be a bintray user 2 for the third party to authenticate them for project B.

In project B there is a dependency on project A like so:

repositories {
    jcenter()

    maven {
        credentials {
            username = 'bintrayUser1'
            password = 'bintrayAPIKeyForUser1'
        }
        url  "https://url-to-projectA"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.project:A:1.0.0'
}

Now there is another project C which has a dependency on Project B like so:

allprojects {
    repositories {
        jcenter()
        maven {
            url "https://link-to-projectB"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.project:B:1.0.0'
}

The problem

The problem that occurs is that bintray user 2 is asked to tell Project C where Project A is and needs to authenticate for it. I am wondering if it is possible that bintray user 2 does not need to tell Project C where Project A is located and instead copy it over from Project B.

The same goes for the authentication. Is there a way bintray user 2 can copy over the authentication from bintray user 1 for Project A?

The nonpreferred solution

Now what I could do is have project C also tell the location for each dependency in project B, but this doesn't scale well. This would be that each private dependency that I would put into project B, project C would need to locate and need authentication to. It would look something like this:

allprojects {
    repositories {
        jcenter()
        maven {
            url "https://link-to-projectA"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
        maven {
            url "https://link-to-projectB"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
        maven {
            url "https://link-to-projectX"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
        maven {
            url "https://link-to-projectX"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
        maven {
            url "https://link-to-projectX"
            credentials {
                username = 'bintrayUser2'
                password = 'bintrayAPIKeyForUser2'
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.project:B:1.0.0'
}

This would become hard to manage and something you might not want to give bintray user 2 authority to.

So again, is there a way to copy over the dependency locations and authorization?

Upvotes: 1

Views: 871

Answers (1)

Gabriele Mariotti
Gabriele Mariotti

Reputation: 364654

You have to use the "nonpreferred solution".

When Gradle builds the projectC it donwloads from maven the dependency compile 'com.project:B:1.0.0'.

With the dependency ,it downloads also the pom file which contains the nested dependency com.project:A:1.0.0. Then it tries to download the dependency from the repositories you have added in the projectC/build.gradle (or top level).
In this moment gradle doesn't use the projectB/build.gradle, but only uses the pom file.

It means that gradle can't know the credentials to download the dependency wihtout addind them in the projectC/build.gradle file.

Upvotes: 4

Related Questions