Splitties / refreshVersions

Life is too short to google for dependencies and versions
https://splitties.github.io/refreshVersions/
MIT License
1.65k stars 107 forks source link

Configuring plugins versions #60

Closed sigurdurrafn closed 5 years ago

sigurdurrafn commented 5 years ago

To apply a plugin, we can use the plugins DSL https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block

plugins {
  id 'com.github.jk1.dependency-license-report' version '1.9'
}

The problem is replacing the hard-coded version 1.9 with Versions.gradle_license_report does not work for Groovy files.

Is there a workaround to be able to use buildSrcVersions for managing plugin dependencies as well as Library dependencies?

This is already done for the special case of buildSrcVersions itself (https://github.com/jmfayard/buildSrcVersions/issues/47) , although that only works in .kts files.

plugins {
-  id("de.fayard.buildSrcVersions") version "0.4.2"
+ buildSrcVersions
}
jmfayard commented 5 years ago

Hello, this is a good question. I don't really get why this works in Kotlin but not in Groovy.

plugins {
  id 'com.github.jk1.dependency-license-report' version Versions.dependency_license_report
}

The generated version is a static string

image

I wonder if in Groovy this is compiled to Versions.INSTANCE.dependency_license_report

jmfayard commented 5 years ago

@sigurdurrafn If you are using Gradle 5.6 or have the possibility to update, I would recommend to try the new Plugins version Management feature

https://docs.gradle.org/5.6/userguide/plugins.html#sec:plugin_management

// settings.gradle
pluginManagement {
  plugins {
      id 'com.github.jk1.dependency-license-report' version Versions.gradle_license_report
    }
}
sigurdurrafn commented 5 years ago

Yes, moving to 5.6 helps. I can now use Versions.kt for the version.

It would be nice if we were also able to use a const for the library name:

 id Paths.dependency-license-report version Versions.gradle_license_report

but this solves my main concern, thanks!

jmfayard commented 5 years ago

Good to know! I edited your ticket so that it can serve as documentation for people facing the same issue.

It would be nice if we were also able to use a const for the library name: id Paths.dependency-license-report version Versions.gradle_license_report

Maybe we can generate code that helps with this if we detect that Versions.currentGradleVersion >= 5.6. I will have to think about it.

nkiesel commented 5 years ago

Yeah!

Just switched to Gradle 5.6.2 in my ever-lasting quest not to repeat myself. My build.gradle files (I have a multi-project build) now contain id "com.github.voplex95.lesscompiler" and the top-level settings.gradle contains id "com.github.voplex95.lesscompiler" version Versions.com_github_voplex95_lesscompiler_gradle_plugin.

The next big step forward would be to replace the repeated "com.github.voplex95.lesscompiler". This string is of course already contained in Libs.com_github_voplex95_lesscompiler_gradle_plugin. Perhaps it can be moved into a separate object like the Paths.com_github_voplex95_lesscompiler_gradle_plugin and then used in Libs.kt?

Actually, I have not yet found a use for the Libs constants for Gradle plugins. Is there any?

jmfayard commented 5 years ago

Perhaps it can be moved into a separate object like the Paths.com_github_voplex95_lesscompiler_gradle_plugin and then used in Libs.kt?

Yes, a solution similar to this: https://github.com/jmfayard/buildSrcVersions/issues/61

Actually, I have not yet found a use for the Libs constants for Gradle plugins. Is there any?

I don't think so, but they are inclueded in the report.json that I use as a source.

jmfayard commented 5 years ago

If someone wants to work on this, I think we can copy the solution from here https://github.com/icerockdev/moko-mvvm

nkiesel commented 5 years ago

Hmm, I took a peek at that and can't see the connection. Perhaps because I can't read Cyrillic?

jmfayard commented 5 years ago

They do this:

// settings.gradle.kts
pluginManagement {
    resolutionStrategy.eachPlugin {
        val module = Plugins.map[requested.id.id] ?: return@eachPlugin
        useModule(module)
    }
}

// buildSrc/src/main/kotlin/Plugins.kt

object Plugins {
    const val android =
        "com.android.tools.build:gradle:${Versions.Plugins.android}"
    const val kotlin =
        "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.Plugins.kotlin}"
    const val androidExtensions =
        "org.jetbrains.kotlin:kotlin-android-extensions:${Versions.Plugins.androidExtensions}"

    val map: Map<String, String> = mapOf(
        "com.android.application" to Plugins.android,
        "com.android.library" to Plugins.android,
        "org.jetbrains.kotlin.multiplatform" to Plugins.kotlin,
        "kotlin-kapt" to Plugins.kotlin,
        "kotlin-android" to Plugins.kotlin,
        "kotlin-android-extensions" to Plugins.androidExtensions
    )
} 
vlsi commented 5 years ago

Here are my 2c.

gradle.properties:

com.gradle.plugin-publish.version=0.10.1

settings.gradle.kts:

fun PluginDependenciesSpec.idv(name: String) =
  id(name) version (extra["$name.version"] as String)

pluginManagement {
    plugins {
        idv("com.gradle.plugin-publish")
    }
}

idv stands for id+version So it looks like a regular plugin declaration. The version is taken from gradle.properties. Plugin version could be overridden via -P... and so on.

vlsi commented 5 years ago

Hmm, I took a peek at that and can't see the connection. Perhaps because I can't read Cyrillic?

@nkiesel ,

The plugin-relevant bits there are

https://github.com/icerockdev/moko-mvvm/blob/2525a284783469981897a84c3569ec239f4049ef/buildSrc/src/main/kotlin/Deps.kt#L1-L8

and

https://github.com/icerockdev/moko-mvvm/blob/2525a284783469981897a84c3569ec239f4049ef/settings.gradle.kts#L17-L20

jmfayard commented 5 years ago

The gradle.properties solution is better because it works fine both for the buildSrc mode and the singleFileMode. Also it can be overwritten from the command-line as you note.

tadfisher commented 5 years ago

buildSrc access from settings.gradle is going to be completely removed in Gradle 6.0, so gradle.properties or some other mechanism is the only method that will continue working in the next release.

jmfayard commented 5 years ago

The good news is that I tried the propose solution with gradle.properties and it's very nice https://github.com/jmfayard/buildSrcVersions/commit/76dce4a6e4aa102725eb8ab6b69a6397abaf73bd

The bad news is that I have no idea on how to find which plugins are applied to a project.

From PluginManager and PluginContainer I can only find the class of the plugin.

pluginManagement.resolutionStrategy.eachPlugin { } is only available in the settings.

So for now I have now idea on how to generate the gradle.properties

jmfayard commented 5 years ago

ok, I found a way so I have a prototype for this feature now https://github.com/jmfayard/buildSrcVersions/pull/71/files

nkiesel commented 5 years ago

buildSrc access from settings.gradle is going to be completely removed in Gradle 6.0, so gradle.properties or some other mechanism is the only method that will continue working in the next release.

Hmm, that seems unfortunate because pluginManagement.plugins in settings.gradle allows to use buildSrc variables as version numbers while the plugins in build.gradle only allows string literals. I just consolidated my plugins versions in settings.gradle for that reason. I trust that the Gradle team will come up with a proper solution.

nkiesel commented 5 years ago

ok, I found a way so I have a prototype for this feature now https://github.com/jmfayard/buildSrcVersions/pull/71/files

Interesting. Couple of questions:

  1. Seems that will always append the dependencies to gradle.properties but never remove existing dependencies. Is that really the case?
  2. I loved the fact that I could see available newer plugin versions in Versions.kt and wanted to be able to upgrade a plugin simply by editing that file, similar to normal jar dependencies. But seems the proposed solution also does not allow this. Or am I misunderstanding this approach?
jmfayard commented 5 years ago

@nkiesel

  1. Correct, the rest of the gradle.properties file should/must be kept intact. If that's not the case, feel a ticket.
  2. Adding the information of plugins versions: Yes! But it was 2am so I decided to go to bed :)

It's part of my todo-list "Polishing versionsOnlyMode" before I release 0.5.1 https://github.com/jmfayard/buildSrcVersions/issues/67

jmfayard commented 5 years ago

@nkiesel @tadfisher @tadfisher @sigurdurrafn Check out the brand new $ ./gradlew :refreshVersions introduced in version 0.6.0 It generates gradle.properties with versions and available updates and from there you can set the plugins versions!

https://github.com/jmfayard/buildSrcVersions/issues/77