【问题标题】:In gradle, how to use a variable for a plugin version?在 gradle 中,如何为插件版本使用变量?
【发布时间】:2016-09-30 00:38:27
【问题描述】:

我的一个构建脚本导入了那个 nebula 插件:

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”块,它有效,但似乎必须有一种方法可以在一行中完成这项工作?

【问题讨论】:

    标签: gradle netflix-nebula-plugins


    【解决方案1】:

    你不能在这里使用变量:

    其中 «plugin version» 和 «plugin id» 必须是常量、字面量、 字符串。不允许有其他陈述;他们的存在将导致 编译错误。

    【讨论】:

    【解决方案2】:

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

    例如gradle.properties文件:

    springBootVersion=2.2.0.RELEASE
    

    build.gradle 中的 plugins 块:

    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

    【讨论】:

    • 注意:这适用于 groovy build.gradle,但不适用于 kotlin DSL,build.gradle.kts,尚未支持 kotlin DSL,github.com/gradle/gradle/issues/9830
    • 谢谢!大括号其实不需要,直接放id "org.springframework.boot" version "$springBootVersion"
    • "插件 [id: ...] 未在以下任何来源中找到:"(未在同一目录中找到 gradle.properties 或忽略它)
    【解决方案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
        // ...
    }
    

    【讨论】:

      【解决方案4】:

      总结

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

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

      完整示例

      对于 Android,我可以通过省略 plugin 块中的版本,然后在 buildscript 依赖项中将其指定为 const 来做到这一点。该块允许变量,而插件块只允许字符串文字。从那里,我在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 文件中完成代码!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-01
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多