Как применить плагин только к одному аромату в Gradle?

У меня есть многоуровневый андроид-проект со множеством сборок, и я хочу интегрировать плагин NewRelic. Но я должен применять его только для одного из клиентов, то есть только для одного продукта.
NewRelic использует инструментарий, и плагин генерировал бы код в других вариантах, если бы я применил плагин там, и это нам не разрешено.

Итак, мой вопрос: как я могу использовать apply plugin: something команда в файле Gradle, которая будет применена только к одному из моих ароматов?

7 ответов

Используйте этот код:

if (!getGradle().getStartParameter().getTaskRequests()
        .toString().contains("Develop")){
    apply plugin: 'com.google.gms.google-services'
}

getGradle().getStartParameter().getTaskRequests().toString() возвращает что-то вроде [DefaultTaskExecutionRequest{args=[:app:generateDevelopDebugSources],projectPath='null'}] так как указано в комментариях Develop должен начинаться с заглавной буквы.

Пробовал разные решения, но ни одно из них не помогло мне. Это то, что я придумал и, кажется, работает, насколько я тестировал:

build.gradle

productFlavors {
    someFlavorWithGoogleGcm {
        dimension "type"
        applicationId "com.example.withGcm"
        ext.useGoogleGcm = true
    }
    someFlavorWithoutGoogleGcm {
        dimension "type"
        applicationId "com.example.withoutGcm"
    }
}

И вне конфигурации, внутри build.gradle файл:

android.productFlavors.each { flavor ->
    if (getGradle().getStartParameter().getTaskRequests().toString().toLowerCase().contains(flavor.name) && flavor.ext.useGoogleGcm) {
        println("Building flavor with Google GCM [${flavor.name}] - applying plugin")
        apply plugin: 'com.google.gms.google-services'
    }
}

Я просто использовал apply plugin: 'com.google.gms.google-services' внутри аромата на уровне приложения build.gradle, и он отлично работает.

productFlavors {
    ..... your other flavors ....
    yourFlv {
        ....
        ....
        apply plugin: 'com.google.gms.google-services'
    }
}

Никаких дополнительных шагов не требуется.

  1. Определить переменную - def fl
  2. Инициализируйте переменную в ваших Flavors (и / или builds)

        productFlavors {
    
                freeFlavour {
                    (...)
                    fl = "free"
                }
    
                paidFlavour {
                    (...)
                    fl = "paid"
                }
            }
    
  3. Используйте оператор if -

    if (fl == "free") { apply plugin: something }

Я нашел решение, но оно пока не самое лучшее. Так что я больше не уверен, что то, что я хотел сделать изначально, возможно. Оценка файла Gradle и выбор правильного варианта и типа сборки находятся на разных этапах сборки Gradle, поэтому я сделал следующее:

Я использую параметр сборки из командной строки. Когда этот параметр имеет значение true, я применяю плагин, когда его даже нет, я также применяю его (для сборки IDE). Я использую Jenkins, чтобы я мог записать этот параметр в задании на сборку.

файл build.gradle:

// First we have to attach a task to the project, which will be running first
gradle.projectsEvaluated {
    preBuild.dependsOn(applyNewRelicByProperty)
}

// Then check on the parameter, which comes from the command line
task applyNewRelicByProperty {
    if(!project.hasProperty('compileNewRelic')) {
        // NewRelic on: 'compileNewRelic' property not set, so running from IDE.
        apply plugin: 'newrelic'
    } else if(project.hasProperty('compileNewRelic') && project.getProperties().get('compileNewRelic').equals('true')) {
        // NewRelic on: 'compileNewRelic' property is set and it is 'true'.
        apply plugin: 'newrelic'
    } else {
        // NewRelic off
        println("No NewRelic")
    }
}

И вы должны запустить сборку gradle следующим образом:

assembleYourApp -PcompileNewRelic=true

После обновления до Gradle 4.2 подход Tarps перестал работать, поэтому в итоге я объединил его с ответом Эрика.

Задавать ext.useGoogleGcm для каждого аромата в вашем build.gradle:

      productFlavors {
    a {
        ...
        ext.useGoogleGcm = true
    }
    b {
        ...
        ext.useGoogleGcm = false
    }
}

Затем внизу файла:

      apply plugin: 'com.google.gms.google-services'

afterEvaluate {
    android.productFlavors.each { flavor ->
        tasks.matching {
            it.name.contains('GoogleServices') && it.name.contains(flavor.name.capitalize())
        }*.enabled = flavor.ext.useGoogleGcm
    }
}

На выходе для вашего assembleReleaseзадача, вы должны увидеть, что задачи с "GoogleServices" в названии выполнены для тех, которые являются истинными, и пропущены для тех, которые являются ложными. Если ваша сборка жалуется на toCapitalize, вы могли бы использовать toLowerCase на обоих it.name и flavor.name.

В случае плагина Google Services Gradle работает следующее.

      apply plugin: 'com.google.gms.google-services'

afterEvaluate {
    tasks.matching { it.name.contains("GoogleServices") && !it.name.contains(yourFlavorName) }*.enabled = false
}

где - строка с заглавной буквы, содержащая название вашего вкуса, к которому должен применяться плагин; все другие разновидности не используют плагин.

Обратите внимание, что плагин по-прежнему применяется к другим разновидностям; это решение просто отключает *GoogleServices*задачи для них. Это предполагает, что плагин Google Services Gradle применяет изменения только путем добавления задачи, содержащей подстроку "GoogleServices", который может не работать в будущем.

Чтобы убедиться, что это работает, вы можете проверить зависимости, например, вот так:

./gradlew app:dependencyInsight --configuration yourFlavorNameDebugCompileClasspath --dependency google | grep -i services

Это должно показать некоторые зависимости для yourFlavorName но не для других названий ароматов:

./gradlew app:dependencyInsight --configuration otherFlavorNameDebugCompileClasspath --dependency google | grep -i services

Другие вопросы по тегам