diff --git a/.github/workflows/check-build.yml b/.github/workflows/check-build.yml index 7ed9beb01..fe543a22d 100644 --- a/.github/workflows/check-build.yml +++ b/.github/workflows/check-build.yml @@ -52,3 +52,8 @@ jobs: wrapper-directory: sample-multi-modules build-root-directory: sample-multi-modules arguments: check --stacktrace + - uses: eskatos/gradle-command-action@v1 + with: + wrapper-directory: sample-include-build + build-root-directory: sample-include-build + arguments: check --stacktrace diff --git a/CHANGELOG.md b/CHANGELOG.md index 70dbdf366..1ebac8b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - In Android projects, if you used the version placeholder (`_`) directly in `build.gradle(.kts)` files, Android lint would trigger an unwanted warning, or error in the case of the Android build tools (aka. AGP, the Android Gradle Plugin). To avoid this inconvenience, running the refreshVersions task will now automatically check if it's running on an Android project, and in such cases, will edit (safely) the `lint.xml` file, creating it if needed, and add the needed rules to have these specific warnings and errors ignored. +### Changes + +- `versionFor` was moved to `versions.versionFor`, proper deprecation notices should make migration easy + ### Fixes - Fix a bug that prevented from using the correct version of `org.jetbrains.kotlinx.benchmark` and any other Gradle plugin with an id starting with `org.jetbrains.kotlinx` because it matched over `org.jetbrains.kotlin` as well. We are now matching on `org.jetbrains.kotlin.` to avoid this issue. diff --git a/docs/add-dependencies.md b/docs/add-dependencies.md index 12de49d14..9df320d03 100644 --- a/docs/add-dependencies.md +++ b/docs/add-dependencies.md @@ -84,32 +84,24 @@ As you see, the convention is pretty simple. The key is the id of the plugin, pr ## Get the version from anywhere In some cases, you might need to get the version defined in the `versions.properties` file in a Gradle script. -For these cases, there's the `versionFor` function that takes either a version key, or a full dependency notation. +For these cases, there's the `versions.versionFor` function that takes either a version key, or a full dependency notation. Here's a usage example with Jetpack Compose in an Android project: === "build.gradle.kts" ```kotlin - import de.fayard.refreshVersions.core.versionFor - - ... - composeOptions { - kotlinCompilerExtensionVersion = versionFor(AndroidX.compose.ui) + kotlinCompilerExtensionVersion = versions.versionFor(AndroidX.compose.ui) } ``` === "build.gradle" ```groovy - import static de.fayard.refreshVersions.core.Versions.versionFor - - ... - composeOptions { - kotlinCompilerExtensionVersion = versionFor(AndroidX.compose.ui) + kotlinCompilerExtensionVersion = versions.versionFor(AndroidX.compose.ui) } ``` -Using `versionFor("version.androidx.compose.ui")` would also work, so long as `version.androidx.compose.ui` is defined in the `versions.properties` file. +Using `versions.versionFor("version.androidx.compose.ui")` would also work, so long as `version.androidx.compose.ui` is defined in the `versions.properties` file. ## Non-built-in dependency notations diff --git a/plugins/buildSrc/src/main/kotlin/publishing/Publishing.kt b/plugins/buildSrc/src/main/kotlin/publishing/Publishing.kt index de46e3234..9793b5d70 100644 --- a/plugins/buildSrc/src/main/kotlin/publishing/Publishing.kt +++ b/plugins/buildSrc/src/main/kotlin/publishing/Publishing.kt @@ -7,6 +7,7 @@ import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.tasks.TaskContainer import org.gradle.api.tasks.TaskProvider import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.maven import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.withType diff --git a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt index 03cc0c5b2..48a9b3773 100644 --- a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt +++ b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt @@ -52,17 +52,18 @@ open class BuildSrcLibsTask : DefaultTask() { @TaskAction fun initVersionsProperties() { require(project == project.rootProject) { "Expected a rootProject but got $project" } + val config = RefreshVersionsConfigHolder.getConfigForProject(project) val configurationsWithHardcodedDependencies = project.findHardcodedDependencies() - val versionsMap = RefreshVersionsConfigHolder.readVersionsMap() - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val versionsMap = config.readVersionsMap() + val versionKeyReader = config.versionKeyReader val newEntries: Map = findMissingEntries( configurations = configurationsWithHardcodedDependencies, versionsMap = versionsMap, versionKeyReader = versionKeyReader ) - writeMissingEntriesInVersionProperties(newEntries) + writeMissingEntriesInVersionProperties(config, newEntries) OutputFile.VERSIONS_PROPERTIES.logFileWasModified() Thread.sleep(1000) } @@ -106,7 +107,8 @@ open class BuildSrcLibsTask : DefaultTask() { } internal fun Project.findHardcodedDependencies(): List { - val versionsMap = RefreshVersionsConfigHolder.readVersionsMap() + val config = RefreshVersionsConfigHolder.getConfigForProject(this) + val versionsMap = config.readVersionsMap() val projectsWithHardcodedDependenciesVersions: List = rootProject.allprojects.filter { it.countDependenciesWithHardcodedVersions(versionsMap) > 0 } @@ -115,7 +117,7 @@ internal fun Project.findHardcodedDependencies(): List { project.configurations.filterNot { configuration -> configuration.shouldBeIgnored() || 0 == configuration.countDependenciesWithHardcodedVersions( versionsMap = versionsMap, - versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + versionKeyReader = config.versionKeyReader ) } } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCorePlugin.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCorePlugin.kt index af2b0fabe..299d92530 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCorePlugin.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCorePlugin.kt @@ -15,11 +15,13 @@ open class RefreshVersionsCorePlugin : Plugin { override fun apply(project: Project) { check(project.isRootProject) { "ERROR: de.fayard.refreshVersions.core should not be applied manually" } if (project.isBuildSrc.not()) { + val config = RefreshVersionsConfigHolder.getConfigForProject(project) + val versionsFileName = config.versionsPropertiesFile.name project.tasks.register(name = "refreshVersions") { group = "Help" - val versionsFileName = RefreshVersionsConfigHolder.versionsPropertiesFile.name description = "Search for new dependencies versions and update $versionsFileName" } + project.extensions.add("versions", VersionExtension(config)) } cleanFilesFromPreviousVersions(project) } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCoreSetup.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCoreSetup.kt index 155740549..177e0038d 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCoreSetup.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCoreSetup.kt @@ -43,18 +43,20 @@ import java.io.File fun Settings.bootstrapRefreshVersionsCore( artifactVersionKeyRules: List = emptyList(), versionsPropertiesFile: File = rootDir.resolve("versions.properties") -) { +): RefreshVersionsConfig { require(settings.isBuildSrc.not()) { "This bootstrap is only for the root project. For buildSrc, please call " + "bootstrapRefreshVersionsCoreForBuildSrc() instead (Kotlin DSL)," + "or RefreshVersionsCoreSetup.bootstrapForBuildSrc() if you're using Groovy DSL." } - RefreshVersionsConfigHolder.initialize( + //TODO: use versionsPropertiesFile as key + val config = RefreshVersionsConfigHolder.initialize( settings = settings, artifactVersionKeyRules = artifactVersionKeyRules, versionsPropertiesFile = versionsPropertiesFile ) - setupRefreshVersions(settings = settings) + setupRefreshVersions(config = config, settings = settings) + return config } /** @@ -87,8 +89,8 @@ fun Settings.bootstrapRefreshVersionsCore( */ @JvmName("bootstrapForBuildSrc") fun Settings.bootstrapRefreshVersionsCoreForBuildSrc() { - RefreshVersionsConfigHolder.initializeBuildSrc(this) - setupRefreshVersions(settings = settings) + val config = RefreshVersionsConfigHolder.initializeBuildSrc(this) + setupRefreshVersions(settings = settings, config = config) } /** @@ -104,7 +106,7 @@ fun Settings.bootstrapRefreshVersionsCoreForBuildSrc() { * This function also sets up the module for the Android and Fabric (Crashlytics) Gradle plugins, so you can avoid the * buildscript classpath configuration boilerplate. */ -private fun setupRefreshVersions(settings: Settings) { +private fun setupRefreshVersions(config: RefreshVersionsConfig, settings: Settings) { val supportedGradleVersion = "6.3" // 6.2 fail with this error: https://gradle.com/s/shp7hbtd3i3ii if (GradleVersion.current() < GradleVersion.version(supportedGradleVersion)) { throw UnsupportedVersionException(""" @@ -113,15 +115,18 @@ private fun setupRefreshVersions(settings: Settings) { """.trimIndent()) } - - val versionsMap = RefreshVersionsConfigHolder.readVersionsMap() + val versionsMap = config.readVersionsMap() @Suppress("unchecked_cast") setupPluginsVersionsResolution( + config = config, settings = settings, properties = versionsMap ) - settings.gradle.setupVersionPlaceholdersResolving(versionsMap = versionsMap) + settings.gradle.setupVersionPlaceholdersResolving( + config = config, + versionsMap = versionsMap + ) settings.gradle.rootProject { apply() @@ -129,6 +134,7 @@ private fun setupRefreshVersions(settings: Settings) { } private fun setupPluginsVersionsResolution( + config: RefreshVersionsConfig, settings: Settings, properties: Map ) { @@ -152,14 +158,14 @@ private fun setupPluginsVersionsResolution( when { pluginNamespace.startsWith("com.android") -> { val dependencyNotation = "com.android.tools.build:gradle:$version" - UsedPluginsHolder.noteUsedPluginDependency( + config.usedPlugins.noteUsedPluginDependency( dependencyNotation = dependencyNotation, repositories = repositories ) useModule(dependencyNotation) } else -> { - UsedPluginsHolder.noteUsedPluginDependency( + config.usedPlugins.noteUsedPluginDependency( dependencyNotation = "$pluginId:$pluginId.gradle.plugin:$version", repositories = repositories ) diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsTask.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsTask.kt index 050ae6806..eaed8c58f 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsTask.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsTask.kt @@ -1,7 +1,6 @@ package de.fayard.refreshVersions.core -import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder -import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder.settings +import de.fayard.refreshVersions.core.internal.* import de.fayard.refreshVersions.core.internal.SettingsPluginsUpdater import de.fayard.refreshVersions.core.internal.configureLintIfRunningOnAnAndroidProject import de.fayard.refreshVersions.core.internal.legacy.LegacyBootstrapUpdater @@ -56,16 +55,18 @@ open class RefreshVersionsTask : DefaultTask() { // will reduce the number of repositories lookups, improving performance a little more. runBlocking { + logger.lifecycle("${project.rootDir.name} task action") + val config = RefreshVersionsConfigHolder.getConfigForProject(project) val lintUpdatingProblemsAsync = async { - configureLintIfRunningOnAnAndroidProject(settings, RefreshVersionsConfigHolder.readVersionsMap()) + configureLintIfRunningOnAnAndroidProject(config.settings, config.readVersionsMap()) } val result = lookupVersionCandidates( - httpClient = RefreshVersionsConfigHolder.httpClient, + httpClient = config.httpClient, project = project, - versionMap = RefreshVersionsConfigHolder.readVersionsMap(), - versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + versionMap = config.readVersionsMap(), + versionKeyReader = config.versionKeyReader ) - VersionsPropertiesModel.writeWithNewVersions(result.dependenciesUpdates) + VersionsPropertiesModel.writeWithNewVersions(config, result.dependenciesUpdates) SettingsPluginsUpdater.updateGradleSettingsWithAvailablePluginsUpdates( rootProject = project, settingsPluginsUpdates = result.settingsPluginsUpdates, @@ -78,7 +79,7 @@ open class RefreshVersionsTask : DefaultTask() { ) } - warnAboutHardcodedVersionsIfAny(result.dependenciesWithHardcodedVersions) + warnAboutHardcodedVersionsIfAny(config, result.dependenciesWithHardcodedVersions) warnAboutDynamicVersionsIfAny(result.dependenciesWithDynamicVersions) warnAboutGradleUpdateAvailableIfAny(result.gradleUpdates) lintUpdatingProblemsAsync.await().forEach { problem -> @@ -126,13 +127,13 @@ open class RefreshVersionsTask : DefaultTask() { } } - private fun warnAboutHardcodedVersionsIfAny(dependenciesWithHardcodedVersions: List) { + private fun warnAboutHardcodedVersionsIfAny(config: RefreshVersionsConfig, dependenciesWithHardcodedVersions: List) { if (dependenciesWithHardcodedVersions.isNotEmpty()) { //TODO: Suggest running a diagnosis task to list the hardcoded versions. val warnFor = (dependenciesWithHardcodedVersions).take(3).map { "${it.group}:${it.name}:${it.version}" } - val versionsFileName = RefreshVersionsConfigHolder.versionsPropertiesFile.name + val versionsFileName = config.versionsPropertiesFile.name logger.warn( """Found ${dependenciesWithHardcodedVersions.count()} hardcoded dependencies versions. | diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/VersionExtension.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/VersionExtension.kt new file mode 100644 index 000000000..406855af7 --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/VersionExtension.kt @@ -0,0 +1,20 @@ +package de.fayard.refreshVersions.core + +import de.fayard.refreshVersions.core.internal.RefreshVersionsConfig + +open class VersionExtension(private val config: RefreshVersionsConfig) { + fun versionFor(versionKey: String): String { + // This function is overloaded to allow named parameter usage in Kotlin. + // However, no check is performed here because we cannot detect if + // the function wasn't called with named argument. + return retrieveVersionFor(config = config, dependencyNotationOrVersionKey = versionKey) + } + + fun versionFor(dependencyNotation: CharSequence): String { + // This function is overloaded to allow named parameter usage in Kotlin. + // However, no check is performed here because we cannot detect if + // the function wasn't called with named argument. + return retrieveVersionFor(config = config, dependencyNotationOrVersionKey = dependencyNotation) + } +} + diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/Versions.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/Versions.kt index e5aff4e32..eb96dfe9e 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/Versions.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/Versions.kt @@ -2,25 +2,41 @@ package de.fayard.refreshVersions.core +import de.fayard.refreshVersions.core.internal.RefreshVersionsConfig import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder import de.fayard.refreshVersions.core.internal.getVersionPropertyName import de.fayard.refreshVersions.core.internal.resolveVersion +import org.gradle.api.Project +@Deprecated("use versions extension", ReplaceWith("versions.versionFor(versionKey)"), level = DeprecationLevel.ERROR) fun versionFor(versionKey: String): String { + throw NotImplementedError("use versions.versionFor") +} + +@Deprecated("use versions extension", ReplaceWith("versions.versionFor(dependencyNotation)"), level = DeprecationLevel.ERROR) +fun versionFor(dependencyNotation: CharSequence): String { + throw NotImplementedError("use versions.versionFor") +} + +@Deprecated("use versions extension", ReplaceWith("versions.versionFor(versionKey)")) +fun Project.versionFor(versionKey: String): String { // This function is overloaded to allow named parameter usage in Kotlin. // However, no check is performed here because we cannot detect if // the function wasn't called with named argument. - return retrieveVersionFor(dependencyNotationOrVersionKey = versionKey) + val config = RefreshVersionsConfigHolder.getConfigForProject(this) + return retrieveVersionFor(config = config, dependencyNotationOrVersionKey = versionKey) } -fun versionFor(dependencyNotation: CharSequence): String { +@Deprecated("use versions extension", ReplaceWith("versions.versionFor(dependencyNotation)")) +fun Project.versionFor(dependencyNotation: CharSequence): String { // This function is overloaded to allow named parameter usage in Kotlin. // However, no check is performed here because we cannot detect if // the function wasn't called with named argument. - return retrieveVersionFor(dependencyNotationOrVersionKey = dependencyNotation) + val config = RefreshVersionsConfigHolder.getConfigForProject(this) + return retrieveVersionFor(config = config, dependencyNotationOrVersionKey = dependencyNotation) } -private fun retrieveVersionFor(dependencyNotationOrVersionKey: CharSequence): String { +internal fun retrieveVersionFor(config: RefreshVersionsConfig, dependencyNotationOrVersionKey: CharSequence): String { val isDependencyNotation = ':' in dependencyNotationOrVersionKey val versionKey = when { isDependencyNotation -> { @@ -36,7 +52,7 @@ private fun retrieveVersionFor(dependencyNotationOrVersionKey: CharSequence): St group = it.substringBefore(':'), name = it.substringBeforeLast(':').substringAfter(':') ), - versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + versionKeyReader = config.versionKeyReader ) } } @@ -47,12 +63,12 @@ private fun retrieveVersionFor(dependencyNotationOrVersionKey: CharSequence): St } } return resolveVersion( - properties = RefreshVersionsConfigHolder.lastlyReadVersionsMap, + properties = config.lastlyReadVersionsMap, key = versionKey ) ?: resolveVersion( - properties = RefreshVersionsConfigHolder.readVersionsMap(), + properties = config.readVersionsMap(), key = versionKey - ) ?: RefreshVersionsConfigHolder.versionsPropertiesFile.name.let { versionsFileName -> + ) ?: config.versionsPropertiesFile.name.let { versionsFileName -> val errorMessage = when { isDependencyNotation -> "The version of the artifact $dependencyNotationOrVersionKey requested in " + "versionFor call wasn't found in the $versionsFileName file.\n" + diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Settings.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Settings.kt index 83940740b..b5f68634d 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Settings.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Settings.kt @@ -5,3 +5,6 @@ import org.gradle.api.initialization.Settings @InternalRefreshVersionsApi val Settings.isBuildSrc: Boolean get() = rootProject.name == "buildSrc" + +@InternalRefreshVersionsApi +val Settings.isIncluded: Boolean get() = startParameter.projectDir == null diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/NewRefreshVersionsImpl.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/NewRefreshVersionsImpl.kt index 6bff64be4..3e774c065 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/NewRefreshVersionsImpl.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/NewRefreshVersionsImpl.kt @@ -25,7 +25,9 @@ internal suspend fun lookupVersionCandidates( require(project.isRootProject) - val projects = RefreshVersionsConfigHolder.allProjects(project) + val config = RefreshVersionsConfigHolder.getConfigForProject(project) + + val projects = config.allProjects(project) val dependenciesWithHardcodedVersions = mutableListOf() val dependenciesWithDynamicVersions = mutableListOf() @@ -46,12 +48,12 @@ internal suspend fun lookupVersionCandidates( val dependencyVersionsFetchers: Set = projects.flatMap { it.getDependencyVersionFetchers(httpClient = httpClient, dependencyFilter = dependencyFilter) }.plus( - getUsedPluginsDependencyVersionFetchers(httpClient = httpClient) + getUsedPluginsDependencyVersionFetchers(config = config, httpClient = httpClient) ).toSet() return coroutineScope { - val resultMode = RefreshVersionsConfigHolder.resultMode + val resultMode = config.resultMode val dependenciesWithVersionCandidatesAsync = dependencyVersionsFetchers.groupBy { it.moduleId }.map { (moduleId: ModuleId, versionFetchers: List) -> @@ -60,6 +62,7 @@ internal suspend fun lookupVersionCandidates( properties = versionMap, key = propertyName ) ?: `Write versions candidates using latest most stable version and get it`( + config = config, propertyName = propertyName, dependencyVersionsFetchers = versionFetchers ) @@ -76,16 +79,16 @@ internal suspend fun lookupVersionCandidates( } val settingsPluginsUpdatesAsync = async { - SettingsPluginsUpdatesFinder.getSettingsPluginUpdates(httpClient, resultMode) + SettingsPluginsUpdatesFinder.getSettingsPluginUpdates(config, httpClient, resultMode) } val selfUpdateAsync: Deferred? = when { - RefreshVersionsConfigHolder.isSetupViaPlugin -> null - else -> async { LegacyBoostrapUpdatesFinder.getSelfUpdates(httpClient, resultMode) } + config.isSetupViaPlugin -> null + else -> async { LegacyBoostrapUpdatesFinder.getSelfUpdates(config, httpClient, resultMode) } } val gradleUpdatesAsync = async { - if (GRADLE_UPDATES.isEnabled) lookupAvailableGradleVersions() else emptyList() + if (GRADLE_UPDATES.isEnabled) lookupAvailableGradleVersions(config) else emptyList() } val dependenciesWithVersionCandidates = dependenciesWithVersionCandidatesAsync.awaitAll() @@ -103,8 +106,8 @@ internal suspend fun lookupVersionCandidates( } } -private suspend fun lookupAvailableGradleVersions(): List = coroutineScope { - val checker = GradleUpdateChecker(RefreshVersionsConfigHolder.httpClient) +private suspend fun lookupAvailableGradleVersions(config: RefreshVersionsConfig): List = coroutineScope { + val checker = GradleUpdateChecker(config.httpClient) val currentGradleVersion = GradleVersion.current() GradleUpdateChecker.VersionType.values().filterNot { it == GradleUpdateChecker.VersionType.All @@ -153,9 +156,10 @@ private fun Project.getDependencyVersionFetchers( ) private fun getUsedPluginsDependencyVersionFetchers( + config: RefreshVersionsConfig, httpClient: OkHttpClient ): Sequence { - return UsedPluginsHolder.read().flatMap { (dependency, repositories) -> + return config.usedPlugins.read().flatMap { (dependency, repositories) -> repositories.filterIsInstance().mapNotNull { repo -> DependencyVersionsFetcher( httpClient = httpClient, diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/RefreshVersionsConfigHolder.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/RefreshVersionsConfigHolder.kt index 0c2556234..7774ff61f 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/RefreshVersionsConfigHolder.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/RefreshVersionsConfigHolder.kt @@ -12,12 +12,70 @@ import org.gradle.api.initialization.Settings import java.io.File import java.io.ObjectInputStream import java.io.ObjectOutputStream +import java.util.concurrent.atomic.AtomicInteger -@InternalRefreshVersionsApi object RefreshVersionsConfigHolder { + internal val resettableDelegates = ResettableDelegates() + private val configs: MutableMap by resettableDelegates.Lazy { mutableMapOf() } + private val configCounter = AtomicInteger() + + internal fun initialize( + settings: Settings, + artifactVersionKeyRules: List, + versionsPropertiesFile: File + ): RefreshVersionsConfig { + require(settings.isBuildSrc.not()) + val key: String = settings.rootDir.path + + val config = configs.getOrPut(key) { RefreshVersionsConfig() } + + config.initialize( + settings = settings, + artifactVersionKeyRules = artifactVersionKeyRules, + versionsPropertiesFile = versionsPropertiesFile + ) + + configCounter.incrementAndGet() + settings.gradle.buildFinished { + val current = configCounter.decrementAndGet() + if(current == 0) { + resettableDelegates.reset() + } + } + return config + } + internal fun initializeBuildSrc(settings: Settings): RefreshVersionsConfig { + require(settings.isBuildSrc) + val key: String = settings.rootDir.parentFile.path + val config = configs.getOrPut(key) { RefreshVersionsConfig() } + + config.initializeBuildSrc(settings) + + configCounter.incrementAndGet() + settings.gradle.buildFinished { + val current = configCounter.decrementAndGet() + if(current == 0) { + resettableDelegates.reset() + } + } + + return config + } + + @InternalRefreshVersionsApi + fun getConfigForProject(project: Project): RefreshVersionsConfig { + val key = project.rootDir.path + return configs[key] ?: error("failed to load config for $key, available: ${configs.keys}") + } +} + +@InternalRefreshVersionsApi +class RefreshVersionsConfig { internal val resettableDelegates = ResettableDelegates() + internal val usedPlugins by resettableDelegates.Lazy { UsedPlugins() } + fun markSetupViaSettingsPlugin() { isSetupViaPlugin = true } @@ -121,7 +179,7 @@ object RefreshVersionsConfigHolder { } } - private fun clearStaticState() { + internal fun clearStaticState() { httpClient.dispatcher.executorService.shutdown() resettableDelegates.reset() // Clearing static state is needed because Gradle holds onto previous builds, yet, diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/SettingsPluginsUpdatesFinder.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/SettingsPluginsUpdatesFinder.kt index 6970f020f..32cc364bd 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/SettingsPluginsUpdatesFinder.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/SettingsPluginsUpdatesFinder.kt @@ -19,12 +19,13 @@ internal object SettingsPluginsUpdatesFinder { ) suspend fun getSettingsPluginUpdates( + config: RefreshVersionsConfig, httpClient: OkHttpClient, mode: VersionCandidatesResultMode ): UpdatesLookupResult { - val rootProjectSettings = RefreshVersionsConfigHolder.settings - val buildSrcSettings = RefreshVersionsConfigHolder.buildSrcSettings + val rootProjectSettings = config.settings + val buildSrcSettings = config.buildSrcSettings val rootProjectSettingsPlugins = rootProjectSettings.getPluginsList() val buildSrcSettingsPlugins = buildSrcSettings?.let { settings -> diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsHolder.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsHolder.kt index 63c06ef81..1c45c8cca 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsHolder.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsHolder.kt @@ -6,6 +6,10 @@ import org.gradle.api.internal.artifacts.dependencies.AbstractDependency internal object UsedPluginsHolder { +} + +internal class UsedPlugins { + fun noteUsedPluginDependency( dependencyNotation: String, repositories: ArtifactRepositoryContainer diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsPlaceholdersReplacement.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsPlaceholdersReplacement.kt index bd44773f5..c68983728 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsPlaceholdersReplacement.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsPlaceholdersReplacement.kt @@ -16,9 +16,9 @@ import org.gradle.api.invocation.Gradle internal const val versionPlaceholder = "_" -internal fun Gradle.setupVersionPlaceholdersResolving(versionsMap: Map) { +internal fun Gradle.setupVersionPlaceholdersResolving(config: RefreshVersionsConfig, versionsMap: Map) { - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val versionKeyReader = config.versionKeyReader var currentVersionsMap: Map = versionsMap val refreshVersionsMap = { updatedMap: Map -> currentVersionsMap = updatedMap @@ -33,6 +33,7 @@ internal fun Gradle.setupVersionPlaceholdersResolving(versionsMap: Map, refreshVersionsMap: (updatedMap: Map) -> Unit ) { - val repositories = if (isFromBuildscript) project.buildscript.repositories else project.repositories var properties = initialVersionsMap @Suppress("UnstableApiUsage") @@ -137,17 +138,18 @@ private fun Configuration.replaceVersionPlaceholdersFromDependencies( properties = properties, key = propertyName ) ?: synchronized(lock) { - RefreshVersionsConfigHolder.readVersionsMap().let { updatedMap -> + config.readVersionsMap().let { updatedMap -> properties = updatedMap refreshVersionsMap(updatedMap) } resolveVersion(properties, propertyName) ?: `Write versions candidates using latest most stable version and get it`( + config = config, repositories = repositories, propertyName = propertyName, dependency = dependency ).also { - RefreshVersionsConfigHolder.readVersionsMap().let { updatedMap -> + config.readVersionsMap().let { updatedMap -> properties = updatedMap refreshVersionsMap(updatedMap) } @@ -167,7 +169,9 @@ fun Project.writeCurrentVersionInProperties( versionKey: String, currentVersion: String ) { + val config = RefreshVersionsConfigHolder.getConfigForProject(this) VersionsPropertiesModel.writeWithNewEntry( + config = config, propertyName = versionKey, versionsCandidates = listOf(Version(currentVersion)) ) @@ -175,15 +179,17 @@ fun Project.writeCurrentVersionInProperties( @Suppress("FunctionName") private fun `Write versions candidates using latest most stable version and get it`( + config: RefreshVersionsConfig, repositories: ArtifactRepositoryContainer, propertyName: String, dependency: ExternalDependency ): String = `Write versions candidates using latest most stable version and get it`( + config = config, propertyName = propertyName, dependencyVersionsFetchers = repositories.filterIsInstance() .mapNotNull { repo -> DependencyVersionsFetcher( - httpClient = RefreshVersionsConfigHolder.httpClient, + httpClient = config.httpClient, dependency = dependency, repository = repo ) @@ -192,16 +198,18 @@ private fun `Write versions candidates using latest most stable version and get @Suppress("FunctionName") internal fun `Write versions candidates using latest most stable version and get it`( + config: RefreshVersionsConfig, propertyName: String, dependencyVersionsFetchers: List ): String = runBlocking { dependencyVersionsFetchers.getVersionCandidates( currentVersion = Version(""), - resultMode = RefreshVersionsConfigHolder.resultMode + resultMode = config.resultMode ).let { versionCandidates -> val bestStability = versionCandidates.minBy { it.stabilityLevel }!!.stabilityLevel val versionToUse = versionCandidates.last { it.stabilityLevel == bestStability } VersionsPropertiesModel.writeWithNewEntry( + config = config, propertyName = propertyName, versionsCandidates = versionCandidates.dropWhile { it != versionToUse } ) diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBoostrapUpdatesFinder.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBoostrapUpdatesFinder.kt index c3ee360d9..49aed12f4 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBoostrapUpdatesFinder.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBoostrapUpdatesFinder.kt @@ -3,8 +3,8 @@ package de.fayard.refreshVersions.core.internal.legacy import de.fayard.refreshVersions.core.ModuleId import de.fayard.refreshVersions.core.RefreshVersionsCorePlugin import de.fayard.refreshVersions.core.Version +import de.fayard.refreshVersions.core.internal.* import de.fayard.refreshVersions.core.internal.DependencyWithVersionCandidates -import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder import de.fayard.refreshVersions.core.internal.VersionCandidatesResultMode import de.fayard.refreshVersions.core.internal.getDependencyVersionFetchers import de.fayard.refreshVersions.core.internal.getVersionCandidates @@ -13,12 +13,13 @@ import okhttp3.OkHttpClient internal object LegacyBoostrapUpdatesFinder { suspend fun getSelfUpdates( + config: RefreshVersionsConfig, httpClient: OkHttpClient, resultMode: VersionCandidatesResultMode ): DependencyWithVersionCandidates { val moduleId = ModuleId(group = "de.fayard.refreshVersions", name = "refreshVersions") - val versionsFetchers = RefreshVersionsConfigHolder.settings.getDependencyVersionFetchers( + val versionsFetchers = config.settings.getDependencyVersionFetchers( httpClient = httpClient, dependencyFilter = { dependency -> dependency.group == moduleId.group && dependency.name == moduleId.name diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBootstrapUpdater.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBootstrapUpdater.kt index 25677861e..52210c9b0 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBootstrapUpdater.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/legacy/LegacyBootstrapUpdater.kt @@ -19,7 +19,8 @@ internal object LegacyBootstrapUpdater { require(rootProject.isRootProject) require(rootProject.isBuildSrc.not()) rootProject.updateGradleSettings(selfUpdates) - RefreshVersionsConfigHolder.buildSrc?.updateGradleSettings(selfUpdates) + val config = RefreshVersionsConfigHolder.getConfigForProject(rootProject) + config.buildSrc?.updateGradleSettings(selfUpdates) } class ExpectedValues private constructor( diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/versions/VersionsPropertiesWriting.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/versions/VersionsPropertiesWriting.kt index 8997b8bef..8dbb9cd06 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/versions/VersionsPropertiesWriting.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/versions/VersionsPropertiesWriting.kt @@ -3,10 +3,8 @@ package de.fayard.refreshVersions.core.internal.versions import de.fayard.refreshVersions.core.RefreshVersionsCorePlugin import de.fayard.refreshVersions.core.Version import de.fayard.refreshVersions.core.extensions.gradle.toModuleIdentifier +import de.fayard.refreshVersions.core.internal.* import de.fayard.refreshVersions.core.internal.DependencyWithVersionCandidates -import de.fayard.refreshVersions.core.internal.InternalRefreshVersionsApi -import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder -import de.fayard.refreshVersions.core.internal.getVersionPropertyName import de.fayard.refreshVersions.core.internal.isAVersionAlias import de.fayard.refreshVersions.core.internal.versions.VersionsPropertiesModel.Companion.availableComment import de.fayard.refreshVersions.core.internal.versions.VersionsPropertiesModel.Section.Comment @@ -15,8 +13,11 @@ import org.gradle.api.artifacts.ExternalDependency import java.io.File @InternalRefreshVersionsApi -fun writeMissingEntriesInVersionProperties(newEntries: Map) { - VersionsPropertiesModel.update { model -> +fun writeMissingEntriesInVersionProperties( + config: RefreshVersionsConfig, + newEntries: Map +) { + VersionsPropertiesModel.update(config.versionsPropertiesFile) { model -> val newSections = newEntries.map { (key, d) -> VersionEntry(emptyList(), key, d.version!!, emptyList(), emptyList()) }.sortedBy { it.key } @@ -25,15 +26,16 @@ fun writeMissingEntriesInVersionProperties(newEntries: Map ) { - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val versionKeyReader = config.versionKeyReader val candidatesMap = dependenciesWithLastVersion.associateBy { getVersionPropertyName(it.moduleId.toModuleIdentifier(), versionKeyReader) } - update { model -> + update(config.versionsPropertiesFile) { model -> model.copy( sections = model.sections.map { section -> when (section) { @@ -53,10 +55,11 @@ internal fun VersionsPropertiesModel.Companion.writeWithNewVersions( } internal fun VersionsPropertiesModel.Companion.writeWithNewEntry( + config: RefreshVersionsConfig, propertyName: String, versionsCandidates: List ) { - VersionsPropertiesModel.update { model -> + VersionsPropertiesModel.update(config.versionsPropertiesFile) { model -> model + VersionEntry( key = propertyName, currentVersion = versionsCandidates.first().value, @@ -76,7 +79,7 @@ internal fun VersionsPropertiesModel.writeTo(versionsPropertiesFile: File) { * [transform] is crossinline to enforce synchronous execution of (no suspension points). */ private inline fun VersionsPropertiesModel.Companion.update( - versionsPropertiesFile: File = RefreshVersionsConfigHolder.versionsPropertiesFile, + versionsPropertiesFile: File, crossinline transform: (model: VersionsPropertiesModel) -> VersionsPropertiesModel ) { require(versionsPropertiesFile.name == "versions.properties") diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt index ca362aef8..972aea590 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt @@ -4,6 +4,7 @@ import de.fayard.refreshVersions.core.RefreshVersionsCorePlugin import de.fayard.refreshVersions.core.bootstrapRefreshVersionsCore import de.fayard.refreshVersions.core.bootstrapRefreshVersionsCoreForBuildSrc import de.fayard.refreshVersions.core.extensions.gradle.isBuildSrc +import de.fayard.refreshVersions.core.internal.RefreshVersionsConfig import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder import de.fayard.refreshVersions.internal.getArtifactNameToConstantMapping import org.gradle.api.DefaultTask @@ -51,7 +52,6 @@ open class RefreshVersionsPlugin : Plugin { } private fun bootstrap(settings: Settings) { - RefreshVersionsConfigHolder.markSetupViaSettingsPlugin() if (settings.extensions.findByName("refreshVersions") == null) { // If using legacy bootstrap, the extension has already been created. settings.extensions.create("refreshVersions") @@ -66,7 +66,7 @@ open class RefreshVersionsPlugin : Plugin { val extension: RefreshVersionsExtension = extensions.getByType() - bootstrapRefreshVersionsCore( + val config = bootstrapRefreshVersionsCore( artifactVersionKeyRules = if (extension.extraArtifactVersionKeyRules.isEmpty()) { artifactVersionKeyRules // Avoid unneeded list copy. } else { @@ -75,6 +75,7 @@ open class RefreshVersionsPlugin : Plugin { versionsPropertiesFile = extension.versionsPropertiesFile ?: settings.rootDir.resolve("versions.properties") ) + config.markSetupViaSettingsPlugin() if (extension.isBuildSrcLibsEnabled) gradle.beforeProject { if (project != project.rootProject) return@beforeProject diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/ConfigurationDependenciesMigration.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/ConfigurationDependenciesMigration.kt index f047cb6c8..4f5f23d4b 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/ConfigurationDependenciesMigration.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/ConfigurationDependenciesMigration.kt @@ -13,9 +13,10 @@ internal fun runConfigurationDependenciesMigration( versionsMap: Map, configuration: Configuration ) { + val config = RefreshVersionsConfigHolder.getConfigForProject(project) configuration.dependencies.forEach { dependency -> if (dependency !is ExternalDependency) return@forEach - project.attemptDependencyMigration(versionsMap, dependency) + project.attemptDependencyMigration(config, versionsMap, dependency) } } @@ -28,10 +29,11 @@ private fun DependencyMapping.matches(dependency: ExternalDependency): Boolean { } private fun Project.attemptDependencyMigration( + config: RefreshVersionsConfig, versionsMap: Map, dependency: ExternalDependency ) { - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val versionKeyReader = config.versionKeyReader if (dependency.hasHardcodedVersion(versionsMap, versionKeyReader).not()) return val currentVersion = dependency.version ?: return @@ -54,7 +56,7 @@ private fun Project.attemptDependencyMigration( versionKey = versionKey, currentVersion = currentVersion ) - logAddedVersionsKey(versionKey) + logAddedVersionsKey(config, versionKey) } private fun offerReplacingHardcodedVersionWithPlaceholder(moduleIdentifier: ModuleIdentifier): Boolean { @@ -93,8 +95,11 @@ private fun offerReplacingHardcodedVersionWithConstantOrPlaceholder( ) } -private fun logAddedVersionsKey(versionKey: String) { - val versionsFileName = RefreshVersionsConfigHolder.versionsPropertiesFile.name +private fun logAddedVersionsKey( + config: RefreshVersionsConfig, + versionKey: String +) { + val versionsFileName = config.versionsPropertiesFile.name println("Moved the current version to the $versionsFileName file under the following key:") print(AnsiColor.WHITE.boldHighIntensity) print(AnsiColor.YELLOW.background) diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/MigrationToDependenciesConstants.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/MigrationToDependenciesConstants.kt index 4161d8498..fd1d17b91 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/MigrationToDependenciesConstants.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/internal/MigrationToDependenciesConstants.kt @@ -35,7 +35,8 @@ fun Configuration.countDependenciesWithHardcodedVersions( @InternalRefreshVersionsApi fun Project.countDependenciesWithHardcodedVersions(versionsMap: Map): Int { - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val config = RefreshVersionsConfigHolder.getConfigForProject(project) + val versionKeyReader = config.versionKeyReader return configurations.sumBy { configuration -> if (configuration.shouldBeIgnored()) 0 else { configuration.countDependenciesWithHardcodedVersions(versionsMap, versionKeyReader) @@ -45,7 +46,8 @@ fun Project.countDependenciesWithHardcodedVersions(versionsMap: Map> = rootProject.allprojects.mapNotNull { val hardcodedDependenciesVersionsCount = it.countDependenciesWithHardcodedVersions(versionsMap) if (hardcodedDependenciesVersionsCount > 0) { @@ -64,7 +66,8 @@ internal fun promptProjectSelection(rootProject: Project): Project? { } internal suspend fun runInteractiveMigrationToDependenciesConstants(project: Project) { - val versionsMap = RefreshVersionsConfigHolder.readVersionsMap() + val config = RefreshVersionsConfigHolder.getConfigForProject(project) + val versionsMap = config.readVersionsMap() while (coroutineContext.isActive) { val selectedConfiguration = project.promptConfigurationSelection(versionsMap) ?: return runConfigurationDependenciesMigration( @@ -77,7 +80,8 @@ internal suspend fun runInteractiveMigrationToDependenciesConstants(project: Pro private fun Project.promptConfigurationSelection(versionsMap: Map): Configuration? { @Suppress("UnstableApiUsage") - val versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + val config = RefreshVersionsConfigHolder.getConfigForProject(this) + val versionKeyReader = config.versionKeyReader val configurationsWithHardcodedDependenciesVersions = configurations.mapNotNull { configuration -> if (configuration.shouldBeIgnored()) return@mapNotNull null val count = configuration.countDependenciesWithHardcodedVersions(versionsMap, versionKeyReader) diff --git a/plugins/settings.gradle.kts b/plugins/settings.gradle.kts index 3ed934fca..6f1bf07ca 100644 --- a/plugins/settings.gradle.kts +++ b/plugins/settings.gradle.kts @@ -1,12 +1,16 @@ import de.fayard.refreshVersions.bootstrapRefreshVersions +import de.fayard.refreshVersions.migrateRefreshVersionsIfNeeded buildscript { repositories { gradlePluginPortal() } dependencies.classpath("de.fayard.refreshVersions:refreshVersions:0.9.7") +//// # available:0.10.0") } +migrateRefreshVersionsIfNeeded("0.9.7") // Will be automatically removed by refreshVersions when upgraded to the latest version. + bootstrapRefreshVersions() plugins { diff --git a/sample-groovy/build.gradle b/sample-groovy/build.gradle index c9098edf6..a550afcb5 100644 --- a/sample-groovy/build.gradle +++ b/sample-groovy/build.gradle @@ -23,5 +23,5 @@ dependencies { implementation("org.jetbrains:annotations:_") } -println("The version for artifact org.jetbrains:annotations:_ is " + versionFor("org.jetbrains:annotations:_")) -println("The version for version key version.com.google.guava..guava is " + versionFor("version.com.google.guava..guava")) +println("The version for artifact org.jetbrains:annotations:_ is " + versions.versionFor("org.jetbrains:annotations:_")) +println("The version for version key version.com.google.guava..guava is " + versions.versionFor("version.com.google.guava..guava")) diff --git a/sample-include-build/build.gradle.kts b/sample-include-build/build.gradle.kts new file mode 100644 index 000000000..e95d5f79d --- /dev/null +++ b/sample-include-build/build.gradle.kts @@ -0,0 +1,93 @@ +import de.fayard.refreshVersions.core.versionFor +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +buildscript { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } + dependencies { + classpath("org.gradle:gradle-hello-world-plugin:_") + } +} + +plugins { + kotlin("jvm") +} + +group = "de.fayard" + +repositories { + mavenLocal() + mavenCentral() + google() +} + +fun DependencyHandler.implementations(deps: List) = + deps.forEach { implementation(it) } + +fun DependencyHandler.testImplementations(deps: List) = + deps.forEach { testImplementation(it) } + + +dependencies { + api("de.fayard:included") +// api("de.fayard:subproject") +// api("de.fayard:subproject2") + + implementations(listOf(AndroidX.browser, AndroidX.cardView)) + implementation(AndroidX.core) + implementation("com.google.guava:guava:15.0") + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("script-runtime")) + + testImplementations(listOf(KotlinX.coroutines.core, KotlinX.coroutines.jdk8)) + testImplementation(Testing.kotest.assertions.core) + testImplementation(platform(notation = "org.junit:junit-bom:_")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") { + because("allows tests to run from IDEs that bundle older version of launcher") + } + + api("org.apache.poi:poi:_") + api("org.apache.poi:poi-ooxml:_") +} + + +getKotlinPluginVersion().let { + val kotlinStdlibVersion = versions.versionFor(dependencyNotation = Kotlin.stdlib) + check(it == kotlinStdlibVersion) { + "Unexpected mismatch between the version of the Kotlin plugin and the stdlib. " + + "Is the versionFor function implementation correct?" + + "Got respectively $it and $kotlinStdlibVersion" + } + val kotlinVersion = versions.versionFor(versionKey = "version.kotlin") + check(it == kotlinVersion) { + "Unexpected mismatch between the version of the Kotlin plugin and the one from versions.properties. " + + "Is the versionFor function implementation correct?" + + "Got respectively $it and $kotlinStdlibVersion" + } +} + +tasks.register("run", JavaExec::class.java) { + this.main = "de.fayard.GuavaTest" +} + +tasks.withType { + kotlinOptions.jvmTarget = "1.8" +} + +tasks.withType { + useJUnitPlatform() +} + +tasks.withType(JavaExec::class.java) { + classpath = sourceSets["main"].runtimeClasspath +} + +tasks.register("hello") { + group = "Custom" + description = "Minimal task that do nothing. Useful to debug a failing build" +} diff --git a/sample-include-build/buildSrc/.gitignore b/sample-include-build/buildSrc/.gitignore new file mode 100644 index 000000000..192221b47 --- /dev/null +++ b/sample-include-build/buildSrc/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ \ No newline at end of file diff --git a/sample-include-build/buildSrc/build.gradle.kts b/sample-include-build/buildSrc/build.gradle.kts new file mode 100644 index 000000000..ccb5a0580 --- /dev/null +++ b/sample-include-build/buildSrc/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} + +dependencies { + compileOnly(gradleKotlinDsl()) + implementation(Square.okHttp3.okHttp) + implementation(KotlinX.collections.immutable) +} diff --git a/sample-include-build/buildSrc/settings.gradle.kts b/sample-include-build/buildSrc/settings.gradle.kts new file mode 100644 index 000000000..da210fd8c --- /dev/null +++ b/sample-include-build/buildSrc/settings.gradle.kts @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } + + val versionFile = rootDir.parentFile.parentFile.resolve("plugins/version.txt") + val pluginsVersion = versionFile.readLines().first() + + @Suppress("UnstableApiUsage") + plugins { + id("de.fayard.refreshVersions").version(pluginsVersion) + } +} + +plugins { + id("de.fayard.refreshVersions") +} diff --git a/sample-include-build/gradle b/sample-include-build/gradle new file mode 120000 index 000000000..26be11736 --- /dev/null +++ b/sample-include-build/gradle @@ -0,0 +1 @@ +../sample-kotlin/gradle \ No newline at end of file diff --git a/sample-include-build/gradlew b/sample-include-build/gradlew new file mode 120000 index 000000000..64d70aa2c --- /dev/null +++ b/sample-include-build/gradlew @@ -0,0 +1 @@ +../sample-kotlin/gradlew \ No newline at end of file diff --git a/sample-include-build/gradlew.bat b/sample-include-build/gradlew.bat new file mode 120000 index 000000000..32254ef15 --- /dev/null +++ b/sample-include-build/gradlew.bat @@ -0,0 +1 @@ +../sample-kotlin/gradlew.bat \ No newline at end of file diff --git a/sample-include-build/included/build.gradle.kts b/sample-include-build/included/build.gradle.kts new file mode 100644 index 000000000..015475f7f --- /dev/null +++ b/sample-include-build/included/build.gradle.kts @@ -0,0 +1,36 @@ +import Testing.JunitJupiter.api +import de.fayard.refreshVersions.core.versionFor +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +buildscript { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } + dependencies { + classpath("org.gradle:gradle-hello-world-plugin:_") + } +} + +plugins { + kotlin("jvm") + `maven-publish` +} + +group = "de.fayard" + +repositories { + mavenLocal() + mavenCentral() + google() +} + +dependencies { +// api(project(":subproject")) +// api(project(":subproject2")) + +// api("org.apache.poi:poi:_") +// api("org.apache.poi:poi-ooxml:_") +} diff --git a/sample-include-build/included/buildSrc/.gitignore b/sample-include-build/included/buildSrc/.gitignore new file mode 100644 index 000000000..192221b47 --- /dev/null +++ b/sample-include-build/included/buildSrc/.gitignore @@ -0,0 +1,2 @@ +.gradle/ +build/ \ No newline at end of file diff --git a/sample-include-build/included/buildSrc/build.gradle.kts b/sample-include-build/included/buildSrc/build.gradle.kts new file mode 100644 index 000000000..ccb5a0580 --- /dev/null +++ b/sample-include-build/included/buildSrc/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} + +dependencies { + compileOnly(gradleKotlinDsl()) + implementation(Square.okHttp3.okHttp) + implementation(KotlinX.collections.immutable) +} diff --git a/sample-include-build/included/buildSrc/settings.gradle.kts b/sample-include-build/included/buildSrc/settings.gradle.kts new file mode 100644 index 000000000..01f720e95 --- /dev/null +++ b/sample-include-build/included/buildSrc/settings.gradle.kts @@ -0,0 +1,20 @@ +import de.fayard.refreshVersions.core.FeatureFlag.* + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } + + val versionFile = rootDir.parentFile.parentFile.parentFile.resolve("plugins/version.txt") + val pluginsVersion = versionFile.readLines().first() + + @Suppress("UnstableApiUsage") + plugins { + id("de.fayard.refreshVersions").version(pluginsVersion) + } +} + +plugins { + id("de.fayard.refreshVersions") +} diff --git a/sample-include-build/included/gradle b/sample-include-build/included/gradle new file mode 120000 index 000000000..b51f9a79d --- /dev/null +++ b/sample-include-build/included/gradle @@ -0,0 +1 @@ +../../sample-kotlin/gradle \ No newline at end of file diff --git a/sample-include-build/included/gradlew b/sample-include-build/included/gradlew new file mode 120000 index 000000000..7a0f353fc --- /dev/null +++ b/sample-include-build/included/gradlew @@ -0,0 +1 @@ +../../sample-kotlin/gradlew \ No newline at end of file diff --git a/sample-include-build/included/gradlew.bat b/sample-include-build/included/gradlew.bat new file mode 120000 index 000000000..c66f6a706 --- /dev/null +++ b/sample-include-build/included/gradlew.bat @@ -0,0 +1 @@ +../../sample-kotlin/gradlew.bat \ No newline at end of file diff --git a/sample-include-build/included/refreshVersions-extra-rules.txt b/sample-include-build/included/refreshVersions-extra-rules.txt new file mode 100644 index 000000000..74886adc0 --- /dev/null +++ b/sample-include-build/included/refreshVersions-extra-rules.txt @@ -0,0 +1,2 @@ +org.apache.poi:poi(-*) + ^^^^^^.^^^ diff --git a/sample-include-build/included/settings.gradle.kts b/sample-include-build/included/settings.gradle.kts new file mode 100644 index 000000000..3b9fa9385 --- /dev/null +++ b/sample-include-build/included/settings.gradle.kts @@ -0,0 +1,42 @@ +import de.fayard.refreshVersions.core.FeatureFlag.* + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } + + val versionFile = rootDir.parentFile.parentFile.resolve("plugins/version.txt") + val pluginsVersion = versionFile.readLines().first() + + @Suppress("UnstableApiUsage") + plugins { + id("de.fayard.refreshVersions").version(pluginsVersion) + } +} + +plugins { + id("com.gradle.enterprise").version("3.6.2") + id("de.fayard.refreshVersions") +} + +refreshVersions { +// versionsPropertiesFile = rootDir.parentFile.resolve("versions.properties") + featureFlags { + enable(LIBS) + disable(GRADLE_UPDATES) + } + + extraArtifactVersionKeyRules(file("refreshVersions-extra-rules.txt")) +} + +gradleEnterprise { + buildScan { + termsOfServiceUrl = "https://gradle.com/terms-of-service" + termsOfServiceAgree = "yes" + } +} + +include(":subproject") +include(":subproject2") +rootProject.name = "included" diff --git a/sample-include-build/included/src/main/kotlin/included.kt b/sample-include-build/included/src/main/kotlin/included.kt new file mode 100644 index 000000000..5643a5760 --- /dev/null +++ b/sample-include-build/included/src/main/kotlin/included.kt @@ -0,0 +1,2 @@ +fun included() = true + diff --git a/sample-include-build/included/subproject/build.gradle.kts b/sample-include-build/included/subproject/build.gradle.kts new file mode 100644 index 000000000..fe301c1cc --- /dev/null +++ b/sample-include-build/included/subproject/build.gradle.kts @@ -0,0 +1,32 @@ +import de.fayard.refreshVersions.core.versionFor +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +buildscript { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } + dependencies { + classpath("org.gradle:gradle-hello-world-plugin:_") + } +} + +plugins { + kotlin("jvm") + `maven-publish` +} + +group = "de.fayard" + +repositories { + mavenLocal() + mavenCentral() + google() +} + +dependencies { + api("org.apache.poi:poi:_") + api("org.apache.poi:poi-ooxml:_") +} diff --git a/sample-include-build/included/subproject/src/main/kotlin/included.kt b/sample-include-build/included/subproject/src/main/kotlin/included.kt new file mode 100644 index 000000000..92690bf1b --- /dev/null +++ b/sample-include-build/included/subproject/src/main/kotlin/included.kt @@ -0,0 +1 @@ +fun includedSubproject() = true diff --git a/sample-include-build/included/subproject2/build.gradle.kts b/sample-include-build/included/subproject2/build.gradle.kts new file mode 100644 index 000000000..2882db25f --- /dev/null +++ b/sample-include-build/included/subproject2/build.gradle.kts @@ -0,0 +1,38 @@ +import de.fayard.refreshVersions.core.versionFor +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +buildscript { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } + dependencies { + classpath("org.gradle:gradle-hello-world-plugin:_") + } +} + +plugins { + kotlin("jvm") + `maven-publish` +} + +group = "de.fayard" + +repositories { + mavenLocal() + mavenCentral() + google() +} + +fun DependencyHandler.implementations(deps: List) = + deps.forEach { implementation(it) } + +fun DependencyHandler.testImplementations(deps: List) = + deps.forEach { testImplementation(it) } + +dependencies { + api("org.apache.poi:poi:_") + api("org.apache.poi:poi-ooxml:_") +} diff --git a/sample-include-build/included/subproject2/src/main/kotlin/included.kt b/sample-include-build/included/subproject2/src/main/kotlin/included.kt new file mode 100644 index 000000000..cd0d39cdb --- /dev/null +++ b/sample-include-build/included/subproject2/src/main/kotlin/included.kt @@ -0,0 +1 @@ +fun includedSubproject2() = true diff --git a/sample-include-build/included/versions.properties b/sample-include-build/included/versions.properties new file mode 100644 index 000000000..cc3976f4e --- /dev/null +++ b/sample-include-build/included/versions.properties @@ -0,0 +1,27 @@ +#### Dependencies and Plugin versions with their available updates. +#### Generated by `./gradlew refreshVersions` version 0.10.1-SNAPSHOT +#### +#### Don't manually edit or split the comments that start with four hashtags (####), +#### they will be overwritten by refreshVersions. +#### +#### suppress inspection "SpellCheckingInspection" for whole file +#### suppress inspection "UnusedProperty" for whole file + +version.apache.poi=5.0.0 + +version.kotlin=1.4.32 +## # available=1.5.0-M1 +## # available=1.5.0-M2 +## # available=1.5.0-RC +## # available=1.5.0 +## # available=1.5.10 +## # available=1.5.20-M1 + +version.kotlinx.collections.immutable=0.3.4 + +version.okhttp3=4.9.1 +## # available=4.10.0-RC1 +## # available=5.0.0-alpha.1 +## # available=5.0.0-alpha.2 + +version.org.gradle..gradle-hello-world-plugin=0.2 diff --git a/sample-include-build/refreshVersions-extra-rules.txt b/sample-include-build/refreshVersions-extra-rules.txt new file mode 100644 index 000000000..74886adc0 --- /dev/null +++ b/sample-include-build/refreshVersions-extra-rules.txt @@ -0,0 +1,2 @@ +org.apache.poi:poi(-*) + ^^^^^^.^^^ diff --git a/sample-include-build/settings.gradle.kts b/sample-include-build/settings.gradle.kts new file mode 100644 index 000000000..50076d844 --- /dev/null +++ b/sample-include-build/settings.gradle.kts @@ -0,0 +1,48 @@ +import de.fayard.refreshVersions.core.FeatureFlag.GRADLE_UPDATES +import de.fayard.refreshVersions.core.FeatureFlag.LIBS + +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } + + val versionFile = rootDir.parentFile.resolve("plugins/version.txt") + val pluginsVersion = versionFile.readLines().first() + + @Suppress("UnstableApiUsage") + plugins { + id("de.fayard.refreshVersions").version(pluginsVersion) + } +} + +plugins { + id("com.gradle.enterprise").version("3.6.2") + id("de.fayard.refreshVersions") +} + +refreshVersions { + featureFlags { + enable(LIBS) + disable(GRADLE_UPDATES) + } + + extraArtifactVersionKeyRules(file("refreshVersions-extra-rules.txt")) +} + +gradleEnterprise { + buildScan { + termsOfServiceUrl = "https://gradle.com/terms-of-service" + termsOfServiceAgree = "yes" + } +} + +includeBuild("included") { +// dependencySubstitution { +// substitute(module("de.fayard:included")).with(project(":")) +// substitute(module("de.fayard:subproject2")).with(project(":subproject2")) +// substitute(module("de.fayard:subproject")).with(project(":subproject")) +// } +} + +rootProject.name = "sample-include-build" diff --git a/sample-include-build/src/test/kotlin/de/fayard/GuavaTest.kt b/sample-include-build/src/test/kotlin/de/fayard/GuavaTest.kt new file mode 100644 index 000000000..dce727c28 --- /dev/null +++ b/sample-include-build/src/test/kotlin/de/fayard/GuavaTest.kt @@ -0,0 +1,20 @@ +@file:JvmName("GuavaTest") + +package de.fayard + +import com.google.common.math.DoubleMath +import included +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +internal class GuavaTest { + @Test + fun test() { + val mean = DoubleMath.mean(4, 2) + mean shouldBe 3 + println("Guava says: mean(4, 2)=$mean") + + println(included()) +// println(includedSubproject2()) + } +} diff --git a/sample-include-build/versions.properties b/sample-include-build/versions.properties new file mode 100644 index 000000000..a3e5c1a6d --- /dev/null +++ b/sample-include-build/versions.properties @@ -0,0 +1,122 @@ +#### Dependencies and Plugin versions with their available updates. +#### Generated by `./gradlew refreshVersions` version 0.10.1-SNAPSHOT +#### +#### Don't manually edit or split the comments that start with four hashtags (####), +#### they will be overwritten by refreshVersions. +#### +#### suppress inspection "SpellCheckingInspection" for whole file +#### suppress inspection "UnusedProperty" for whole file + +plugin.org.jetbrains.kotlin.jvm=version.kotlin + +version.androidx.browser=1.0.0 +## # available=1.2.0-alpha07 +## # available=1.2.0-alpha08 +## # available=1.2.0-alpha09 +## # available=1.2.0-beta01 +## # available=1.2.0-rc01 +## # available=1.2.0 +## # available=1.3.0-alpha01 +## # available=1.3.0-alpha03 +## # available=1.3.0-alpha04 +## # available=1.3.0-alpha05 +## # available=1.3.0-alpha06 +## # available=1.3.0-beta01 +## # available=1.3.0-rc01 +## # available=1.3.0 + +version.androidx.cardview=1.0.0 + +version.androidx.core=1.3.1 +## # available=1.3.2 +## # available=1.4.0-alpha01 +## # available=1.5.0-alpha01 +## # available=1.5.0-alpha02 +## # available=1.5.0-alpha03 +## # available=1.5.0-alpha04 +## # available=1.5.0-alpha05 +## # available=1.5.0-beta01 +## # available=1.5.0-beta02 +## # available=1.5.0-beta03 +## # available=1.5.0-rc01 +## # available=1.5.0-rc02 +## # available=1.5.0 +## # available=1.6.0-alpha01 +## # available=1.6.0-alpha02 +## # available=1.6.0-alpha03 +## # available=1.6.0-beta01 +## # available=1.6.0-beta02 + +version.apache.poi=4.0.0 +## # available=4.0.1 +## # available=4.1.0 +## # available=4.1.1 +## # available=4.1.2 +## # available=5.0.0 + +version.kotest=4.1.3 +## # available=4.2.0.RC1 +## # available=4.2.0.RC2 +## # available=4.2.0.RC3 +## # available=4.2.0 +## # available=4.2.2 +## # available=4.2.3 +## # available=4.2.4 +## # available=4.2.5 +## # available=4.2.6 +## # available=4.3.0 +## # available=4.3.1 +## # available=4.3.2 +## # available=4.4.0.RC1 +## # available=4.4.0.RC2 +## # available=4.4.0.RC3 +## # available=4.4.0 +## # available=4.4.1 +## # available=4.4.2 +## # available=4.4.3 +## # available=4.5.0.RC1 +## # available=4.5.0 +## # available=4.6.0 + +version.kotlin=1.4.32 +## # available=1.5.0-M1 +## # available=1.5.0-M2 +## # available=1.5.0-RC +## # available=1.5.0 +## # available=1.5.10 +## # available=1.5.20-M1 + +version.kotlinx.collections.immutable=0.3.4 + +version.kotlinx.coroutines=1.3.8 +## # available=1.3.8-1.4.0-rc +## # available=1.3.9-native-mt +## # available=1.3.9-native-mt-2 +## # available=1.3.9 +## # available=1.4.0-M1 +## # available=1.4.0 +## # available=1.4.1-native-mt +## # available=1.4.1 +## # available=1.4.2-native-mt +## # available=1.4.2 +## # available=1.4.3-native-mt +## # available=1.4.3 +## # available=1.5.0-native-mt +## # available=1.5.0-RC-native-mt +## # available=1.5.0-RC +## # available=1.5.0 + +version.okhttp3=4.9.1 +## # available=4.10.0-RC1 +## # available=5.0.0-alpha.1 +## # available=5.0.0-alpha.2 + +version.org.apache.poi..poi=4.1.2 + +version.org.apache.poi..poi-ooxml=4.1.2 + +version.org.gradle..gradle-hello-world-plugin=0.1 +## # available=0.2 + +version.org.junit..junit-bom=5.7.2 +## # available=5.8.0-M1 diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/build.gradle.kts index 1e7e3ae2b..25eb78e46 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/build.gradle.kts @@ -50,13 +50,13 @@ dependencies { } getKotlinPluginVersion().let { - val kotlinStdlibVersion = versionFor(dependencyNotation = Kotlin.stdlib) + val kotlinStdlibVersion = versions.versionFor(dependencyNotation = Kotlin.stdlib) check(it == kotlinStdlibVersion) { "Unexpected mismatch between the version of the Kotlin plugin and the stdlib. " + "Is the versionFor function implementation correct?" + "Got respectively $it and $kotlinStdlibVersion" } - val kotlinVersion = versionFor(versionKey = "version.kotlin") + val kotlinVersion = versions.versionFor(versionKey = "version.kotlin") check(it == kotlinVersion) { "Unexpected mismatch between the version of the Kotlin plugin and the one from versions.properties. " + "Is the versionFor function implementation correct?" +