diff --git a/checkPlugins.sh b/checkPlugins.sh index 32b403f46..acd425932 100755 --- a/checkPlugins.sh +++ b/checkPlugins.sh @@ -1,14 +1,50 @@ #!/usr/bin/env bash +fail() { + echo "$1" + exit 1 +} +checkInstalled() { + which "$1" || fail "ERROR: please install $1" +} -cd plugins -./gradlew test publishToMavenLocal +runGradleTaskInFolder() { + echo + echo "== cd $1 ==" + cd $1 || fail "ERROR: Folder $1 doesn't exist" + pwd + + echo '$' "./gradlew $TASK" + ./gradlew $TASK || fail "ERROR for task $TASK" + cd .. +} + +DIR="$(basename $PWD)" +TASK="check refreshVersions" + +test -n "$1" && TASK="$*" +echo "TASK=$TASK" -cd ../sample-plugins -./gradlew check refreshVersions +test "$DIR" = "refreshVersions" || fail "ERROR: must be called from the refreshVersions folder" +checkInstalled java +checkInstalled node +checkInstalled yarn + + +cd plugins || fail "can't cd plugins" +./gradlew test publishToMavenLocal +cd .. -cd ../sample-kotlin -./gradlew check refreshVersions +runGradleTaskInFolder sample-kotlin +runGradleTaskInFolder sample-multi-modules +runGradleTaskInFolder sample-groovy +runGradleTaskInFolder sample-kotlin-js -cd ..sample-groovy -./gradlew check refreshVersions +test -n "$ANDROID_SDK_ROOT" && { + runGradleTaskInFolder sample-android +} +echo "SUCCESS" +test "$TASK" = "refreshVersionsCleanup" || { + echo "To clean up your git history, you can run:" + echo " ./checkPlugins.sh refreshVersionsCleanup" +} diff --git a/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.jar b/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.jar index 7454180f2..249e5832f 100644 Binary files a/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.jar and b/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.jar differ diff --git a/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.properties b/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.properties index 2e6e5897b..ae04661ee 100644 --- a/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.properties +++ b/dummy-library-for-testing/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/dummy-library-for-testing/gradlew b/dummy-library-for-testing/gradlew index 1b6c78733..a69d9cb6c 100755 --- a/dummy-library-for-testing/gradlew +++ b/dummy-library-for-testing/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/dummy-library-for-testing/gradlew.bat b/dummy-library-for-testing/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/dummy-library-for-testing/gradlew.bat +++ b/dummy-library-for-testing/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/plugins/buildSrcLibs/build.gradle.kts b/plugins/buildSrcLibs/build.gradle.kts index 7ebe2c8af..85cb2cde1 100644 --- a/plugins/buildSrcLibs/build.gradle.kts +++ b/plugins/buildSrcLibs/build.gradle.kts @@ -50,8 +50,8 @@ dependencies { testImplementation(Testing.kotest.runner.junit5) - testImplementation(platform(notation = "org.junit:junit-bom:_")) - testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation(platform(notation = Testing.junit.bom)) + testImplementation(Testing.junit.jupiter) testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("allows tests to run from IDEs that bundle older version of launcher") } diff --git a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsPlugin.kt b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsPlugin.kt index e52d58656..49f619b3c 100644 --- a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsPlugin.kt +++ b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsPlugin.kt @@ -1,5 +1,6 @@ package de.fayard.buildSrcLibs +import de.fayard.refreshVersions.core.internal.skipConfigurationCache import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project @@ -14,6 +15,7 @@ class BuildSrcLibsPlugin : Plugin { group = "refreshVersions" description = "Update buildSrc/src/main/kotlin/Libs.kt" outputs.upToDateWhen { false } + skipConfigurationCache() } project.tasks.register( name = "buildSrcVersions" 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 c39a7fbcf..c3a055ea3 100644 --- a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt +++ b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/BuildSrcLibsTask.kt @@ -3,7 +3,12 @@ package de.fayard.buildSrcLibs import com.squareup.kotlinpoet.FileSpec import de.fayard.buildSrcLibs.internal.* import de.fayard.refreshVersions.core.addMissingEntriesInVersionsProperties +import de.fayard.refreshVersions.core.internal.Case +import de.fayard.refreshVersions.core.internal.MEANING_LESS_NAMES import de.fayard.refreshVersions.core.internal.OutputFile +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.DefaultTask import org.gradle.api.tasks.TaskAction @@ -17,7 +22,7 @@ open class BuildSrcLibsTask : DefaultTask() { @TaskAction fun taskActionInitializeBuildSrc() { - OutputFile.checkWhichFilesExist(project.rootDir) + OutputFile.checkWhichFilesExist() project.file(OutputFile.OUTPUT_DIR.path).also { if (it.isDirectory.not()) it.mkdirs() } @@ -42,11 +47,10 @@ open class BuildSrcLibsTask : DefaultTask() { @TaskAction fun taskUpdateLibsKt() { - val outputDir = project.file(OutputFile.OUTPUT_DIR.path) + val outputDir = OutputFile.OUTPUT_DIR.file val allDependencies = project.findDependencies() - val resolvedUseFqdn = computeUseFqdnFor( - libraries = allDependencies, + val resolvedUseFqdn = allDependencies.computeAliases( configured = emptyList(), byDefault = MEANING_LESS_NAMES ) diff --git a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/DependencyNotations.kt b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/DependencyNotations.kt deleted file mode 100644 index 94e5a8f16..000000000 --- a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/DependencyNotations.kt +++ /dev/null @@ -1,131 +0,0 @@ -package de.fayard.buildSrcLibs.internal - -import org.gradle.api.Project -import org.gradle.api.artifacts.ExternalDependency - -internal enum class Case { - camelCase, snake_case; //, PascalCase, `kebab-case` - - companion object { - internal fun toCamelCase(input: String): String = buildString { - var wasWordBreak = false - val wordBreaks = setOf(' ', '-', '_') - for (c in input) { - when { - c in wordBreaks -> { - } - wasWordBreak -> append(c.toUpperCase()) - else -> append(c) - } - wasWordBreak = c in wordBreaks - } - } - } -} - -/** - * We don't want to use meaningless generic libs like Libs.core - * - * Found many inspiration for bad libs here https://developer.android.com/jetpack/androidx/migrate - * **/ -internal val MEANING_LESS_NAMES: MutableList = mutableListOf( - "common", "core", "testing", "runtime", "extensions", - "compiler", "migration", "db", "rules", "runner", "monitor", "loader", - "media", "print", "io", "collection", "gradle", "android" -) - -internal fun computeUseFqdnFor( - libraries: List, - configured: List, - byDefault: List = MEANING_LESS_NAMES -): List { - val groups = (configured + byDefault).filter { it.contains(".") }.distinct() - val depsFromGroups = libraries.filter { it.group in groups }.map { it.module } - val ambiguities = libraries.groupBy { it.module }.filter { it.value.size > 1 }.map { it.key } - return (configured + byDefault + ambiguities + depsFromGroups - groups).distinct().sorted() -} - -internal fun escapeLibsKt(name: String): String { - val escapedChars = listOf('-', '.', ':') - return buildString { - for (c in name) { - append(if (c in escapedChars) '_' else c.toLowerCase()) - } - } -} - -internal fun Project.findDependencies(): List { - val allDependencies = mutableListOf() - allprojects { - (configurations + buildscript.configurations) - .flatMapTo(allDependencies) { configuration -> - configuration.allDependencies - .filterIsInstance() - .filter { - @Suppress("SENSELESS_COMPARISON") - it.group != null - } - .map { dependency -> - Library(dependency.group, dependency.name, dependency.version ?: "none") - } - } - } - return allDependencies.distinctBy { d -> d.groupModule() } -} - - -internal data class Library( - val group: String = "", - val module: String = "", - val version: String = "" -) { - val name: String get() = module - fun groupModuleVersion() = "$group:$module:$version" - fun groupModuleUnderscore() = "$group:$module:_" - fun groupModule() = "$group:$module" - fun versionNameCamelCase(mode: VersionMode): String = - Case.toCamelCase(versionNameSnakeCase(mode)) - - fun versionNameSnakeCase(mode: VersionMode): String = escapeLibsKt( - when (mode) { - VersionMode.MODULE -> module - VersionMode.GROUP -> group - VersionMode.GROUP_MODULE -> "${group}_$module" - } - ) - - override fun toString() = groupModuleVersion() -} - -internal class Deps( - val libraries: List, - val names: Map -) - - -internal enum class VersionMode { - GROUP, GROUP_MODULE, MODULE -} - -internal fun List.checkModeAndNames(useFdqnByDefault: List, case: Case): Deps { - val dependencies = this - - val modes: Map = - dependencies.associateWith { d -> - when { - d.module in useFdqnByDefault -> VersionMode.GROUP_MODULE - escapeLibsKt(d.module) in useFdqnByDefault -> VersionMode.GROUP_MODULE - else -> VersionMode.MODULE - } - }.toMutableMap() - - val versionNames = dependencies.associateWith { d -> - val mode = modes.getValue(d) - when (case) { - Case.camelCase -> d.versionNameCamelCase(mode) - Case.snake_case -> d.versionNameSnakeCase(mode) - } - } - val sortedDependencies = dependencies.sortedBy { d: Library -> d.groupModule() } - return Deps(sortedDependencies, versionNames) -} diff --git a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/KotlinPoetry.kt b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/KotlinPoetry.kt index 8affc4d5a..c3cfbc497 100644 --- a/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/KotlinPoetry.kt +++ b/plugins/buildSrcLibs/src/main/kotlin/de/fayard/buildSrcLibs/internal/KotlinPoetry.kt @@ -1,9 +1,15 @@ package de.fayard.buildSrcLibs.internal -import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec +import de.fayard.refreshVersions.core.internal.Deps +import de.fayard.refreshVersions.core.internal.Library internal fun kotlinpoet( - deps: Deps + deps: Deps, ): FileSpec { val libraries: List = deps.libraries val indent = " " @@ -11,8 +17,8 @@ internal fun kotlinpoet( val libsProperties: List = libraries .distinctBy { it.groupModule() } .map { d -> - val libValue = when { - d.version == "none" -> CodeBlock.of("%S", d.groupModule()) + val libValue = when (d.version) { + null -> CodeBlock.of("%S", d.groupModule()) else -> CodeBlock.of("%S", d.groupModuleUnderscore()) } constStringProperty( @@ -36,11 +42,10 @@ internal fun kotlinpoet( } - internal fun constStringProperty( name: String, initializer: CodeBlock, - kdoc: CodeBlock? = null + kdoc: CodeBlock? = null, ): PropertySpec = PropertySpec.builder(name, String::class) .addModifiers(KModifier.CONST) .initializer(initializer) diff --git a/plugins/buildSrcLibs/src/test/kotlin/CaseTest.kt b/plugins/buildSrcLibs/src/test/kotlin/CaseTest.kt deleted file mode 100644 index cee04c0cf..000000000 --- a/plugins/buildSrcLibs/src/test/kotlin/CaseTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -import de.fayard.buildSrcLibs.internal.Case -import io.kotest.core.spec.style.StringSpec -import io.kotest.inspectors.forAll -import io.kotest.matchers.shouldBe - -class CaseTest : StringSpec({ - val transformations = listOf( - "hoplite_yaml" to "hopliteYaml", - "picnic" to "picnic", - "h2_ok" to "h2Ok", - "mockito_kotlin" to "mockitoKotlin", - "retrofit2_kotlinx_serialization_converter" to "retrofit2KotlinxSerializationConverter", - "dagger_compiler" to "daggerCompiler" - ) - - "From snake_case to camelCase" { - transformations.forAll { (snake, caml) -> - Case.toCamelCase(snake) shouldBe caml - } - } - -}) diff --git a/plugins/core/build.gradle.kts b/plugins/core/build.gradle.kts index f6ac3f68a..04ed134ce 100644 --- a/plugins/core/build.gradle.kts +++ b/plugins/core/build.gradle.kts @@ -51,8 +51,8 @@ dependencies { implementation(Square.moshi.kotlinReflect) testImplementation(Square.okHttp3.loggingInterceptor) - testImplementation(platform(notation = "org.junit:junit-bom:_")) - testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation(platform(notation = Testing.junit.bom)) + testImplementation(Testing.junit.jupiter) testImplementation(Testing.kotest.runner.junit5) testImplementation(Kotlin.test.annotationsCommon) testImplementation(Kotlin.test.junit5) diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/FeatureFlag.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/FeatureFlag.kt index 4f759dfdd..f20a45aa8 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/FeatureFlag.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/FeatureFlag.kt @@ -37,7 +37,8 @@ enum class FeatureFlag(private val enabledByDefault: Boolean?) { GRADLE_UPDATES(enabledByDefault = true), LIBS(enabledByDefault = false), - NPM_IMPLICIT_RANGE(enabledByDefault = false) + NPM_IMPLICIT_RANGE(enabledByDefault = false), + VERSIONS_CATALOG(enabledByDefault = true), ; companion object { @@ -59,4 +60,7 @@ enum class FeatureFlag(private val enabledByDefault: Boolean?) { true -> userSettings[this] != false null -> false } + + internal val isNotEnabled + get() = isEnabled.not() } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/MissingVersionEntries.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/MissingVersionEntries.kt index f49a324a8..70f406f24 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/MissingVersionEntries.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/MissingVersionEntries.kt @@ -9,8 +9,7 @@ import org.gradle.api.artifacts.ExternalDependency @InternalRefreshVersionsApi fun addMissingEntriesInVersionsProperties(project: Project) { - require(project == project.rootProject) { "Expected a rootProject but got $project" } - OutputFile.checkWhichFilesExist(project.rootDir) + OutputFile.checkWhichFilesExist() val configurationsWithHardcodedDependencies = project.findHardcodedDependencies() val versionsMap = RefreshVersionsConfigHolder.readVersionsMap() diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCleanupTask.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCleanupTask.kt index b320f9ca7..e2f6e4a5f 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCleanupTask.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/RefreshVersionsCleanupTask.kt @@ -1,18 +1,24 @@ package de.fayard.refreshVersions.core +import de.fayard.refreshVersions.core.internal.OutputFile import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder import de.fayard.refreshVersions.core.internal.SettingsPluginsUpdater.removeCommentsAddedByUs +import de.fayard.refreshVersions.core.internal.VersionsCatalogUpdater +import de.fayard.refreshVersions.core.internal.VersionsCatalogs +import de.fayard.refreshVersions.core.internal.VersionsCatalogs.LIBS_VERSIONS_TOML import de.fayard.refreshVersions.core.internal.versions.VersionsPropertiesModel import de.fayard.refreshVersions.core.internal.versions.VersionsPropertiesModel.Section import de.fayard.refreshVersions.core.internal.versions.readFromFile import de.fayard.refreshVersions.core.internal.versions.writeTo import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction +import java.io.File open class RefreshVersionsCleanupTask : DefaultTask() { @TaskAction fun cleanUpVersionsProperties() { + OutputFile.checkWhichFilesExist() val model = VersionsPropertiesModel.readFromFile(RefreshVersionsConfigHolder.versionsPropertiesFile) val sectionsWithoutAvailableUpdates = model.sections.map { section -> @@ -23,18 +29,13 @@ open class RefreshVersionsCleanupTask : DefaultTask() { } val newModel = model.copy(sections = sectionsWithoutAvailableUpdates) newModel.writeTo(RefreshVersionsConfigHolder.versionsPropertiesFile) + OutputFile.VERSIONS_PROPERTIES.logFileWasModified() } @TaskAction fun cleanUpSettings() { - val settingsFiles = listOf( - "settings.gradle", - "settings.gradle.kts", - "buildSrc/settings.gradle", - "buildSrc/settings.gradle.kts" - ).mapNotNull { path -> - project.file(path).takeIf { it.exists() } - } + val settingsFiles = OutputFile.settingsFiles + .filter { it.existed } settingsFiles.forEach { settingsFile -> val initialContent = settingsFile.readText() @@ -46,5 +47,16 @@ open class RefreshVersionsCleanupTask : DefaultTask() { settingsFile.writeText(newContent) } } + + settingsFiles.forEach { it.logFileWasModified() } + } + + @TaskAction + fun cleanUpVersionsCatalog() { + if (VersionsCatalogs.isSupported() && FeatureFlag.VERSIONS_CATALOG.isEnabled) { + val file = File(LIBS_VERSIONS_TOML) + VersionsCatalogUpdater(file, emptyList()).cleanupComments(file) + OutputFile.GRADLE_VERSIONS_CATALOG.logFileWasModified() + } } } 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 484c9e4b7..2d0d63a58 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 @@ -3,7 +3,9 @@ package de.fayard.refreshVersions.core import de.fayard.refreshVersions.core.extensions.gradle.isBuildSrc import de.fayard.refreshVersions.core.extensions.gradle.isRootProject import de.fayard.refreshVersions.core.internal.InternalRefreshVersionsApi +import de.fayard.refreshVersions.core.internal.OutputFile import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder +import de.fayard.refreshVersions.core.internal.skipConfigurationCache import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.register @@ -14,6 +16,7 @@ open class RefreshVersionsCorePlugin : Plugin { override fun apply(project: Project) { check(project.isRootProject) { "ERROR: de.fayard.refreshVersions.core should not be applied manually" } + OutputFile.rootDir = project.rootDir if (project.isBuildSrc.not()) { // In the case where this runs in includedBuilds, the task configuration lambda may (will) run // after RefreshVersionsConfigHolder content is cleared (via its ClearStaticStateBuildService), @@ -23,6 +26,7 @@ open class RefreshVersionsCorePlugin : Plugin { project.tasks.register(name = "refreshVersions") { group = "refreshVersions" description = "Search for new dependencies versions and update $versionsFileName" + skipConfigurationCache() } project.tasks.register(name = "refreshVersionsCleanup") { 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 b0ecd9173..00654298b 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 @@ -48,7 +48,8 @@ fun Settings.bootstrapRefreshVersionsCore( versionsPropertiesFile: File = rootDir.resolve("versions.properties"), getDependenciesMapping: () -> List = { emptyList() }, getRemovedDependenciesVersionsKeys: () -> Map = { emptyMap() }, - getRemovedDependencyNotationsReplacementInfo: (() -> RemovedDependencyNotationsReplacementInfo)? = null + getRemovedDependencyNotationsReplacementInfo: (() -> RemovedDependencyNotationsReplacementInfo)? = null, + versionRejectionFilter: (DependencySelection.() -> Boolean)? = null ) { null.checkGradleVersionIsSupported() require(settings.isBuildSrc.not()) { @@ -70,7 +71,8 @@ fun Settings.bootstrapRefreshVersionsCore( settings = settings, artifactVersionKeyRules = artifactVersionKeyRules, getRemovedDependenciesVersionsKeys = getRemovedDependenciesVersionsKeys, - versionsPropertiesFile = versionsPropertiesFile + versionsPropertiesFile = versionsPropertiesFile, + versionRejectionFilter = versionRejectionFilter ) val versionsPropertiesModel = RefreshVersionsConfigHolder.readVersionsPropertiesModel() getRemovedDependencyNotationsReplacementInfo?.let { 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 4e9e74cb8..85e90c211 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,9 @@ package de.fayard.refreshVersions.core +import de.fayard.refreshVersions.core.extensions.gradle.getVersionsCatalog import de.fayard.refreshVersions.core.internal.* import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder.settings +import de.fayard.refreshVersions.core.internal.VersionsCatalogs.LIBS_VERSIONS_TOML import de.fayard.refreshVersions.core.internal.problems.log import de.fayard.refreshVersions.core.internal.versions.VersionsPropertiesModel import de.fayard.refreshVersions.core.internal.versions.writeWithNewVersions @@ -9,6 +11,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import org.gradle.api.DefaultTask import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction @@ -46,7 +49,7 @@ open class RefreshVersionsTask : DefaultTask() { @TaskAction fun taskActionRefreshVersions() { - OutputFile.checkWhichFilesExist(project.rootDir) + OutputFile.checkWhichFilesExist() if (FeatureFlag.userSettings.isNotEmpty()) { logger.lifecycle("Feature flags: " + FeatureFlag.userSettings) @@ -54,6 +57,21 @@ open class RefreshVersionsTask : DefaultTask() { //TODO: Filter using known grouping strategies to only use the main artifact to resolve latest version, this // will reduce the number of repositories lookups, improving performance a little more. + val shouldUpdateVersionCatalogs = VersionsCatalogs.isSupported() && FeatureFlag.VERSIONS_CATALOG.isEnabled + + + val versionsCatalogLibraries: Set + val versionsCatalogPlugins: Set + if (shouldUpdateVersionCatalogs) { + val versionCatalog = project.getVersionsCatalog() + versionsCatalogLibraries = VersionsCatalogs.libraries(versionCatalog) + versionsCatalogPlugins = VersionsCatalogs.plugins(versionCatalog) + } else { + versionsCatalogLibraries = emptySet() + versionsCatalogPlugins = emptySet() + } + + runBlocking { val lintUpdatingProblemsAsync = async { configureLintIfRunningOnAnAndroidProject(settings, RefreshVersionsConfigHolder.readVersionsMap()) @@ -65,10 +83,12 @@ open class RefreshVersionsTask : DefaultTask() { httpClient = httpClient, project = project, versionMap = RefreshVersionsConfigHolder.readVersionsMap(), - versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader + versionKeyReader = RefreshVersionsConfigHolder.versionKeyReader, + versionsCatalogLibraries = versionsCatalogLibraries, + versionsCatalogPlugins = versionsCatalogPlugins ) } - VersionsPropertiesModel.writeWithNewVersions(result.dependenciesUpdates) + VersionsPropertiesModel.writeWithNewVersions(result.dependenciesUpdatesForVersionsProperties) SettingsPluginsUpdater.updateGradleSettingsWithAvailablePluginsUpdates( rootProject = project, settingsPluginsUpdates = result.settingsPluginsUpdates, @@ -83,6 +103,17 @@ open class RefreshVersionsTask : DefaultTask() { logger.log(problem) } OutputFile.VERSIONS_PROPERTIES.logFileWasModified() + + if (shouldUpdateVersionCatalogs) { + val libsToml = project.file(LIBS_VERSIONS_TOML) + if (libsToml.canRead()) { + VersionsCatalogUpdater( + file = libsToml, + dependenciesUpdates = result.dependenciesUpdatesForVersionCatalog + ).updateNewVersions(libsToml) + OutputFile.GRADLE_VERSIONS_CATALOG.logFileWasModified() + } + } } } 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 588ff5177..78c92668d 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 @@ -46,7 +46,7 @@ private fun retrieveVersionFor( ).also { version -> UsedVersionForTracker.noteUsedDependencyNotation( project = project, - dependencyNotation = it, + moduleId = moduleId, version = version ) } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Dependency.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Dependency.kt index c0f98a098..8103c604e 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Dependency.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Dependency.kt @@ -21,3 +21,7 @@ internal fun Dependency.npmModuleId(): ModuleId.Npm { val nameWithoutScope = name.substringAfter('/') return ModuleId.Npm(scope, nameWithoutScope) } + +internal fun Dependency.matches(moduleId: ModuleId): Boolean { + return moduleId.group == group && moduleId.name == name +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Project.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Project.kt index 01a6e0851..32dd65536 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Project.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/Project.kt @@ -1,6 +1,18 @@ package de.fayard.refreshVersions.core.extensions.gradle +import de.fayard.refreshVersions.core.internal.InternalRefreshVersionsApi import org.gradle.api.Project +import org.gradle.api.UnknownDomainObjectException +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.getByType internal val Project.isRootProject: Boolean get() = this == rootProject + internal val Project.isBuildSrc: Boolean get() = isRootProject && name == "buildSrc" + +@InternalRefreshVersionsApi +fun Project.getVersionsCatalog() = try { + project.extensions.getByType().named("libs") +} catch (e: UnknownDomainObjectException) { + null +} \ No newline at end of file diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/VersionConstraint.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/VersionConstraint.kt index c31f49d9c..c5c07cf5d 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/VersionConstraint.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/extensions/gradle/VersionConstraint.kt @@ -18,3 +18,13 @@ internal fun VersionConstraint.hasDynamicVersion(): Boolean { if (requiredVersion.isVersionDynamic().not()) return false return true } + +internal fun VersionConstraint.tryExtractingSimpleVersion(): String? { + fun String.isVersionRange(): Boolean = first() in "[]()" && ',' in this || '+' in this + + return sequence { + yield(strictVersion) + yield(requiredVersion) + yield(preferredVersion) + }.firstOrNull { it.isNotEmpty() && it.isVersionRange().not() } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ArtifactVersionKeyRule.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ArtifactVersionKeyRule.kt index f5e822ce2..b0ec39941 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ArtifactVersionKeyRule.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ArtifactVersionKeyRule.kt @@ -1,7 +1,7 @@ package de.fayard.refreshVersions.core.internal /** - * The rules are case sensitive. + * The rules are case-sensitive. */ @InternalRefreshVersionsApi abstract class ArtifactVersionKeyRule protected constructor( diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ConfigurationLessDependency.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ConfigurationLessDependency.kt new file mode 100644 index 000000000..5f77714fc --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/ConfigurationLessDependency.kt @@ -0,0 +1,49 @@ +package de.fayard.refreshVersions.core.internal + +import de.fayard.refreshVersions.core.ModuleId +import org.gradle.api.artifacts.Dependency +import org.gradle.api.internal.artifacts.dependencies.AbstractDependency + +internal class ConfigurationLessDependency( + private val group: String, + private val name: String, + private val version: String? +) : AbstractDependency() { + + constructor( + moduleId: ModuleId.Maven, + version: String + ) : this( + group = moduleId.group, + name = moduleId.name, + version = version + ) + + companion object { + operator fun invoke(dependencyNotation: String): ConfigurationLessDependency { + val beforeFirstColon = dependencyNotation.substringBefore(':') + val afterFirstColon = dependencyNotation.substringAfter(':') + val name = afterFirstColon.substringBefore(':') + val version = if (afterFirstColon == name) null else afterFirstColon.substringAfterLast(':') + return ConfigurationLessDependency( + group = beforeFirstColon, + name = name, + version = version + ) + } + } + + override fun getGroup() = group + override fun getName() = name + override fun getVersion() = version + + override fun contentEquals(dependency: Dependency): Boolean = throw UnsupportedOperationException() + + override fun copy(): Dependency = ConfigurationLessDependency( + group = group, + name = name, + version = version + ) + + override fun toString(): String = if (version == null) "$group:$name" else "$group:$name:$version" +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyNotations.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyNotations.kt new file mode 100644 index 000000000..2fc164bde --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyNotations.kt @@ -0,0 +1,135 @@ +package de.fayard.refreshVersions.core.internal + +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.ExternalDependency + +@Suppress("EnumEntryName") +@InternalRefreshVersionsApi +enum class Case( + val convert: (String) -> String +) { + snake_case({ it }), + `kebab-case`({ + it.map { c -> + if (c in ".-_") '-' else c + }.joinToString(separator = "") + }); +} + +/** + * We don't want to use meaningless generic libs like Libs.core + * + * Found many inspiration for bad libs here https://developer.android.com/jetpack/androidx/migrate + * **/ +@InternalRefreshVersionsApi +val MEANING_LESS_NAMES: MutableList = mutableListOf( + "common", "core", "testing", "runtime", "extensions", + "compiler", "migration", "db", "rules", "runner", "monitor", "loader", + "media", "print", "io", "collection", "gradle", "android" +) + +@InternalRefreshVersionsApi +fun List.computeAliases( + configured: List, + byDefault: List = MEANING_LESS_NAMES +): List { + val groups = (configured + byDefault).filter { it.contains(".") }.toSet() + val depsFromGroups = filter { it.group in groups }.map { it.module } + val ambiguities = groupBy { it.module }.filter { it.value.size > 1 }.map { it.key } + return (configured + byDefault + ambiguities + depsFromGroups - groups).distinct().sorted() +} + +@InternalRefreshVersionsApi +fun escapeLibsKt(name: String): String { + val escapedChars = listOf('-', '.', ':') + return buildString { + for (c in name) { + append(if (c in escapedChars) '_' else c.toLowerCase()) + } + } +} + +@InternalRefreshVersionsApi +fun Project.findDependencies(): List { + val allDependencies = mutableListOf() + allprojects { + (buildscript.configurations + configurations).flatMapTo(allDependencies) { configuration -> + configuration.allDependencies + .filterIsInstance() + .mapNotNull { dependency -> + Library( + group = dependency.group ?: return@mapNotNull null, + module = dependency.name, + version = dependency.version + ) + } + } + } + return allDependencies.distinctBy { d -> d.groupModule() } +} + + +@InternalRefreshVersionsApi +data class Library( + val group: String = "", + val module: String = "", + val version: String? = null +) { + fun toDependency(): Dependency = ConfigurationLessDependency( + group = group, + name = name, + version = version + ) + + val name: String get() = module + fun groupModuleUnderscore() = "$group:$module:_" + fun groupModule() = "$group:$module" + + @Suppress("LocalVariableName") + fun versionName(mode: VersionMode, case: Case): String { + val name_with_underscores = escapeLibsKt( + when (mode) { + VersionMode.MODULE -> module + VersionMode.GROUP -> group + VersionMode.GROUP_MODULE -> "${group}_$module" + } + ) + return case.convert(name_with_underscores) + } + + override fun toString(): String = if (version == null) "$group:$name" else "$group:$name:$version" +} + +@InternalRefreshVersionsApi +class Deps( + val libraries: List, + val names: Map +) + + +@InternalRefreshVersionsApi +enum class VersionMode { + GROUP, GROUP_MODULE, MODULE +} + +@InternalRefreshVersionsApi +fun List.checkModeAndNames(useFdqnByDefault: List, case: Case): Deps { + val dependencies = this + + val modes: Map = + dependencies.associateWith { d -> + when { + d.module in useFdqnByDefault -> VersionMode.GROUP_MODULE + escapeLibsKt(d.module) in useFdqnByDefault -> VersionMode.GROUP_MODULE + else -> VersionMode.MODULE + } + }.toMutableMap() + + val versionNames = dependencies.associateWith { d -> + val mode = modes.getValue(d) + d.versionName(mode, case) + } + val sortedDependencies = dependencies.sortedBy { d: Library -> d.groupModule() } + return Deps(sortedDependencies, versionNames) +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyWithVersionCandidates.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyWithVersionCandidates.kt index db386fd26..9f8c0843f 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyWithVersionCandidates.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/DependencyWithVersionCandidates.kt @@ -4,9 +4,9 @@ import de.fayard.refreshVersions.core.DependencyVersionsFetcher import de.fayard.refreshVersions.core.ModuleId import de.fayard.refreshVersions.core.Version -internal data class DependencyWithVersionCandidates( +internal class DependencyWithVersionCandidates( val moduleId: ModuleId, - val currentVersion: String, - val versionsCandidates: List, + val currentVersion: String, // TODO: Ensure VersionsCatalogUpdater can have the data it needs, and remove this. + val versionsCandidates: (currentVersion: Version) -> List, val failures: List ) diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/GettingVersionCandidates.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/GettingVersionCandidates.kt index fbbc29699..1c9e347c7 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/GettingVersionCandidates.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/GettingVersionCandidates.kt @@ -12,8 +12,14 @@ internal suspend fun List.getVersionCandidates( currentVersion: Version, resultMode: VersionCandidatesResultMode ): Pair, List> { - val results = getVersionCandidates(versionFilter = { it > currentVersion }) + return results.sortWith(resultMode) +} + +internal fun List.sortWith( + resultMode: VersionCandidatesResultMode +): Pair, List> { + val results = this val versionsList = results.filterIsInstance() val failures = results.filterIsInstance() return when (resultMode.filterMode) { diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/InternalExtensions.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/InternalExtensions.kt deleted file mode 100644 index ea5ac3496..000000000 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/InternalExtensions.kt +++ /dev/null @@ -1,34 +0,0 @@ -package de.fayard.refreshVersions.core.internal - -import de.fayard.refreshVersions.core.ModuleId -import de.fayard.refreshVersions.core.extensions.gradle.moduleId -import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.ExternalDependency - -@InternalRefreshVersionsApi -fun Dependency.hasHardcodedVersion( - versionMap: Map, - versionKeyReader: ArtifactVersionKeyReader -): Boolean = isManageableVersion(versionMap, versionKeyReader).not() - -@InternalRefreshVersionsApi -fun Dependency.isManageableVersion( - versionMap: Map, - versionKeyReader: ArtifactVersionKeyReader -): Boolean { - return when { - version == versionPlaceholder -> true - this is ExternalDependency && versionPlaceholder in this.versionConstraint.rejectedVersions -> true - name.endsWith(".gradle.plugin") -> { - when (val moduleId = moduleId()) { - is ModuleId.Maven -> { - val versionFromProperty = versionMap[getVersionPropertyName(moduleId, versionKeyReader)] - ?: return false - versionFromProperty.isAVersionAlias().not() - } - else -> false - } - } - else -> false - } -} 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 0aeb714e1..fdde0af95 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 @@ -18,6 +18,7 @@ import org.gradle.api.artifacts.ArtifactRepositoryContainer import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.ExternalDependency +import org.gradle.api.artifacts.MinimalExternalModuleDependency import org.gradle.api.artifacts.dsl.RepositoryHandler import org.gradle.api.artifacts.repositories.MavenArtifactRepository import org.gradle.api.initialization.Settings @@ -27,90 +28,177 @@ internal suspend fun lookupVersionCandidates( httpClient: OkHttpClient, project: Project, versionMap: Map, - versionKeyReader: ArtifactVersionKeyReader + versionKeyReader: ArtifactVersionKeyReader, + versionsCatalogLibraries: Set, + versionsCatalogPlugins: Set ): VersionCandidatesLookupResult { require(project.isRootProject) val projects = RefreshVersionsConfigHolder.allProjects(project) + val dependenciesFromVersionFor = UsedVersionForTracker.read() + + return lookupVersionCandidates( + dependencyVersionsFetchers = { dependencyFilter -> + projects.flatMap { + it.getDependencyVersionFetchers(httpClient = httpClient, dependencyFilter = dependencyFilter) + }.plus( + UsedPluginsTracker.read().getDependencyVersionsFetchers(httpClient) + ).plus( + dependenciesFromVersionFor.asSequence().onEach { (dependency, _) -> + check(dependencyFilter(dependency)) // Needed because dependencyFilter also tracks dependencies usage. + }.getDependencyVersionsFetchers(httpClient) + ).toSet() + }, + lookupAvailableGradleVersions = { + if (GRADLE_UPDATES.isEnabled) lookupAvailableGradleVersions(httpClient) else emptyList() + }, + lookupSettingsPluginUpdates = { resultMode -> + SettingsPluginsUpdatesFinder.getSettingsPluginUpdates(httpClient, resultMode) + }, + versionMap = versionMap, + versionKeyReader = versionKeyReader, + versionsCatalogLibraries = versionsCatalogLibraries, + versionsCatalogPlugins = versionsCatalogPlugins, + dependenciesFromVersionFor = dependenciesFromVersionFor.map { (dependency, _) -> dependency } + ) +} + +internal suspend fun lookupVersionCandidates( + dependencyVersionsFetchers: (dependencyFilter: (Dependency) -> Boolean) -> Set, + lookupAvailableGradleVersions: suspend () -> List, + lookupSettingsPluginUpdates: suspend (VersionCandidatesResultMode) -> SettingsPluginsUpdatesFinder.UpdatesLookupResult, + versionMap: Map, + versionKeyReader: ArtifactVersionKeyReader, + versionsCatalogLibraries: Set, + versionsCatalogPlugins: Set, + dependenciesFromVersionFor: List +): VersionCandidatesLookupResult { + val dependenciesWithHardcodedVersions = mutableListOf() val dependenciesWithDynamicVersions = mutableListOf() + val managedDependencies = mutableListOf>() + val dependencyFilter: (Dependency) -> Boolean = { dependency -> - dependency.isManageableVersion(versionMap, versionKeyReader).also { manageable -> - if (manageable) return@also - if (dependency.version != null) { - // null version means it's expected to be added by a BoM or a plugin, so we ignore them. - dependenciesWithHardcodedVersions.add(dependency) + val versionManagementKind = dependency.versionManagementKind( + versionMap = versionMap, + versionKeyReader = versionKeyReader, + versionsCatalogLibraries = versionsCatalogLibraries, + versionsCatalogPlugins = versionsCatalogPlugins, + dependenciesFromVersionFor = dependenciesFromVersionFor + ) + when (versionManagementKind) { + is VersionManagementKind.Match -> { + managedDependencies.add(dependency to versionManagementKind) + true } - if (dependency is ExternalDependency && - dependency.versionConstraint.hasDynamicVersion() - ) { - dependenciesWithDynamicVersions.add(dependency) + VersionManagementKind.NoMatch -> { + if (dependency.version != null) { + // null version means it's expected to be added by a BoM or a plugin, so we ignore them. + dependenciesWithHardcodedVersions.add(dependency) + } + if (dependency is ExternalDependency && + dependency.versionConstraint.hasDynamicVersion() + ) { + dependenciesWithDynamicVersions.add(dependency) + } + false } } } - val dependencyVersionsFetchers: Set = projects.flatMap { - it.getDependencyVersionFetchers(httpClient = httpClient, dependencyFilter = dependencyFilter) - }.plus( - UsedPluginsTracker.read().getDependencyVersionsFetchers(httpClient) - ).plus( - UsedVersionForTracker.read().getDependencyVersionsFetchers(httpClient) - ).toSet() return coroutineScope { val resultMode = RefreshVersionsConfigHolder.resultMode val versionRejectionFilter = RefreshVersionsConfigHolder.versionRejectionFilter ?: { false } - val dependenciesWithVersionCandidatesAsync = dependencyVersionsFetchers.groupBy { + val dependenciesWithVersionCandidatesAsync = dependencyVersionsFetchers(dependencyFilter).groupBy { it.moduleId }.map { (moduleId: ModuleId, versionFetchers: List) -> - val propertyName = getVersionPropertyName(moduleId, versionKeyReader) - val resolvedVersion = resolveVersion( - properties = versionMap, - key = propertyName - )?.let { Version(it) } async { + val propertyName = getVersionPropertyName(moduleId, versionKeyReader) + val emptyVersion = Version("") + val resolvedVersion = resolveVersion( + properties = versionMap, + key = propertyName + )?.let { Version(it) } ?: emptyVersion + val lowestVersionInCatalog = versionsCatalogLibraries.mapNotNull { + val matches = it.module.group == moduleId.group && it.module.name == it.module.name + when { + matches -> it.versionConstraint.tryExtractingSimpleVersion()?.let { rawVersion -> + Version(rawVersion) + } + else -> null + } + }.minOrNull() + val lowestUsedVersion = minOf(resolvedVersion, lowestVersionInCatalog ?: resolvedVersion) val (versions, failures) = versionFetchers.getVersionCandidates( - currentVersion = resolvedVersion ?: Version(""), + currentVersion = lowestUsedVersion, resultMode = resultMode ) - val currentVersion = resolvedVersion ?: versions.latestMostStable() - val selection = DependencySelection(moduleId, currentVersion, propertyName) DependencyWithVersionCandidates( moduleId = moduleId, - currentVersion = currentVersion.value, - versionsCandidates = versions.filterNot { version -> - selection.candidate = version - versionRejectionFilter(selection) + currentVersion = lowestUsedVersion.value, + versionsCandidates = { currentVersion -> + val selection = DependencySelection(moduleId, currentVersion, propertyName) + versions.filter { version -> + selection.candidate = version + version > currentVersion && versionRejectionFilter(selection).not() + } }, failures = failures ) } } - val settingsPluginsUpdatesAsync = async { - SettingsPluginsUpdatesFinder.getSettingsPluginUpdates(httpClient, resultMode) - } + val settingsPluginsUpdatesAsync = async { lookupSettingsPluginUpdates(resultMode) } + val gradleUpdatesAsync = async { lookupAvailableGradleVersions() } - val gradleUpdatesAsync = async { - if (GRADLE_UPDATES.isEnabled) lookupAvailableGradleVersions(httpClient) else emptyList() - } - - val dependenciesWithVersionCandidates = dependenciesWithVersionCandidatesAsync.awaitAll() + val versionsCandidatesResult = dependenciesWithVersionCandidatesAsync.awaitAll().splitForTargets( + managedDependencies = managedDependencies + ) return@coroutineScope VersionCandidatesLookupResult( - dependenciesUpdates = dependenciesWithVersionCandidates, + dependenciesUpdatesForVersionsProperties = versionsCandidatesResult.forVersionsProperties, + dependenciesUpdatesForVersionCatalog = versionsCandidatesResult.forVersionsCatalog, dependenciesWithHardcodedVersions = dependenciesWithHardcodedVersions, dependenciesWithDynamicVersions = dependenciesWithDynamicVersions, gradleUpdates = gradleUpdatesAsync.await(), settingsPluginsUpdates = settingsPluginsUpdatesAsync.await().settings, buildSrcSettingsPluginsUpdates = settingsPluginsUpdatesAsync.await().buildSrcSettings ) - TODO("Check version candidates for the same key are the same, or warn the user with actionable details") + //TODO: Check version candidates for the same key are the same, or warn the user with actionable details. } } +private class VersionCandidatesResult( + val forVersionsProperties: List, + val forVersionsCatalog: List, +) + +private fun List.splitForTargets( + managedDependencies: MutableList> +): VersionCandidatesResult { + val forVersionsProperties = mutableListOf() + val forVersionCatalog = mutableListOf() + + forEach { dependencyWithVersionCandidates -> + managedDependencies.forEach { (dependency, versionManagementKind) -> + if (dependency.matches(dependencyWithVersionCandidates.moduleId)) { + val targetList = when (versionManagementKind) { + is VersionManagementKind.Match.VersionsCatalog -> forVersionCatalog + is VersionManagementKind.Match.VersionsFile -> forVersionsProperties + } + targetList.add(dependencyWithVersionCandidates) + } + } + } + return VersionCandidatesResult( + forVersionsProperties = forVersionsProperties, + forVersionsCatalog = forVersionCatalog + ) +} + private suspend fun lookupAvailableGradleVersions(httpClient: OkHttpClient): List = coroutineScope { val checker = GradleUpdateChecker(httpClient) val currentGradleVersion = GradleVersion.current() diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/OutputFile.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/OutputFile.kt index f41d58f6a..5867a8da1 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/OutputFile.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/OutputFile.kt @@ -1,6 +1,6 @@ package de.fayard.refreshVersions.core.internal -import org.gradle.api.Project +import de.fayard.refreshVersions.core.internal.VersionsCatalogs.LIBS_VERSIONS_TOML import java.io.File @InternalRefreshVersionsApi @@ -13,24 +13,31 @@ enum class OutputFile(var path: String, var existed: Boolean = false, val altern VERSIONS_PROPERTIES("versions.properties"), SETTINGS_GRADLE("settings.gradle"), SETTINGS_GRADLE_KTS("settings.gradle.kts"), - GRADLE_VERSIONS_CATALOG("gradle/libs.versions.toml"), + BUILD_SETTINGS_GRADLE("build/settings.gradle"), + BUILD_SETTINGS_GRADLE_KTS("build/settings.gradle.kts"), + GRADLE_VERSIONS_CATALOG(LIBS_VERSIONS_TOML), ; + val file get() = rootDir.resolve(path) - fun readText(project: Project) = when { - project.file(path).canRead() -> project.file(path).readText() - alternativePath != null && project.file(alternativePath).canRead() -> project.file(alternativePath).readText() - else -> { - println("${ANSI_RED}Cannot read file $path ${alternativePath ?: ""} $ANSI_RESET") - error("File not found $this") + val alternativeFile: File? + get() = alternativePath + ?.let { rootDir.resolve(it) } + ?.takeIf { it.canRead() } + + fun readText() = when { + file.canRead() -> file.readText() + alternativeFile != null -> alternativeFile!!.readText() + else -> { + println("${ANSI_RED}Cannot read file $path ${alternativePath ?: ""} $ANSI_RESET") + error("File not found $this") + } } - } - fun writeText(text: String, project: Project, mustExists: Boolean = false) = when { - !mustExists -> project.file(path).writeText(text) - project.file(path).exists() -> project.file(path).writeText(text) - alternativePath != null && project.file(alternativePath).canRead() -> project.file(alternativePath) - .writeText(text) + fun writeText(text: String, mustExists: Boolean = false) = when { + !mustExists -> file.writeText(text) + file.exists() -> file.writeText(text) + alternativeFile != null -> alternativeFile!!.writeText(text) else -> { println("${ANSI_RED}Cannot write file $path ${alternativePath ?: ""} $ANSI_RESET") error("File not found $this") @@ -43,6 +50,10 @@ enum class OutputFile(var path: String, var existed: Boolean = false, val altern } companion object { + lateinit var rootDir: File + + val settingsFiles = listOf(SETTINGS_GRADLE, SETTINGS_GRADLE_KTS, BUILD_SETTINGS_GRADLE, BUILD_SETTINGS_GRADLE_KTS) + // COLORS private const val ANSI_RESET = "\u001B[0m" private const val ANSI_GREEN = "\u001B[32m" @@ -63,7 +74,7 @@ enum class OutputFile(var path: String, var existed: Boolean = false, val altern println("$color$status$path$ANSI_RESET") } - fun checkWhichFilesExist(rootDir: File) { + fun checkWhichFilesExist() { values().forEach { outputFile -> outputFile.existed = when { rootDir.resolve(outputFile.path).exists() -> true diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/PluginDependencyCompat.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/PluginDependencyCompat.kt new file mode 100644 index 000000000..311758c1e --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/PluginDependencyCompat.kt @@ -0,0 +1,18 @@ +package de.fayard.refreshVersions.core.internal + +import org.gradle.api.artifacts.VersionConstraint +import org.gradle.plugin.use.PluginDependency + +/** + * The [PluginDependency] class has been introduced in Gradle 7.2, but we support Gradle 6.8, + * so we have this compatibility class, so that we can reference its type safely even on older Gradle versions. + */ +internal data class PluginDependencyCompat( + val pluginId: String, + val version: VersionConstraint +) { + constructor(pluginDependency: PluginDependency) : this( + pluginId = pluginDependency.pluginId, + version = pluginDependency.version + ) +} 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 abc8db105..a3d918195 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 @@ -88,14 +88,17 @@ object RefreshVersionsConfigHolder { settings: Settings, artifactVersionKeyRules: List, getRemovedDependenciesVersionsKeys: () -> Map, - versionsPropertiesFile: File + versionsPropertiesFile: File, + versionRejectionFilter: (DependencySelection.() -> Boolean)? ) { require(settings.isBuildSrc.not()) + resettableDelegates.reset() this.settings = settings this.versionsPropertiesFile = versionsPropertiesFile.also { it.createNewFile() // Creates the file if it doesn't exist yet } + this.versionRejectionFilter = versionRejectionFilter this.artifactVersionKeyRules = artifactVersionKeyRules versionKeyReader = ArtifactVersionKeyReader.fromRules( filesContent = artifactVersionKeyRules, diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Tasks.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Tasks.kt new file mode 100644 index 000000000..5ec276ff3 --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Tasks.kt @@ -0,0 +1,14 @@ +package de.fayard.refreshVersions.core.internal + +import org.gradle.api.Task +import kotlin.reflect.full.memberFunctions + +@InternalRefreshVersionsApi +fun Task.skipConfigurationCache() { + this::class.memberFunctions + .firstOrNull { it.name == "notCompatibleWithConfigurationCache" } + ?.call(this, "Task $name does not support Configuration Cache") + ?: run { + println("warning: task $name not compatible with the configuration cache.") + } +} \ No newline at end of file diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Toml.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Toml.kt new file mode 100644 index 000000000..75572ee7d --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/Toml.kt @@ -0,0 +1,58 @@ +package de.fayard.refreshVersions.core.internal + +internal data class Toml( + val sections: MutableMap> +) { + + override fun toString() = format() + + internal operator fun set(section: TomlSection, lines: List) { + sections[section] = lines + } + + fun merge( + section: TomlSection, + newLines: List + ) { + val existingKeys = get(section).map { it.key }.toSet() - "" + val filteredLines = newLines.filterNot { it.key in existingKeys } + val updateExistingLines = get(section).map { line -> + newLines.firstOrNull { it.key == line.key } ?: line + } + sections[section] = updateExistingLines + filteredLines + } + + internal operator fun get(section: TomlSection): List = sections[section] ?: emptyList() + + private fun format(): String = buildString { + initializeRoot() + for (section in sortedSections()) { + val lines = get(section) + + if (lines.isNotEmpty()) { + if (section != TomlSection.Root) append("\n[$section]\n\n") + append(lines.removeDuplicateBlanks().toText().trim()) + append("\n") + } + } + } + + private fun List.removeDuplicateBlanks(): List { + return filterIndexed { index, tomlLine -> + if (index == 0) return@filterIndexed true + val previous = this[index - 1] + tomlLine.text.isNotBlank() || previous.text.isNotBlank() + } + } + + private fun sortedSections() = (TomlSection.orderedSections + sections.keys).toSet() + + private fun initializeRoot() { + if (get(TomlSection.Root).none { it.text.isNotBlank() }) { + this[TomlSection.Root] = listOf( + TomlLine(TomlSection.Root, "## Generated by \$ ./gradlew refreshVersionsCatalog"), + TomlLine.newLine, + ) + } + } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlLine.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlLine.kt new file mode 100644 index 000000000..eb905772c --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlLine.kt @@ -0,0 +1,174 @@ +package de.fayard.refreshVersions.core.internal + +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.* +import org.gradle.api.artifacts.Dependency + +/** + * Despite TOML supporting braces in its syntax, they must open and close on + * the same line, so having a per-line model is fine. + */ +internal data class TomlLine( + val section: TomlSection, + val text: String, +) { + + internal enum class Kind { Ignore, Deletable, Libs, LibsUnderscore, LibsVersionRef, Version, Plugin, PluginVersionRef } + //TODO: Maybe convert to sealed class/interface? + + val textWithoutComment = text.substringBefore("#") + + val key = textWithoutComment.substringBefore("=", missingDelimiterValue = "").trim() + val hasKey = key.isNotBlank() + + val unparsedValue: String = if (hasKey.not()) "" else textWithoutComment.substringAfter("=").trim() + + fun String.unquote() = trim().removeSurrounding("\"") + + val value = if (unparsedValue.startsWith('"')) unparsedValue.unquote() else "" + + val kind: Kind = this.guessTomlLineKind() + + val map: Map = parseTomlMap(kind).withDefault { "" } + + val versionRef get() = map["version.ref"] + + val module get() = "$group:$name" + + val version: String get() = if (section == TomlSection.Versions) value else map["version"] ?: "" + + val group: String get() = if (section == TomlSection.Plugins) id else map["group"]!! + + val name: String get() = if (section == TomlSection.Plugins) "$id.gradle.plugin" else map["name"]!! + + val id: String by map + + override fun toString(): String = "TomlLine(section=$section, kind=$kind, key=$key, value=$value, map=$map)\n$text" + + internal companion object { + val newLine = TomlLine(TomlSection.Custom("blank"), "") + } +} + +internal fun List.toText(): String = joinToString("\n", postfix = "\n", prefix = "\n") { it.text } + +internal fun TomlLine( + section: TomlSection, + key: String, + value: String +): TomlLine = TomlLine(section, """$key = "$value"""") + +internal fun TomlLine( + section: TomlSection, + key: String, + dependency: Dependency +): TomlLine = when (dependency.version) { + null -> TomlLine( + section = section, + key = key, + value = """${dependency.group}:${dependency.name}""" + ) + else -> TomlLine( + section = section, + key = key, + value = """${dependency.group}:${dependency.name}:${dependency.version}""" + ) +} + +internal fun TomlLine( + section: TomlSection, + key: String, + map: Map +): TomlLine { + require((map.keys - validKeys).isEmpty()) { "Map $map has invalid keys. Valid: $validKeys" } + val formatMap = map.entries + .joinToString(", ") { (key, value) -> """$key = "$value"""" } + return TomlLine(section, "$key = { $formatMap }") +} + +private val validKeys = listOf("module", "group", "name", "version.ref", "version", "id") + +private fun TomlLine.parseTomlMap(kind: TomlLine.Kind): Map { + val splitByColon = value.split(":") + + val map: MutableMap = when { + unparsedValue.startsWith('{').not() -> mutableMapOf() + else -> unparsedValue + .removeSurrounding("{", "}") + .split(",") + .associate { entry -> + val (key, value) = entry.split("=") + key.unquote() to value.unquote() + }.toMutableMap() + } + + return when (kind) { + Ignore -> emptyMap() + Deletable -> emptyMap() + LibsUnderscore -> emptyMap() + Version -> emptyMap() + Plugin, PluginVersionRef -> when { + value.isNotBlank() -> mutableMapOf().apply { //TODO: Replace with buildMap later. + this["id"] = splitByColon.first() + splitByColon.getOrNull(1)?.also { version -> + this["version"] = version + } + } + else -> map + } + Libs, LibsVersionRef -> when { + value.isNotBlank() -> { + val (group, name) = splitByColon + val version = splitByColon.getOrNull(2) + lineMap(group = group, name = name, version = version, versionRef = null) + } + else -> { + map["module"]?.also { module -> + val (group, name) = module.split(":") + map.remove("module") + map["group"] = group + map["name"] = name + } + map + } + } + } +} + +private fun lineMap( + group: String, + name: String, + version: String?, + versionRef: String? +) = listOfNotNull( + "group" to group, + "name" to name, + version?.let { "version" to it }, + versionRef?.let { "version.ref" to it } +).toMap() + +private fun TomlLine.guessTomlLineKind(): TomlLine.Kind { + if (text.startsWith("##")) return Deletable + + val hasVersionRef = textWithoutComment.contains("version.ref") + + return when (section) { + is TomlSection.Custom -> Ignore + TomlSection.Root -> Ignore + TomlSection.Bundles -> Ignore + TomlSection.Versions -> when { + hasKey -> Version + else -> Ignore + } + TomlSection.Libraries -> when { + hasKey.not() -> Ignore + textWithoutComment.endsWith(":_\"") -> LibsUnderscore + hasVersionRef -> LibsVersionRef + else -> Libs + } + TomlSection.Plugins -> when { + hasKey.not() -> Ignore + hasVersionRef -> PluginVersionRef + else -> Plugin + } + } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlSection.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlSection.kt new file mode 100644 index 000000000..be2563920 --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/TomlSection.kt @@ -0,0 +1,19 @@ +package de.fayard.refreshVersions.core.internal + +internal sealed class TomlSection(open val name: String) { + + override fun toString() = name + + object Root: TomlSection("root") + object Versions: TomlSection("versions") + object Plugins: TomlSection("plugins") + object Bundles: TomlSection("bundles") + object Libraries: TomlSection("libraries") + data class Custom(override val name: String) : TomlSection(name) + + companion object { + val orderedSections = listOf(Root, Bundles, Plugins, Versions, Libraries) + + fun from(name: String): TomlSection = orderedSections.firstOrNull { it.name == name } ?: Custom(name) + } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsTracker.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsTracker.kt index 100a3b165..f5e63affa 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsTracker.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedPluginsTracker.kt @@ -5,9 +5,9 @@ import org.gradle.api.artifacts.ArtifactRepositoryContainer import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.ExternalDependency import org.gradle.api.initialization.Settings -import org.gradle.api.internal.artifacts.dependencies.AbstractDependency -internal object UsedPluginsTracker { +@InternalRefreshVersionsApi +object UsedPluginsTracker { fun clearFor(settings: Settings) { if (settings.isBuildSrc) buildSrcHolder = null else projectHolder = null @@ -75,22 +75,4 @@ internal object UsedPluginsTracker { val usedPluginDependencies = mutableListOf() val usedPluginsWithoutEntryInVersionsFile = mutableListOf() } - - private class ConfigurationLessDependency(val dependencyNotation: String) : AbstractDependency() { - - override fun getGroup() = group - override fun getName() = name - override fun getVersion(): String? = version - - override fun contentEquals(dependency: Dependency): Boolean = throw UnsupportedOperationException() - override fun copy(): Dependency = ConfigurationLessDependency(dependencyNotation) - - private val group = dependencyNotation.substringBefore(':').unwrappedNullableValue() - private val name = dependencyNotation.substringAfter(':').substringBefore(':') - private val version = dependencyNotation.substringAfterLast(':').unwrappedNullableValue() - - private fun String.unwrappedNullableValue(): String? = if (this == "null") null else this - - override fun toString() = "$group:$name:$version" - } } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedVersionForTracker.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedVersionForTracker.kt index 4246ca4d2..367473eaa 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedVersionForTracker.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/UsedVersionForTracker.kt @@ -1,11 +1,11 @@ package de.fayard.refreshVersions.core.internal +import de.fayard.refreshVersions.core.ModuleId import de.fayard.refreshVersions.core.extensions.gradle.isBuildSrc import org.gradle.api.Project import org.gradle.api.artifacts.ArtifactRepositoryContainer import org.gradle.api.artifacts.Dependency import org.gradle.api.initialization.Settings -import org.gradle.api.internal.artifacts.dependencies.AbstractDependency internal object UsedVersionForTracker { @@ -15,12 +15,12 @@ internal object UsedVersionForTracker { fun noteUsedDependencyNotation( project: Project, - dependencyNotation: String, + moduleId: ModuleId.Maven, version: String ) { editHolder(project) { holder -> holder.usedInVersionsFor += VersionForUsage( - dependencyNotation = dependencyNotation, + moduleId = moduleId, version = version, repositories = project.repositories ) @@ -33,11 +33,11 @@ internal object UsedVersionForTracker { } } - fun read(): Sequence> { - return usedInVersionsFor.asSequence().map { + fun read(): List> { + return usedInVersionsFor.map { ConfigurationLessDependency( - it.dependencyNotation, - it.version + moduleId = it.moduleId, + version = it.version ) to it.repositories } } @@ -72,7 +72,7 @@ internal object UsedVersionForTracker { private var buildSrcHolder: Holder? = null private data class VersionForUsage( - val dependencyNotation: String, + val moduleId: ModuleId.Maven, val version: String, val repositories: ArtifactRepositoryContainer ) @@ -81,24 +81,4 @@ internal object UsedVersionForTracker { val usedInVersionsFor = mutableListOf() val usedVersionKeys = mutableListOf() } - - private class ConfigurationLessDependency( - val dependencyNotation: String, - private val version: String - ) : AbstractDependency() { - - override fun getGroup() = group - override fun getName() = name - override fun getVersion(): String = version - - override fun contentEquals(dependency: Dependency): Boolean = throw UnsupportedOperationException() - override fun copy(): Dependency = ConfigurationLessDependency(dependencyNotation, version) - - private val group = dependencyNotation.substringBefore(':').unwrappedNullableValue() - private val name = dependencyNotation.substringAfter(':').substringBefore(':') - - private fun String.unwrappedNullableValue(): String? = if (this == "null") null else this - - override fun toString() = "$group:$name:$version" - } } diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionCandidatesLookupResult.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionCandidatesLookupResult.kt index bf3ad7690..56ec884cd 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionCandidatesLookupResult.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionCandidatesLookupResult.kt @@ -4,7 +4,8 @@ import de.fayard.refreshVersions.core.Version import org.gradle.api.artifacts.Dependency internal class VersionCandidatesLookupResult( - val dependenciesUpdates: List, + val dependenciesUpdatesForVersionsProperties: List, + val dependenciesUpdatesForVersionCatalog: List, val dependenciesWithHardcodedVersions: List, val dependenciesWithDynamicVersions: List, val gradleUpdates: List, diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionManagementKind.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionManagementKind.kt new file mode 100644 index 000000000..22ca962e0 --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionManagementKind.kt @@ -0,0 +1,103 @@ +package de.fayard.refreshVersions.core.internal + +import de.fayard.refreshVersions.core.ModuleId +import de.fayard.refreshVersions.core.extensions.gradle.moduleId +import de.fayard.refreshVersions.core.internal.VersionManagementKind.Match +import de.fayard.refreshVersions.core.internal.VersionManagementKind.NoMatch +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.ExternalDependency +import org.gradle.api.artifacts.MinimalExternalModuleDependency + +@InternalRefreshVersionsApi +fun Dependency.hasHardcodedVersion( //TODO: Remove code calling this and remove this. + versionMap: Map, + versionKeyReader: ArtifactVersionKeyReader +): Boolean = versionManagementKind( + versionMap = versionMap, + versionKeyReader = versionKeyReader, + versionsCatalogLibraries = emptySet(), + versionsCatalogPlugins = emptySet(), + dependenciesFromVersionFor = emptyList() +) == NoMatch + +internal sealed class VersionManagementKind { + sealed class Match : VersionManagementKind() { + + sealed class VersionsCatalog : Match() { + /** Matching version constraint doesn't guarantee the version catalog entry is actually used. */ + object MatchingVersionConstraint : VersionsCatalog() + } + + /** The versions.properties file for now, possibly versions catalogs in the future. */ + sealed class VersionsFile : Match() { + + /** Matching version constraint doesn't guarantee the version catalog entry is actually used. */ + object MatchingPluginVersion : VersionsFile() + + object VersionPlaceholder : VersionsFile() + + object UsedInVersionFor : VersionsFile() + } + + } + object NoMatch : VersionManagementKind() +} + +internal fun Dependency.versionManagementKind( + versionMap: Map, + versionKeyReader: ArtifactVersionKeyReader, + versionsCatalogLibraries: Collection, + versionsCatalogPlugins: Set, + dependenciesFromVersionFor: List, +): VersionManagementKind = when { + this in dependenciesFromVersionFor -> Match.VersionsFile.UsedInVersionFor + version == versionPlaceholder -> Match.VersionsFile.VersionPlaceholder + this is ExternalDependency && versionPlaceholder in this.versionConstraint.rejectedVersions -> { + Match.VersionsFile.VersionPlaceholder + } + name.endsWith(".gradle.plugin") -> { + when (val moduleId = moduleId()) { + is ModuleId.Maven -> { + val versionFromProperty = resolveVersion( + properties = versionMap, + key = getVersionPropertyName(moduleId, versionKeyReader) + ) + when (versionFromProperty) { + null -> when { + hasVersionInVersionCatalog( + versionsCatalogMapping = versionsCatalogLibraries, + versionsCatalogLibraries = versionsCatalogPlugins + ) -> Match.VersionsCatalog.MatchingVersionConstraint + else -> NoMatch + } + version -> Match.VersionsFile.MatchingPluginVersion + else -> NoMatch + } + } + else -> NoMatch + } + } + else -> when { + hasVersionInVersionCatalog( + versionsCatalogMapping = versionsCatalogLibraries + ) -> Match.VersionsCatalog.MatchingVersionConstraint + else -> NoMatch + } +} + +private fun Dependency.hasVersionInVersionCatalog( + versionsCatalogMapping: Collection, + versionsCatalogLibraries: Set = emptySet() +): Boolean { + if (this !is ExternalDependency) return false + + val matchingLib = versionsCatalogMapping.any { + it.module.group == group && it.module.name == name && it.versionConstraint == versionConstraint + } + if (matchingLib) return true + + if (name.endsWith(".gradle.plugin").not()) return false + + val pluginId = name.substringBeforeLast(".gradle.plugin") + return versionsCatalogLibraries.any { it.pluginId == pluginId && it.version == versionConstraint } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogUpdater.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogUpdater.kt new file mode 100644 index 000000000..79efb2cb4 --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogUpdater.kt @@ -0,0 +1,96 @@ +package de.fayard.refreshVersions.core.internal + +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.* +import java.io.File +import de.fayard.refreshVersions.core.Version as MavenVersion + +internal class VersionsCatalogUpdater( + private val fileContent: String, + private val dependenciesUpdates: List +) { + + private val toml = VersionsCatalogs.parseToml(fileContent) + + fun updateNewVersions(actual: File) { + if (fileContent.isBlank()) return + + toml.sections.forEach { (section, lines) -> + toml[section] = updateNewVersions(lines) + } + actual.writeText(toml.toString()) + } + + fun cleanupComments(actual: File) { + if (fileContent.isBlank()) return + + toml.sections.forEach { (section, lines) -> + toml[section] = lines.filter { it.kind != Deletable } + } + actual.writeText(toml.toString()) + } + + private fun updateNewVersions(lines: List): List = lines.flatMap { line -> + when (line.kind) { + Ignore, LibsUnderscore, LibsVersionRef, PluginVersionRef -> listOf(line) + Deletable -> emptyList() + Version -> { + linesForUpdate(line, findLineReferencing(line)) + } + Libs, Plugin -> { + val updates = dependenciesUpdates.firstOrNull { + it.moduleId.name == line.name && it.moduleId.group == line.group + } + linesForUpdate(line, updates) + } + } + } + + private fun findLineReferencing(version: TomlLine): DependencyWithVersionCandidates? { + val libOrPlugin = toml.sections.values.flatten().firstOrNull { line -> + line.versionRef == version.key + } ?: return null + + return dependenciesUpdates.firstOrNull { + val moduleId = it.moduleId + (moduleId.name == libOrPlugin.name) && (moduleId.group == libOrPlugin.group) + } + } + + private fun linesForUpdate( + line: TomlLine, + update: DependencyWithVersionCandidates? + ): List { + val result = mutableListOf(line) + val version = line.version + if (update == null) return result + val versions = update.versionsCandidates(MavenVersion(version)) + + val isObject = line.unparsedValue.endsWith("}") + + fun suffix(v: MavenVersion) = when { + isObject -> """ = "${v.value}" }""" + line.section == TomlSection.Versions -> """ = "${v.value}"""" + else -> """:${v.value}"""" + } + + val nbSpaces = line.text.indexOf(version) - if (isObject) 17 else 14 + val space = " ".repeat(nbSpaces.coerceAtLeast(0)) + + versions.mapTo(result) { v: MavenVersion -> + TomlLine( + section = line.section, + text = "##${space}# available${suffix(v)}" + ) + } + return result + } +} + + +internal fun VersionsCatalogUpdater( + file: File, + dependenciesUpdates: List +): VersionsCatalogUpdater { + val text: String = if (file.canRead()) file.readText() else "" + return VersionsCatalogUpdater(text, dependenciesUpdates) +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogs.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogs.kt new file mode 100644 index 000000000..038a272be --- /dev/null +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/VersionsCatalogs.kt @@ -0,0 +1,221 @@ +package de.fayard.refreshVersions.core.internal + +import de.fayard.refreshVersions.core.FeatureFlag +import de.fayard.refreshVersions.core.ModuleId +import org.gradle.api.artifacts.Dependency +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.util.GradleVersion + +@InternalRefreshVersionsApi +object VersionsCatalogs { + + const val LIBS_VERSIONS_TOML = "gradle/libs.versions.toml" + + val minimumGradleVersion: GradleVersion = GradleVersion.version("7.4") + + fun isSupported(): Boolean = GradleVersion.current() >= minimumGradleVersion + + internal fun libraries(versionCatalog: VersionCatalog?): Set { + if (versionCatalog == null) return emptySet() + val aliases = versionCatalog.libraryAliases + return aliases.mapTo(LinkedHashSet(aliases.size)) { alias -> + versionCatalog.findLibrary(alias).get().get() + } + } + + internal fun plugins(versionCatalog: VersionCatalog?): Set { + if (versionCatalog == null) return emptySet() + val aliases = versionCatalog.pluginAliases + return aliases.mapTo(LinkedHashSet(aliases.size)) { alias -> + PluginDependencyCompat(versionCatalog.findPlugin(alias).get().get()) + } + } + + fun dependencyAliases(versionCatalog: VersionCatalog?): Map = when { + FeatureFlag.VERSIONS_CATALOG.isNotEnabled -> emptyMap() + versionCatalog == null -> emptyMap() + else -> versionCatalog.libraryAliases.mapNotNull { alias -> + versionCatalog.findLibrary(alias) + .orElse(null) + ?.orNull + ?.let { dependency: MinimalExternalModuleDependency -> + ModuleId.Maven(dependency.module.group, dependency.module.name) to "libs.$alias" + } + }.toMap() + } + + internal fun parseToml(toml: String): Toml { + val map = parseTomlInSections(toml) + .map { (sectionName, paragraph) -> + val section = TomlSection.from(sectionName) + section to paragraph.lines().map { TomlLine(section, it) } + }.toMap() + return Toml(map.toMutableMap()) + } + + /** + * Returns a map where the key is the section name, and the value, the section content. + */ + internal fun parseTomlInSections(toml: String): Map { + val result = mutableMapOf() + result["root"] = StringBuilder() + var current: StringBuilder = result["root"]!! + val lines = toml.lines() + for ((index, line) in lines.withIndex()) { + val trimmed = line.trim() + val isSectionHeader = trimmed.startsWith("[") && trimmed.endsWith("]") + if (isSectionHeader) { + val sectionName = trimmed.removePrefix("[").removeSuffix("]") + result[sectionName] = StringBuilder() + current = result[sectionName]!! + } else { + current.append(line) + if (index != lines.lastIndex) current.append("\n") + } + } + return result.mapValues { it.value.toString() } + } + + fun generateVersionsCatalogText( + versionsMap: Map = RefreshVersionsConfigHolder.readVersionsMap(), + versionKeyReader: ArtifactVersionKeyReader = RefreshVersionsConfigHolder.versionKeyReader, + dependenciesAndNames: Map, + currentText: String, + withVersions: Boolean, + plugins: List + ): String { + val dependencies = dependenciesAndNames.keys.toList() + val versionRefMap = dependenciesWithVersionRefsMapIfAny( + versionsMap = versionsMap, + versionKeyReader = versionKeyReader, + dependencies = dependencies + ) + + val toml = parseToml(currentText) + toml.merge(TomlSection.Plugins, addPlugins(plugins, versionRefMap)) + toml.merge( + section = TomlSection.Libraries, + newLines = versionsCatalogLibraries( + versionsMap = versionsMap, + versionKeyReader = versionKeyReader, + dependenciesAndNames = dependenciesAndNames, + versionRefMap = versionRefMap, + withVersions = withVersions + ) + ) + toml.merge(TomlSection.Versions, addVersions(dependenciesAndNames, versionRefMap)) + return toml.toString() + } + + private fun addPlugins( + plugins: List, + versionRefMap: Map + ): List = plugins.distinctBy { d -> + "${d.group}:${d.name}" + }.mapNotNull { d -> + val version = d.version ?: return@mapNotNull null + + val pair = if (d in versionRefMap) { + "version.ref" to versionRefMap.getValue(d)!!.key + } else { + "version" to version + } + + val pluginId = d.name.removeSuffix(".gradle.plugin") + TomlLine( + TomlSection.Plugins, + pluginId.replace(".", "-"), + mapOf("id" to pluginId, pair) + ) + + }.flatMap { + listOf(TomlLine.newLine, it) + } + + private fun addVersions( + dependenciesAndNames: Map, + versionRefMap: Map + ): List = dependenciesAndNames.keys.distinctBy { dependency -> + versionRefMap[dependency]?.key + }.flatMap { dependency -> + val (versionName, versionValue) = versionRefMap[dependency] ?: return@flatMap emptyList() + + val versionLine = TomlLine(TomlSection.Versions, versionName, versionValue) + listOf(TomlLine.newLine, versionLine) + } + + private data class TomlVersionRef(val key: String, val version: String) + + private fun dependenciesWithVersionRefsMapIfAny( + versionsMap: Map, + versionKeyReader: ArtifactVersionKeyReader, + dependencies: List + ): Map = dependencies.mapNotNull { dependency -> + val group = dependency.group ?: return@mapNotNull null + if (dependency.version == null) return@mapNotNull null + + val name = getVersionPropertyName(ModuleId.Maven(group, dependency.name), versionKeyReader) + + if (name.contains("..") || name.startsWith("plugin")) { + return@mapNotNull null + } + val version = versionsMap[name] ?: dependency.version + val versionRef = version?.let { + TomlVersionRef( + key = name.removePrefix("version.").replace(".", "-"), // Better match TOML naming convention. + version = it + ) + } + dependency to versionRef + }.toMap() + + private fun versionsCatalogLibraries( + versionsMap: Map, + versionKeyReader: ArtifactVersionKeyReader, + dependenciesAndNames: Map, + versionRefMap: Map, + withVersions: Boolean, + ): List = dependenciesAndNames.keys.filterNot { dependency -> + dependency.name.endsWith("gradle.plugin") && dependency.group != null + }.flatMap { dependency: Dependency -> + val group = dependency.group!! + val line: TomlLine = if (dependency in versionRefMap) { + val versionRef: TomlVersionRef? = versionRefMap[dependency] + TomlLine( + section = TomlSection.Libraries, + key = dependenciesAndNames.getValue(dependency), + map = mutableMapOf().apply { //TODO: Replace with buildMap later. + put("group", dependency.group) + put("name", dependency.name) + put("version.ref", versionRef?.key ?: return@apply) + } + ) + } else { + val version = when { + dependency.version == null -> null + withVersions.not() -> "_" + else -> when ( + val versionKey = getVersionPropertyName( + moduleId = ModuleId.Maven(group, dependency.name), + versionKeyReader = versionKeyReader + ) + ) { + in versionsMap -> versionsMap[versionKey]!! + else -> dependency.version + } + } + TomlLine( + section = TomlSection.Libraries, + key = dependenciesAndNames.getValue(dependency), + dependency = ConfigurationLessDependency( + group = group, + name = dependency.name, + version = version + ) + ) + } + + listOf(TomlLine.newLine, line) + } +} diff --git a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/removals_replacement/ReplacementOfRemovedDependencyNotations.kt b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/removals_replacement/ReplacementOfRemovedDependencyNotations.kt index fcd53e4c7..7f870b9e5 100644 --- a/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/removals_replacement/ReplacementOfRemovedDependencyNotations.kt +++ b/plugins/core/src/main/kotlin/de/fayard/refreshVersions/core/internal/removals_replacement/ReplacementOfRemovedDependencyNotations.kt @@ -28,6 +28,8 @@ internal fun replaceRemovedDependencyNotationReferencesIfNeeded( currentRevision = revisionOfLastRefreshVersionsRun ) + if (history.isEmpty()) return + val shortestDependencyMapping: Map by lazy { dependencyMapping.associateShortestByMavenCoordinate() } 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 bd2376795..eb0de9945 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 @@ -45,7 +45,7 @@ internal fun VersionsPropertiesModel.Companion.writeWithNewVersions( when (val data = candidatesMap[section.key]) { null -> section.asUnused(isUnused = true) else -> section.copy( - availableUpdates = data.versionsCandidates.map { it.value }, + availableUpdates = data.versionsCandidates(Version(section.currentVersion)).map { it.value }, ).asUnused(isUnused = false).withFailures(data.failures) } } diff --git a/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/CaseTest.kt b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/CaseTest.kt new file mode 100644 index 000000000..4a3e8bb0a --- /dev/null +++ b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/CaseTest.kt @@ -0,0 +1,24 @@ +package de.fayard.refreshVersions.core + +import de.fayard.refreshVersions.core.internal.Case +import io.kotest.core.spec.style.StringSpec +import io.kotest.inspectors.forAll +import io.kotest.matchers.shouldBe + +class CaseTest : StringSpec({ + val transformations = listOf( + "hoplite_yaml" to "hoplite-yaml", + "picnic" to "picnic", + "h2_ok" to "h2-ok", + "mockito_kotlin" to "mockito-kotlin", + "retrofit2_kotlinx_serialization_converter" to "retrofit2-kotlinx-serialization-converter", + "dagger_compiler" to "dagger-compiler" + ) + + "From snake_case to kebab-case" { + transformations.forAll { (snake, kebab) -> + Case.`kebab-case`.convert(snake) shouldBe kebab + } + } + +}) diff --git a/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlLineTest.kt b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlLineTest.kt new file mode 100644 index 000000000..45cc43e6c --- /dev/null +++ b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlLineTest.kt @@ -0,0 +1,217 @@ +package de.fayard.refreshVersions.core + +import de.fayard.refreshVersions.core.internal.ConfigurationLessDependency +import de.fayard.refreshVersions.core.internal.TomlLine +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.Deletable +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.Ignore +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.Libs +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.LibsUnderscore +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.LibsVersionRef +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.Plugin +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.PluginVersionRef +import de.fayard.refreshVersions.core.internal.TomlLine.Kind.Version +import de.fayard.refreshVersions.core.internal.TomlSection +import io.kotest.assertions.assertSoftly +import io.kotest.inspectors.forAll +import io.kotest.inspectors.forAny +import io.kotest.matchers.shouldBe +import kotlin.test.Test + +class TomlLineTest { + + + @Test + fun `Parsing kind for libraries`() { + + val lines = """ + groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" } + groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" } + groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" } + + # another comment + + refreshVersionsLib = "de.fayard:lib:_" + + my-lib = "com.mycompany:mylib:1.4" + ## # available:1.5" + + my-other-lib = { module = "com.mycompany:other", version = "1.4" } + + my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } + ## + """.trimIndent().lines() + + val expectedKinds: List = listOf( + LibsVersionRef, LibsVersionRef, LibsVersionRef, + Ignore, Ignore, Ignore, + LibsUnderscore, Ignore, + Libs, Deletable, Ignore, + Libs, Ignore, + Libs, Deletable, + ) + + val testCases = lines.zip(expectedKinds) + + testCases.forAll { (line, expectedKind) -> + TomlLine(TomlSection.Libraries, line).kind shouldBe expectedKind + } + } + + @Test + fun `Parsing kind for versions`() { + + val lines = """ + # some comment + + groovy = "3.0.5" + ## available: "1.5" + ## available: "1.6" + + checkstyle = "8.37" + common = "3.4" + """.trimIndent().lines() + + val expectedKinds: List = listOf( + Ignore, Ignore, + Version, Deletable, Deletable, Ignore, + Version, Version, + ) + + val testCases = lines.zip(expectedKinds) + + testCases.forAll { (line, expectedKind) -> + TomlLine(TomlSection.Versions, line).kind shouldBe expectedKind + } + } + + @Test + fun `Parsing kind for plugins`() { + + val lines = """ + short-notation = "some.plugin.id:1.4" + ## # available:"1.5" + + # yet another comment + long-notation = { id = "some.plugin.id", version = "1.4" } + reference-notation = { id = "some.plugin.id", version.ref = "common" } + """.trimIndent().lines() + + val expectedKinds: List = listOf( + Plugin, Deletable, Ignore, Ignore, + Plugin, PluginVersionRef + ) + + val testCases = lines.zip(expectedKinds) + + testCases.forAll { (line, expectedKind) -> + TomlLine(TomlSection.Plugins, line).kind shouldBe expectedKind + } + } + + @Test + fun `Parsing libraries values`() { + fun map( + group: String, + name: String, + version: String?, + versionRef: String? + ) = listOfNotNull( + "group" to group, + "name" to name, + version?.let { "version" to it }, + versionRef?.let { "version.ref" to it } + ).toMap() + + val lines = """ + ## # available:1.5" + # comment + refreshVersionsLib = "de.fayard:lib:_" + my-lib = "com.mycompany:mylib:1.4" + my-other-lib = { module = "com.mycompany:other", version = "1.4" } + my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } + groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" } + groovy-io = { group = "org.codehaus.groovy", name = "io", version.ref = "groovy" } + """.trimIndent().lines() + + val expected = listOf( + emptyMap(), + emptyMap(), + emptyMap(), + map("com.mycompany", "mylib", "1.4", null), + map("com.mycompany", "other", "1.4", null), + map("com.mycompany", "alternate", "1.4", null), + map("org.codehaus.groovy", "groovy-nio", null, "groovy"), + map("org.codehaus.groovy", "io", null, "groovy"), + ) + + val testCases = lines.zip(expected) + + testCases.forAll { (line, map) -> + TomlLine(TomlSection.Libraries, line).map shouldBe map + } + + } + + @Test + fun `Parsing plugins values`() { + fun map(id: String, version: String?, versionRef: String?) = + listOfNotNull("id" to id, version?.let { "version" to it }, versionRef?.let { "version.ref" to it }) + .toMap() + + val lines = """ + # yet another comment + ## # available:"1.5" + + short-notation = "some.plugin.id:1.4" + long-notation = { id = "some.plugin.id", version = "1.4" } + reference-notation = { id = "some.plugin.id", version.ref = "common" } + """.trimIndent().lines() + + val expected = listOf( + emptyMap(), + emptyMap(), + emptyMap(), + map("some.plugin.id", "1.4", null), + map("some.plugin.id", "1.4", null), + map("some.plugin.id", null, "common"), + ) + + val testCases = lines.zip(expected) + + testCases.forAll { (line, map) -> + TomlLine(TomlSection.Plugins, line).map shouldBe map + } + } + + @Test + fun `Parsing for warning or error messages`() { + val lines = """ + ## error: something happened + ## warning: just a warning + ## unused + """.trimIndent().lines() + + lines.forAny { + TomlLine(TomlSection.Libraries, it).kind shouldBe Deletable + } + } + + @Test + fun `Constructors for TomlLine`() { + assertSoftly { + TomlLine(TomlSection.Plugins, "org-jetbrains-kotlin-jvm", mapOf("id" to "org.jetbrains.kotlin.jvm", "version" to "1.6.10")) + .text shouldBe """org-jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version = "1.6.10" }""" + + TomlLine(TomlSection.Libraries, "my-lib", "com.example:name:1.0") + .text shouldBe """my-lib = "com.example:name:1.0"""" + + val d = ConfigurationLessDependency("com.example:name:1.0") + TomlLine(TomlSection.Libraries, "my-lib", d) + .text shouldBe """my-lib = "com.example:name:1.0"""" + + val noVersion = ConfigurationLessDependency("com.example:name") + TomlLine(TomlSection.Libraries, "my-lib", noVersion) + .text shouldBe """my-lib = "com.example:name"""" + } + } +} diff --git a/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlSectionTest.kt b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlSectionTest.kt new file mode 100644 index 000000000..13556ac87 --- /dev/null +++ b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/TomlSectionTest.kt @@ -0,0 +1,41 @@ +package de.fayard.refreshVersions.core + +import de.fayard.refreshVersions.core.internal.VersionsCatalogs +import io.kotest.matchers.shouldBe +import kotlin.test.Test + +class TomlSectionTest { + + private val toml = """ + ## This is a great comment + + [versions] + groovy = "2.5.14" + guava = "30.0-jre" + jupiter = "5.7.1" + + [libraries] + guava = { module="com.google.guava:guava", version.ref="guava" } + junit-jupiter = { module="org.junit.jupiter:junit-jupiter-api", version.ref="jupiter" } + junit-engine = { module="org.junit.jupiter:junit-jupiter-engine" } + + groovy-core = { module="org.codehaus.groovy:groovy", version.ref="groovy" } + groovy-json = { module="org.codehaus.groovy:groovy-json", version.ref="groovy" } + + [bundles] + testDependencies = ["junit-jupiter", "junit-engine"] + """.trimIndent() + + @Test + fun `Parse Toml in Sections`() { + + val (a, b, c, d) = toml.split( + "[versions]\n", + "[libraries]\n", + "[bundles]\n" + ) + + val expected = mapOf("root" to a, "versions" to b, "libraries" to c, "bundles" to d) + VersionsCatalogs.parseTomlInSections(toml) shouldBe expected + } +} diff --git a/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/VersionsCatalogUpdaterTest.kt b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/VersionsCatalogUpdaterTest.kt new file mode 100644 index 000000000..04ae0e1c0 --- /dev/null +++ b/plugins/core/src/test/kotlin/de/fayard/refreshVersions/core/VersionsCatalogUpdaterTest.kt @@ -0,0 +1,184 @@ +package de.fayard.refreshVersions.core + +import de.fayard.refreshVersions.core.internal.ArtifactVersionKeyReader +import de.fayard.refreshVersions.core.internal.ConfigurationLessDependency +import de.fayard.refreshVersions.core.internal.DependencyWithVersionCandidates +import de.fayard.refreshVersions.core.internal.TomlLine +import de.fayard.refreshVersions.core.internal.TomlSection +import de.fayard.refreshVersions.core.internal.VersionsCatalogUpdater +import de.fayard.refreshVersions.core.internal.VersionsCatalogs +import io.kotest.assertions.asClue +import io.kotest.matchers.shouldBe +import org.gradle.api.artifacts.Dependency +import org.junit.jupiter.api.TestFactory +import testutils.junit.dynamicTest +import java.io.File +import kotlin.test.Test +import de.fayard.refreshVersions.core.Version as MavenVersion + +class VersionsCatalogUpdaterTest { + + @Test + fun `Folder toml-refreshversions - update new versions`() = testVersionsCatalogUpdater( + inputFolderName = "toml-refreshversions" + ) { actual: File -> updateNewVersions(actual) } + + @Test + fun `Folder toml-cleanup - remove refreshVersions comments`() = testVersionsCatalogUpdater( + inputFolderName = "toml-cleanup" + ) { actual: File -> cleanupComments(actual) } + + private fun testVersionsCatalogUpdater( + inputFolderName: String, + action: VersionsCatalogUpdater.(actual: File) -> Unit + ) { + val input = FolderInput(inputFolderName) + sequence { + yield(input.initial to input.actual) + yield(input.expected to input.expected) // check idempotence + }.forEach { (initial, actual) -> + VersionsCatalogUpdater( + file = initial, + dependenciesUpdates = dependencyWithVersionCandidates(input.folder) + ).action(actual) + input.actual.readText() shouldBe input.expectedText + } + + // delete actual file if successful + input.actual.delete() + } + + @Test + fun `Folder toml-merge-properties - modify file incrementally`() { + val input = FolderInput("toml-merge-properties") + + val toml = VersionsCatalogs.parseToml(input.initial.readText()) + toml.merge( + TomlSection.Versions, listOf( + TomlLine(TomlSection.Versions, "groovy", "3.0.6"), + TomlLine(TomlSection.Versions, "ktor", "2.0"), + ) + ) + + toml.merge( + TomlSection.Libraries, listOf( + TomlLine(TomlSection.Libraries, "my-lib", "com.mycompany:mylib:1.5"), + TomlLine(TomlSection.Libraries, "other-lib", "com.mycompany:other:1.5"), + ) + ) + + toml.merge( + TomlSection.Plugins, listOf( + TomlLine(TomlSection.Plugins, "short-notation", "some.plugin.id:1.6"), + TomlLine(TomlSection.Plugins, "ben-manes", "ben.manes:versions:1.0"), + ) + ) + + input.actual.writeText(toml.toString()) + input.asClue { + toml.toString() shouldBe input.expectedText + } + // delete actual file if successful + input.actual.delete() + } + + + private val rulesDir = File(".").absoluteFile.parentFile.parentFile + .resolve("dependencies/src/main/resources/refreshVersions-rules") + .also { require(it.canRead()) { "Can't read folder $it" } } + private val versionsMap = mapOf( + "version.junit.jupiter" to "42" + ) + private val versionKeyReader = ArtifactVersionKeyReader.fromRules(rulesDir.listFiles()!!.map { it.readText() }) + + @TestFactory + fun refreshVersionsCatalog() = testResources.resolve("refreshVersionsCatalog").listFiles()!!.mapNotNull { folder -> + if (folder.isDirectory.not()) return@mapNotNull null + dynamicTest(folder.name) { + val input = FolderInput(folder) + val withVersions = input.folder.name.contains("versions") + + val currentText = input.initial.readText() + val dependenciesDataFile = folder.resolve("dependencies.txt").takeIf { it.exists() } + ?: folder.parentFile.resolve("default-dependencies.txt") + val dependenciesAndNames = dependenciesDataFile.useLines { lines -> + lines.filter { + it.isNotBlank() && it.startsWith("//").not() + }.toList() + }.associate { + val dependencyNotation = it.substringBefore('|').trimEnd() + val tomlPropertyName = it.substringAfter('|').trim() + val dependency: Dependency = ConfigurationLessDependency(dependencyNotation) + dependency to tomlPropertyName + } + val plugins = dependenciesAndNames.keys.filter { it.name.endsWith(".gradle.plugin") } + val newText = VersionsCatalogs.generateVersionsCatalogText( + versionsMap = versionsMap, + versionKeyReader = versionKeyReader, + dependenciesAndNames = dependenciesAndNames, + currentText = currentText, + withVersions = withVersions, + plugins = plugins + ) + input.actual.writeText(newText) + input.asClue { + newText shouldBe input.expectedText + } + input.actual.delete() + } + } +} + +private data class FolderInput( + val folder: File, + val initial: File, + val expected: File, + val actual: File, +) { + val expectedText = expected.readText() + + override fun toString() = + "Comparing from resources folder=${folder.name}: actual=${actual.name} and expected=${expected.name}" +} + +private fun FolderInput(folderName: String): FolderInput = FolderInput(testResources.resolve(folderName)) + +private fun FolderInput(folder: File): FolderInput { + require(folder.canRead()) { "Invalid folder ${folder.absolutePath}" } + return FolderInput( + folder = folder, + initial = folder.resolve("initial.libs.toml"), + actual = folder.resolve("actual.libs.toml"), + expected = folder.resolve("expected.libs.toml"), + ) +} + +private fun dependencyWithVersionCandidates(folder: File): List { + val file = folder.resolve("dependencies.txt") + .takeIf { it.canRead() } + ?: folder.parentFile.resolve("default-dependencies.txt") + .takeIf { it.canRead() } ?: return emptyList() + + return file.useLines { lines -> + lines.filter { + it.isNotBlank() + }.map { line -> + val dependencyNotation = line.substringBefore('|').trimEnd() + val moduleId = ModuleId.Maven( + group = dependencyNotation.substringBefore(':'), + name = dependencyNotation.substringAfter(':').substringBefore(':') + ) + val versions = line.substringAfter('|').trim().split(',') + DependencyWithVersionCandidates( + moduleId = moduleId, + currentVersion = dependencyNotation.substringAfterLast(':'), + versionsCandidates = { currentVersion -> + versions.mapNotNull { rawVersion -> + MavenVersion(rawVersion.trim()).takeIf { it > currentVersion } + } + }, + failures = emptyList() //TODO: Test failures + ) + }.toList() + } +} diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/default-dependencies.txt b/plugins/core/src/test/resources/refreshVersionsCatalog/default-dependencies.txt new file mode 100644 index 000000000..cf6eaccea --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/default-dependencies.txt @@ -0,0 +1,17 @@ +// Represents dependencies that we would get in a Gradle build, +// and the key assigned by refreshVersions for +// the version catalog at migration time. +// +// Note: Gradle plugin dependencies should be filtered out by the code, +// and should not appear as libraries in the toml file. + +org.codehaus.groovy:groovy-kotlin:3.0.5 | groovy-kotlin +com.mycompany:mylib:1.4 | my-lib +com.mycompany:other:1.4 | my-other-lib +com.mycompany:alternate:1.2 | my-alternate-lib +some.plugin.id:some.plugin.id.gradle.plugin:1.4 | some-plugin-id +other.plugin.id:other.plugin.id.gradle.plugin:3.4 | other-plugin-id +io.kotest:kotest:3.0 | kotest-core +io.kotest:kotest-property:3.0 | kotest-property +org.junit.jupiter:junit-jupiter-bom:1.0 | junit-jupiter-bom +org.junit.jupiter:junit-jupiter | junit-jupiter diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/expected.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/expected.libs.toml new file mode 100644 index 000000000..bd812c70a --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/expected.libs.toml @@ -0,0 +1,45 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" + +long-notation = { id = "some.plugin.id", version = "1.4" } + +some-plugin-id = { id = "some.plugin.id", version = "1.4" } + +other-plugin-id = { id = "other.plugin.id", version = "3.4" } + +[versions] + +groovy = "3.0.5" + +kotest = "3.0" + +junit-jupiter = "42" + +[libraries] + +my-lib-ok = "com.mycompany:mylib-ok:1.0" + +groovy-kotlin = "org.codehaus.groovy:groovy-kotlin:_" + +my-lib = "com.mycompany:mylib:_" + +my-other-lib = "com.mycompany:other:_" + +my-alternate-lib = "com.mycompany:alternate:_" + +kotest-core = { group = "io.kotest", name = "kotest", version.ref = "kotest" } + +kotest-property = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } + +junit-jupiter-bom = { group = "org.junit.jupiter", name = "junit-jupiter-bom", version.ref = "junit-jupiter" } + +junit-jupiter = "org.junit.jupiter:junit-jupiter" diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/initial.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/initial.libs.toml new file mode 100644 index 000000000..1b88e9588 --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-existing/initial.libs.toml @@ -0,0 +1,21 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[versions] + +groovy = "3.0.5" + +[libraries] + +my-lib-ok = "com.mycompany:mylib-ok:1.0" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" + +long-notation = { id = "some.plugin.id", version = "1.4" } diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/expected.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/expected.libs.toml new file mode 100644 index 000000000..f5ff53dc6 --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/expected.libs.toml @@ -0,0 +1,33 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[plugins] + +some-plugin-id = { id = "some.plugin.id", version = "1.4" } + +other-plugin-id = { id = "other.plugin.id", version = "3.4" } + +[versions] + +kotest = "3.0" + +junit-jupiter = "42" + +[libraries] + +groovy-kotlin = "org.codehaus.groovy:groovy-kotlin:_" + +my-lib = "com.mycompany:mylib:_" + +my-other-lib = "com.mycompany:other:_" + +my-alternate-lib = "com.mycompany:alternate:_" + +kotest-core = { group = "io.kotest", name = "kotest", version.ref = "kotest" } + +kotest-property = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } + +junit-jupiter-bom = { group = "org.junit.jupiter", name = "junit-jupiter-bom", version.ref = "junit-jupiter" } + +junit-jupiter = "org.junit.jupiter:junit-jupiter" diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/initial.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/initial.libs.toml new file mode 100644 index 000000000..ca6f603bf --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/underscore-new/initial.libs.toml @@ -0,0 +1,3 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/expected.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/expected.libs.toml new file mode 100644 index 000000000..804aa5112 --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/expected.libs.toml @@ -0,0 +1,45 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" + +long-notation = { id = "some.plugin.id", version = "1.4" } + +some-plugin-id = { id = "some.plugin.id", version = "1.4" } + +other-plugin-id = { id = "other.plugin.id", version = "3.4" } + +[versions] + +groovy = "3.0.5" + +kotest = "3.0" + +junit-jupiter = "42" + +[libraries] + +my-lib-ok = "com.mycompany:mylib-ok:1.0" + +groovy-kotlin = "org.codehaus.groovy:groovy-kotlin:3.0.5" + +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib = "com.mycompany:other:1.4" + +my-alternate-lib = "com.mycompany:alternate:1.2" + +kotest-core = { group = "io.kotest", name = "kotest", version.ref = "kotest" } + +kotest-property = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } + +junit-jupiter-bom = { group = "org.junit.jupiter", name = "junit-jupiter-bom", version.ref = "junit-jupiter" } + +junit-jupiter = "org.junit.jupiter:junit-jupiter" diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/initial.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/initial.libs.toml new file mode 100644 index 000000000..1b88e9588 --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-existing/initial.libs.toml @@ -0,0 +1,21 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[versions] + +groovy = "3.0.5" + +[libraries] + +my-lib-ok = "com.mycompany:mylib-ok:1.0" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" + +long-notation = { id = "some.plugin.id", version = "1.4" } diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/expected.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/expected.libs.toml new file mode 100644 index 000000000..e413b7e1c --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/expected.libs.toml @@ -0,0 +1,33 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[plugins] + +some-plugin-id = { id = "some.plugin.id", version = "1.4" } + +other-plugin-id = { id = "other.plugin.id", version = "3.4" } + +[versions] + +kotest = "3.0" + +junit-jupiter = "42" + +[libraries] + +groovy-kotlin = "org.codehaus.groovy:groovy-kotlin:3.0.5" + +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib = "com.mycompany:other:1.4" + +my-alternate-lib = "com.mycompany:alternate:1.2" + +kotest-core = { group = "io.kotest", name = "kotest", version.ref = "kotest" } + +kotest-property = { group = "io.kotest", name = "kotest-property", version.ref = "kotest" } + +junit-jupiter-bom = { group = "org.junit.jupiter", name = "junit-jupiter-bom", version.ref = "junit-jupiter" } + +junit-jupiter = "org.junit.jupiter:junit-jupiter" diff --git a/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/initial.libs.toml b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/initial.libs.toml new file mode 100644 index 000000000..ca6f603bf --- /dev/null +++ b/plugins/core/src/test/resources/refreshVersionsCatalog/versions-new/initial.libs.toml @@ -0,0 +1,3 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" diff --git a/plugins/core/src/test/resources/toml-cleanup/expected.libs.toml b/plugins/core/src/test/resources/toml-cleanup/expected.libs.toml new file mode 100644 index 000000000..21e0dbe2b --- /dev/null +++ b/plugins/core/src/test/resources/toml-cleanup/expected.libs.toml @@ -0,0 +1,27 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" + +# yet another comment + +[versions] + +# some comment + +groovy = "3.0.5" + +[libraries] + +# another comment + +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } diff --git a/plugins/core/src/test/resources/toml-cleanup/initial.libs.toml b/plugins/core/src/test/resources/toml-cleanup/initial.libs.toml new file mode 100644 index 000000000..4ab31d61a --- /dev/null +++ b/plugins/core/src/test/resources/toml-cleanup/initial.libs.toml @@ -0,0 +1,36 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +## strange key +key = "some key" + +[bundles] + +## unused +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" +## # available:1.5" +## # available:1.6" + +# yet another comment + +[versions] + +# some comment + +## warning: Kotlin is better than Groovy +groovy = "3.0.5" +### available = "3.1.0" +### available = "3.2.0" + +[libraries] + +# another comment + +## error: could not resolve this dependency on mavenCentral() +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } +## # available = "1.5" } diff --git a/plugins/core/src/test/resources/toml-merge-properties/expected.libs.toml b/plugins/core/src/test/resources/toml-merge-properties/expected.libs.toml new file mode 100644 index 000000000..c9105ec5c --- /dev/null +++ b/plugins/core/src/test/resources/toml-merge-properties/expected.libs.toml @@ -0,0 +1,29 @@ +## Generated by $ ./gradlew refreshVersionsCatalog + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.6" + +refreshversions = "de.fayard.refreshversions:1.0" + +ben-manes = "ben.manes:versions:1.0" + +[versions] + +groovy = "3.0.6" + +kotlin = "1.6" + +ktor = "2.0" + +[libraries] + +my-lib = "com.mycompany:mylib:1.5" + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } + +other-lib = "com.mycompany:other:1.5" diff --git a/plugins/core/src/test/resources/toml-merge-properties/initial.libs.toml b/plugins/core/src/test/resources/toml-merge-properties/initial.libs.toml new file mode 100644 index 000000000..cd9a9d4c9 --- /dev/null +++ b/plugins/core/src/test/resources/toml-merge-properties/initial.libs.toml @@ -0,0 +1,21 @@ +[libraries] + +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } + +[versions] + +groovy = "3.0.5" + +kotlin = "1.6" + +[plugins] + +short-notation = "some.plugin.id:1.4" + +refreshversions = "de.fayard.refreshversions:1.0" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] diff --git a/plugins/core/src/test/resources/toml-refreshversions/dependencies.txt b/plugins/core/src/test/resources/toml-refreshversions/dependencies.txt new file mode 100644 index 000000000..408957ae6 --- /dev/null +++ b/plugins/core/src/test/resources/toml-refreshversions/dependencies.txt @@ -0,0 +1,10 @@ +// Represents dependencies that we would get in a Gradle build, +// and the versions that we would get by reaching the repositories. + +org.codehaus.groovy:groovy:3.0.5 | 1.0, 2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.1.0, 3.2.0 +com.mycompany:mylib-ok:1.4 | 1.0, 1.4, 1.4.1, 2.0 +com.mycompany:mylib-ko:1.4 | 1.0, 1.1, 1.2, 1.3, 1.4 +com.mycompany:other:1.4 | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 +com.mycompany:alternate:1.4 | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 +some.plugin.id:some.plugin.id.gradle.plugin:1.4 | 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 +other.plugin.id:other.plugin.id.gradle.plugin:3.4 | 1.0, 2.0, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6 diff --git a/plugins/core/src/test/resources/toml-refreshversions/expected.libs.toml b/plugins/core/src/test/resources/toml-refreshversions/expected.libs.toml new file mode 100644 index 000000000..df19d519f --- /dev/null +++ b/plugins/core/src/test/resources/toml-refreshversions/expected.libs.toml @@ -0,0 +1,57 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" +## # available:1.5" +## # available:1.6" +## # available:1.7" + +# yet another comment + +long-notation = { id = "some.plugin.id", version = "1.4" } +## # available = "1.5" } +## # available = "1.6" } +## # available = "1.7" } + +reference-notation = { id = "other.plugin.id", version.ref = "common" } + +[versions] + +# some comment + +groovy = "3.0.5" +### available = "3.1.0" +### available = "3.2.0" + +checkstyle = "8.37" +common = "3.4" +### available = "3.5" +### available = "3.6" + +[libraries] + +groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" } +groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" } +groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" } + +# another comment + +refreshVersionsLib = "de.fayard:lib:_" + +my-lib = "com.mycompany:mylib:1.4" + +my-other-lib = { module = "com.mycompany:other", version = "1.4" } +## # available = "1.5" } +## # available = "1.6" } + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } +## # available = "1.5" } + +log4j-jul = { module = "org.apache.logging.log4j:log4j-jul" } diff --git a/plugins/core/src/test/resources/toml-refreshversions/initial.libs.toml b/plugins/core/src/test/resources/toml-refreshversions/initial.libs.toml new file mode 100644 index 000000000..5fd72c4b5 --- /dev/null +++ b/plugins/core/src/test/resources/toml-refreshversions/initial.libs.toml @@ -0,0 +1,49 @@ +# See https://docs.gradle.org/current/userguide/platforms.html#sub:conventional-dependencies-toml + +key = "some key" + +[versions] +# some comment + +groovy = "3.0.5" +### available="1.5" +### available="1.6" + +checkstyle = "8.37" +common = "3.4" + +[libraries] +groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" } +groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" } +groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" } + +# another comment + +refreshVersionsLib = "de.fayard:lib:_" + +my-lib = "com.mycompany:mylib:1.4" +## # available:1.5" + +my-other-lib = { module = "com.mycompany:other", version = "1.4" } + +my-other-lib2 = { group = "com.mycompany", name = "alternate", version = "1.4" } +## # available="1.5" } + +log4j-jul = { module = "org.apache.logging.log4j:log4j-jul" } + +[bundles] + +groovy = ["groovy-core", "groovy-json", "groovy-nio"] + +[plugins] + +short-notation = "some.plugin.id:1.4" +## # available:"1.5" + +# yet another comment + +long-notation = { id = "some.plugin.id", version = "1.4" } +## # available="1.5" } +## # available="1.6" } + +reference-notation = { id = "other.plugin.id", version.ref = "common" } diff --git a/plugins/dependencies/build.gradle.kts b/plugins/dependencies/build.gradle.kts index 0a8c03365..1d558376e 100644 --- a/plugins/dependencies/build.gradle.kts +++ b/plugins/dependencies/build.gradle.kts @@ -43,8 +43,8 @@ publishing { dependencies { testImplementation(Testing.kotest.runner.junit5) - testImplementation(platform(notation = "org.junit:junit-bom:_")) - testImplementation("org.junit.jupiter:junit-jupiter") + testImplementation(platform(notation = Testing.junit.bom)) + testImplementation(Testing.junit.jupiter) testRuntimeOnly("org.junit.platform:junit-platform-launcher") { because("allows tests to run from IDEs that bundle older version of launcher") } diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsCatalogTask.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsCatalogTask.kt new file mode 100644 index 000000000..44cba0f58 --- /dev/null +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsCatalogTask.kt @@ -0,0 +1,91 @@ +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.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 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() { + + @Input + @Option(option = "versions", description = "Add the versions in $LIBS_VERSIONS_TOML") + var withVersions: Boolean = false + + @Input + @Option(option = "all", description = "Add all libraries in $LIBS_VERSIONS_TOML") + var withAllLibraries: Boolean = false + + @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() + ) + } + + // Update versions.properties + addMissingEntriesInVersionsProperties(project) + + // Generate LIBS_VERSIONS_TOML + val catalog = OutputFile.GRADLE_VERSIONS_CATALOG + + val builtInDependencies = getArtifactNameToConstantMapping() + .map { Library(it.group, it.artifact, "_") } + + val allDependencies: List = project.findDependencies() + + val dependenciesToUse = when { + withAllLibraries -> allDependencies + else -> allDependencies.filter { it.copy(version = "_") !in builtInDependencies } + } + + val plugins = UsedPluginsTracker.usedPluginsWithoutEntryInVersionsFile + + UsedPluginsTracker.read().map { it.first } + + val versionCatalogAliases: List = dependenciesToUse.computeAliases( + configured = emptyList(), + byDefault = MEANING_LESS_NAMES + ) + + val deps: Deps = dependenciesToUse.checkModeAndNames(versionCatalogAliases, Case.`kebab-case`) + val dependenciesAndNames: Map = deps.names.mapKeys { it.key.toDependency() } + + val currentText = if (catalog.existed) catalog.readText() else "" + val newText = VersionsCatalogs.generateVersionsCatalogText( + dependenciesAndNames = dependenciesAndNames, + currentText = currentText, + withVersions = withVersions, + 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() + ) + } +} diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsExtension.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsExtension.kt index c16549cb1..b6d3e884a 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsExtension.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsExtension.kt @@ -2,7 +2,6 @@ package de.fayard.refreshVersions import de.fayard.refreshVersions.core.DependencySelection import de.fayard.refreshVersions.core.FeatureFlag -import de.fayard.refreshVersions.core.internal.RefreshVersionsConfigHolder import groovy.lang.Closure import org.gradle.api.Action import org.gradle.api.Incubating @@ -13,6 +12,7 @@ open class RefreshVersionsExtension { var versionsPropertiesFile: File? = null var extraArtifactVersionKeyRules: List = emptyList() internal var isBuildSrcLibsEnabled = false + internal var versionRejectionFilter: (DependencySelection.() -> Boolean)? = null @Incubating fun enableBuildSrcLibs() { @@ -32,14 +32,14 @@ open class RefreshVersionsExtension { } fun rejectVersionIf(filter: Closure) { - RefreshVersionsConfigHolder.versionRejectionFilter = { + versionRejectionFilter = { filter.delegate = this filter.call() } } fun rejectVersionIf(filter: DependencySelection.() -> Boolean) { - RefreshVersionsConfigHolder.versionRejectionFilter = filter + versionRejectionFilter = filter } } diff --git a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsMigrateTask.kt b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsMigrateTask.kt index 52f3621ed..4bba83e7f 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsMigrateTask.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsMigrateTask.kt @@ -2,15 +2,23 @@ package de.fayard.refreshVersions import de.fayard.refreshVersions.core.ModuleId 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.internal.getArtifactNameToConstantMapping import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.options.Option import org.intellij.lang.annotations.Language 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 + @TaskAction fun refreshVersionsMissingEntries() { addMissingEntriesInVersionsProperties(project) @@ -18,12 +26,27 @@ open class RefreshVersionsMigrateTask : DefaultTask() { @TaskAction fun migrateBuild() { - val dependencyMapping = getArtifactNameToConstantMapping() + val versionsCatalogMapping: Map = + VersionsCatalogs.dependencyAliases(project.getVersionsCatalog()) + + val builtInDependenciesMapping: Map = getArtifactNameToConstantMapping() .associateShortestByMavenCoordinate() - findFilesWithDependencyNotations(project.rootDir).forEach { buildFile -> + val dependencyMapping = if (tomlFirst) { + builtInDependenciesMapping + versionsCatalogMapping + } else { + versionsCatalogMapping + builtInDependenciesMapping + } + + val findFiles = findFilesWithDependencyNotations(project.rootDir).toSet() + findFiles.forEach { buildFile -> migrateFileIfNeeded(buildFile, dependencyMapping) } + project.allprojects { + if (buildFile !in findFiles) { + migrateFileIfNeeded(buildFile, dependencyMapping) + } + } println() println(""" To find available updates, run this: @@ -33,6 +56,7 @@ open class RefreshVersionsMigrateTask : DefaultTask() { } } + //TODO: Don't replace random versions in build.gradle(.kts) files to avoid breaking plugins. //TODO: Don't rely on a regex to extract the version so we detect absolutely any version string literal. //TODO: Use CharSequence.findSymbolsRanges(…) to find the plugins block. @@ -46,13 +70,11 @@ open class RefreshVersionsMigrateTask : DefaultTask() { // - Interactive task // - separate CLI tool // - FIXME/TODO comments insertion -//TODO: Release BEFORE the 30th of June. -//TODO: Replace versions with underscore in the Gradle Versions Catalog files. - -private val buildFilesNames = setOf("build.gradle", "build.gradle.kts") internal fun migrateFileIfNeeded(file: File, dependencyMapping: Map) { - val isBuildFile = file.name in buildFilesNames + if (file.canRead().not()) return + + val isBuildFile = file.name.removeSuffix(".kts").endsWith(".gradle") val oldContent = file.readText() val newContent = oldContent.lines() .detectPluginsBlock() @@ -65,9 +87,9 @@ internal fun migrateFileIfNeeded(file: File, dependencyMapping: Map = emptyMap() + dependencyMapping: Map = emptyMap(), ): String? = when { isInsidePluginsBlock -> line.replace(pluginVersionRegex, "") isBuildFile -> when { @@ -98,7 +120,7 @@ internal fun withVersionPlaceholder( if (coordinate in dependencyMapping) { line.replace(mavenCoordinateRegex, dependencyMapping[coordinate]!!) } else { - line.replace(mavenCoordinateRegex, "\$1_\$2") + line.replace(mavenCoordinateRegex, "\$1:_\$2") } } else -> null @@ -110,12 +132,12 @@ internal fun withVersionPlaceholder( private fun extractCoordinate(line: String): ModuleId.Maven { val coordinate = mavenCoordinateRegex.find(line)!!.value - coordinate.replaceAfterLast(':', "").let { - return ModuleId.Maven( - group = it.substringBefore(':').removePrefix("'").removePrefix("\""), - name = it.substringAfter(':').removeSuffix(":") - ) - } + .replace("'", "") + .replace("\"", "") + + val (group, name) = coordinate.split(":") + + return ModuleId.Maven(group = group, name = name) } private const val mavenChars = "[a-zA-Z0-9_.-]" @@ -123,15 +145,17 @@ private const val versionChars = "[a-zA-Z0-9_.{}$-]" @Language("RegExp") private val mavenCoordinateRegex = - "(['\"]$mavenChars{4,}:$mavenChars{2,}:)(?:_|$versionChars{3,})([\"'])".toRegex() + "(['\"]$mavenChars{4,}:$mavenChars{2,})(?:|:_|:$versionChars{3,})([\"'])".toRegex() internal fun findFilesWithDependencyNotations(fromDir: File): List { require(fromDir.isDirectory) { "Expected a directory, got ${fromDir.absolutePath}" } val expectedNames = listOf("build", "build.gradle", "deps", "dependencies", "libs", "libraries", "versions") val expectedExtensions = listOf("gradle", "kts", "groovy", "kt") - return fromDir.walkBottomUp().filter { - it.extension in expectedExtensions && it.nameWithoutExtension.toLowerCase() in expectedNames - }.toList() + return fromDir.walkBottomUp() + .onEnter { dir -> dir.name !in listOf("resources", "build") } + .filter { + it.extension in expectedExtensions && it.nameWithoutExtension.toLowerCase() in expectedNames + }.toList() } /** 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 e0a47c6a9..00d032982 100644 --- a/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt +++ b/plugins/dependencies/src/main/kotlin/de/fayard/refreshVersions/RefreshVersionsPlugin.kt @@ -2,7 +2,9 @@ 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 import org.gradle.api.DefaultTask import org.gradle.api.Plugin @@ -132,7 +134,8 @@ open class RefreshVersionsPlugin : Plugin { ?: settings.rootDir.resolve("versions.properties"), getDependenciesMapping = ::getArtifactNameToConstantMapping, getRemovedDependenciesVersionsKeys = ::getRemovedDependenciesVersionsKeys, - getRemovedDependencyNotationsReplacementInfo = ::getRemovedDependencyNotationsReplacementInfo + getRemovedDependencyNotationsReplacementInfo = ::getRemovedDependencyNotationsReplacementInfo, + versionRejectionFilter = extension.versionRejectionFilter ) if (extension.isBuildSrcLibsEnabled) gradle.beforeProject { if (project != project.rootProject) return@beforeProject @@ -166,6 +169,7 @@ open class RefreshVersionsPlugin : Plugin { description = "Assists migration from hardcoded dependencies to constants of " + "the refreshVersions dependencies plugin" finalizedBy("refreshVersions") + skipConfigurationCache() } project.tasks.register( @@ -177,12 +181,21 @@ open class RefreshVersionsPlugin : Plugin { println(getArtifactNameToConstantMapping().joinToString("\n")) } } + project.tasks.register( + name = "refreshVersionsCatalog" + ) { + group = "refreshVersions" + description = "Update $LIBS_VERSIONS_TOML" + outputs.upToDateWhen { false } + skipConfigurationCache() + } project.tasks.register( name = "refreshVersionsMigrate" ) { group = "refreshVersions" description = "Migrate build to refreshVersions" + skipConfigurationCache() } } diff --git a/plugins/dependencies/src/main/resources/version-to-removals-revision-mapping.txt b/plugins/dependencies/src/main/resources/version-to-removals-revision-mapping.txt index e69de29bb..2c059d3d0 100644 --- a/plugins/dependencies/src/main/resources/version-to-removals-revision-mapping.txt +++ b/plugins/dependencies/src/main/resources/version-to-removals-revision-mapping.txt @@ -0,0 +1,7 @@ +0.30.0->3 +0.30.1->3 +0.30.2->8 +0.30.2->8 +0.40.0->9 +0.40.1->9 +0.40.2->10 diff --git a/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/MigrationTest.kt b/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/MigrationTest.kt index 4a071770d..a6cb3d79a 100644 --- a/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/MigrationTest.kt +++ b/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/MigrationTest.kt @@ -8,7 +8,9 @@ import io.kotest.inspectors.forAll import io.kotest.matchers.ints.shouldBeExactly import io.kotest.matchers.shouldBe import java.io.File +import kotlin.time.ExperimentalTime +@OptIn(ExperimentalTime::class) class MigrationTest : StringSpec({ val testResources: File = File(".").absoluteFile.resolve("src/test/resources") @@ -179,7 +181,8 @@ class MigrationTest : StringSpec({ val dependencyMapping = mapOf( "com.squareup.okio:okio" to "Square.okio", "com.squareup.moshi:moshi" to "Square.moshi", - "com.google.firebase:firebase-analytics" to "Firebase.analytics" + "com.google.firebase:firebase-analytics" to "Firebase.analytics", + "org.apache.logging.log4j:log4j-jul" to "libs.log4j.jul", ).mapKeys { (key, _) -> ModuleId.Maven( group = key.substringBefore(':'), @@ -190,11 +193,13 @@ class MigrationTest : StringSpec({ implementation 'com.squareup.okio:okio:1.2' implementation("com.squareup.moshi:moshi:_") implementation("com.google.firebase:firebase-analytics:3.4") + implementation("org.apache.logging.log4j:log4j-jul") """.trimIndent().lines() val expected = """ implementation Square.okio implementation(Square.moshi) implementation(Firebase.analytics) + implementation(libs.log4j.jul) """.trimIndent().lines() input.size shouldBeExactly expected.size List(input.size) { input[it] to expected[it] } diff --git a/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/RemovedDependencyNotationsHistoryCorrectnessTest.kt b/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/RemovedDependencyNotationsHistoryCorrectnessTest.kt new file mode 100644 index 000000000..8a740f2ae --- /dev/null +++ b/plugins/dependencies/src/test/kotlin/de/fayard/refreshVersions/RemovedDependencyNotationsHistoryCorrectnessTest.kt @@ -0,0 +1,37 @@ +package de.fayard.refreshVersions + +import io.kotest.assertions.withClue +import io.kotest.matchers.ints.shouldBeGreaterThan +import io.kotest.matchers.shouldBe +import io.kotest.matchers.string.shouldContainOnlyOnce +import io.kotest.matchers.string.shouldHaveMinLength +import org.junit.jupiter.api.Test + +class RemovedDependencyNotationsHistoryCorrectnessTest { + + @Test + fun `Mapping of version to removals revision should have correct format`() { + val separator = "->" + val fileName = "version-to-removals-revision-mapping.txt" + val file = mainResources.resolve(fileName) + file.useLines { lines -> + val nonEmptyLines = lines.withIndex().sumBy { (index, line) -> + if (line.isEmpty()) return@sumBy 0 + withClue("Line $index of $file") { + line shouldContainOnlyOnce separator + val version = line.substringBefore(separator) + val revision = line.substringAfter(separator).toInt() + revision shouldBeGreaterThan 0 + version shouldHaveMinLength 1 + withClue("Unexpected character in the version") { + version.all { it.isLetterOrDigit() || it in ".-" } shouldBe true + } + } + 1 + } + withClue("File must not be empty $file") { + nonEmptyLines shouldBeGreaterThan 0 + } + } + } +} diff --git a/plugins/gradle/wrapper/gradle-wrapper.jar b/plugins/gradle/wrapper/gradle-wrapper.jar index 41d9927a4..249e5832f 100644 Binary files a/plugins/gradle/wrapper/gradle-wrapper.jar and b/plugins/gradle/wrapper/gradle-wrapper.jar differ diff --git a/plugins/gradle/wrapper/gradle-wrapper.properties b/plugins/gradle/wrapper/gradle-wrapper.properties index aa991fcea..ae04661ee 100644 --- a/plugins/gradle/wrapper/gradle-wrapper.properties +++ b/plugins/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plugins/gradlew b/plugins/gradlew index 1b6c78733..a69d9cb6c 100755 --- a/plugins/gradlew +++ b/plugins/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/plugins/gradlew.bat b/plugins/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/plugins/gradlew.bat +++ b/plugins/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/plugins/versions.properties b/plugins/versions.properties index d69f7a0d9..a8dd9a837 100644 --- a/plugins/versions.properties +++ b/plugins/versions.properties @@ -8,9 +8,17 @@ #### suppress inspection "UnusedProperty" for whole file plugin.com.gradle.plugin-publish=0.20.0 +## # available=0.21.0 +## # available=1.0.0-rc-1 +## # available=1.0.0-rc-2 +## # available=1.0.0-rc-3 +## # available=1.0.0 version.junit=5.8.1 ### available=5.8.2 +### available=5.9.0-M1 +### available=5.9.0-RC1 +### available=5.9.0 version.kotest=4.6.3 ## # available=4.6.4 @@ -25,6 +33,14 @@ version.kotest=4.6.3 ## # available=5.0.2 ## # available=5.0.3 ## # available=5.1.0 +## # available=5.2.0 +## # available=5.2.1 +## # available=5.2.2 +## # available=5.2.3 +## # available=5.3.0 +## # available=5.3.1 +## # available=5.3.2 +## # available=5.4.0 version.kotlin=1.4.20 ## # available=1.4.21 @@ -54,6 +70,16 @@ version.kotlin=1.4.20 ## # available=1.6.0 ## # available=1.6.10-RC ## # available=1.6.10 +## # available=1.6.20-M1 +## # available=1.6.20-RC +## # available=1.6.20-RC2 +## # available=1.6.20 +## # available=1.6.21 +## # available=1.7.0-Beta +## # available=1.7.0-RC +## # available=1.7.0-RC2 +## # available=1.7.0 +## # available=1.7.10 version.kotlinpoet=1.7.2 ## # available=1.8.0 @@ -61,8 +87,16 @@ version.kotlinpoet=1.7.2 ## # available=1.10.0 ## # available=1.10.1 ## # available=1.10.2 +## # available=1.11.0 +## # available=1.12.0 version.kotlinx.coroutines=1.6.0 +## # available=1.6.1-native-mt +## # available=1.6.1 +## # available=1.6.2 +## # available=1.6.3-native-mt +## # available=1.6.3 +## # available=1.6.4 version.moshi=1.11.0 ### available=1.12.0 @@ -70,9 +104,16 @@ version.moshi=1.11.0 version.okhttp3=4.9.3 ## # available=4.10.0-RC1 +## # available=4.10.0 ## # available=5.0.0-alpha.1 ## # available=5.0.0-alpha.2 ## # available=5.0.0-alpha.3 ## # available=5.0.0-alpha.4 +## # available=5.0.0-alpha.5 +## # available=5.0.0-alpha.6 +## # available=5.0.0-alpha.7 +## # available=5.0.0-alpha.8 +## # available=5.0.0-alpha.9 +## # available=5.0.0-alpha.10 version.retrofit2=2.9.0 diff --git a/sample-android/gradle/wrapper/gradle-wrapper.jar b/sample-android/gradle/wrapper/gradle-wrapper.jar index 41d9927a4..249e5832f 100644 Binary files a/sample-android/gradle/wrapper/gradle-wrapper.jar and b/sample-android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/sample-android/gradle/wrapper/gradle-wrapper.properties b/sample-android/gradle/wrapper/gradle-wrapper.properties index aa991fcea..ae04661ee 100644 --- a/sample-android/gradle/wrapper/gradle-wrapper.properties +++ b/sample-android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample-android/gradlew b/sample-android/gradlew index 1b6c78733..a69d9cb6c 100755 --- a/sample-android/gradlew +++ b/sample-android/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/sample-android/gradlew.bat b/sample-android/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/sample-android/gradlew.bat +++ b/sample-android/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/sample-android/versions.properties b/sample-android/versions.properties index 6ec863687..ed334ca72 100644 --- a/sample-android/versions.properties +++ b/sample-android/versions.properties @@ -1,6 +1,6 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.40.2-SNAPSHOT -#### Revision of dependency notations removals: 9 +#### Generated by `./gradlew refreshVersions` version 0.41.0-SNAPSHOT +#### Revision of dependency notations removals: 11 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -14,6 +14,10 @@ plugin.gradle.site=0.6 version.androidx.activity=1.2.2 +version.androidx.test.rules=1.3.0 + +version.androidx.test.runner=1.3.0 + version.firebase-bom=27.1.0 version.google.android.material=1.3.0 diff --git a/sample-groovy/gradle/wrapper/gradle-wrapper.jar b/sample-groovy/gradle/wrapper/gradle-wrapper.jar index 41d9927a4..249e5832f 100644 Binary files a/sample-groovy/gradle/wrapper/gradle-wrapper.jar and b/sample-groovy/gradle/wrapper/gradle-wrapper.jar differ diff --git a/sample-groovy/gradle/wrapper/gradle-wrapper.properties b/sample-groovy/gradle/wrapper/gradle-wrapper.properties index aa991fcea..ae04661ee 100644 --- a/sample-groovy/gradle/wrapper/gradle-wrapper.properties +++ b/sample-groovy/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample-groovy/gradlew b/sample-groovy/gradlew index 1b6c78733..a69d9cb6c 100755 --- a/sample-groovy/gradlew +++ b/sample-groovy/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/sample-groovy/gradlew.bat b/sample-groovy/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/sample-groovy/gradlew.bat +++ b/sample-groovy/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/sample-groovy/settings.gradle b/sample-groovy/settings.gradle index d22f96dfe..04bda98de 100644 --- a/sample-groovy/settings.gradle +++ b/sample-groovy/settings.gradle @@ -14,6 +14,7 @@ pluginManagement { plugins { id("com.gradle.enterprise").version("3.10.2") +//// # available:"3.10.3") id 'de.fayard.refreshVersions' } diff --git a/sample-groovy/versions.properties b/sample-groovy/versions.properties index 22308d416..e9e2cd6c9 100644 --- a/sample-groovy/versions.properties +++ b/sample-groovy/versions.properties @@ -13,107 +13,11 @@ plugin.org.gradle.hello-world=0.2 version.androidx.annotation=1.1.0 -## # available=1.2.0 -## # available=1.3.0 -## # available=1.4.0 version.androidx.compose.compiler=1.2.0-alpha01 -## # available=1.2.0-alpha02 -## # available=1.2.0-alpha03 -## # available=1.2.0-alpha04 -## # available=1.2.0-alpha05 -## # available=1.2.0-alpha06 -## # available=1.2.0-alpha07 -## # available=1.2.0-alpha08 -## # available=1.2.0-beta01 -## # available=1.2.0-beta02 -## # available=1.2.0-beta03 -## # available=1.2.0-rc01 -## # available=1.2.0-rc02 version.com.google.guava..guava=15.0 -## # available=16.0 -## # available=16.0.1 -## # available=17.0 -## # available=18.0 -## # available=19.0 -## # available=20.0 -## # available=21.0 -## # available=22.0 -## # available=22.0-android -## # available=23.0 -## # available=23.0-android -## # available=23.1-android -## # available=23.1-jre -## # available=23.2-android -## # available=23.2-jre -## # available=23.3-android -## # available=23.3-jre -## # available=23.4-android -## # available=23.4-jre -## # available=23.5-android -## # available=23.5-jre -## # available=23.6-android -## # available=23.6-jre -## # available=23.6.1-android -## # available=23.6.1-jre -## # available=24.0-android -## # available=24.0-jre -## # available=24.1-android -## # available=24.1-jre -## # available=24.1.1-android -## # available=24.1.1-jre -## # available=25.0-android -## # available=25.0-jre -## # available=25.1-android -## # available=25.1-jre -## # available=26.0-android -## # available=26.0-jre -## # available=27.0-android -## # available=27.0-jre -## # available=27.0.1-android -## # available=27.0.1-jre -## # available=27.1-android -## # available=27.1-jre -## # available=28.0-android -## # available=28.0-jre -## # available=28.1-android -## # available=28.1-jre -## # available=28.2-android -## # available=28.2-jre -## # available=29.0-android -## # available=29.0-jre -## # available=30.0-android -## # available=30.0-jre -## # available=30.1-android -## # available=30.1-jre -## # available=30.1.1-android -## # available=30.1.1-jre -## # available=31.0-android -## # available=31.0-jre -## # available=31.0.1-android -## # available=31.0.1-jre -## # available=31.1-android -## # available=31.1-jre version.com.google.inject..guice=2.0 -## # available=3.0 -## # available=4.0 -## # available=4.1.0 -## # available=4.2.0 -## # available=4.2.1 -## # available=4.2.2 -## # available=4.2.3 -## # available=5.0.0 -## # available=5.0.1 -## # available=5.1.0 version.org.jetbrains..annotations=17.0.0 -## # available=18.0.0 -## # available=19.0.0 -## # available=20.0.0 -## # available=20.1.0 -## # available=21.0.0 -## # available=21.0.1 -## # available=22.0.0 -## # available=23.0.0 diff --git a/sample-kotlin-js/kotlin-js-store/yarn.lock b/sample-kotlin-js/kotlin-js-store/yarn.lock new file mode 100644 index 000000000..b3c9cfe9c --- /dev/null +++ b/sample-kotlin-js/kotlin-js-store/yarn.lock @@ -0,0 +1,2458 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@googlemaps/js-api-loader@1.10.0 - 1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@googlemaps/js-api-loader/-/js-api-loader-1.11.1.tgz#b7f02c04d8d8602fb4bd873b03685fccefce1c6f" + integrity sha512-2ug4uBu0onRXTAo7Yxkay5N7pdNIz3XpTElMTLdCtEfQDxikbjeR6GS8atVhblX+ubFBNlXvDzz7VtuXv0vMRQ== + dependencies: + fast-deep-equal "^3.1.3" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.5" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.5.tgz#acdfb7dd36b91cc5d812d7c093811a8f3d9b31e4" + integrity sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.30" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" + integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.1.tgz#828e4785ccca13f44e2fb6852ae0ef11e3e20ba5" + integrity sha512-z+2vB6yDt1fNwKOeGbckpmirO+VBDuQqecXkgeIqDlaOtmKn6hPR/viQ8cxCfqLU4fTlvM3+YjM367TukWdxpg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.4.1, acorn@^8.5.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.13" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" + integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +browserslist@^4.14.5: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001370: + version "1.0.30001370" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001370.tgz#0a30d4f20d38b9e108cc5ae7cc62df9fe66cd5ba" + integrity sha512-3PDmaP56wz/qz7G508xzjx8C+MC2qEm4SYhSEzC9IBROo+dGXFWRuaXkWti0A9tuI00g+toiriVqxtWMgl350g== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.3.4, debug@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +"decamelize@>=4.0.0 <5.0.0", decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.202: + version "1.4.202" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.202.tgz#0c2ed733f42b02ec49a955c5badfcc65888c390b" + integrity sha512-JYsK2ex9lmQD27kj19fhXYxzFJ/phLAkLKHv49A5UY6kMRV2xED3qMMLg/voW/+0AR6wMiI+VxlmK9NDtdxlPA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.9.3: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.0" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.10.3" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.14" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.14.tgz#9054384e4b7a78c88d01a4432dc18871af0ac859" + integrity sha512-tFfWHjnuUfKE186Tfgr+jtaFc0mZTApEgKDOeyN+FwOqRkO/zK/3h1AiRd8u8CY53owL3CUmGr/oI9p/RdyLTA== + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +follow-redirects@^1.0.0: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + +format-util@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mocha@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +moment@2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +prop-types@^15.6.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react@16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.9.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== + dependencies: + node-forge "^1" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map-loader@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.0.tgz#bdc6b118bc6c87ee4d8d851f2d4efcc5abdb2ef5" + integrity sha512-i3KVgM3+QPAHNbGavK+VBq03YoJl24m9JWNbLgsjTj8aJzXG9M61bantBTNBt7CNwY2FYf+RJRYJ3pzalKjIrw== + dependencies: + abab "^2.0.6" + iconv-lite "^0.6.3" + source-map-js "^1.0.2" + +source-map-support@0.5.21, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" + integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.7.2" + +terser@^5.7.2: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +watchpack@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz#c188db28c7bff12f87deda2a5595679ebbc3c9bc" + integrity sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^1.6.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@5.73.0: + version "5.73.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" + integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.9.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.1" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.4.2: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/sample-kotlin-js/versions.properties b/sample-kotlin-js/versions.properties index cbb1f9fa3..63cefdf4a 100644 --- a/sample-kotlin-js/versions.properties +++ b/sample-kotlin-js/versions.properties @@ -1,6 +1,6 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.24.0-SNAPSHOT -#### Revision of dependency notations removals: 1 +#### Generated by `./gradlew refreshVersions` version 0.41.0-SNAPSHOT +#### Revision of dependency notations removals: 11 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -10,58 +10,21 @@ #### #### NOTE: Some versions are filtered by the rejectVersionsIf predicate. See the settings.gradle.kts file. -version.kotest=4.6.0 -## # available=4.6.1 -## # available=4.6.2 +version.kotest=5.4.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 -## # available=1.5.20-RC -## # available=1.5.20 -## # available=1.5.21 -## # available=1.5.30-M1 -## # available=1.5.30-RC -## # available=1.5.30 +version.kotlin=1.7.10 version.npm.@googlemaps/js-api-loader=1.10.0 - 1.11.1 -## # available=1.11.0 -## # available=1.11.1 -## # available=1.11.2 -## # available=1.11.3 -## # available=1.11.4 -## # available=1.12.0 -## # available=1.12.1 -## # available=1.12.2 ## unused version.npm.bootstrap-icons=1.4.x -## # available=1.4.0 -## # available=1.4.1 -## # available=1.5.0 # equivalent to ~5.1.0 ## unused version.npm.css-loader=>=5.1.0 <5.2.0 -## # available=5.1.1 -## # available=5.1.2 -## # available=5.1.3 -## # available=5.1.4 -## # available=5.2.0 -## # available=5.2.1 -## # available=5.2.2 -## # available=5.2.3 -## # available=5.2.4 -## # available=5.2.5 -## # available=5.2.6 # equivalent to ^4.0.0 version.npm.decamelize=>=4.0.0 <5.0.0 -## # available=5.0.0 ## unused version.npm.file-loader=^6.2.0 @@ -71,10 +34,6 @@ version.npm.leaflet=^1.7.1 ## unused version.npm.debug=4.3.x -## # available=4.2.0 -## # available=4.3.0 -## # available=4.3.1 -## # available=4.3.2 ## unused version.npm.leaflet-imageoverlay-rotated=^0.2.1 @@ -82,9 +41,6 @@ version.npm.leaflet-imageoverlay-rotated=^0.2.1 version.npm.moment=2.29.1 version.npm.react=16.14.0 -## # available=17.0.0 -## # available=17.0.1 -## # available=17.0.2 ## unused version.npm.style-loader=^2.0.0 diff --git a/sample-kotlin/gradle.properties b/sample-kotlin/gradle.properties new file mode 100644 index 000000000..8ac56d9ba --- /dev/null +++ b/sample-kotlin/gradle.properties @@ -0,0 +1,5 @@ + + +org.gradle.unsafe.configuration-cache=true +#org.gradle.unsafe.configuration-cache-problems=warn + diff --git a/sample-kotlin/gradle/libs.versions.toml b/sample-kotlin/gradle/libs.versions.toml new file mode 100644 index 000000000..da5c13de7 --- /dev/null +++ b/sample-kotlin/gradle/libs.versions.toml @@ -0,0 +1,66 @@ +## Generated by $ ./gradlew refreshVersionsCatalog + +## This comment should be removed by ` ./gradlew refreshVersionsCleanup` +## unless feature flag VERSIONS_CATALOG is disabled + +[plugins] + +org-jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } + +org-jetbrains-kotlinx-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version = "0.4.2" } + +[versions] + +androidx-core = "1.3.1" + +okhttp3 = "3.10.0" + +kotest = "5.1.0" + +junit-junit = "4.12" + +apache-poi = "4.0.0" + +kotlin = "1.6.10" + +kotlinx-coroutines = "1.6.0" + +[libraries] + +androidx-core-core = { group = "androidx.core", name = "core", version.ref = "androidx-core" } + +guava = "com.google.guava:guava:15.0" + +guice = "com.google.inject:guice:2.0" + +okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp3" } + +okhttp-urlconnection = { group = "com.squareup.okhttp3", name = "okhttp-urlconnection", version.ref = "okhttp3" } + +kotest-runner-junit4 = { group = "io.kotest", name = "kotest-runner-junit4", version.ref = "kotest" } + +junit = { group = "junit", name = "junit", version.ref = "junit-junit" } + +poi = { group = "org.apache.poi", name = "poi", version.ref = "apache-poi" } + +poi-ooxml = { group = "org.apache.poi", name = "poi-ooxml", version.ref = "apache-poi" } + +gradle-hello-world-plugin = "org.gradle:gradle-hello-world-plugin:0.1" + +kotlin-script-runtime = { group = "org.jetbrains.kotlin", name = "kotlin-script-runtime", version.ref = "kotlin" } + +kotlin-scripting-compiler-embeddable = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-compiler-embeddable", version.ref = "kotlin" } + +kotlin-stdlib-jdk8 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" } + +kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } + +kotlinx-coroutines-jdk8 = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-jdk8", version.ref = "kotlinx-coroutines" } + +mongo-java-driver = "org.mongodb:mongo-java-driver:3.11.0" + +log4j-bom = "org.apache.logging.log4j:log4j-bom:2.17.2" + +log4j-jul = { group = "org.apache.logging.log4j", name = "log4j-jul" } + +log4j-slf4j-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j-impl" } diff --git a/sample-kotlin/gradle/wrapper/gradle-wrapper.jar b/sample-kotlin/gradle/wrapper/gradle-wrapper.jar index e708b1c02..249e5832f 100644 Binary files a/sample-kotlin/gradle/wrapper/gradle-wrapper.jar and b/sample-kotlin/gradle/wrapper/gradle-wrapper.jar differ diff --git a/sample-kotlin/gradle/wrapper/gradle-wrapper.properties b/sample-kotlin/gradle/wrapper/gradle-wrapper.properties index 28ff446a2..ae04661ee 100644 --- a/sample-kotlin/gradle/wrapper/gradle-wrapper.properties +++ b/sample-kotlin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sample-kotlin/gradlew b/sample-kotlin/gradlew index 4f906e0c8..a69d9cb6c 100755 --- a/sample-kotlin/gradlew +++ b/sample-kotlin/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,101 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/sample-kotlin/gradlew.bat b/sample-kotlin/gradlew.bat index 107acd32c..f127cfd49 100644 --- a/sample-kotlin/gradlew.bat +++ b/sample-kotlin/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/sample-kotlin/build.gradle.kts b/sample-kotlin/sample-kotlin.gradle.kts similarity index 92% rename from sample-kotlin/build.gradle.kts rename to sample-kotlin/sample-kotlin.gradle.kts index fe89c6304..2df109e84 100644 --- a/sample-kotlin/build.gradle.kts +++ b/sample-kotlin/sample-kotlin.gradle.kts @@ -46,6 +46,11 @@ dependencies { api("org.apache.poi:poi:_") api("org.apache.poi:poi-ooxml:_") + + // logging + implementation(platform("org.apache.logging.log4j:log4j-bom:2.17.2")) + runtimeOnly("org.apache.logging.log4j:log4j-slf4j-impl") + runtimeOnly("org.apache.logging.log4j:log4j-jul") } getKotlinPluginVersion().let { diff --git a/sample-kotlin/settings.gradle.kts b/sample-kotlin/settings.gradle.kts index 1effe00d4..d35d6dbc9 100644 --- a/sample-kotlin/settings.gradle.kts +++ b/sample-kotlin/settings.gradle.kts @@ -25,6 +25,7 @@ refreshVersions { featureFlags { enable(LIBS) disable(GRADLE_UPDATES) + disable(VERSIONS_CATALOG) } extraArtifactVersionKeyRules(file("refreshVersions-extra-rules.txt")) @@ -56,7 +57,9 @@ gradleEnterprise { buildScan { termsOfServiceUrl = "https://gradle.com/terms-of-service" termsOfServiceAgree = "yes" + publishOnFailure() } } rootProject.name = "sample-kotlin" +rootProject.buildFileName = "${rootProject.name}.gradle.kts" diff --git a/sample-kotlin/versions.properties b/sample-kotlin/versions.properties index ce2b89245..bb4b18e92 100644 --- a/sample-kotlin/versions.properties +++ b/sample-kotlin/versions.properties @@ -1,6 +1,6 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.40.2-SNAPSHOT -#### Revision of dependency notations removals: 9 +#### Generated by `./gradlew refreshVersions` version 0.41.0-SNAPSHOT +#### Revision of dependency notations removals: 11 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -15,9 +15,20 @@ plugin.org.jetbrains.kotlinx.benchmark=0.4.2 ## unused plugin.com.example.unused=42 +## unused version.com.example..dummy-library-for-testing=0.1.0-alpha01 -## # available=0.1.0-alpha02 -## # available=0.1.0-alpha03 + +version.org.apache.logging.log4j..log4j-bom=2.17.2 + +version.org.mongodb..mongo-java-driver=3.11.0 + +version.okhttp3=3.10.0 + +version.junit.junit=4.12 + +version.com.google.inject..guice=2.0 + +version.com.google.guava..guava=15.0 ## unused version.unused=42 @@ -29,19 +40,8 @@ version.androidx.browser=1.0.0 version.androidx.cardview=1.0.0 version.androidx.core=1.3.1 -## # available=1.3.2 -## # available=1.5.0 -## # available=1.6.0 -## # available=1.7.0 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 -## # available=5.1.0 -## # available=5.2.0 version.kotest=5.1.0 @@ -56,4 +56,3 @@ 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 diff --git a/sample-multi-modules/settings.gradle.kts b/sample-multi-modules/settings.gradle.kts index 8ed92ae7e..3f1fa7086 100644 --- a/sample-multi-modules/settings.gradle.kts +++ b/sample-multi-modules/settings.gradle.kts @@ -16,6 +16,12 @@ pluginManagement { plugins { id("com.gradle.enterprise").version("3.8") +//// # available:"3.8.1") +//// # available:"3.9") +//// # available:"3.10") +//// # available:"3.10.1") +//// # available:"3.10.2") +//// # available:"3.10.3") id("de.fayard.refreshVersions") } diff --git a/sample-multi-modules/versions.properties b/sample-multi-modules/versions.properties index d2da39b57..f3a637480 100644 --- a/sample-multi-modules/versions.properties +++ b/sample-multi-modules/versions.properties @@ -1,6 +1,6 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.40.2-SNAPSHOT -#### Revision of dependency notations removals: 9 +#### Generated by `./gradlew refreshVersions` version 0.41.0-SNAPSHOT +#### Revision of dependency notations removals: 11 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -9,7 +9,6 @@ #### suppress inspection "UnusedProperty" for whole file plugin.org.gradle.hello-world=0.1 -## # available=0.2 version.com.nhaarman.mockitokotlin2..mockito-kotlin=2.2.0 @@ -23,11 +22,6 @@ version.io.mockk..mockk-common=1.10.0 version.junit=5.7.1 version.junit.jupiter=5.7.1 -## # available=5.7.2 -## # available=5.8.0-M1 -## # available=5.8.0-RC1 -## # available=5.8.0 -## # available=5.8.1 version.kotest=5.1.0 @@ -35,57 +29,16 @@ version.kotlin=1.6.10 version.kotlinx.collections.immutable=0.3.2 -## # available=0.3.3 -## # available=0.3.4 version.kotlinx.coroutines=1.6.0 version.ktor=1.3.2-1.4-M1 -### available=1.3.2-1.4.0-rc -### available=1.4.0 -### available=1.4.1 -### available=1.4.2 -### available=1.4.3 -### available=1.5.0 -### available=1.5.1 -### available=1.5.2 -### available=1.5.3 -### available=1.5.4 -### available=1.6.0 -### available=1.6.1 -### available=1.6.2 -### available=1.6.3 -### available=1.6.4 -### available=1.6.5 version.mockito=3.9.0 -## # available=3.10.0 -## # available=3.11.0 -## # available=3.11.1 -## # available=3.11.2 -## # available=3.12.0 -## # available=3.12.1 -## # available=3.12.2 -## # available=3.12.3 -## # available=3.12.4 -## # available=4.0.0 -## # available=4.1.0 version.mockk=1.11.0 -### available=1.12.0 -### available=1.12.1 version.okhttp3=4.7.2 -## # available=4.8.0 -## # available=4.8.1 -## # available=4.9.0 -## # available=4.9.1 -## # available=4.9.2 -## # available=4.9.3 -## # available=4.10.0-RC1 -## # available=5.0.0-alpha.1 -## # available=5.0.0-alpha.2 -## # available=5.0.0-alpha.3 ## unused version.org.junit.jupiter..junit-jupiter=5.6.2 @@ -114,17 +67,5 @@ version.org.mockito..mockito-junit-jupiter=3.3.3 version.retrofit2=2.9.0 version.com.github.ajalt.clikt..clikt=3.0.0 -## # available=3.0.1 -## # available=3.1.0 -## # available=3.2.0 -## # available=3.3.0 version.junit.junit=4.12 -## # available=4.13-beta-1 -## # available=4.13-beta-2 -## # available=4.13-beta-3 -## # available=4.13-rc-1 -## # available=4.13-rc-2 -## # available=4.13 -## # available=4.13.1 -## # available=4.13.2