在gradle中,如何将变量用于插件版本?

时间:2016-05-31 20:37:22

标签: gradle netflix-nebula-plugins

我的一个构建脚本导入了这个星云插件:

plugins {
  id 'nebula.ospackage' version '3.5.0'
}

我一直在将所有版本信息移动到一个所有项目都可以访问的单独文件中,并且想知道转换为以下内容的正确语法是什么:

plugins {
  id 'nebula.ospackage' version "$versions.nebula_gradle_ospackage_plugin"
}

当我尝试使用" gradle clean build"运行上面的操作时,我收到以下错误:

  

构建文件' build.gradle':2:参数列表必须正好是1个字面值   非空字符串

     

请参阅   https://docs.gradle.org/2.7/userguide/plugins.html#sec:plugins_block   有关插件{}阻止

的信息      

@第2行,第33栏。          id' nebula.ospackage'版本" $ versions.nebula_gradle_ospackage_plugin"

链接文章展示了我如何使用" buildscript"阻止,这是有效的,但似乎必须有一种方法使这项工作在一行?

4 个答案:

答案 0 :(得分:31)

你不能在这里使用变量:

  

其中«插件版本»和«插件ID»必须是常量,字面,   字符串。不允许其他陈述;他们的存在会导致一个   编译错误。

答案 1 :(得分:3)

这是旧文章,但the bug仍然开放,我发现这篇文章正在寻找解决方法。

您似乎已经意识到这一点,并且实际上拥有BoygeniusDexter's answer,但是我认为这可能会帮助其他人像我一样找到这篇文章。以下变通办法基于Gradle docs,并为我解决了该问题:

buildscript {
    ext {
        springBootVersion = '2.0.4.RELEASE'
    }
    repositories {
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

plugins {
    id 'java'
    // and other plugins
    id 'io.spring.dependency-management' version '1.0.6.RELEASE'
}
// but the one with the variable version is applied the old way:
apply plugin: 'org.springframework.boot'

// We can use the variable in dependencies, too:
dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
    // ...
}

答案 2 :(得分:1)

从Gradle 5.6开始,您可以在gradle.properties文件中声明插件版本,并在plugins块中引用这些属性。

例如gradle.properties文件:

springBootVersion=2.2.0.RELEASE

plugins中的build.gradle块:

plugins {
    id "org.springframework.boot" version "${springBootVersion}"
}

请参阅:https://github.com/gradle/gradle/issues/1697#issuecomment-506910915

另请参阅:

  1. https://docs.gradle.org/5.6/release-notes.html#central-management-of-plugin-versions-with-settings-script
  2. https://docs.gradle.org/5.6/userguide/plugins.html#sec:plugin_management

答案 3 :(得分:1)

摘要

  1. plugin块中省略版本
  2. 代替,在buildscript.dependencies块中移动/指定版本
  3. that 块中使用一个const变量

简而言之,plugin块需要字符串文字或属性,而dependency块则允许变量。最初的问题要求“单行”执行此操作,并且使用这种方法,您的插件块会更短,并且所有模块的所有依赖项都放在一个位置。根据您的目标,这可能比“一行”做所有事情要好。

完整示例

对于Android,我可以通过从plugin块中省略版本,然后在buildscript依赖项中将其指定为const来实现。该块允许变量,而plugin块仅允许字符串文字。从那里开始,我在buildSrc中使用一个对象,因为它提供了最大的灵活性,同时将所有模块的所有依赖项信息保留在一个文件中。所以我的设置看起来像这样:

├── project/
│   ├── build.gradle
|   └── app/
|       └── build.gradle
|   └── buildSrc/
|       └── build.gradle.kts
|       └── src/main/java/com/example/package/Deps.kt

从那里开始,要在一个位置将任何插件版本指定为变量,app/build.gradle文件将省略该版本(以kotlin为例,但对任何插件都适用相同的方法):

app / build.gradle
plugins {
    id 'kotlin-android' // omit version property here but provide it in buildscript dependencies
    ...
}
...
dependencies {
    ...
    // Dagger
    implementation Deps.Dagger.ANDROID_SUPPORT
    kapt Deps.Dagger.ANDROID_PROCESSOR
    kapt Deps.Dagger.COMPILER
}

然后,buildscript依赖项部分(通常在父build.gradle文件中,但也可以在同一文件中)提供使用变量的版本!

project / build.gradle
import com.example.package.Deps // object in the buildSrc folder with all version info
buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Deps.kotlinVersion}"
    }
}

最后,所有版本信息都在buildSrc中管理,Deps.kt文件中有一个对象(关于在Android项目中使用buildSrc的博客很多文章):

Deps.kt
object Deps {
    // For use in the top-level buildscript dependency section which only works with a constant rather than `Deps.Kotlin.version`
    const val kotlinVersion = "1.3.72"

    object Kotlin :             Version(kotlinVersion) {
        val STDLIB =            "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version"
    }

    object Dagger :             Version("2.25.2") {
        val ANDROID_SUPPORT =   "com.google.dagger:dagger-android-support:$version"
        val ANDROID_PROCESSOR = "com.google.dagger:dagger-android-processor:$version"
        val COMPILER =          "com.google.dagger:dagger-compiler:$version"
    }

}
open class Version(@JvmField val version: String)

总的来说,我真的很喜欢这个设置。它非常灵活,所有依赖项信息都放在一个地方,甚至可以跨多个模块,而且最重要的是,当键入依赖项时,它可以在gradle文件中完成代码!