Gradle - загрузка зависимостей, блокировка версий и зависимостей обновления вручную

Проблема.

Gradle управление зависимостями сделало так:

  • нет простого способа проверить наличие обновлений зависимостей (используйте только сторонние плагины, такие как ben-manes/gradle-versions-plugin) и загрузите обновления старые версии;
  • артефакты зависимостей загружаются из удаленных репозиториев, а затем сохраняются в кеше gradle и повторно используются в последующих строках; но успешная компиляция вашего проекта не должна зависеть от подключения к Интернету, наличия удаленных репозиториев и наличия определенных версий зависимостей в этих хранилищах.

Цель.

  • загружать и хранить все артефакты зависимостей в VCS;
  • вручную проверяйте обновления для этих зависимостей и загружайте их.

Ответ 1

Мое решение работает для конфигурации Gradle с помощью плагинов java или android.

java плагин определяет конфигурации compile и testCompile. compile предназначен для зависимостей, необходимых для компиляции источника проекта. testCompile предназначен для зависимостей, необходимых для компиляции источника тестирования проекта.

Определим наши собственные конфигурации в build.gradle:

configurations {
    download
    testDownload
}

Далее создадим каталоги:

  • libs/compile/downloaded где download будут сохранены зависимости:
  • libs/testCompile/downloaded где testDownload будут сохранены зависимости.

Далее мы определяем несколько задач.

Удалить зависимости из download конфигурации:

task cleanDownloadedDependencies(type: Delete) {
    delete fileTree('libs/compile/downloaded')
}

Удалить зависимости из testDownload конфигурации:

task cleanDownloadedTestDependencies(type: Delete) {
    delete fileTree('libs/testCompile/downloaded')
}

Загрузка зависимостей из download конфигурации:

task downloadDependencies(type: Copy) {
    from configurations.download
    into "libs/compile/downloaded/"
}

Загрузка зависимостей из testDownload конфигурации:

task downloadTestDependencies(type: Copy) {
    from configurations.testDownload
    into "libs/testCompile/downloaded/"
}

Выполните все описанные выше задачи для обновления зависимостей:

task updateDependencies {
    dependsOn cleanDownloadedDependencies, cleanDownloadedTestDependencies, downloadDependencies, downloadTestDependencies
}

Далее мы определяем наши зависимости:

dependencies {
    download(
            'com.google.code.gson:gson:+',
            'joda-time:joda-time:+',
    )
    testDownload(
            'junit:junit:+'
    )

И затем мы расскажем, где compile и testCompile конфигурации должны принимать зависимости, используемые для компиляции.

    compile fileTree(dir: 'libs/compile', include: '**/*.jar')
    testCompile fileTree(dir: 'libs/testCompile', include: '**/*.jar')
}

Теперь вы можете загружать или обновлять уже загруженные зависимости:

./gradlew updateDependencies

Если вы используете плагин android, вы также можете добавить конфигурацию androidTestDownload для зависимостей, необходимых для компиляции и запуска тестов на Android-устройстве. Также некоторые зависимости могут быть представлены как aar артефакты.

Это пример конфигурации Gradle с использованием плагина android:

...

repositories {

    ...

    flatDir {
        dirs 'libs/compile', 'libs/compile/downloaded',
                'libs/testCompile', 'libs/testCompileDownloaded',
                'libs/androidTestCompile', 'libs/androidTestCompile/downloaded'
    }
}

configurations {
    download
    testDownload
    androidTestDownload
}

android {
    ...
}

dependencies {
    download(
            'com.android.support:support-v4:+',
            'com.android.support:appcompat-v7:+',
            'com.google.android.gms:play-services-location:+',
            'com.facebook.android:facebook-android-sdk:+',
            'com.vk:androidsdk:+',
            'com.crashlytics.sdk.android:crashlytics:+',
            'oauth.signpost:signpost-core:+',
            'oauth.signpost:signpost-commonshttp4:+',
            'org.twitter4j:twitter4j-core:+',
            'commons-io:commons-io:+',
            'com.google.code.gson:gson:+',
            'org.jdeferred:jdeferred-android-aar:+'
    )
    compile fileTree(dir: 'libs/compile', include: '**/*.jar')
    testCompile fileTree(dir: 'libs/testCompile', include: '**/*.jar')
    androidTestCompile fileTree(dir: 'libs/androidTestCompile', include: '**/*.jar')
}


task cleanDownloadedDependencies(type: Delete) {
    delete fileTree('libs/compile/downloaded')
}

task cleanDownloadedTestDependencies(type: Delete) {
    delete fileTree('libs/testCompile/downloaded')
}

task cleanDownloadedAndroidTestDependencies(type: Delete) {
    delete fileTree('libs/androidTestCompile/downloaded')
}

task downloadDependencies(type: Copy) {
    from configurations.download
    into 'libs/compile/downloaded/'
}

task downloadTestDependencies(type: Copy) {
    from configurations.testDownload
    into 'libs/testCompile/downloaded/'
}

task downloadAndroidTestDependencies(type: Copy) {
    from configurations.androidTestDownload
    into 'libs/androidTestCompile/downloaded/'
}

task updateDependencies {
    dependsOn cleanDownloadedDependencies, cleanDownloadedTestDependencies, cleanDownloadedAndroidTestDependencies, downloadDependencies, downloadTestDependencies, downloadAndroidTestDependencies
}

fileTree(dir: 'libs/compile', include: '**/*.aar')
        .each { File file ->
    dependencies.add("compile",
            [name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}

fileTree(dir: 'libs/testCompile', include: '**/*.aar')
        .each { File file ->
    dependencies.add("testCompile",
            [name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}

fileTree(dir: 'libs/androidTestCompile', include: '**/*.aar')
        .each { File file ->
    dependencies.add("androidTestCompile",
            [name: file.name.lastIndexOf('.').with { it != -1 ? file.name[0..<it] : file.name }, ext: 'aar'])
}