renovatebot / renovate

Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io
https://mend.io/renovate
GNU Affero General Public License v3.0
17.66k stars 2.33k forks source link

depTypes for gradle #4316

Closed ZyanKLee closed 2 years ago

ZyanKLee commented 5 years ago

What would you like Renovate to be able to do? Renovate does not differentiate between gradle plugins and software dependencies. In some environments it might be desirable to have different behavior for each variant.

As an example: with some legacy software we did not want to change that softwares dependencies at all, but wanted to make use of renovates features for gradle and its plugins itself to avoid our CI/CD pipelines from decaying.

Describe the solution you'd like I would like to be able to select depTypes for gradle, like some other managers provide. I know of at least "plugins" and "dependencies"

Describe alternatives you've considered @rarkins helped us with finding a packageRule that fit our specific scheme of package names. Although that might not always fit:

  "packageRules": [{
    "managers": ["gradle"],
    "excludePackagePatterns": ["^.+gradle[.-]plugin$"],
    "enabled": false
  }]

Additional context https://github.com/renovatebot/config-help/issues/321

gmariotti commented 4 years ago

From my side, it would be nice if this solution would also allow distinguishing between chore updates, e.g. plugins or test dependencies, and fix updates, e.g. dependencies in the implementation or api configuration.

rarkins commented 4 years ago

@gmariotti can you show an example config file you have with examples of what you'd like mapped into our depTypes fields?

gmariotti commented 4 years ago

I haven't tried anything yet because I'm not sure how it would work. I guess it would look something like

"extends": [
    "config:base",
    ":semanticPrefixChore"
],
packageRules: [{
  managers: ["gradle"],
  devTypeList: ["implementation", "api"],
  extends: [":semanticPrefixFix"]
}]
rarkins commented 4 years ago

Thanks. And can you give an example of the corresponding gradle file(s) that this would map to?

gmariotti commented 4 years ago

Sure, an example of gradle.build.kts file could be:

plugins {
  `java-library`
  kotlin("jvm") version "1.3.60"
}

repositories {
  mavenCentral()
}

dependencies {
  api("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.60")
  implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.60")

  testImplementation("org.assertj:assertj-core:3.14.0")
}

From a gradle point of view, the dependencies will go into the api, implementation and testImplementation configuration, however, I'm not sure the plugins in which configuration they would go. What plugin(s) do you use with gradle to check for new dependencies?

rarkins commented 4 years ago

We do all lookups using our own API handling, i.e. we parse the files using a Gradle plugin but then the logic to know what all the possible releases are is done without Gradle support.

It looks to me that we need to support multiple depTypes, e.g. in your example we'd have ['plugins'] for the kotlin jvm one but ['dependencies', 'api'] for kotlin-gradle-plugin. Does that sound right?

gmariotti commented 4 years ago

I guess so. Probably it would be easier to have a notation for the configurations in the depedencies block, something like dependencies.api, to avoid collisions between the plugins block and a user-created configuration called plugins. What do you think?

rarkins commented 4 years ago

We might want to make it ['dependencies', 'api', 'dependencies.api'] for fullest flexibility?

gmariotti commented 4 years ago

I don't really have a strong opinion about it, I would go with the simplest one to implement and, eventually, extend it if people find the need for it.

gjoseph commented 4 years ago

On a somewhat related note, for a gradle build like the below, I get 3 individual PRs, despite having declared a group in renovate.json - i'd expect a single PR?

    {
      "sourceUrlPrefixes": ["https://github.com/JetBrains/kotlin"],
      "groupName": "Kotlin packages"
    }
plugins {
    id "org.jetbrains.kotlin.jvm" version "1.3.60"
    id "org.jetbrains.kotlin.plugin.spring" version "1.3.60"
}
...
dependencies {
    implementation platform("org.jetbrains.kotlin:kotlin-bom:1.3.60")
}
....
gmariotti commented 4 years ago

Hi @rarkins, any update on this? If needed, I can try to contribute it if you point me to the right files.

rarkins commented 4 years ago

@gmariotti if you can help in any way, that would be great. The function being called is this one: https://github.com/renovatebot/renovate/blob/fc0b3d3026bd823c1ec81bc2c9c35a79aec1f6b6/lib/manager/gradle/index.ts#L96 and it returns results here: https://github.com/renovatebot/renovate/blob/fc0b3d3026bd823c1ec81bc2c9c35a79aec1f6b6/lib/manager/gradle/index.ts#L154

It needs to be enhanced so that gradleFiles.deps includes either depType (string) or depTypes (array of strings). That should be all that's required to then be able to using the depTypeList filter within packageFiles.

gmariotti commented 4 years ago

@rarkins I might have found where to get the configuration of each dependency, however, I don't have any Groovy experience so I don't really know what is the best way to do it.

https://github.com/renovatebot/renovate/blob/fc0b3d3026bd823c1ec81bc2c9c35a79aec1f6b6/lib/manager/gradle/gradle-updates-report.ts#L49 The it object contains a property called name that it is set to the name of the configuration, except for plugins to which name is set to classpath. I think we should extract the depType from there but my lack of Groovy knowledge blocks me there. Can you give me any help?