Skip to content

Commit

Permalink
Replace the refreshVersionsCatalog task
Browse files Browse the repository at this point in the history
We replace it with the new required mode option
on the refreshVersionsMigrate task.
  • Loading branch information
LouisCAD committed Sep 7, 2022
1 parent ea30433 commit 009e5d4
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 109 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Change log for refreshVersions

## [Unreleased] Version 0.41.0 (2022-08-26)
## [Unreleased] Version 0.41.0 (2022-09-07)

### Highlights

Expand All @@ -18,7 +18,9 @@ Note that both work simultaneously, so you can have some versions in the propert

What if you don't use versions catalogs yet, but want to make the jump?
Along with support for them, we also brought a migration facility!
To use it… TK

It lives right into the `refreshVersionsMigrate` task you might already be familiar with.
The task will now require you to specify which mode you want to run it in, listing all the different ones, among which you will find 3 that relate to versions catalog support.

### Fixes

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
package de.fayard.refreshVersions

import de.fayard.refreshVersions.core.addMissingEntriesInVersionsProperties
import de.fayard.refreshVersions.core.internal.Case
import de.fayard.refreshVersions.core.internal.Deps
import de.fayard.refreshVersions.core.internal.Library
import de.fayard.refreshVersions.core.internal.MEANING_LESS_NAMES
import de.fayard.refreshVersions.core.internal.OutputFile
import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder
import de.fayard.refreshVersions.core.internal.UsedPluginsTracker
import de.fayard.refreshVersions.core.internal.VersionsCatalogs
import de.fayard.refreshVersions.core.internal.VersionsCatalogs.LIBS_VERSIONS_TOML
import de.fayard.refreshVersions.core.internal.checkModeAndNames
import de.fayard.refreshVersions.core.internal.computeAliases
import de.fayard.refreshVersions.core.internal.findDependencies
import de.fayard.refreshVersions.internal.getArtifactNameToConstantMapping
import de.fayard.refreshVersions.internal.generateVersionsCatalogFromCurrentDependencies
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.artifacts.Dependency
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
import org.gradle.util.GradleVersion

open class RefreshVersionsCatalogTask : DefaultTask() {

Expand Down Expand Up @@ -59,63 +45,11 @@ open class RefreshVersionsCatalogTask : DefaultTask() {

@TaskAction
fun refreshVersionsCatalogAction() {
if (VersionsCatalogs.isSupported().not()) {
throw GradleException(
"""
|Gradle versions catalogs are not supported in ${GradleVersion.current()}
|Upgrade Gradle with this command
| ./gradlew wrapper --gradle-version ${VersionsCatalogs.minimumGradleVersion.version}
""".trimMargin()
)
}
checkOptions()

// Update versions.properties
addMissingEntriesInVersionsProperties(project)

// Generate LIBS_VERSIONS_TOML
val catalog = OutputFile.GRADLE_VERSIONS_CATALOG

val builtInDependencies = getArtifactNameToConstantMapping()

val allDependencies: List<Library> = project.findDependencies()

val dependenciesToUse = when {
copyBuiltInDependencyNotationsToCatalog -> allDependencies
else -> allDependencies.filter {
builtInDependencies.none { builtInDependency ->
builtInDependency.group == it.group && builtInDependency.artifact == it.name
}
}
}

val plugins = UsedPluginsTracker.usedPluginsWithoutEntryInVersionsFile +
UsedPluginsTracker.read().map { it.first }

val versionCatalogAliases: List<String> = dependenciesToUse.computeAliases(
configured = emptyList(),
byDefault = MEANING_LESS_NAMES
)

val deps: Deps = dependenciesToUse.checkModeAndNames(versionCatalogAliases, Case.`kebab-case`)
val dependenciesAndNames: Map<Dependency, String> = deps.names.mapKeys { it.key.toDependency() }

val currentText = if (catalog.existed) catalog.readText() else ""
val newText = VersionsCatalogs.generateVersionsCatalogText(
dependenciesAndNames = dependenciesAndNames,
currentText = currentText,
moveVersionsToCatalog = moveVersionsToCatalog,
plugins = plugins
)
catalog.writeText(newText)
catalog.logFileWasModified()

println(
"""
You can now automatically migrate your build.gradle/build.gradle.kts file with the command:
$ANSI_GREEN./gradlew refreshVersionsMigrate$ANSI_RESET
""".trimIndent()
generateVersionsCatalogFromCurrentDependencies(
project = project,
keepVersionsPlaceholders = keepVersionsPlaceholders,
copyBuiltInDependencyNotationsToCatalog = copyBuiltInDependencyNotationsToCatalog
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import de.fayard.refreshVersions.core.addMissingEntriesInVersionsProperties
import de.fayard.refreshVersions.core.extensions.gradle.getVersionsCatalog
import de.fayard.refreshVersions.core.internal.VersionsCatalogs
import de.fayard.refreshVersions.core.internal.associateShortestByMavenCoordinate
import de.fayard.refreshVersions.core.internal.skipConfigurationCache
import de.fayard.refreshVersions.internal.generateVersionsCatalogFromCurrentDependencies
import de.fayard.refreshVersions.internal.getArtifactNameToConstantMapping
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.options.Option
import org.intellij.lang.annotations.Language
Expand All @@ -16,44 +20,105 @@ import java.io.File
open class RefreshVersionsMigrateTask : DefaultTask() {

@Input
@Option(option = "toml", description = "Use libraries from ${VersionsCatalogs.LIBS_VERSIONS_TOML} before built-in dependency notations")
var tomlFirst: Boolean = false
@Optional
@Option(
option = "mode",
description = "Which migration mode to use."
)
var mode: Mode? = null

enum class Mode {
VersionsPropertiesOnly,
VersionsPropertiesAndPlaceholdersInCatalog,
VersionCatalogAndVersionProperties,
VersionCatalogOnly
}

@TaskAction
fun refreshVersionsMissingEntries() {
addMissingEntriesInVersionsProperties(project)
init {
group = "refreshVersions"
skipConfigurationCache()
}

private fun requireMode(): Mode = requireNotNull(mode) {
buildString {
appendLine("You need to provide which mode you want to run the migration in.")
appendLine("Specify the `mode` option in one of the following ways and re-run.")
Mode.values().forEach { mode ->
appendLine("--mode=$mode")
}
}
}

@TaskAction
fun migrateBuild() {
val versionsCatalogMapping: Map<ModuleId.Maven, String> =
VersionsCatalogs.dependencyAliases(project.getVersionsCatalog())

val builtInDependenciesMapping: Map<ModuleId.Maven, String> = getArtifactNameToConstantMapping()
.associateShortestByMavenCoordinate()

val dependencyMapping = if (tomlFirst) {
builtInDependenciesMapping + versionsCatalogMapping
} else {
versionsCatalogMapping + builtInDependenciesMapping
val mode = requireMode()
when (mode) {
Mode.VersionsPropertiesOnly -> Unit
Mode.VersionsPropertiesAndPlaceholdersInCatalog -> {
generateVersionsCatalogFromCurrentDependencies(
project = project,
keepVersionsPlaceholders = true,
copyBuiltInDependencyNotationsToCatalog = false
)
}
Mode.VersionCatalogAndVersionProperties -> {
generateVersionsCatalogFromCurrentDependencies(
project = project,
keepVersionsPlaceholders = false,
copyBuiltInDependencyNotationsToCatalog = false
)
}
Mode.VersionCatalogOnly -> {
generateVersionsCatalogFromCurrentDependencies(
project = project,
keepVersionsPlaceholders = false,
copyBuiltInDependencyNotationsToCatalog = true
)
}
}
migrateBuildToRefreshVersions(
project = project,
versionCatalogOnly = mode == Mode.VersionCatalogOnly
)
}
}

internal fun migrateBuildToRefreshVersions(
project: Project,
versionCatalogOnly: Boolean
) {
if (versionCatalogOnly.not()) {
addMissingEntriesInVersionsProperties(project)
}
val versionsCatalogMapping: Map<ModuleId.Maven, String> =
VersionsCatalogs.dependencyAliases(project.getVersionsCatalog())

val builtInDependenciesMapping: Map<ModuleId.Maven, String> = getArtifactNameToConstantMapping()
.associateShortestByMavenCoordinate()

val dependencyMapping = if (versionCatalogOnly) {
versionsCatalogMapping
} else {
versionsCatalogMapping + builtInDependenciesMapping
}

val findFiles = findFilesWithDependencyNotations(project.rootDir).toSet()
findFiles.forEach { buildFile ->
val findFiles = findFilesWithDependencyNotations(project.rootDir).toSet()
findFiles.forEach { buildFile ->
migrateFileIfNeeded(buildFile, dependencyMapping)
}
project.allprojects {
if (buildFile !in findFiles) {
migrateFileIfNeeded(buildFile, dependencyMapping)
}
project.allprojects {
if (buildFile !in findFiles) {
migrateFileIfNeeded(buildFile, dependencyMapping)
}
}
println()
println("""
}
println()
println(
"""
To find available updates, run this:
$ANSI_GREEN./gradlew refreshVersions$ANSI_RESET
""".trimIndent())
}
""".trimIndent()
)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package de.fayard.refreshVersions

import de.fayard.refreshVersions.core.*
import de.fayard.refreshVersions.core.extensions.gradle.isBuildSrc
import de.fayard.refreshVersions.core.internal.VersionsCatalogs.LIBS_VERSIONS_TOML
import de.fayard.refreshVersions.core.internal.removals_replacement.RemovedDependencyNotationsReplacementInfo
import de.fayard.refreshVersions.core.internal.skipConfigurationCache
import de.fayard.refreshVersions.internal.getArtifactNameToConstantMapping
Expand Down Expand Up @@ -183,21 +182,12 @@ open class RefreshVersionsPlugin : Plugin<Any> {
println(getArtifactNameToConstantMapping().joinToString("\n"))
}
}
project.tasks.register<RefreshVersionsCatalogTask>(
name = "refreshVersionsCatalog"
) {
group = "refreshVersions"
description = "Update $LIBS_VERSIONS_TOML"
outputs.upToDateWhen { false }
skipConfigurationCache()
}

project.tasks.register<RefreshVersionsMigrateTask>(
name = "refreshVersionsMigrate"
) {
group = "refreshVersions"
description = "Migrate build to refreshVersions"
skipConfigurationCache()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package de.fayard.refreshVersions.internal

import de.fayard.refreshVersions.core.addMissingEntriesInVersionsProperties
import de.fayard.refreshVersions.core.internal.Case
import de.fayard.refreshVersions.core.internal.Deps
import de.fayard.refreshVersions.core.internal.Library
import de.fayard.refreshVersions.core.internal.MEANING_LESS_NAMES
import de.fayard.refreshVersions.core.internal.OutputFile
import de.fayard.refreshVersions.core.internal.UsedPluginsTracker
import de.fayard.refreshVersions.core.internal.VersionsCatalogs
import de.fayard.refreshVersions.core.internal.checkModeAndNames
import de.fayard.refreshVersions.core.internal.computeAliases
import de.fayard.refreshVersions.core.internal.findDependencies
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.util.GradleVersion

internal fun generateVersionsCatalogFromCurrentDependencies(
project: Project,
keepVersionsPlaceholders: Boolean,
copyBuiltInDependencyNotationsToCatalog: Boolean
) {
if (VersionsCatalogs.isSupported().not()) {
throw GradleException(
"""
|Gradle versions catalogs are not supported in ${GradleVersion.current()}
|Upgrade Gradle with this command
| ./gradlew wrapper --gradle-version ${VersionsCatalogs.minimumGradleVersion.version}
""".trimMargin()
)
}
// Update versions.properties
addMissingEntriesInVersionsProperties(project)

// Generate LIBS_VERSIONS_TOML
val catalog = OutputFile.GRADLE_VERSIONS_CATALOG

val builtInDependencies = getArtifactNameToConstantMapping()

val allDependencies: List<Library> = project.findDependencies()

val dependenciesToUse = when {
copyBuiltInDependencyNotationsToCatalog -> allDependencies
else -> allDependencies.filter {
builtInDependencies.none { builtInDependency ->
builtInDependency.group == it.group && builtInDependency.artifact == it.name
}
}
}

val plugins = UsedPluginsTracker.usedPluginsWithoutEntryInVersionsFile +
UsedPluginsTracker.read().map { it.first }

val versionCatalogAliases: List<String> = dependenciesToUse.computeAliases(
configured = emptyList(),
byDefault = MEANING_LESS_NAMES
)

val deps: Deps = dependenciesToUse.checkModeAndNames(versionCatalogAliases, Case.`kebab-case`)
val dependenciesAndNames: Map<Dependency, String> = deps.names.mapKeys { it.key.toDependency() }

val currentText = if (catalog.existed) catalog.readText() else ""
val newText = VersionsCatalogs.generateVersionsCatalogText(
dependenciesAndNames = dependenciesAndNames,
currentText = currentText,
moveVersionsToCatalog = keepVersionsPlaceholders.not(),
plugins = plugins
)
catalog.writeText(newText)
catalog.logFileWasModified()
}

0 comments on commit 009e5d4

Please sign in to comment.