From f096983032abe700b8d3c0570248e18530b2ee9a Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Wed, 26 Jul 2023 19:01:04 +0300 Subject: [PATCH 01/18] WIP --- .github/codecov.yml | 7 + .github/workflows/build_and_test.yml | 139 ++++ .github/workflows/detekt.yml | 25 + .github/workflows/diktat.yml | 31 + build.gradle.kts | 13 + buildSrc/build.gradle.kts | 19 + buildSrc/settings.gradle.kts | 7 + .../osv4k/buildutils/DetektConfiguration.kt | 35 + .../osv4k/buildutils/DiktatConfiguration.kt | 45 ++ .../buildutils/VersioningConfiguration.kt | 74 ++ .../buildutils/kotlin-library.gradle.kts | 118 +++ detekt.yml | 679 ++++++++++++++++++ diktat-analysis.yml | 111 +++ gradle/libs.versions.toml | 27 + settings.gradle.kts | 30 +- 15 files changed, 1332 insertions(+), 28 deletions(-) create mode 100644 .github/codecov.yml create mode 100644 .github/workflows/build_and_test.yml create mode 100644 .github/workflows/detekt.yml create mode 100644 .github/workflows/diktat.yml create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/settings.gradle.kts create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts create mode 100644 detekt.yml create mode 100644 diktat-analysis.yml create mode 100644 gradle/libs.versions.toml diff --git a/.github/codecov.yml b/.github/codecov.yml new file mode 100644 index 0000000..d2504c7 --- /dev/null +++ b/.github/codecov.yml @@ -0,0 +1,7 @@ +codecov: + max_report_age: off +coverage: + status: + project: + default: + threshold: 2% \ No newline at end of file diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml new file mode 100644 index 0000000..32f3a85 --- /dev/null +++ b/.github/workflows/build_and_test.yml @@ -0,0 +1,139 @@ +name: Build and test + +on: + pull_request: + push: + branches: + - 'main' + +jobs: + build_and_test_with_code_coverage: + name: Build and test + runs-on: ${{ matrix.os }} + strategy: + # We need multiple builds to run even if the 1st one is failing, because + # test failures may be OS-specific (or the tests themselves flaky). + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + + # A possible workaround for . + permissions: + checks: write + contents: write + pull-requests: write + statuses: write + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: 11 + distribution: temurin + - name: Retrieve Kotlin version + shell: bash + run: | + kv=$(cat gradle/libs.versions.toml | grep '^kotlin =' | awk -F'[=]' '{print $2}' | tr -d '" ') + echo KOTLIN_VERSION=$kv >> $GITHUB_ENV + - name: Cache konan + uses: actions/cache@v3 + with: + # [@actions/glob](https://github.com/actions/toolkit/tree/main/packages/glob) is used to match paths + # It should correctly expand `~` on every OS. + path: ~/.konan + key: ${{ runner.os }}-gradle-konan-${{ env.KOTLIN_VERSION }} + - uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + # The `--continue` flag is necessary so that Gradle keeps going after the 1st test failure. + # By default, when test for all MPP targets are executed, Kotlin Gradle Plugin generates a single aggregated HTML report. + # Property `kotlin.tests.individualTaskReports` enables individual Junit-style XML reports. + # See org.jetbrains.kotlin.gradle.testing.internal.KotlinTestReport. + arguments: | + build + --continue + -x detekt + -Pkotlin.tests.individualTaskReports=true + -Porg.gradle.caching=true + -Pdetekt.multiplatform.disabled=true + -PdisableRedundantTargets=true + -PenabledExecutables=debug + -PgprUser=${{ github.actor }} + -PgprKey=${{ secrets.GITHUB_TOKEN }} + + # This step needs a Git repository, so it's impossible to extract it + # into a separate job (or, otherwise, we'd need to upload the content + # of the whole `.git` folder as an artifact). + - name: JUnit Tests (dorny/test-reporter@v1) + uses: dorny/test-reporter@v1 + if: ${{ always() }} + with: + name: JUnit Tests (${{ runner.os }}, dorny/test-reporter@v1) + # Comma-separated values. + path: "**/build/test-results/*/TEST-*.xml" + reporter: java-junit + # Ignore the "Resource not accessible by integration" error when a PR + # originates from a non-collaborator. This is + # which may be + # potentially fixed with . + continue-on-error: true + + - name: Upload test results + uses: actions/upload-artifact@v3 + if: ${{ always() }} + with: + name: xml-test-reports-${{ runner.os }} + path: | + **/build/test-results/*/TEST-*.xml + retention-days: 1 + + - name: Upload gradle reports + if: ${{ always() }} + uses: actions/upload-artifact@v3 + with: + name: gradle-reports-${{ matrix.os }} + path: '**/build/reports/' + - name: Code coverage report + if: ${{ runner.os == 'Linux' }} + uses: codecov/codecov-action@v3 + with: + flags: unittests + fail_ci_if_error: false # optional (default = false) + + report: + name: Publish JUnit test results + if: ${{ always() }} + needs: build_and_test_with_code_coverage + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + + permissions: + checks: write + pull-requests: write + + steps: + - uses: actions/download-artifact@v3 + if: ${{ always() }} + with: + name: xml-test-reports-${{ runner.os }} + + # Uses Docker, that's why Linux-only. + - name: JUnit Tests (EnricoMi/publish-unit-test-result-action@v1, Linux) + uses: EnricoMi/publish-unit-test-result-action@v1 + if: ${{ runner.os == 'Linux' }} + with: + check_name: JUnit Tests (${{ runner.os }}, EnricoMi/publish-unit-test-result-action@v1) + files: | + **/build/test-results/*/TEST-*.xml + + - name: JUnit Tests (EnricoMi/publish-unit-test-result-action@v1, Windows or Mac OS X) + uses: EnricoMi/publish-unit-test-result-action/composite@v1 + if: ${{ runner.os == 'Windows' || runner.os == 'macOS' }} + with: + check_name: JUnit Tests (${{ runner.os }}, EnricoMi/publish-unit-test-result-action@v1) + files: | + **/build/test-results/*/TEST-*.xml diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml new file mode 100644 index 0000000..7cfcfe4 --- /dev/null +++ b/.github/workflows/detekt.yml @@ -0,0 +1,25 @@ +name: Run deteKT + +on: + push: + branches: [ main ] + pull_request: + +jobs: + detekt_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: 11 + distribution: temurin + - uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + detektAll + --build-cache + -PgprUser=${{ github.actor }} + -PgprKey=${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/diktat.yml b/.github/workflows/diktat.yml new file mode 100644 index 0000000..8bd86e4 --- /dev/null +++ b/.github/workflows/diktat.yml @@ -0,0 +1,31 @@ +name: Run diKTat + +on: + push: + branches: [ main ] + pull_request: + +jobs: + diktat_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + java-version: 11 + distribution: temurin + - uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + diktatCheck + mergeDiktatReports + -Pdetekt.multiplatform.disabled=true + -Pdiktat.githubActions=true + --continue + - name: Upload SARIF report to Github + if: always() + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: build/reports/diktat/diktat-merged.sarif diff --git a/build.gradle.kts b/build.gradle.kts index 00cbb04..584bafa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,13 @@ +import com.saveourtool.osv4k.buildutils.configureDiktat +import com.saveourtool.osv4k.buildutils.configurePublishing +import com.saveourtool.osv4k.buildutils.configureVersioning +import com.saveourtool.osv4k.buildutils.createDetektTask +import com.saveourtool.osv4k.buildutils.installGitHooks + plugins { alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.kotlin.plugin.serialization) + id("com.saveourtool.osv4k.buildutils.kotlin-library") } group = "com.saveourtool.osv4k" @@ -9,6 +16,12 @@ repositories { mavenCentral() } +// version generation +configureVersioning() +// checks and validations +configureDiktat() +createDetektTask() + kotlin { jvm { withJava() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..9eea781 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + // workaround https://github.com/gradle/gradle/issues/15383 + implementation(files(project.libs.javaClass.superclass.protectionDomain.codeSource.location)) + implementation(libs.diktat.gradle.plugin) + implementation(libs.detekt.gradle.plugin) + implementation(libs.kotlin.gradle.plugin) + implementation(libs.kotlin.plugin.serialization) + implementation("io.github.gradle-nexus:publish-plugin:1.3.0") + implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") +} \ No newline at end of file diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..b5a0fab --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt new file mode 100644 index 0000000..e263c96 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt @@ -0,0 +1,35 @@ +/** + * Configuration for detekt static analysis + */ + +package com.saveourtool.osv4k.buildutils + +import io.gitlab.arturbosch.detekt.Detekt +import io.gitlab.arturbosch.detekt.DetektPlugin +import io.gitlab.arturbosch.detekt.extensions.DetektExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType + +/** + * Configure Detekt for a single project + */ +fun Project.configureDetekt() { + apply() + configure { + config = rootProject.files("detekt.yml") + buildUponDefaultConfig = true + } +} + +/** + * Register a unified detekt task + */ +fun Project.createDetektTask() { + tasks.register("detektAll") { + allprojects { + this@register.dependsOn(tasks.withType()) + } + } +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt new file mode 100644 index 0000000..82dfff0 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt @@ -0,0 +1,45 @@ +/** + * Configuration for diktat static analysis + */ + +package com.saveourtool.save.buildutils + +import org.cqfn.diktat.plugin.gradle.DiktatExtension +import org.cqfn.diktat.plugin.gradle.DiktatGradlePlugin +import org.cqfn.diktat.plugin.gradle.DiktatJavaExecTaskBase +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.withType + +/** + * Applies diktat gradle plugin and configures diktat for [this] project + */ +fun Project.configureDiktat() { + apply() + configure { + diktatConfigFile = rootProject.file("diktat-analysis.yml") + githubActions = findProperty("diktat.githubActions")?.toString()?.toBoolean() ?: false + inputs { + if (path == rootProject.path) { + include( + "buildSrc/src/**/*.kt", + "buildSrc/**/*.kts", + "*.kts" + ) + exclude("build", "buildSrc/build") + } else { + include("src/**/*.kt", "*.kts", "src/**/*.kts") + exclude("build/**") + } + } + } + fixDiktatTask() +} + +private fun Project.fixDiktatTask() { + tasks.withType().configureEach { + // https://github.com/saveourtool/diktat/issues/1269 + systemProperty("user.home", rootDir.toString()) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt new file mode 100644 index 0000000..80c63c8 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt @@ -0,0 +1,74 @@ +/** + * Version configuration file. + */ + +package com.saveourtool.osv4k.buildutils + +import org.ajoberstar.reckon.core.Scope +import org.ajoberstar.reckon.core.VersionTagParser +import org.ajoberstar.reckon.gradle.ReckonExtension +import org.ajoberstar.reckon.gradle.ReckonPlugin +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.internal.storage.file.FileRepository +import org.eclipse.jgit.storage.file.FileRepositoryBuilder +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import java.util.Optional + +/** + * Configures how project version is determined. + * + * @throws GradleException if there was an attempt to run release build with dirty working tree + */ +fun Project.configureVersioning() { + apply() + + val isSnapshot = hasProperty("reckon.stage") && property("reckon.stage") == "snapshot" + configure { + setDefaultInferredScope(Scope.MINOR.name) + setScopeCalc(calcScopeFromProp()) + if (isSnapshot) { + // we should build snapshots only for snapshot publishing, so it requires explicit parameter + snapshots() + setStageCalc(calcStageFromProp()) + fixForSnapshot() + } else { + stages("alpha", "rc", "final") + setStageCalc(calcStageFromProp()) + } + } + + // to activate release, provide `-Prelease` or `-Prelease=true`. To deactivate, either omit the property, or set `-Prelease=false`. + val isRelease = hasProperty("release") && (property("release") as String != "false") + if (isRelease) { + failOnUncleanTree() + } +} + +private fun Project.failOnUncleanTree() { + val status = FileRepositoryBuilder() + .findGitDir(project.rootDir) + .setup() + .let(::FileRepository) + .let(::Git) + .status() + .call() + if (!status.isClean) { + throw GradleException("Release build will be performed with not clean git tree; aborting. " + + "Untracked files: ${status.untracked}, uncommitted changes: ${status.uncommittedChanges}") + } +} + +/** + * A terrible hack to remove all pre-release tags. Because in semver `0.1.0-SNAPSHOT` < `0.1.0-alpha`, in snapshot mode + * we remove tags like `0.1.0-alpha`, and then reckoned version will still be `0.1.0-SNAPSHOT` and it will be compliant. + */ +private fun ReckonExtension.fixForSnapshot() { + setTagParser { tagName -> + Optional.of(tagName) + .filter { it.matches(Regex("""^v\d+\.\d+\.\d+$""")) } + .flatMap { VersionTagParser.getDefault().parse(it) } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts new file mode 100644 index 0000000..706e92e --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -0,0 +1,118 @@ +/** + * Precompiled script plugin, that applies common configuration for a KMP project. + * It specifies common targets and sets some common compiler flags. + * It creates a number of useful source sets and adds common dependencies. + * These source sets can be retrieved in a particular build script and configured further as needed. + */ + +package com.saveourtool.save.buildutils + +import org.gradle.kotlin.dsl.kotlin +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest + +plugins { + kotlin("multiplatform") + kotlin("plugin.serialization") +} + +kotlin { + jvm { + compilations.all { + kotlinOptions { + jvmTarget = "11" + freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + } + } + } + val nativeTargets = listOf(linuxX64(), mingwX64(), macosX64()) + if (project.name == "save-common") { + // additionally, save-common should be available for JS too + // fixme: shouldn't rely on hardcoded project name here + js(IR).browser() + + // store yarn.lock in the root directory + rootProject.extensions.configure { + lockFileDirectory = rootProject.projectDir + } + } + + if (hasProperty("disableRedundantTargets") && (property("disableRedundantTargets") as String?) != "false") { + // with this flag we exclude targets that are present on multiple OS to speed up build + val currentOs = DefaultNativePlatform.getCurrentOperatingSystem() + val redundantTarget: String? = when { + currentOs.isWindows -> "linuxX64" + currentOs.isMacOsX -> "linuxX64" + currentOs.isLinux -> null + else -> throw GradleException("Unknown operating system ${currentOs.name}") + } + tasks.matching { redundantTarget != null && it.name.contains(redundantTarget, ignoreCase = true) } + .configureEach { + logger.lifecycle("Disabling task :${project.name}:$name on host $currentOs") + enabled = false + } + } + + /* + * Common structure for MPP libraries: + * common + * | + * nonJs + * / \ + * native JVM + * / | \ + * linux mingw macos + */ + sourceSets { + all { + languageSettings.optIn("kotlin.RequiresOptIn") + } + val commonMain by getting + val commonTest by getting { + dependencies { + implementation("io.kotest:kotest-assertions-core:5.6.2") + } + } + val commonNonJsMain by creating { + dependsOn(commonMain) + } + val commonNonJsTest by creating { + dependsOn(commonTest) + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val jvmMain by getting { + dependsOn(commonNonJsMain) + } + val jvmTest by getting { + dependsOn(commonNonJsTest) + dependencies { + implementation(kotlin("test-junit5")) + implementation("org.junit.jupiter:junit-jupiter-engine:5.10.0") + } + } + val nativeMain by creating { + dependsOn(commonNonJsMain) + } + val nativeTest by creating { + dependsOn(commonNonJsTest) + } + nativeTargets.forEach { + getByName("${it.name}Main").dependsOn(nativeMain) + } + nativeTargets.forEach { + getByName("${it.name}Test").dependsOn(nativeTest) + } + } +} + +configureJacoco() +configurePublishing() +configureDiktat() +configureDetekt() + +tasks.withType { + useJUnitPlatform() +} \ No newline at end of file diff --git a/detekt.yml b/detekt.yml new file mode 100644 index 0000000..5361bd6 --- /dev/null +++ b/detekt.yml @@ -0,0 +1,679 @@ +build: + maxIssues: 0 + excludeCorrectable: false + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +config: + validation: true + # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' + excludes: '' + +processors: + active: true + exclude: + - 'DetektProgressListener' + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ClassCountProcessor' + # - 'PackageCountProcessor' + # - 'KtFileCountProcessor' + +console-reports: + active: true + exclude: + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' + # - 'FindingsReport' + - 'FileBasedFindingsReport' + +comments: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + AbsentOrWrongFileLicense: + excludes: ['**/resources/**'] + active: false + + licenseTemplateFile: 'license.template' + CommentOverPrivateFunction: + excludes: ['**/resources/**'] + active: false + CommentOverPrivateProperty: + excludes: ['**/resources/**'] + active: false + EndOfSentenceFormat: + excludes: ['**/resources/**'] + active: false + endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + UndocumentedPublicClass: + excludes: ['**/resources/**'] + active: false + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: + excludes: ['**/resources/**'] + active: false + UndocumentedPublicProperty: + excludes: ['**/resources/**'] + active: false + +complexity: + active: true + ComplexCondition: + excludes: ['**/resources/**'] + active: false + threshold: 4 + ComplexInterface: + excludes: ['**/resources/**'] + active: false + threshold: 10 + includeStaticDeclarations: false + includePrivateDeclarations: false + ComplexMethod: + excludes: ['**/resources/**'] + active: true + threshold: 15 + ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false + ignoreNestingFunctions: false + nestingFunctions: [run, let, apply, with, also, use, forEach, isNotNull, ifNull] + LabeledExpression: + excludes: ['**/resources/**'] + active: false + ignoredLabels: [] + LargeClass: + excludes: ['**/resources/**'] + active: true + threshold: 600 + LongMethod: + excludes: ['**/resources/**', '**/build/**'] + active: true + threshold: 60 + LongParameterList: + excludes: ['**/resources/**'] + active: true + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: false + ignoreDataClasses: true + ignoreAnnotated: [] + MethodOverloading: + excludes: ['**/resources/**'] + active: false + threshold: 6 + NestedBlockDepth: + excludes: ['**/resources/**'] + active: true + threshold: 5 + ReplaceSafeCallChainWithRun: + active: false + StringLiteralDuplication: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +coroutines: + active: true + GlobalCoroutineUsage: + excludes: ['**/resources/**'] + active: false + RedundantSuspendModifier: + excludes: ['**/resources/**'] + active: false + SuspendFunWithFlowReturnType: + active: false + +empty-blocks: + active: true + EmptyCatchBlock: + excludes: ['**/resources/**'] + active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' + EmptyClassBlock: + excludes: ['**/resources/**'] + active: true + EmptyDefaultConstructor: + excludes: ['**/resources/**'] + active: true + EmptyDoWhileBlock: + excludes: ['**/resources/**'] + active: true + EmptyElseBlock: + excludes: ['**/resources/**'] + active: true + EmptyFinallyBlock: + excludes: ['**/resources/**'] + active: true + EmptyForBlock: + excludes: ['**/resources/**'] + active: true + EmptyFunctionBlock: + excludes: ['**/resources/**'] + active: true + ignoreOverridden: false + EmptyIfBlock: + excludes: ['**/resources/**'] + active: true + EmptyInitBlock: + excludes: ['**/resources/**'] + active: true + EmptyKtFile: + excludes: ['**/resources/**'] + active: true + EmptySecondaryConstructor: + excludes: ['**/resources/**'] + active: true + EmptyTryBlock: + excludes: ['**/resources/**'] + active: true + EmptyWhenBlock: + excludes: ['**/resources/**'] + active: true + EmptyWhileBlock: + excludes: ['**/resources/**'] + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + excludes: ['**/resources/**'] + active: false + methodNames: [toString, hashCode, equals, finalize] + InstanceOfCheckForException: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + NotImplementedDeclaration: + excludes: ['**/resources/**'] + active: false + PrintStackTrace: + excludes: ['**/resources/**'] + active: false + RethrowCaughtException: + excludes: ['**/resources/**'] + active: false + ReturnFromFinally: + excludes: ['**/resources/**'] + active: false + ignoreLabeled: false + SwallowedException: + excludes: ['**/resources/**'] + active: false + ignoredExceptionTypes: + - InterruptedException + - NumberFormatException + - ParseException + - MalformedURLException + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + excludes: ['**/resources/**'] + active: false + ThrowingExceptionInMain: + excludes: ['**/resources/**'] + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptions: + - IllegalArgumentException + - IllegalStateException + - IOException + ThrowingNewInstanceOfSameException: + excludes: ['**/resources/**'] + active: false + TooGenericExceptionCaught: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptionNames: + - ArrayIndexOutOfBoundsException + - Error + - Exception + - IllegalMonitorStateException + - NullPointerException + - IndexOutOfBoundsException + - RuntimeException + - Throwable + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + excludes: ['**/resources/**'] + active: true + exceptionNames: + - Error + - Exception + - Throwable + - RuntimeException + +naming: + active: true + ClassNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + EnumNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + forbiddenName: [] + FunctionMaxLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + minimumFunctionNameLength: 3 + FunctionNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)' + excludeClassPattern: '$^' + ignoreOverridden: true + ignoreAnnotated: ['Composable'] + FunctionParameterNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + InvalidPackageDeclaration: + excludes: ['**/resources/**'] + active: false + rootPackage: '' + MatchingDeclarationName: + excludes: ['**/resources/**'] + active: true + mustBeFirst: true + MemberNameEqualsClassName: + excludes: ['**/resources/**'] + active: true + ignoreOverridden: true + NoNameShadowing: + # Different rule (in Diktat) checks that implicit lambda hasn't been shadowed. + active: false + NonBooleanPropertyPrefixedWithIs: + active: true + ObjectPropertyNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' + VariableMaxLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + maximumVariableNameLength: 64 + VariableMinLength: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + minimumVariableNameLength: 1 + VariableNaming: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + +performance: + active: true + ArrayPrimitive: + excludes: ['**/resources/**'] + active: true + ForEachOnRange: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + SpreadOperator: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryTemporaryInstantiation: + excludes: ['**/resources/**'] + active: true + +potential-bugs: + active: true + Deprecation: + excludes: ['**/resources/**'] + active: false + DuplicateCaseInWhenExpression: + excludes: ['**/resources/**'] + active: true + EqualsAlwaysReturnsTrueOrFalse: + excludes: ['**/resources/**'] + active: true + EqualsWithHashCodeExist: + excludes: ['**/resources/**'] + active: true + ExplicitGarbageCollectionCall: + excludes: ['**/resources/**'] + active: true + HasPlatformType: + excludes: ['**/resources/**'] + active: false + IgnoredReturnValue: + excludes: ['**/resources/**'] + active: false + restrictToAnnotatedMethods: true + returnValueAnnotations: ['*.CheckReturnValue', '*.CheckResult'] + ImplicitDefaultLocale: + excludes: ['**/resources/**'] + active: false + ImplicitUnitReturnType: + excludes: ['**/resources/**'] + active: false + allowExplicitReturnType: true + InvalidRange: + excludes: ['**/resources/**'] + active: true + IteratorHasNextCallsNextMethod: + excludes: ['**/resources/**'] + active: true + IteratorNotThrowingNoSuchElementException: + excludes: ['**/resources/**'] + active: true + LateinitUsage: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreAnnotated: [] + ignoreOnClassesPattern: '' + MapGetWithNotNullAssertionOperator: + excludes: ['**/resources/**'] + active: false + MissingWhenCase: + excludes: ['**/resources/**'] + active: true + NullableToStringCall: + active: false + RedundantElseInWhen: + excludes: ['**/resources/**'] + active: true + UnconditionalJumpStatementInLoop: + excludes: ['**/resources/**'] + active: false + UnnecessaryNotNullOperator: + excludes: ['**/resources/**'] + active: false + UnnecessarySafeCall: + excludes: ['**/resources/**'] + active: false + UnreachableCode: + excludes: ['**/resources/**'] + active: true + UnsafeCallOnNullableType: + excludes: ['**/resources/**'] + active: true + UnsafeCast: + excludes: ['**/resources/**'] + active: false + UselessPostfixExpression: + excludes: ['**/resources/**'] + active: false + WrongEqualsTypeParameter: + excludes: ['**/resources/**'] + active: true + +style: + active: true + ClassOrdering: + active: true + CollapsibleIfStatements: + excludes: ['**/resources/**'] + active: false + DataClassContainsFunctions: + excludes: ['**/resources/**'] + active: false + conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + excludes: ['**/resources/**'] + active: false + EqualsNullCall: + excludes: ['**/resources/**'] + active: true + EqualsOnSignatureLine: + excludes: ['**/resources/**'] + active: false + ExplicitCollectionElementAccessMethod: + excludes: ['**/resources/**'] + active: false + ExplicitItLambdaParameter: + excludes: ['**/resources/**'] + active: false + ExpressionBodySyntax: + excludes: ['**/resources/**'] + active: false + includeLineWrapping: false + ForbiddenComment: + active: false + ForbiddenImport: + excludes: ['**/resources/**'] + active: false + imports: [] + forbiddenPatterns: '' + ForbiddenMethodCall: + excludes: ['**/resources/**', '**/src/test/**', '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + active: true + methods: ['kotlin.io.println', 'kotlin.io.print'] + ForbiddenPublicDataClass: + excludes: ['**/resources/**'] + active: false + ignorePackages: ['*.internal', '*.internal.*'] + ForbiddenVoid: + excludes: ['**/resources/**'] + active: false + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: + excludes: ['**/resources/**'] + active: true + ignoreOverridableFunction: true + excludedFunctions: 'describeContents' + ignoreAnnotated: ['dagger.Provides'] + LibraryCodeMustSpecifyReturnType: + excludes: ['**/resources/**'] + active: false + LibraryEntitiesShouldNotBePublic: + active: false + LoopWithTooManyJumpStatements: + excludes: ['**/resources/**'] + active: true + maxJumpCount: 1 + MagicNumber: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreNumbers: ['-1', '0', '1', '2'] + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreLocalVariableDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + ignoreRanges: false + MandatoryBracesIfStatements: + excludes: ['**/resources/**'] + active: false + MandatoryBracesLoops: + excludes: ['**/resources/**'] + active: false + MaxLineLength: + excludes: ['**/resources/**'] + active: true + maxLineLength: 180 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: + excludes: ['**/resources/**'] + active: true + ModifierOrder: + excludes: ['**/resources/**'] + active: true + NestedClassesVisibility: + excludes: ['**/resources/**'] + active: false + NewLineAtEndOfFile: + excludes: ['**/resources/**'] + active: true + NoTabs: + excludes: ['**/resources/**'] + active: false + OptionalAbstractKeyword: + excludes: ['**/resources/**'] + active: true + OptionalUnit: + excludes: ['**/resources/**'] + active: false + OptionalWhenBraces: + excludes: ['**/resources/**'] + active: false + PreferToOverPairSyntax: + excludes: ['**/resources/**'] + active: false + ProtectedMemberInFinalClass: + excludes: ['**/resources/**'] + active: true + RedundantExplicitType: + excludes: ['**/resources/**'] + active: false + RedundantHigherOrderMapUsage: + active: true + RedundantVisibilityModifierRule: + excludes: ['**/resources/**'] + active: false + ReturnCount: + excludes: ['**/resources/**'] + active: false + max: 4 + excludedFunctions: 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + excludes: ['**/resources/**'] + active: true + SerialVersionUIDInSerializableClass: + excludes: ['**/resources/**'] + active: false + SpacingBetweenPackageAndImports: + excludes: ['**/resources/**'] + active: false + ThrowsCount: + excludes: ['**/resources/**'] + active: true + max: 2 + TrailingWhitespace: + excludes: ['**/resources/**'] + active: false + UnderscoresInNumericLiterals: + excludes: ['**/resources/**'] + active: false + acceptableLength: 5 + UnnecessaryAbstractClass: + excludes: ['**/resources/**'] + active: true + ignoreAnnotated: ['dagger.Module'] + UnnecessaryAnnotationUseSiteTarget: + excludes: ['**/resources/**'] + active: false + UnnecessaryApply: + excludes: ['**/resources/**'] + active: false + UnnecessaryInheritance: + excludes: ['**/resources/**'] + active: true + UnnecessaryLet: + excludes: ['**/resources/**'] + active: false + UnnecessaryParentheses: + excludes: ['**/resources/**'] + active: false + UntilInsteadOfRangeTo: + excludes: ['**/resources/**'] + active: false + UnusedImports: + excludes: ['**/resources/**'] + active: false + UnusedPrivateClass: + excludes: ['**/resources/**'] + active: true + UnusedPrivateMember: + excludes: ['**/resources/**'] + active: false + allowedNames: '(_|ignored|expected|serialVersionUID)' + UseArrayLiteralsInAnnotations: + excludes: ['**/resources/**'] + active: false + UseCheckNotNull: + active: true + UseCheckOrError: + excludes: ['**/resources/**'] + active: false + UseDataClass: + excludes: ['**/resources/**'] + active: false + ignoreAnnotated: [] + allowVars: false + UseEmptyCounterpart: + active: true + UseIfEmptyOrIfBlank: + active: true + UseIfInsteadOfWhen: + excludes: ['**/resources/**'] + active: false + UseRequire: + excludes: ['**/resources/**'] + active: false + UseRequireNotNull: + active: true + UselessCallOnNotNull: + excludes: ['**/resources/**'] + active: true + UtilityClassWithPublicConstructor: + excludes: ['**/resources/**'] + active: true + VarCouldBeVal: + excludes: ['**/resources/**'] + active: false + WildcardImport: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludeImports: ['java.util.*', 'kotlinx.android.synthetic.*', 'kotlinx.serialization'] \ No newline at end of file diff --git a/diktat-analysis.yml b/diktat-analysis.yml new file mode 100644 index 0000000..5cfd180 --- /dev/null +++ b/diktat-analysis.yml @@ -0,0 +1,111 @@ +- name: DIKTAT_COMMON + enabled: true + configuration: + domainName: com.saveourtool.save + kotlinVersion: 1.6 + srcDirectories: "commonMain,commonNonJvmMain,jvmMain" + testDirs: "commonTest,jvmTest" +- name: AVOID_NULL_CHECKS + enabled: false +- name: ENUM_VALUE + enabled: true + configuration: + enumStyle: snakeCase +- name: KDOC_CONTAINS_DATE_OR_AUTHOR + enabled: true + configuration: + versionRegex: \d+\.\d+\.\d+[-.\w\d]* +- name: HEADER_MISSING_OR_WRONG_COPYRIGHT + enabled: true + configuration: + isCopyrightMandatory: false + copyrightText: '' +- name: FILE_IS_TOO_LONG + enabled: true + configuration: + maxSize: 450 + ignoreFolders: '' +- name: FILE_UNORDERED_IMPORTS + enabled: true + configuration: + useRecommendedImportsOrder: true +- name: FILE_WILDCARD_IMPORTS + enabled: true + configuration: + allowedWildcards: "kotlinx.serialization.*" +- name: BRACES_BLOCK_STRUCTURE_ERROR + enabled: true + configuration: + openBraceNewline: true + closeBraceNewline: true +- name: WRONG_INDENTATION + enabled: true + configuration: + # Is newline at the end of a file needed + newlineAtEnd: true + # If true: in parameter list when parameters are split by newline they are indented with two indentations instead of one + extendedIndentOfParameters: false + # If true: if first parameter in parameter list is on the same line as opening parenthesis, then other parameters can be aligned with it + alignedParameters: true + # If true: if expression is split by newline after operator like +/-/`*`, then the next line is indented with two indentations instead of one + extendedIndentAfterOperators: true + # If true: when dot qualified expression starts on a new line, this line will be indented with two indentations instead of one + extendedIndentBeforeDot: false + # The indentation size for each file + indentationSize: 4 + extendedIndentForExpressionBodies: true +- name: EMPTY_BLOCK_STRUCTURE_ERROR + enabled: true + configuration: + styleEmptyBlockWithNewline: true + allowEmptyBlocks: false +- name: LONG_LINE + enabled: true + configuration: + lineLength: 180 +- name: WRONG_NEWLINES + enabled: true + configuration: + maxParametersInOneLine: 2 +- name: TOO_MANY_CONSECUTIVE_SPACES + enabled: true + configuration: + maxSpaces: 1 + saveInitialFormattingForEnums: false +- name: LONG_NUMERICAL_VALUES_SEPARATED + enabled: true + configuration: + maxNumberLength: 5 + maxBlockLength: 3 +- name: WRONG_DECLARATIONS_ORDER + enabled: true + configuration: + sortEnum: true + sortProperty: true +- name: COMMENT_WHITE_SPACE + enabled: true + configuration: + maxSpacesBeforeComment: 2 + maxSpacesInComment: 1 +- name: TYPE_ALIAS + enabled: true + configuration: + typeReferenceLength: 25 +- name: TOO_LONG_FUNCTION + enabled: true + configuration: + maxFunctionLength: 35 # max length of function + isIncludeHeader: false # count function's header +- name: TOO_MANY_PARAMETERS + enabled: true + configuration: + maxParameterListSize: 5 +- name: NESTED_BLOCK + enabled: true + configuration: + maxNestedBlockQuantity: 4 +- name: TRAILING_COMMA + enabled: false + configuration: + valueArgument: true + valueParameter: true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..a4664f4 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,27 @@ +[versions] +kotlin = "1.9.0" +kotlinx-serialization = "1.5.1" +kotlinx-datetime = "0.4.0" +jackson = "2.15.2" +diktat = "1.2.5" +detekt = "1.23.0" + +[plugins] +kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } + +[libraries] +# plugins as dependency +kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-plugin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } +diktat-gradle-plugin = { module = "org.cqfn.diktat:diktat-gradle-plugin", version.ref = "diktat" } +detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } + +jetbrains-annotations = { module = "org.jetbrains:annotations", version = "24.0.1" } +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } +jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } +jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" } +jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } +jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } + diff --git a/settings.gradle.kts b/settings.gradle.kts index 82c7caa..392c808 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,34 +4,8 @@ dependencyResolutionManagement { repositories { mavenCentral() } - versionCatalogs { - create("libs") { - version("kotlin", "1.9.0") - version("kotlinx-serialization", "1.5.1") - version("kotlinx-datetime", "0.4.0") - version("jackson", "2.15.2") - - plugin("kotlin-multiplatform", "org.jetbrains.kotlin.multiplatform") - .versionRef("kotlin") - plugin("kotlin-plugin-serialization", "org.jetbrains.kotlin.plugin.serialization") - .versionRef("kotlin") - - library("jetbrains-annotations", "org.jetbrains:annotations:24.0.1") - library("kotlinx-serialization-json", "org.jetbrains.kotlinx", "kotlinx-serialization-json") - .versionRef("kotlinx-serialization") - library("kotlinx-datetime", "org.jetbrains.kotlinx", "kotlinx-datetime") - .versionRef("kotlinx-datetime") - library("jackson-annotations", "com.fasterxml.jackson.core", "jackson-annotations") - .versionRef("jackson") - library("jackson-module-kotlin", "com.fasterxml.jackson.module", "jackson-module-kotlin") - .versionRef("jackson") - library("jackson-databind", "com.fasterxml.jackson.core", "jackson-databind") - .versionRef("jackson") - library("jackson-datatype-jsr310", "com.fasterxml.jackson.datatype", "jackson-datatype-jsr310") - .versionRef("jackson") - } - } } +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { repositories { @@ -41,7 +15,7 @@ pluginManagement { } plugins { - id("com.gradle.enterprise") version "3.13.3" + id("com.gradle.enterprise") version "3.14" } gradleEnterprise { From 1c64574edd1fae5fe12fba3c9bb8d508d17098d4 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 12:36:37 +0300 Subject: [PATCH 02/18] does compile --- build.gradle.kts | 10 ++-- buildSrc/build.gradle.kts | 9 ++-- .../osv4k/buildutils/DiktatConfiguration.kt | 2 +- .../buildutils/VersioningConfiguration.kt | 52 +++++++++---------- .../buildutils/kotlin-library.gradle.kts | 9 ++-- settings.gradle.kts | 1 + 6 files changed, 44 insertions(+), 39 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 584bafa..b5a3399 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,10 @@ import com.saveourtool.osv4k.buildutils.configureDiktat -import com.saveourtool.osv4k.buildutils.configurePublishing import com.saveourtool.osv4k.buildutils.configureVersioning import com.saveourtool.osv4k.buildutils.createDetektTask -import com.saveourtool.osv4k.buildutils.installGitHooks plugins { - alias(libs.plugins.kotlin.multiplatform) - alias(libs.plugins.kotlin.plugin.serialization) +// alias(libs.plugins.kotlin.multiplatform) +// alias(libs.plugins.kotlin.plugin.serialization) id("com.saveourtool.osv4k.buildutils.kotlin-library") } @@ -17,14 +15,14 @@ repositories { } // version generation -configureVersioning() +//configureVersioning() // checks and validations configureDiktat() createDetektTask() kotlin { jvm { - withJava() +// withJava() compilations.all { kotlinOptions.run { jvmTarget = "1.8" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 9eea781..cded02f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,10 +10,13 @@ repositories { dependencies { // workaround https://github.com/gradle/gradle/issues/15383 implementation(files(project.libs.javaClass.superclass.protectionDomain.codeSource.location)) + implementation(libs.kotlin.gradle.plugin) { + because("Add plugin on plugin classpath here to automatically set its version for the whole build") + } implementation(libs.diktat.gradle.plugin) implementation(libs.detekt.gradle.plugin) - implementation(libs.kotlin.gradle.plugin) implementation(libs.kotlin.plugin.serialization) - implementation("io.github.gradle-nexus:publish-plugin:1.3.0") - implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") +// implementation("io.github.gradle-nexus:publish-plugin:1.3.0") + implementation("org.ajoberstar.reckon:reckon-gradle:0.13.2") +// implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt index 82dfff0..21a47ed 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt @@ -2,7 +2,7 @@ * Configuration for diktat static analysis */ -package com.saveourtool.save.buildutils +package com.saveourtool.osv4k.buildutils import org.cqfn.diktat.plugin.gradle.DiktatExtension import org.cqfn.diktat.plugin.gradle.DiktatGradlePlugin diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt index 80c63c8..2d0ad14 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt @@ -5,7 +5,7 @@ package com.saveourtool.osv4k.buildutils import org.ajoberstar.reckon.core.Scope -import org.ajoberstar.reckon.core.VersionTagParser +//import org.ajoberstar.reckon.core.VersionTagParser import org.ajoberstar.reckon.gradle.ReckonExtension import org.ajoberstar.reckon.gradle.ReckonPlugin import org.eclipse.jgit.api.Git @@ -25,26 +25,26 @@ import java.util.Optional fun Project.configureVersioning() { apply() - val isSnapshot = hasProperty("reckon.stage") && property("reckon.stage") == "snapshot" - configure { - setDefaultInferredScope(Scope.MINOR.name) - setScopeCalc(calcScopeFromProp()) - if (isSnapshot) { - // we should build snapshots only for snapshot publishing, so it requires explicit parameter - snapshots() - setStageCalc(calcStageFromProp()) - fixForSnapshot() - } else { - stages("alpha", "rc", "final") - setStageCalc(calcStageFromProp()) - } - } - - // to activate release, provide `-Prelease` or `-Prelease=true`. To deactivate, either omit the property, or set `-Prelease=false`. - val isRelease = hasProperty("release") && (property("release") as String != "false") - if (isRelease) { - failOnUncleanTree() - } +// val isSnapshot = hasProperty("reckon.stage") && property("reckon.stage") == "snapshot" +// configure { +// setDefaultInferredScope(Scope.MINOR.name) +// setScopeCalc(calcScopeFromProp()) +// if (isSnapshot) { +// // we should build snapshots only for snapshot publishing, so it requires explicit parameter +// snapshots() +// setStageCalc(calcStageFromProp()) +// fixForSnapshot() +// } else { +// stages("alpha", "rc", "final") +// setStageCalc(calcStageFromProp()) +// } +// } +// +// // to activate release, provide `-Prelease` or `-Prelease=true`. To deactivate, either omit the property, or set `-Prelease=false`. +// val isRelease = hasProperty("release") && (property("release") as String != "false") +// if (isRelease) { +// failOnUncleanTree() +// } } private fun Project.failOnUncleanTree() { @@ -66,9 +66,9 @@ private fun Project.failOnUncleanTree() { * we remove tags like `0.1.0-alpha`, and then reckoned version will still be `0.1.0-SNAPSHOT` and it will be compliant. */ private fun ReckonExtension.fixForSnapshot() { - setTagParser { tagName -> - Optional.of(tagName) - .filter { it.matches(Regex("""^v\d+\.\d+\.\d+$""")) } - .flatMap { VersionTagParser.getDefault().parse(it) } - } +// setTagParser { tagName -> +// Optional.of(tagName) +// .filter { it.matches(Regex("""^v\d+\.\d+\.\d+$""")) } +// .flatMap { VersionTagParser.getDefault().parse(it) } +// } } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts index 706e92e..423ad98 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -5,7 +5,7 @@ * These source sets can be retrieved in a particular build script and configured further as needed. */ -package com.saveourtool.save.buildutils +package com.saveourtool.osv4k.buildutils import org.gradle.kotlin.dsl.kotlin import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform @@ -17,6 +17,9 @@ plugins { } kotlin { + jvmToolchain { + this.languageVersion.set(JavaLanguageVersion.of("11")) + } jvm { compilations.all { kotlinOptions { @@ -108,8 +111,8 @@ kotlin { } } -configureJacoco() -configurePublishing() +//configureJacoco() +//configurePublishing() configureDiktat() configureDetekt() diff --git a/settings.gradle.kts b/settings.gradle.kts index 392c808..3b323b1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,7 @@ dependencyResolutionManagement { mavenCentral() } } + enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { From 43e718c5e7ef6abf1ff75df701e545c9a1b3f1f5 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 13:15:08 +0300 Subject: [PATCH 03/18] make gradlew executable --- gradlew | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 0e3043acd9be81412e83f227a668c3e893c2f9c9 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 13:17:29 +0300 Subject: [PATCH 04/18] enable dashboard for renovate --- renovate.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/renovate.json b/renovate.json index cebf5fd..7513327 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,7 @@ { + "$schema": "https://docs.renovatebot.com/renovate-schema.json", "enabled": true, + "dependencyDashboard": true, "schedule": [ "before 4am on Monday" ], From 12099e84da3cfcb57eb25b9fffdb4ac6c84ebdce Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 13:25:53 +0300 Subject: [PATCH 05/18] diktatFix --- build.gradle.kts | 9 ++--- buildSrc/build.gradle.kts | 6 +-- .../osv4k/buildutils/DiktatConfiguration.kt | 2 +- .../buildutils/VersioningConfiguration.kt | 38 ------------------- .../buildutils/kotlin-library.gradle.kts | 6 +-- diktat-analysis.yml | 6 +-- 6 files changed, 14 insertions(+), 53 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b5a3399..038b9aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,9 @@ import com.saveourtool.osv4k.buildutils.configureDiktat -import com.saveourtool.osv4k.buildutils.configureVersioning import com.saveourtool.osv4k.buildutils.createDetektTask plugins { -// alias(libs.plugins.kotlin.multiplatform) -// alias(libs.plugins.kotlin.plugin.serialization) + // alias(libs.plugins.kotlin.multiplatform) + // alias(libs.plugins.kotlin.plugin.serialization) id("com.saveourtool.osv4k.buildutils.kotlin-library") } @@ -15,14 +14,14 @@ repositories { } // version generation -//configureVersioning() +// configureVersioning() // checks and validations configureDiktat() createDetektTask() kotlin { jvm { -// withJava() + // withJava() compilations.all { kotlinOptions.run { jvmTarget = "1.8" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index cded02f..1076f69 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -16,7 +16,7 @@ dependencies { implementation(libs.diktat.gradle.plugin) implementation(libs.detekt.gradle.plugin) implementation(libs.kotlin.plugin.serialization) -// implementation("io.github.gradle-nexus:publish-plugin:1.3.0") + // implementation("io.github.gradle-nexus:publish-plugin:1.3.0") implementation("org.ajoberstar.reckon:reckon-gradle:0.13.2") -// implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") -} \ No newline at end of file + // implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt index 21a47ed..794c61d 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt @@ -42,4 +42,4 @@ private fun Project.fixDiktatTask() { // https://github.com/saveourtool/diktat/issues/1269 systemProperty("user.home", rootDir.toString()) } -} \ No newline at end of file +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt index 2d0ad14..0c3e90e 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt @@ -4,9 +4,6 @@ package com.saveourtool.osv4k.buildutils -import org.ajoberstar.reckon.core.Scope -//import org.ajoberstar.reckon.core.VersionTagParser -import org.ajoberstar.reckon.gradle.ReckonExtension import org.ajoberstar.reckon.gradle.ReckonPlugin import org.eclipse.jgit.api.Git import org.eclipse.jgit.internal.storage.file.FileRepository @@ -14,8 +11,6 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.configure -import java.util.Optional /** * Configures how project version is determined. @@ -24,27 +19,6 @@ import java.util.Optional */ fun Project.configureVersioning() { apply() - -// val isSnapshot = hasProperty("reckon.stage") && property("reckon.stage") == "snapshot" -// configure { -// setDefaultInferredScope(Scope.MINOR.name) -// setScopeCalc(calcScopeFromProp()) -// if (isSnapshot) { -// // we should build snapshots only for snapshot publishing, so it requires explicit parameter -// snapshots() -// setStageCalc(calcStageFromProp()) -// fixForSnapshot() -// } else { -// stages("alpha", "rc", "final") -// setStageCalc(calcStageFromProp()) -// } -// } -// -// // to activate release, provide `-Prelease` or `-Prelease=true`. To deactivate, either omit the property, or set `-Prelease=false`. -// val isRelease = hasProperty("release") && (property("release") as String != "false") -// if (isRelease) { -// failOnUncleanTree() -// } } private fun Project.failOnUncleanTree() { @@ -60,15 +34,3 @@ private fun Project.failOnUncleanTree() { "Untracked files: ${status.untracked}, uncommitted changes: ${status.uncommittedChanges}") } } - -/** - * A terrible hack to remove all pre-release tags. Because in semver `0.1.0-SNAPSHOT` < `0.1.0-alpha`, in snapshot mode - * we remove tags like `0.1.0-alpha`, and then reckoned version will still be `0.1.0-SNAPSHOT` and it will be compliant. - */ -private fun ReckonExtension.fixForSnapshot() { -// setTagParser { tagName -> -// Optional.of(tagName) -// .filter { it.matches(Regex("""^v\d+\.\d+\.\d+$""")) } -// .flatMap { VersionTagParser.getDefault().parse(it) } -// } -} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts index 423ad98..e118244 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -111,11 +111,11 @@ kotlin { } } -//configureJacoco() -//configurePublishing() +// configureJacoco() +// configurePublishing() configureDiktat() configureDetekt() tasks.withType { useJUnitPlatform() -} \ No newline at end of file +} diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 5cfd180..19177c6 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -1,10 +1,10 @@ - name: DIKTAT_COMMON enabled: true configuration: - domainName: com.saveourtool.save + domainName: com.saveourtool.osv4k kotlinVersion: 1.6 - srcDirectories: "commonMain,commonNonJvmMain,jvmMain" - testDirs: "commonTest,jvmTest" + srcDirectories: "main,commonMain,commonNonJvmMain,jvmMain" + testDirs: "test,commonTest,jvmTest" - name: AVOID_NULL_CHECKS enabled: false - name: ENUM_VALUE From 9134cb8aceffa3583d8ad8348b8cbf0aed22a446 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 13:28:43 +0300 Subject: [PATCH 06/18] diktatFix --- src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt | 1 + .../kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt | 2 ++ .../kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt | 2 +- .../saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt | 2 +- .../com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/Converter.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt | 2 +- .../kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt | 1 + .../kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt | 1 + 13 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt index e8dd326..1a09d72 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt @@ -1,3 +1,3 @@ package com.saveourtool.osv4k.jackson -expect class JavaVoid \ No newline at end of file +expect class JavaVoid diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt index c072e75..12daeba 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt @@ -7,4 +7,4 @@ expect enum class JsonCreatorMode { DEFAULT, PROPERTIES, ; -} \ No newline at end of file +} diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt index 073f840..fa74928 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt @@ -2,6 +2,7 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +@Suppress("LongParameterList") expect annotation class JsonDeserialize( val using: KClass>, val contentUsing: KClass>, diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt index d7c830d..d69dc64 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt @@ -2,4 +2,4 @@ package com.saveourtool.osv4k.jackson expect abstract class JsonDeserializer -expect abstract class JsonDeserializerNone: JsonDeserializer \ No newline at end of file +expect abstract class JsonDeserializerNone: JsonDeserializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt index f9cb58b..08a8a99 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt @@ -2,6 +2,7 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +@Suppress("LongParameterList") expect annotation class JsonSerialize( val using: KClass>, val contentUsing: KClass>, @@ -15,6 +16,7 @@ expect annotation class JsonSerialize( val contentConverter: KClass>, val include: JsonSerializeInclusion, ) + expect enum class JsonSerializeTyping { DEFAULT_TYPING, ; diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt index 661cf14..70a7f79 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt @@ -2,4 +2,4 @@ package com.saveourtool.osv4k.jackson expect abstract class JsonSerializer -expect abstract class JsonSerializerNone : JsonSerializer \ No newline at end of file +expect abstract class JsonSerializerNone : JsonSerializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt index 87b4d3d..42175ec 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt @@ -20,4 +20,4 @@ object LocalDateTimeRfc3339Serializer: KSerializer { override fun serialize(encoder: Encoder, value: LocalDateTime) { encoder.encodeString(LocalDateTimeRfc3339Util.toString(value)) } -} \ No newline at end of file +} diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt index e305de6..cd74b56 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt @@ -10,4 +10,4 @@ object LocalDateTimeRfc3339Util { } return LocalDateTime.parse(value.replace("[t_ ]".toRegex(), "T").replace("[zZ]".toRegex(), "")) } -} \ No newline at end of file +} diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt index de82a9e..e461de7 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt @@ -1,4 +1,4 @@ package com.saveourtool.osv4k.jackson actual interface Converter -actual abstract class ConverterNone : Converter \ No newline at end of file +actual abstract class ConverterNone : Converter diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt index 93bb12f..3da88bb 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt @@ -1,3 +1,3 @@ package com.saveourtool.osv4k.jackson -actual class JavaVoid \ No newline at end of file +actual class JavaVoid diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt index c501e39..83c0fa2 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt @@ -8,4 +8,4 @@ actual enum class JsonCreatorMode { DEFAULT, PROPERTIES, ; -} \ No newline at end of file +} diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt index e91efb8..847b275 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt @@ -2,6 +2,7 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +@Suppress("LongParameterList") actual annotation class JsonDeserialize( actual val using: KClass>, actual val contentUsing: KClass>, diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt index 9ca980c..0631506 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt @@ -2,6 +2,7 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +@Suppress("LongParameterList") actual annotation class JsonSerialize( actual val using: KClass>, actual val contentUsing: KClass>, From c95dffa901542e59876678017fcbdf5eef1c5db6 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 14:41:56 +0300 Subject: [PATCH 07/18] diktatFix --- build.gradle.kts | 1 + .../osv4k/buildutils/DiktatConfiguration.kt | 19 +- diktat-analysis.yml | 2 +- .../kotlin/com/saveourtool/osv4k/OsvSchema.kt | 564 ++++++++++++++++-- .../saveourtool/osv4k/jackson/Converter.kt | 11 + .../com/saveourtool/osv4k/jackson/JavaVoid.kt | 3 + .../saveourtool/osv4k/jackson/JsonCreator.kt | 5 + .../osv4k/jackson/JsonDeserialize.kt | 18 +- .../osv4k/jackson/JsonDeserializer.kt | 4 +- .../saveourtool/osv4k/jackson/JsonInclude.kt | 8 + .../saveourtool/osv4k/jackson/JsonProperty.kt | 10 + .../osv4k/jackson/JsonSerialize.kt | 22 +- .../osv4k/jackson/JsonSerializer.kt | 2 + .../osv4k/jackson/KeyDeserializer.kt | 2 + .../jackson/LocalDateTimeRfc3339Jackson.kt | 4 +- .../utils/LocalDateTimeRfc3339Serializer.kt | 9 +- .../osv4k/utils/LocalDateTimeRfc3339Util.kt | 24 +- .../saveourtool/osv4k/jackson/Converter.kt | 2 + .../saveourtool/osv4k/jackson/JsonCreator.kt | 5 + .../osv4k/jackson/JsonDeserialize.kt | 20 +- .../osv4k/jackson/JsonDeserializer.kt | 4 +- .../saveourtool/osv4k/jackson/JsonInclude.kt | 10 +- .../saveourtool/osv4k/jackson/JsonProperty.kt | 10 + .../osv4k/jackson/JsonSerialize.kt | 22 +- .../osv4k/jackson/JsonSerializer.kt | 4 +- .../osv4k/jackson/KeyDeserializer.kt | 4 +- .../jackson/LocalDateTimeRfc3339Jackson.kt | 4 +- .../com/saveourtool/osv4k/DebianTest.kt | 80 +-- .../kotlin/com/saveourtool/osv4k/GoTest.kt | 466 ++++++++------- .../saveourtool/osv4k/OsvSchemaTestUtil.kt | 19 +- .../saveourtool/osv4k/jackson/JacksonAlias.kt | 5 +- ...LocalDateTimeRfc3339JacksonDeserializer.kt | 86 +++ .../LocalDateTimeRfc3339JacksonSerializer.kt | 104 +--- .../com/saveourtool/osv4k/GoJacksonTest.kt | 466 ++++++++------- .../osv4k/OsvSchemaJacksonTestUtil.kt | 6 +- 35 files changed, 1346 insertions(+), 679 deletions(-) create mode 100644 src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonDeserializer.kt diff --git a/build.gradle.kts b/build.gradle.kts index 038b9aa..6c7dad3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,7 @@ repositories { // version generation // configureVersioning() // checks and validations + configureDiktat() createDetektTask() diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt index 794c61d..c63f49e 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DiktatConfiguration.kt @@ -21,17 +21,14 @@ fun Project.configureDiktat() { diktatConfigFile = rootProject.file("diktat-analysis.yml") githubActions = findProperty("diktat.githubActions")?.toString()?.toBoolean() ?: false inputs { - if (path == rootProject.path) { - include( - "buildSrc/src/**/*.kt", - "buildSrc/**/*.kts", - "*.kts" - ) - exclude("build", "buildSrc/build") - } else { - include("src/**/*.kt", "*.kts", "src/**/*.kts") - exclude("build/**") - } + include( + "buildSrc/src/**/*.kt", + "buildSrc/**/*.kts", + "*.kts", + "src/**/*.kt", + "src/**/*.kts", + ) + exclude("build", "buildSrc/build") } } fixDiktatTask() diff --git a/diktat-analysis.yml b/diktat-analysis.yml index 19177c6..bd999b5 100644 --- a/diktat-analysis.yml +++ b/diktat-analysis.yml @@ -32,7 +32,7 @@ - name: FILE_WILDCARD_IMPORTS enabled: true configuration: - allowedWildcards: "kotlinx.serialization.*" + allowedWildcards: "kotlinx.serialization.*,com.saveourtool.osv4k.jackson.*" - name: BRACES_BLOCK_STRUCTURE_ERROR enabled: true configuration: diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/OsvSchema.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/OsvSchema.kt index a031272..691dd6e 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/OsvSchema.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/OsvSchema.kt @@ -1,3 +1,5 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "FILE_IS_TOO_LONG") + package com.saveourtool.osv4k import com.saveourtool.osv4k.jackson.* @@ -11,6 +13,20 @@ typealias RawOsvSchema = OsvSchema( @SerialName("schema_version") - @get:JsonProperty(value = "schema_version", namespace = "", required = false, index = -1, defaultValue = "1.0.0", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "schema_version", namespace = "", required = false, index = -1, defaultValue = "1.0.0", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "schema_version", + namespace = "", + required = false, + index = -1, + defaultValue = "1.0.0", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "schema_version", + namespace = "", + required = false, + index = -1, + defaultValue = "1.0.0", + access = JsonPropertyAccess.AUTO + ) // TODO: add validation to SemVer or re-use library for it val schemaVersion: String = "1.0.0", - @JsonProperty(value = "id", namespace = "", required = true, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "id", + namespace = "", + required = true, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val id: String, @Serializable(with = LocalDateTimeRfc3339Serializer::class) @JsonSerialize( @@ -53,7 +91,14 @@ data class OsvSchema( keyAs = JavaVoid::class, contentAs = JavaVoid::class, ) - @JsonProperty(value = "modified", namespace = "", required = true, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "modified", + namespace = "", + required = true, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val modified: LocalDateTime, @Serializable(with = LocalDateTimeRfc3339Serializer::class) @@ -81,7 +126,14 @@ data class OsvSchema( keyAs = JavaVoid::class, contentAs = JavaVoid::class, ) - @JsonProperty(value = "published", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "published", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val published: LocalDateTime? = null, @Serializable(with = LocalDateTimeRfc3339Serializer::class) @JsonSerialize( @@ -108,31 +160,116 @@ data class OsvSchema( keyAs = JavaVoid::class, contentAs = JavaVoid::class, ) - @JsonProperty(value = "withdrawn", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "withdrawn", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val withdrawn: LocalDateTime? = null, - @JsonProperty(value = "aliases", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "aliases", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val aliases: List? = null, - @JsonProperty(value = "related", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "related", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val related: List? = null, - @JsonProperty(value = "summary", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "summary", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val summary: String? = null, - @JsonProperty(value = "details", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "details", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val details: String? = null, - @JsonProperty(value = "severity", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "severity", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val severity: List? = null, - @JsonProperty(value = "affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "affected", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val affected: List>? = null, - @JsonProperty(value = "references", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "references", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val references: List? = null, - @JsonProperty(value = "credits", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "credits", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val credits: List? = null, @SerialName("database_specific") - @get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val databaseSpecific: D? = null, ) +/** + * @property `package` + * @property severity + * @property ranges + * @property versions + * @property ecosystemSpecific + * @property databaseSpecific + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -140,27 +277,93 @@ data class OsvSchema( valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Affected ( - @JsonProperty(value = "package", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +@Suppress( + "KDOC_NO_CONSTRUCTOR_PROPERTY", + "BACKTICKS_PROHIBITED", + "GENERIC_NAME" +) +data class Affected( + @JsonProperty( + value = "package", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val `package`: Package? = null, - @JsonProperty(value = "severity", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "severity", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val severity: List? = null, - @JsonProperty(value = "ranges", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "ranges", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val ranges: List>? = null, - @JsonProperty(value = "versions", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "versions", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val versions: List? = null, @SerialName("ecosystem_specific") - @get:JsonProperty(value = "ecosystem_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "ecosystem_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "ecosystem_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "ecosystem_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val ecosystemSpecific: E? = null, @SerialName("database_specific") - @get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val databaseSpecific: D? = null, ) +/** + * @property ecosystem + * @property name + * @property purl + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -168,15 +371,42 @@ data class Affected ( valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Package ( - @JsonProperty(value = "ecosystem", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Package( + @JsonProperty( + value = "ecosystem", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val ecosystem: String, - @JsonProperty(value = "name", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "name", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val name: String, - @JsonProperty(value = "purl", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "purl", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val purl: String? = null ) +/** + * @property type + * @property repo + * @property events + * @property databaseSpecific + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -184,19 +414,60 @@ data class Package ( valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Range ( - @JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Range( + @JsonProperty( + value = "type", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val type: RangeType, - @JsonProperty(value = "repo", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "repo", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val repo: String? = null, - @JsonProperty(value = "events", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "events", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val events: List, @SerialName("database_specific") - @get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "database_specific", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val databaseSpecific: D? = null, ) +/** + * @property introduced + * @property fixed + * @property lastAffected + * @property limit + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -204,28 +475,101 @@ data class Range ( valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Event ( - @JsonProperty(value = "introduced", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Event( + @JsonProperty( + value = "introduced", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val introduced: String? = null, - @JsonProperty(value = "fixed", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "fixed", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val fixed: String? = null, @SerialName("last_affected") - @get:JsonProperty(value = "last_affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) - @JsonProperty(value = "last_affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @get:JsonProperty( + value = "last_affected", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) + @JsonProperty( + value = "last_affected", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val lastAffected: String? = null, - @JsonProperty(value = "limit", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "limit", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val limit: String? = null ) +/** + * In the `ranges` field, the `type` field is required. + * It specifies the type of version range being recorded and defines the interpretation of the `events` object’s `introduced`, `fixed`, and any type-specific fields. + * + * The defined types and their additional fields are: + */ enum class RangeType { + /** + * The versions introduced and fixed are arbitrary, uninterpreted strings specific to the package ecosystem, which does not conform to SemVer 2.0’s version ordering. + * + * It is recommended that you provide an explicitly enumerated versions list when specifying one or more ECOSYSTEM ranges, + * because ECOSYSTEM range inclusion queries may not be able to be answered without reference + * to the package ecosystem’s own logic and therefore may not be able to be used by ecosystem-independent processors. + * The infrastructure and tooling provided by https://osv.dev also provides automation + * for auto-populating the versions list based on supported ECOSYSTEM ranges as part of the ingestion process. + */ ECOSYSTEM, + + /** + * The versions introduced and fixed are full-length Git commit hashes. + * The repository’s commit graph is needed to evaluate whether a given version is in the range. + * The relation u < v is true when commit u is a (perhaps distant) parent of commit v. + * + * Specifying one or more GIT ranges does NOT remove the requirement to specify an explicitly enumerated versions list, + * because GIT range inclusion queries cannot be answered without access to a copy of the underlying Git repository. + */ GIT, + + /** + * The versions introduced and fixed are semantic versions as defined by SemVer 2.0.0, with no leading “v” prefix. + * The relation u < v denotes the precedence order defined in section 11 of SemVer 2.0. + * Ranges listed with type SEMVER should not overlap: since SEMVER is a strict linear ordering, it is always possible to simplify to non-overlapping ranges. + * + * Specifying one or more SEMVER ranges removes the requirement to specify an explicit enumerated versions list (see the discussion above). + * + * Some ecosystems may recommend using SemVer 2.0 for versioning without explicitly enforcing it. In those cases you should use the ECOSYSTEM type instead. + */ SEMVER, ; } +/** + * @property type + * @property score + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -233,19 +577,41 @@ enum class RangeType { valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Severity ( - @JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Severity( + @JsonProperty( + value = "type", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val type: SeverityType, - @JsonProperty(value = "score", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "score", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val score: String ) +/** + * TODO + */ enum class SeverityType { CVSS_V2, CVSS_V3, ; } +/** + * @property name + * @property contact + * @property type + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -253,15 +619,39 @@ enum class SeverityType { valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Credit ( - @JsonProperty(value = "name", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Credit( + @JsonProperty( + value = "name", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val name: String, - @JsonProperty(value = "contact", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "contact", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val contact: List? = null, - @JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "type", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val type: CreditType? = null ) +/** + * TODO + */ enum class CreditType { ANALYST, COORDINATOR, @@ -276,6 +666,10 @@ enum class CreditType { ; } +/** + * @property type + * @property url + */ @Serializable @JsonInclude( value = JsonIncludeType.NON_NULL, @@ -283,25 +677,91 @@ enum class CreditType { valueFilter = JavaVoid::class, contentFilter = JavaVoid::class, ) -data class Reference ( - @JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) +data class Reference( + @JsonProperty( + value = "type", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val type: ReferenceType, - @JsonProperty(value = "url", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO) + @JsonProperty( + value = "url", + namespace = "", + required = false, + index = -1, + defaultValue = "", + access = JsonPropertyAccess.AUTO + ) val url: String ) +/** + * The type specifies what kind of reference the URL is. + * + * The known reference type values are: + */ enum class ReferenceType { + /** + * A published security advisory for the vulnerability. + */ ADVISORY, + + /** + * An article or blog post describing the vulnerability. + */ ARTICLE, + + /** + * A tool, script, scanner, or other mechanism that allows for detection of the vulnerability in production environments. + * e.g. YARA rules, hashes, virus signature, or other scanners. + */ DETECTION, + + /** + * A social media discussion regarding the vulnerability, e.g. a Twitter, Mastodon, Hacker News, or Reddit thread. + */ DISCUSSION, + + /** + * A demonstration of the validity of a vulnerability claim, e.g. app.any.run replaying the exploitation of the vulnerability. + */ EVIDENCE, + + /** + * A source code browser link to the fix (e.g., a GitHub commit) + * Note that the fix type is meant for viewing by people using web browsers. + * Programs interested in analyzing the exact commit range would do better to use the GIT-typed affected[].ranges entries (described above). + */ FIX, + + /** + * A source code browser link to the fix (e.g., a GitHub commit) + * Note that the fix type is meant for viewing by people using web browsers. + * Programs interested in analyzing the exact commit range would do better to use the GIT-typed affected[].ranges entries (described above). + */ GIT, + + /** + * A source code browser link to the introduction of the vulnerability (e.g., a GitHub commit) Note that the introduced type is meant for viewing by people using web browsers. + */ INTRODUCED, + + /** + * A home web page for the package. + */ PACKAGE, + + /** + * A report, typically on a bug or issue tracker, of the vulnerability. + */ REPORT, + + /** + * A web page of some unspecified kind. + */ WEB, ; } - diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt index 98c4394..92bf981 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt @@ -1,4 +1,15 @@ +/** + * Alias for `com.fasterxml.jackson.databind.util.Converter` and `com.fasterxml.jackson.databind.util.Converter.None` + */ + +@file:Suppress( + "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", + "MISSING_KDOC_TOP_LEVEL", + "GENERIC", +) + package com.saveourtool.osv4k.jackson +@Suppress("GENERIC_NAME") expect interface Converter expect abstract class ConverterNone : Converter diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt index 1a09d72..824971e 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JavaVoid.kt @@ -1,3 +1,6 @@ package com.saveourtool.osv4k.jackson +/** + * Alias to java.lang.Void + */ expect class JavaVoid diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt index 12daeba..6b0aeea 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt @@ -1,5 +1,10 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson +/** + * @property mode + */ expect annotation class JsonCreator( val mode: JsonCreatorMode, ) diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt index fa74928..c4197b9 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt @@ -2,7 +2,23 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass -@Suppress("LongParameterList") +/** + * @property using + * @property contentUsing + * @property keyUsing + * @property builder + * @property converter + * @property contentConverter + * @property `as` + * @property keyAs + * @property contentAs + */ +@Suppress( + "LongParameterList", + "KDOC_NO_CONSTRUCTOR_PROPERTY", + "BACKTICKS_PROHIBITED", + "TYPE_ALIAS", +) expect annotation class JsonDeserialize( val using: KClass>, val contentUsing: KClass>, diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt index d69dc64..a24f05b 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt @@ -1,5 +1,7 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson expect abstract class JsonDeserializer -expect abstract class JsonDeserializerNone: JsonDeserializer +expect abstract class JsonDeserializerNone : JsonDeserializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt index a9d8bfb..906ba06 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt @@ -1,7 +1,15 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +/** + * @property value + * @property content + * @property valueFilter + * @property contentFilter + */ expect annotation class JsonInclude( val value: JsonIncludeType, val content: JsonIncludeType, diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt index 4f0df18..9bb3f7e 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt @@ -1,5 +1,15 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson +/** + * @property value + * @property namespace + * @property required + * @property index + * @property defaultValue + * @property access + */ expect annotation class JsonProperty( val value: String, val namespace: String, diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt index 08a8a99..33d4d44 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt @@ -1,8 +1,28 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass -@Suppress("LongParameterList") +/** + * @property using + * @property contentUsing + * @property keyUsing + * @property nullsUsing + * @property `as` + * @property keyAs + * @property contentAs + * @property typing + * @property converter + * @property contentConverter + * @property include + */ +@Suppress( + "LongParameterList", + "KDOC_NO_CONSTRUCTOR_PROPERTY", + "BACKTICKS_PROHIBITED", + "TYPE_ALIAS", +) expect annotation class JsonSerialize( val using: KClass>, val contentUsing: KClass>, diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt index 70a7f79..6197cf0 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt @@ -1,3 +1,5 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson expect abstract class JsonSerializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt index 49c5b42..b585342 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt @@ -1,3 +1,5 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson expect abstract class KeyDeserializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt index 0fc1774..cd361a0 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt @@ -1,7 +1,7 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "MISSING_KDOC_TOP_LEVEL") + package com.saveourtool.osv4k.jackson -import com.saveourtool.osv4k.jackson.JsonDeserializer -import com.saveourtool.osv4k.jackson.JsonSerializer import kotlinx.datetime.LocalDateTime expect class LocalDateTimeRfc3339JacksonSerializer : JsonSerializer diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt index 42175ec..60457fe 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Serializer.kt @@ -8,16 +8,15 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -object LocalDateTimeRfc3339Serializer: KSerializer { +object LocalDateTimeRfc3339Serializer : KSerializer { override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) + PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): LocalDateTime = decoder.decodeString().let { value -> - LocalDateTimeRfc3339Util.fromString(value) + fromRfc339String(value) } - override fun serialize(encoder: Encoder, value: LocalDateTime) { - encoder.encodeString(LocalDateTimeRfc3339Util.toString(value)) + encoder.encodeString(value.toRfc339String()) } } diff --git a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt index cd74b56..983dc9e 100644 --- a/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt +++ b/src/commonMain/kotlin/com/saveourtool/osv4k/utils/LocalDateTimeRfc3339Util.kt @@ -1,13 +1,23 @@ +/** + * Utils method for [kotlinx.datetime.LocalDateTime] + */ + package com.saveourtool.osv4k.utils import kotlinx.datetime.LocalDateTime -object LocalDateTimeRfc3339Util { - internal fun toString(value: LocalDateTime): String = value.toString() + "Z" - internal fun fromString(value: String): LocalDateTime { - require(value.endsWith("z", ignoreCase = true)) { - "Support only RFC339 with 'Z' at the end" - } - return LocalDateTime.parse(value.replace("[t_ ]".toRegex(), "T").replace("[zZ]".toRegex(), "")) +/** + * @return [String] in RFC339 format + */ +internal fun LocalDateTime.toRfc339String(): String = "${this}Z" + +/** + * @param value + * @return [LocalDateTime] + */ +internal fun fromRfc339String(value: String): LocalDateTime { + require(value.endsWith("z", ignoreCase = true)) { + "Support only RFC339 with 'Z' at the end" } + return LocalDateTime.parse(value.replace("[t_ ]".toRegex(), "T").replace("[zZ]".toRegex(), "")) } diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt index e461de7..20cb904 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/Converter.kt @@ -1,3 +1,5 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE", "GENERIC_NAME") + package com.saveourtool.osv4k.jackson actual interface Converter diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt index 83c0fa2..8ea0f5e 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt @@ -1,5 +1,10 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson +/** + * @property mode + */ actual annotation class JsonCreator( actual val mode: JsonCreatorMode, ) diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt index 847b275..63f9390 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserialize.kt @@ -2,7 +2,23 @@ package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass -@Suppress("LongParameterList") +/** + * @property using + * @property contentUsing + * @property keyUsing + * @property builder + * @property converter + * @property contentConverter + * @property `as` + * @property keyAs + * @property contentAs + */ +@Suppress( + "LongParameterList", + "KDOC_NO_CONSTRUCTOR_PROPERTY", + "BACKTICKS_PROHIBITED", + "TYPE_ALIAS", +) actual annotation class JsonDeserialize( actual val using: KClass>, actual val contentUsing: KClass>, @@ -13,4 +29,4 @@ actual annotation class JsonDeserialize( actual val `as`: KClass<*>, actual val keyAs: KClass<*>, actual val contentAs: KClass<*>, -) \ No newline at end of file +) diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt index 798b09a..3c2c8d7 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonDeserializer.kt @@ -1,4 +1,6 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson actual abstract class JsonDeserializer -actual abstract class JsonDeserializerNone : JsonDeserializer() \ No newline at end of file +actual abstract class JsonDeserializerNone : JsonDeserializer() diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt index 77cd0fa..f7e02bd 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonInclude.kt @@ -1,7 +1,15 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass +/** + * @property value + * @property content + * @property valueFilter + * @property contentFilter + */ actual annotation class JsonInclude( actual val value: JsonIncludeType, actual val content: JsonIncludeType, @@ -13,4 +21,4 @@ actual enum class JsonIncludeType { ALWAYS, NON_NULL, ; -} \ No newline at end of file +} diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt index fa4b2d3..166cb98 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonProperty.kt @@ -1,5 +1,15 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson +/** + * @property value + * @property namespace + * @property required + * @property index + * @property defaultValue + * @property access + */ actual annotation class JsonProperty actual constructor( actual val value: String, actual val namespace: String, diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt index 0631506..63c83f5 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerialize.kt @@ -1,8 +1,28 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson import kotlin.reflect.KClass -@Suppress("LongParameterList") +/** + * @property using + * @property contentUsing + * @property keyUsing + * @property nullsUsing + * @property `as` + * @property keyAs + * @property contentAs + * @property typing + * @property converter + * @property contentConverter + * @property include + */ +@Suppress( + "LongParameterList", + "KDOC_NO_CONSTRUCTOR_PROPERTY", + "BACKTICKS_PROHIBITED", + "TYPE_ALIAS", +) actual annotation class JsonSerialize( actual val using: KClass>, actual val contentUsing: KClass>, diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt index 1a10dd3..e583470 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/JsonSerializer.kt @@ -1,4 +1,6 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson actual abstract class JsonSerializer -actual abstract class JsonSerializerNone : JsonSerializer() \ No newline at end of file +actual abstract class JsonSerializerNone : JsonSerializer() diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt index 982d4f4..6b68217 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/KeyDeserializer.kt @@ -1,4 +1,6 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson actual abstract class KeyDeserializer -actual abstract class KeyDeserializerNone : KeyDeserializer() \ No newline at end of file +actual abstract class KeyDeserializerNone : KeyDeserializer() diff --git a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt index 4e4bb80..7eb82ca 100644 --- a/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt +++ b/src/commonNonJvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339Jackson.kt @@ -1,6 +1,8 @@ +@file:Suppress("HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") + package com.saveourtool.osv4k.jackson import kotlinx.datetime.LocalDateTime actual class LocalDateTimeRfc3339JacksonSerializer : JsonSerializer() -actual class LocalDateTimeRfc3339JacksonDeserializer : JsonDeserializer() \ No newline at end of file +actual class LocalDateTimeRfc3339JacksonDeserializer : JsonDeserializer() diff --git a/src/commonTest/kotlin/com/saveourtool/osv4k/DebianTest.kt b/src/commonTest/kotlin/com/saveourtool/osv4k/DebianTest.kt index 41dead8..d079821 100644 --- a/src/commonTest/kotlin/com/saveourtool/osv4k/DebianTest.kt +++ b/src/commonTest/kotlin/com/saveourtool/osv4k/DebianTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION") + package com.saveourtool.osv4k import com.saveourtool.osv4k.OsvSchemaTestUtil.doEncodeDecodeAndCompare @@ -7,44 +9,46 @@ class DebianTest { @Test fun `DSA-3029-1`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "id": "DSA-3029-1", - "modified": "2014-09-20T08:18:07Z", - "published": "2014-09-20T00:00:01Z", - "aliases": [ - "CVE-2014-3616" - ], - "summary": "nginx - security update", - "details": "\nAntoine Delignat-Lavaud and Karthikeyan Bhargavan discovered that it was\npossible to reuse cached SSL sessions in unrelated contexts, allowing\nvirtual host confusion attacks in some configurations by an attacker in\na privileged network position.\n\n\nFor the stable distribution (wheezy), this problem has been fixed in\nversion 1.2.1-2.2+wheezy3.\n\n\nFor the testing distribution (jessie), this problem has been fixed in\nversion 1.6.2-1.\n\n\nFor the unstable distribution (sid), this problem has been fixed in\nversion 1.6.2-1.\n\n\nWe recommend that you upgrade your nginx packages.\n\n\n", - "affected": [ - { - "package": { - "ecosystem": "Debian:7", - "name": "nginx" - }, - "ranges": [ - { - "type": "ECOSYSTEM", - "events": [ - { - "introduced": "0" - }, + doEncodeDecodeAndCompare( + """ { - "fixed": "1.2.1-2.2+wheezy3" + "id": "DSA-3029-1", + "modified": "2014-09-20T08:18:07Z", + "published": "2014-09-20T00:00:01Z", + "aliases": [ + "CVE-2014-3616" + ], + "summary": "nginx - security update", + "details": "\nAntoine Delignat-Lavaud and Karthikeyan Bhargavan discovered that it was\npossible to reuse cached SSL sessions in unrelated contexts, allowing\nvirtual host confusion attacks in some configurations by an attacker in\na privileged network position.\n\n\nFor the stable distribution (wheezy), this problem has been fixed in\nversion 1.2.1-2.2+wheezy3.\n\n\nFor the testing distribution (jessie), this problem has been fixed in\nversion 1.6.2-1.\n\n\nFor the unstable distribution (sid), this problem has been fixed in\nversion 1.6.2-1.\n\n\nWe recommend that you upgrade your nginx packages.\n\n\n", + "affected": [ + { + "package": { + "ecosystem": "Debian:7", + "name": "nginx" + }, + "ranges": [ + { + "type": "ECOSYSTEM", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.2.1-2.2+wheezy3" + } + ] + } + ] + } + ], + "references": [ + { + "type": "ADVISORY", + "url": "https://www.debian.org/security/2014/dsa-3029" + } + ] } - ] - } - ] - } - ], - "references": [ - { - "type": "ADVISORY", - "url": "https://www.debian.org/security/2014/dsa-3029" - } - ] - } - """.trimIndent()) + """.trimIndent() + ) } -} \ No newline at end of file +} diff --git a/src/commonTest/kotlin/com/saveourtool/osv4k/GoTest.kt b/src/commonTest/kotlin/com/saveourtool/osv4k/GoTest.kt index 3c53fad..53e657a 100644 --- a/src/commonTest/kotlin/com/saveourtool/osv4k/GoTest.kt +++ b/src/commonTest/kotlin/com/saveourtool/osv4k/GoTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION") + package com.saveourtool.osv4k import com.saveourtool.osv4k.OsvSchemaTestUtil.doEncodeDecodeAndCompare @@ -7,249 +9,255 @@ class GoTest { @Test fun `GO-2020-0015`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2020-0015", - "modified": "2023-06-12T18:45:41Z", - "published": "2021-04-14T20:04:52Z", - "aliases": [ - "CVE-2020-14040", - "GHSA-5rcv-m4m3-hfh7" - ], - "summary": "Infinite loop when decoding some inputs in golang.org/x/text", - "details": "An attacker could provide a single byte to a UTF16 decoder instantiated with UseBOM or ExpectBOM to trigger an infinite loop if the String function on the Decoder is called, or the Decoder is passed to transform.String. If used to parse user supplied input, this may be used as a denial of service vector.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "golang.org/x/text" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, + doEncodeDecodeAndCompare( + """ { - "fixed": "0.3.3" + "schema_version": "1.3.1", + "id": "GO-2020-0015", + "modified": "2023-06-12T18:45:41Z", + "published": "2021-04-14T20:04:52Z", + "aliases": [ + "CVE-2020-14040", + "GHSA-5rcv-m4m3-hfh7" + ], + "summary": "Infinite loop when decoding some inputs in golang.org/x/text", + "details": "An attacker could provide a single byte to a UTF16 decoder instantiated with UseBOM or ExpectBOM to trigger an infinite loop if the String function on the Decoder is called, or the Decoder is passed to transform.String. If used to parse user supplied input, this may be used as a denial of service vector.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "golang.org/x/text" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "0.3.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "golang.org/x/text/encoding/unicode", + "symbols": [ + "bomOverride.Transform", + "utf16Decoder.Transform" + ] + }, + { + "path": "golang.org/x/text/transform", + "symbols": [ + "String" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/238238" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/39491" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0" + } + ], + "credits": [ + { + "name": "@abacabadabacaba" + }, + { + "name": "Anton Gyllenberg" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2020-0015" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "golang.org/x/text/encoding/unicode", - "symbols": [ - "bomOverride.Transform", - "utf16Decoder.Transform" - ] - }, - { - "path": "golang.org/x/text/transform", - "symbols": [ - "String" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/238238" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/39491" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0" - } - ], - "credits": [ - { - "name": "@abacabadabacaba" - }, - { - "name": "Anton Gyllenberg" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2020-0015" - } - } - """.trimIndent()) + """.trimIndent() + ) } @Test fun `GO-2022-0189`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2022-0189", - "modified": "2023-06-12T18:45:41Z", - "published": "2022-08-04T21:30:35Z", - "aliases": [ - "CVE-2018-16873" - ], - "summary": "Remote command execution via \"go get\" with \"-u\" flag in cmd/go", - "details": "The \"go get\" command is vulnerable to remote code execution when executed with the -u flag and the import path of a malicious Go package, or a package that imports it directly or indirectly.\n\nSpecifically, it is only vulnerable in GOPATH mode, but not in module mode (the distinction is documented at https://golang.org/cmd/go/#hdr-Module_aware_go_get).\n\nUsing custom domains, it's possible to arrange things so that a Git repository is cloned to a folder named \".git\" by using a vanity import path that ends with \"/.git\". If the Git repository root contains a \"HEAD\" file, a \"config\" file, an \"objects\" directory, a \"refs\" directory, with some work to ensure the proper ordering of operations, \"go get -u\" can be tricked into considering the parent directory as a repository root, and running Git commands on it. That will use the \"config\" file in the original Git repository root for its configuration, and if that config file contains malicious commands, they will execute on the system running \"go get -u\".\n\nNote that forbidding import paths with a .git element might not be sufficient to mitigate this issue, as on certain systems there can be other aliases for VCS state folders.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "toolchain" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, - { - "fixed": "1.10.6" - }, + doEncodeDecodeAndCompare( + """ { - "introduced": "1.11.0-0" - }, - { - "fixed": "1.11.3" + "schema_version": "1.3.1", + "id": "GO-2022-0189", + "modified": "2023-06-12T18:45:41Z", + "published": "2022-08-04T21:30:35Z", + "aliases": [ + "CVE-2018-16873" + ], + "summary": "Remote command execution via \"go get\" with \"-u\" flag in cmd/go", + "details": "The \"go get\" command is vulnerable to remote code execution when executed with the -u flag and the import path of a malicious Go package, or a package that imports it directly or indirectly.\n\nSpecifically, it is only vulnerable in GOPATH mode, but not in module mode (the distinction is documented at https://golang.org/cmd/go/#hdr-Module_aware_go_get).\n\nUsing custom domains, it's possible to arrange things so that a Git repository is cloned to a folder named \".git\" by using a vanity import path that ends with \"/.git\". If the Git repository root contains a \"HEAD\" file, a \"config\" file, an \"objects\" directory, a \"refs\" directory, with some work to ensure the proper ordering of operations, \"go get -u\" can be tricked into considering the parent directory as a repository root, and running Git commands on it. That will use the \"config\" file in the original Git repository root for its configuration, and if that config file contains malicious commands, they will execute on the system running \"go get -u\".\n\nNote that forbidding import paths with a .git element might not be sufficient to mitigate this issue, as on certain systems there can be other aliases for VCS state folders.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "toolchain" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.10.6" + }, + { + "introduced": "1.11.0-0" + }, + { + "fixed": "1.11.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "cmd/go/internal/get", + "symbols": [ + "downloadPackage" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/154101" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/go/+/bc82d7c7db83487e05d7a88e06549d4ae2a688c3" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/29230" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" + } + ], + "credits": [ + { + "name": "Etienne Stalmans of Heroku" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2022-0189" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "cmd/go/internal/get", - "symbols": [ - "downloadPackage" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/154101" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/go/+/bc82d7c7db83487e05d7a88e06549d4ae2a688c3" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/29230" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" - } - ], - "credits": [ - { - "name": "Etienne Stalmans of Heroku" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2022-0189" - } - } - """.trimIndent()) + """.trimIndent() + ) } @Test fun `GO-2022-0191`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2022-0191", - "modified": "2023-06-12T18:45:41Z", - "published": "2022-07-15T23:03:26Z", - "aliases": [ - "CVE-2018-16875" - ], - "summary": "Denial of service in chain verification in crypto/x509", - "details": "The crypto/x509 package does not limit the amount of work performed for each chain verification, which might allow attackers to craft pathological inputs leading to a CPU denial of service. Go TLS servers accepting client certificates and TLS clients verifying certificates are affected.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "stdlib" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, - { - "fixed": "1.10.6" - }, - { - "introduced": "1.11.0-0" - }, + doEncodeDecodeAndCompare( + """ { - "fixed": "1.11.3" + "schema_version": "1.3.1", + "id": "GO-2022-0191", + "modified": "2023-06-12T18:45:41Z", + "published": "2022-07-15T23:03:26Z", + "aliases": [ + "CVE-2018-16875" + ], + "summary": "Denial of service in chain verification in crypto/x509", + "details": "The crypto/x509 package does not limit the amount of work performed for each chain verification, which might allow attackers to craft pathological inputs leading to a CPU denial of service. Go TLS servers accepting client certificates and TLS clients verifying certificates are affected.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "stdlib" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.10.6" + }, + { + "introduced": "1.11.0-0" + }, + { + "fixed": "1.11.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "crypto/x509", + "symbols": [ + "CertPool.findVerifiedParents", + "Certificate.buildChains" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/154105" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/go/+/770130659b6fb2acf271476579a3644e093dda7f" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/29233" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" + } + ], + "credits": [ + { + "name": "Netflix" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2022-0191" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "crypto/x509", - "symbols": [ - "CertPool.findVerifiedParents", - "Certificate.buildChains" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/154105" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/go/+/770130659b6fb2acf271476579a3644e093dda7f" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/29233" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" - } - ], - "credits": [ - { - "name": "Netflix" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2022-0191" - } - } - """.trimIndent()) + """.trimIndent() + ) } -} \ No newline at end of file +} diff --git a/src/commonTest/kotlin/com/saveourtool/osv4k/OsvSchemaTestUtil.kt b/src/commonTest/kotlin/com/saveourtool/osv4k/OsvSchemaTestUtil.kt index 115a174..37b80b8 100644 --- a/src/commonTest/kotlin/com/saveourtool/osv4k/OsvSchemaTestUtil.kt +++ b/src/commonTest/kotlin/com/saveourtool/osv4k/OsvSchemaTestUtil.kt @@ -1,11 +1,10 @@ package com.saveourtool.osv4k +import kotlin.test.assertEquals +import kotlin.test.assertNotNull import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import kotlin.test.assertEquals -import kotlin.test.assertNotNull object OsvSchemaTestUtil { @OptIn(ExperimentalSerializationApi::class) @@ -14,6 +13,9 @@ object OsvSchemaTestUtil { prettyPrintIndent = " " } + /** + * @param originalContent + */ fun doEncodeDecodeAndCompare( originalContent: String, ) { @@ -23,6 +25,15 @@ object OsvSchemaTestUtil { assertEquals(originalContent, encode(result)) } + /** + * @param content + * @return decoded schema + */ fun decode(content: String): RawOsvSchema = Json.decodeFromString(content) + + /** + * @param value + * @return encoded schema + */ fun encode(value: RawOsvSchema): String = prettyJson.encodeToString(value) -} \ No newline at end of file +} diff --git a/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/JacksonAlias.kt b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/JacksonAlias.kt index 2691c55..f826524 100644 --- a/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/JacksonAlias.kt +++ b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/JacksonAlias.kt @@ -1,8 +1,7 @@ -@file:Suppress("DEPRECATION") +@file:Suppress("DEPRECATION", "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE") package com.saveourtool.osv4k.jackson - actual typealias Converter = com.fasterxml.jackson.databind.util.Converter actual typealias ConverterNone = com.fasterxml.jackson.databind.util.Converter.None @@ -31,4 +30,4 @@ actual typealias JsonInclude = com.fasterxml.jackson.annotation.JsonInclude actual typealias JsonIncludeType = com.fasterxml.jackson.annotation.JsonInclude.Include actual typealias JsonCreator = com.fasterxml.jackson.annotation.JsonCreator -actual typealias JsonCreatorMode = com.fasterxml.jackson.annotation.JsonCreator.Mode \ No newline at end of file +actual typealias JsonCreatorMode = com.fasterxml.jackson.annotation.JsonCreator.Mode diff --git a/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonDeserializer.kt b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonDeserializer.kt new file mode 100644 index 0000000..c58a389 --- /dev/null +++ b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonDeserializer.kt @@ -0,0 +1,86 @@ +@file:Suppress("DEPRECATION") + +package com.saveourtool.osv4k.jackson + +import com.saveourtool.osv4k.utils.fromRfc339String + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationConfig +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.deser.SettableBeanProperty +import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.jsontype.TypeDeserializer +import com.fasterxml.jackson.databind.type.LogicalType +import com.fasterxml.jackson.databind.util.AccessPattern +import com.fasterxml.jackson.databind.util.NameTransformer + +import kotlinx.datetime.LocalDateTime + +actual class LocalDateTimeRfc3339JacksonDeserializer : JsonDeserializer() { + private val stdDeserializer: StdDeserializer = object : StdDeserializer(LocalDateTime::class.java) { + override fun deserialize(parser: JsonParser, ctxt: DeserializationContext): LocalDateTime = + fromRfc339String(parser.text) + } + + override fun deserialize(parser: JsonParser?, ctxt: DeserializationContext?): LocalDateTime? = + stdDeserializer.deserialize(parser, ctxt) + + override fun deserialize( + parser: JsonParser?, + ctxt: DeserializationContext?, + intoValue: LocalDateTime? + ): LocalDateTime = + stdDeserializer.deserialize(parser, ctxt, intoValue) + + override fun getNullValue(ctxt: DeserializationContext?): LocalDateTime = stdDeserializer.getNullValue(ctxt) + + @Suppress("OVERRIDE_DEPRECATION") + override fun getNullValue(): LocalDateTime? = stdDeserializer.nullValue + + override fun getNullAccessPattern(): AccessPattern = stdDeserializer.nullAccessPattern + + override fun getAbsentValue(ctxt: DeserializationContext?): Any? = stdDeserializer.getAbsentValue(ctxt) + + override fun deserializeWithType( + parser: JsonParser?, + ctxt: DeserializationContext?, + typeDeserializer: TypeDeserializer? + ): Any? = stdDeserializer.deserializeWithType(parser, ctxt, typeDeserializer) + + override fun deserializeWithType( + parser: JsonParser?, + ctxt: DeserializationContext?, + typeDeserializer: TypeDeserializer?, + intoValue: LocalDateTime? + ): Any = stdDeserializer.deserializeWithType(parser, ctxt, typeDeserializer, intoValue) + + override fun unwrappingDeserializer(unwrapper: NameTransformer?): com.fasterxml.jackson.databind.JsonDeserializer = + stdDeserializer.unwrappingDeserializer(unwrapper) + + override fun replaceDelegatee(delegatee: com.fasterxml.jackson.databind.JsonDeserializer<*>?): com.fasterxml.jackson.databind.JsonDeserializer<*> = + stdDeserializer.replaceDelegatee(delegatee) + + override fun handledType(): Class<*> = stdDeserializer.handledType() + + override fun logicalType(): LogicalType = stdDeserializer.logicalType() + + override fun isCachable(): Boolean = stdDeserializer.isCachable + + override fun getDelegatee(): com.fasterxml.jackson.databind.JsonDeserializer<*> = stdDeserializer.delegatee + + override fun getKnownPropertyNames(): MutableCollection = stdDeserializer.knownPropertyNames + + override fun getEmptyValue(ctxt: DeserializationContext?): Any = stdDeserializer.getEmptyValue(ctxt) + + @Suppress("OVERRIDE_DEPRECATION") + override fun getEmptyValue(): Any? = stdDeserializer.emptyValue + + override fun getEmptyAccessPattern(): AccessPattern = stdDeserializer.emptyAccessPattern + + override fun getObjectIdReader(): ObjectIdReader? = stdDeserializer.objectIdReader + + override fun findBackReference(refName: String?): SettableBeanProperty = stdDeserializer.findBackReference(refName) + + override fun supportsUpdate(config: DeserializationConfig?): Boolean = stdDeserializer.supportsUpdate(config) +} diff --git a/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonSerializer.kt b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonSerializer.kt index b497325..53e0537 100644 --- a/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonSerializer.kt +++ b/src/jvmMain/kotlin/com/saveourtool/osv4k/jackson/LocalDateTimeRfc3339JacksonSerializer.kt @@ -2,27 +2,27 @@ package com.saveourtool.osv4k.jackson +import com.saveourtool.osv4k.utils.toRfc339String + import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.* -import com.fasterxml.jackson.databind.deser.SettableBeanProperty -import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader -import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.JavaType +import com.fasterxml.jackson.databind.SerializerProvider import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper -import com.fasterxml.jackson.databind.jsontype.TypeDeserializer import com.fasterxml.jackson.databind.jsontype.TypeSerializer import com.fasterxml.jackson.databind.ser.PropertyWriter import com.fasterxml.jackson.databind.ser.std.StdSerializer -import com.fasterxml.jackson.databind.type.LogicalType -import com.fasterxml.jackson.databind.util.AccessPattern import com.fasterxml.jackson.databind.util.NameTransformer -import com.saveourtool.osv4k.utils.LocalDateTimeRfc3339Util + import kotlinx.datetime.LocalDateTime actual class LocalDateTimeRfc3339JacksonSerializer : JsonSerializer() { private val stdSerializer: StdSerializer = object : StdSerializer(LocalDateTime::class.java) { - override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) { - gen.writeString(LocalDateTimeRfc3339Util.toString(value)) + override fun serialize( + value: LocalDateTime, + gen: JsonGenerator, + provider: SerializerProvider + ) { + gen.writeString(value.toRfc339String()) } } @@ -30,19 +30,17 @@ actual class LocalDateTimeRfc3339JacksonSerializer : JsonSerializer { - return stdSerializer.unwrappingSerializer(unwrapper) - } + override fun unwrappingSerializer(unwrapper: NameTransformer?): JsonSerializer = stdSerializer.unwrappingSerializer(unwrapper) - override fun replaceDelegatee(delegatee: JsonSerializer<*>?): JsonSerializer { - return stdSerializer.replaceDelegatee(delegatee) - } + override fun replaceDelegatee(delegatee: JsonSerializer<*>?): JsonSerializer = stdSerializer.replaceDelegatee(delegatee) - override fun withFilterId(filterId: Any?): JsonSerializer<*> { - return stdSerializer.withFilterId(filterId) - } + override fun withFilterId(filterId: Any?): JsonSerializer<*> = stdSerializer.withFilterId(filterId) - override fun serialize(value: LocalDateTime?, gen: JsonGenerator?, serializers: SerializerProvider?) = stdSerializer.serialize(value, gen, serializers) + override fun serialize( + value: LocalDateTime?, + gen: JsonGenerator?, + serializers: SerializerProvider? + ) = stdSerializer.serialize(value, gen, serializers) override fun serializeWithType( value: LocalDateTime?, @@ -69,67 +67,3 @@ actual class LocalDateTimeRfc3339JacksonSerializer : JsonSerializer = stdSerializer.properties() } - -actual class LocalDateTimeRfc3339JacksonDeserializer : JsonDeserializer() { - private val stdDeserializer: StdDeserializer = object : StdDeserializer(LocalDateTime::class.java) { - override fun deserialize(p: JsonParser, ctxt: DeserializationContext): LocalDateTime = - LocalDateTimeRfc3339Util.fromString(p.text) - } - - override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): LocalDateTime = - stdDeserializer.deserialize(p, ctxt) - - override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?, intoValue: LocalDateTime?): LocalDateTime = - stdDeserializer.deserialize(p, ctxt, intoValue) - - override fun getNullValue(ctxt: DeserializationContext?): LocalDateTime = stdDeserializer.getNullValue(ctxt) - - @Suppress("OVERRIDE_DEPRECATION") - override fun getNullValue(): LocalDateTime = stdDeserializer.nullValue - - override fun getNullAccessPattern(): AccessPattern = stdDeserializer.nullAccessPattern - - override fun getAbsentValue(ctxt: DeserializationContext?): Any? = stdDeserializer.getAbsentValue(ctxt) - - override fun deserializeWithType( - p: JsonParser?, - ctxt: DeserializationContext?, - typeDeserializer: TypeDeserializer? - ): Any = stdDeserializer.deserializeWithType(p, ctxt, typeDeserializer) - - override fun deserializeWithType( - p: JsonParser?, - ctxt: DeserializationContext?, - typeDeserializer: TypeDeserializer?, - intoValue: LocalDateTime? - ): Any = stdDeserializer.deserializeWithType(p, ctxt, typeDeserializer, intoValue) - - override fun unwrappingDeserializer(unwrapper: NameTransformer?): com.fasterxml.jackson.databind.JsonDeserializer = - stdDeserializer.unwrappingDeserializer(unwrapper) - - override fun replaceDelegatee(delegatee: com.fasterxml.jackson.databind.JsonDeserializer<*>?): com.fasterxml.jackson.databind.JsonDeserializer<*> = - stdDeserializer.replaceDelegatee(delegatee) - - override fun handledType(): Class<*> = stdDeserializer.handledType() - - override fun logicalType(): LogicalType = stdDeserializer.logicalType() - - override fun isCachable(): Boolean = stdDeserializer.isCachable - - override fun getDelegatee(): com.fasterxml.jackson.databind.JsonDeserializer<*> = stdDeserializer.delegatee - - override fun getKnownPropertyNames(): MutableCollection = stdDeserializer.knownPropertyNames - - override fun getEmptyValue(ctxt: DeserializationContext?): Any = stdDeserializer.getEmptyValue(ctxt) - - @Suppress("OVERRIDE_DEPRECATION") - override fun getEmptyValue(): Any = stdDeserializer.emptyValue - - override fun getEmptyAccessPattern(): AccessPattern = stdDeserializer.emptyAccessPattern - - override fun getObjectIdReader(): ObjectIdReader? = stdDeserializer.objectIdReader - - override fun findBackReference(refName: String?): SettableBeanProperty = stdDeserializer.findBackReference(refName) - - override fun supportsUpdate(config: DeserializationConfig?): Boolean = stdDeserializer.supportsUpdate(config) -} \ No newline at end of file diff --git a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt index f02166a..cf81579 100644 --- a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt +++ b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION") + package com.saveourtool.osv4k import com.saveourtool.osv4k.OsvSchemaJacksonTestUtil.doEncodeDecodeAndCompare @@ -6,249 +8,255 @@ import kotlin.test.Test class GoJacksonTest { @Test fun `GO-2020-0015`() { - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2020-0015", - "modified": "2023-06-12T18:45:41Z", - "published": "2021-04-14T20:04:52Z", - "aliases": [ - "CVE-2020-14040", - "GHSA-5rcv-m4m3-hfh7" - ], - "summary": "Infinite loop when decoding some inputs in golang.org/x/text", - "details": "An attacker could provide a single byte to a UTF16 decoder instantiated with UseBOM or ExpectBOM to trigger an infinite loop if the String function on the Decoder is called, or the Decoder is passed to transform.String. If used to parse user supplied input, this may be used as a denial of service vector.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "golang.org/x/text" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, + doEncodeDecodeAndCompare( + """ { - "fixed": "0.3.3" + "schema_version": "1.3.1", + "id": "GO-2020-0015", + "modified": "2023-06-12T18:45:41Z", + "published": "2021-04-14T20:04:52Z", + "aliases": [ + "CVE-2020-14040", + "GHSA-5rcv-m4m3-hfh7" + ], + "summary": "Infinite loop when decoding some inputs in golang.org/x/text", + "details": "An attacker could provide a single byte to a UTF16 decoder instantiated with UseBOM or ExpectBOM to trigger an infinite loop if the String function on the Decoder is called, or the Decoder is passed to transform.String. If used to parse user supplied input, this may be used as a denial of service vector.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "golang.org/x/text" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "0.3.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "golang.org/x/text/encoding/unicode", + "symbols": [ + "bomOverride.Transform", + "utf16Decoder.Transform" + ] + }, + { + "path": "golang.org/x/text/transform", + "symbols": [ + "String" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/238238" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/39491" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0" + } + ], + "credits": [ + { + "name": "@abacabadabacaba" + }, + { + "name": "Anton Gyllenberg" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2020-0015" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "golang.org/x/text/encoding/unicode", - "symbols": [ - "bomOverride.Transform", - "utf16Decoder.Transform" - ] - }, - { - "path": "golang.org/x/text/transform", - "symbols": [ - "String" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/238238" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/text/+/23ae387dee1f90d29a23c0e87ee0b46038fbed0e" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/39491" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/bXVeAmGOqz0" - } - ], - "credits": [ - { - "name": "@abacabadabacaba" - }, - { - "name": "Anton Gyllenberg" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2020-0015" - } - } - """.trimIndent()) + """.trimIndent() + ) } @Test fun `GO-2022-0189`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2022-0189", - "modified": "2023-06-12T18:45:41Z", - "published": "2022-08-04T21:30:35Z", - "aliases": [ - "CVE-2018-16873" - ], - "summary": "Remote command execution via \"go get\" with \"-u\" flag in cmd/go", - "details": "The \"go get\" command is vulnerable to remote code execution when executed with the -u flag and the import path of a malicious Go package, or a package that imports it directly or indirectly.\n\nSpecifically, it is only vulnerable in GOPATH mode, but not in module mode (the distinction is documented at https://golang.org/cmd/go/#hdr-Module_aware_go_get).\n\nUsing custom domains, it's possible to arrange things so that a Git repository is cloned to a folder named \".git\" by using a vanity import path that ends with \"/.git\". If the Git repository root contains a \"HEAD\" file, a \"config\" file, an \"objects\" directory, a \"refs\" directory, with some work to ensure the proper ordering of operations, \"go get -u\" can be tricked into considering the parent directory as a repository root, and running Git commands on it. That will use the \"config\" file in the original Git repository root for its configuration, and if that config file contains malicious commands, they will execute on the system running \"go get -u\".\n\nNote that forbidding import paths with a .git element might not be sufficient to mitigate this issue, as on certain systems there can be other aliases for VCS state folders.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "toolchain" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, - { - "fixed": "1.10.6" - }, + doEncodeDecodeAndCompare( + """ { - "introduced": "1.11.0-0" - }, - { - "fixed": "1.11.3" + "schema_version": "1.3.1", + "id": "GO-2022-0189", + "modified": "2023-06-12T18:45:41Z", + "published": "2022-08-04T21:30:35Z", + "aliases": [ + "CVE-2018-16873" + ], + "summary": "Remote command execution via \"go get\" with \"-u\" flag in cmd/go", + "details": "The \"go get\" command is vulnerable to remote code execution when executed with the -u flag and the import path of a malicious Go package, or a package that imports it directly or indirectly.\n\nSpecifically, it is only vulnerable in GOPATH mode, but not in module mode (the distinction is documented at https://golang.org/cmd/go/#hdr-Module_aware_go_get).\n\nUsing custom domains, it's possible to arrange things so that a Git repository is cloned to a folder named \".git\" by using a vanity import path that ends with \"/.git\". If the Git repository root contains a \"HEAD\" file, a \"config\" file, an \"objects\" directory, a \"refs\" directory, with some work to ensure the proper ordering of operations, \"go get -u\" can be tricked into considering the parent directory as a repository root, and running Git commands on it. That will use the \"config\" file in the original Git repository root for its configuration, and if that config file contains malicious commands, they will execute on the system running \"go get -u\".\n\nNote that forbidding import paths with a .git element might not be sufficient to mitigate this issue, as on certain systems there can be other aliases for VCS state folders.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "toolchain" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.10.6" + }, + { + "introduced": "1.11.0-0" + }, + { + "fixed": "1.11.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "cmd/go/internal/get", + "symbols": [ + "downloadPackage" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/154101" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/go/+/bc82d7c7db83487e05d7a88e06549d4ae2a688c3" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/29230" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" + } + ], + "credits": [ + { + "name": "Etienne Stalmans of Heroku" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2022-0189" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "cmd/go/internal/get", - "symbols": [ - "downloadPackage" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/154101" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/go/+/bc82d7c7db83487e05d7a88e06549d4ae2a688c3" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/29230" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" - } - ], - "credits": [ - { - "name": "Etienne Stalmans of Heroku" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2022-0189" - } - } - """.trimIndent()) + """.trimIndent() + ) } @Test fun `GO-2022-0191`() { // language=JSON - doEncodeDecodeAndCompare(""" - { - "schema_version": "1.3.1", - "id": "GO-2022-0191", - "modified": "2023-06-12T18:45:41Z", - "published": "2022-07-15T23:03:26Z", - "aliases": [ - "CVE-2018-16875" - ], - "summary": "Denial of service in chain verification in crypto/x509", - "details": "The crypto/x509 package does not limit the amount of work performed for each chain verification, which might allow attackers to craft pathological inputs leading to a CPU denial of service. Go TLS servers accepting client certificates and TLS clients verifying certificates are affected.", - "affected": [ - { - "package": { - "ecosystem": "Go", - "name": "stdlib" - }, - "ranges": [ - { - "type": "SEMVER", - "events": [ - { - "introduced": "0" - }, - { - "fixed": "1.10.6" - }, - { - "introduced": "1.11.0-0" - }, + doEncodeDecodeAndCompare( + """ { - "fixed": "1.11.3" + "schema_version": "1.3.1", + "id": "GO-2022-0191", + "modified": "2023-06-12T18:45:41Z", + "published": "2022-07-15T23:03:26Z", + "aliases": [ + "CVE-2018-16875" + ], + "summary": "Denial of service in chain verification in crypto/x509", + "details": "The crypto/x509 package does not limit the amount of work performed for each chain verification, which might allow attackers to craft pathological inputs leading to a CPU denial of service. Go TLS servers accepting client certificates and TLS clients verifying certificates are affected.", + "affected": [ + { + "package": { + "ecosystem": "Go", + "name": "stdlib" + }, + "ranges": [ + { + "type": "SEMVER", + "events": [ + { + "introduced": "0" + }, + { + "fixed": "1.10.6" + }, + { + "introduced": "1.11.0-0" + }, + { + "fixed": "1.11.3" + } + ] + } + ], + "ecosystem_specific": { + "imports": [ + { + "path": "crypto/x509", + "symbols": [ + "CertPool.findVerifiedParents", + "Certificate.buildChains" + ] + } + ] + } + } + ], + "references": [ + { + "type": "FIX", + "url": "https://go.dev/cl/154105" + }, + { + "type": "FIX", + "url": "https://go.googlesource.com/go/+/770130659b6fb2acf271476579a3644e093dda7f" + }, + { + "type": "REPORT", + "url": "https://go.dev/issue/29233" + }, + { + "type": "WEB", + "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" + } + ], + "credits": [ + { + "name": "Netflix" + } + ], + "database_specific": { + "url": "https://pkg.go.dev/vuln/GO-2022-0191" + } } - ] - } - ], - "ecosystem_specific": { - "imports": [ - { - "path": "crypto/x509", - "symbols": [ - "CertPool.findVerifiedParents", - "Certificate.buildChains" - ] - } - ] - } - } - ], - "references": [ - { - "type": "FIX", - "url": "https://go.dev/cl/154105" - }, - { - "type": "FIX", - "url": "https://go.googlesource.com/go/+/770130659b6fb2acf271476579a3644e093dda7f" - }, - { - "type": "REPORT", - "url": "https://go.dev/issue/29233" - }, - { - "type": "WEB", - "url": "https://groups.google.com/g/golang-announce/c/Kw31K8G7Fi0" - } - ], - "credits": [ - { - "name": "Netflix" - } - ], - "database_specific": { - "url": "https://pkg.go.dev/vuln/GO-2022-0191" - } - } - """.trimIndent()) + """.trimIndent() + ) } -} \ No newline at end of file +} diff --git a/src/jvmTest/kotlin/com/saveourtool/osv4k/OsvSchemaJacksonTestUtil.kt b/src/jvmTest/kotlin/com/saveourtool/osv4k/OsvSchemaJacksonTestUtil.kt index 0a090fd..1a8f757 100644 --- a/src/jvmTest/kotlin/com/saveourtool/osv4k/OsvSchemaJacksonTestUtil.kt +++ b/src/jvmTest/kotlin/com/saveourtool/osv4k/OsvSchemaJacksonTestUtil.kt @@ -7,9 +7,11 @@ import kotlin.test.assertNotNull object OsvSchemaJacksonTestUtil { private val objectMapper = ObjectMapper() - private val prettyWriter = objectMapper.writerWithDefaultPrettyPrinter() + /** + * @param originalContent + */ fun doEncodeDecodeAndCompare( @Language("JSON") originalContent: String, ) { @@ -28,4 +30,4 @@ object OsvSchemaJacksonTestUtil { ) { assertEquals(objectMapper.readTree(contentExpected), objectMapper.readTree(contentActual)) } -} \ No newline at end of file +} From d043446a09e81df975a132b76e5c4c0c85c549c2 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 15:14:55 +0300 Subject: [PATCH 08/18] detektAll --- build.gradle.kts | 9 ++++++++- .../saveourtool/osv4k/OsvSchemaJacksonJavaTestUtil.java | 5 +++-- .../com/saveourtool/osv4k/OsvSchemaJavaTestUtil.java | 4 ++-- .../kotlin/com/saveourtool/osv4k/GoJacksonTest.kt | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6c7dad3..a8950ac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,8 +21,9 @@ configureDiktat() createDetektTask() kotlin { + jvmToolchain(8) jvm { - // withJava() + withJava() compilations.all { kotlinOptions.run { jvmTarget = "1.8" @@ -63,5 +64,11 @@ kotlin { api(libs.jackson.databind) } } + val jvmTest by getting { + dependsOn(commonTest) + dependencies { + implementation(kotlin("test-junit5")) + } + } } } diff --git a/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJacksonJavaTestUtil.java b/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJacksonJavaTestUtil.java index e50b092..a52e265 100644 --- a/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJacksonJavaTestUtil.java +++ b/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJacksonJavaTestUtil.java @@ -7,8 +7,9 @@ import com.fasterxml.jackson.databind.ObjectWriter; import org.intellij.lang.annotations.Language; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + class OsvSchemaJacksonJavaTestUtil { private static final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJavaTestUtil.java b/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJavaTestUtil.java index d4a54ce..b3c3f3c 100644 --- a/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJavaTestUtil.java +++ b/src/jvmTest/java/com/saveourtool/osv4k/OsvSchemaJavaTestUtil.java @@ -2,8 +2,8 @@ import org.intellij.lang.annotations.Language; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; @SuppressWarnings("unchecked") class OsvSchemaJavaTestUtil { diff --git a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt index cf81579..87dd02c 100644 --- a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt +++ b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt @@ -1,4 +1,4 @@ -@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION") +@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION", "LongMethod") package com.saveourtool.osv4k From e89650a2fe727799af1fc6edb70dc4caa8e86283 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 16:19:27 +0300 Subject: [PATCH 09/18] diktatFix --- src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt index 87dd02c..6ff2120 100644 --- a/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt +++ b/src/jvmTest/kotlin/com/saveourtool/osv4k/GoJacksonTest.kt @@ -1,4 +1,8 @@ -@file:Suppress("LONG_LINE", "TOO_LONG_FUNCTION", "LongMethod") +@file:Suppress( + "LONG_LINE", + "TOO_LONG_FUNCTION", + "LongMethod", +) package com.saveourtool.osv4k From b4e64508631aaae23daa0346c7fdf8ca68c16fe7 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 16:23:24 +0300 Subject: [PATCH 10/18] upgraded jvmToolchain --- build.gradle.kts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a8950ac..5000916 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,13 +21,11 @@ configureDiktat() createDetektTask() kotlin { - jvmToolchain(8) + jvmToolchain(17) jvm { withJava() compilations.all { - kotlinOptions.run { - jvmTarget = "1.8" - } + kotlinOptions.jvmTarget = "1.8" } } linuxX64() From d5aca1239f0754b0dfbd1c7f32309f0f67460591 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 16:46:12 +0300 Subject: [PATCH 11/18] fixed build --- build.gradle.kts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 5000916..ed23912 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ import com.saveourtool.osv4k.buildutils.configureDiktat import com.saveourtool.osv4k.buildutils.createDetektTask +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { // alias(libs.plugins.kotlin.multiplatform) @@ -25,6 +26,7 @@ kotlin { jvm { withJava() compilations.all { + kotlinOptions.options.jvmTarget.set(JvmTarget.JVM_1_8) kotlinOptions.jvmTarget = "1.8" } } @@ -70,3 +72,10 @@ kotlin { } } } + +setOf("compileJava", "compileTestJava").forEach { taskName -> + tasks.named(taskName) { + sourceCompatibility = "1.8" + targetCompatibility = "1.8" + } +} \ No newline at end of file From 97d2e35d1e6cb660b63c9b6f13d14d91b271fc9e Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 16:50:00 +0300 Subject: [PATCH 12/18] diktatFix --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ed23912..164a25d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,4 +78,4 @@ setOf("compileJava", "compileTestJava").forEach { taskName -> sourceCompatibility = "1.8" targetCompatibility = "1.8" } -} \ No newline at end of file +} From 57597b896652e832a3540931f0543f9a9ef6a8c5 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 17:07:05 +0300 Subject: [PATCH 13/18] downgraded jvmToolchain to 11 --- build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 164a25d..6a72e43 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,11 +22,10 @@ configureDiktat() createDetektTask() kotlin { - jvmToolchain(17) + jvmToolchain(11) jvm { withJava() compilations.all { - kotlinOptions.options.jvmTarget.set(JvmTarget.JVM_1_8) kotlinOptions.jvmTarget = "1.8" } } From 34c80353dd791712c36e59414a6269a73a037136 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 17:29:09 +0300 Subject: [PATCH 14/18] diktatFix --- build.gradle.kts | 1 - gradle.properties | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6a72e43..6399e89 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,5 @@ import com.saveourtool.osv4k.buildutils.configureDiktat import com.saveourtool.osv4k.buildutils.createDetektTask -import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { // alias(libs.plugins.kotlin.multiplatform) diff --git a/gradle.properties b/gradle.properties index 9a32788..c20e8f7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ # gradle performance org.gradle.jvmargs=-Xmx4g -Xms3g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +kotlin.native.cacheKind.linuxX64=none From 201ba16f0f589e12f02030c76350fb0434d4bf99 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 27 Jul 2023 18:59:20 +0300 Subject: [PATCH 15/18] PublishingConfiguration.kt --- build.gradle.kts | 5 +- buildSrc/build.gradle.kts | 5 +- .../osv4k/buildutils/DetektConfiguration.kt | 2 +- .../osv4k/buildutils/JacocoConfiguration.kt | 65 +++++++ .../buildutils/PublishingConfiguration.kt | 162 ++++++++++++++++++ .../buildutils/VersioningConfiguration.kt | 15 ++ .../buildutils/kotlin-library.gradle.kts | 3 +- 7 files changed, 249 insertions(+), 8 deletions(-) create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt diff --git a/build.gradle.kts b/build.gradle.kts index 6399e89..0b4bf68 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import com.saveourtool.osv4k.buildutils.configureDiktat +import com.saveourtool.osv4k.buildutils.configureVersioning import com.saveourtool.osv4k.buildutils.createDetektTask plugins { @@ -14,7 +15,7 @@ repositories { } // version generation -// configureVersioning() +configureVersioning() // checks and validations configureDiktat() @@ -38,7 +39,6 @@ kotlin { api(libs.kotlinx.datetime) } } - @Suppress("UNUSED_VARIABLE") val commonTest by getting { dependencies { implementation(kotlin("test")) @@ -62,6 +62,7 @@ kotlin { api(libs.jackson.databind) } } + @Suppress("UNUSED_VARIABLE") val jvmTest by getting { dependsOn(commonTest) dependencies { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1076f69..0d89dee 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -16,7 +16,6 @@ dependencies { implementation(libs.diktat.gradle.plugin) implementation(libs.detekt.gradle.plugin) implementation(libs.kotlin.plugin.serialization) - // implementation("io.github.gradle-nexus:publish-plugin:1.3.0") - implementation("org.ajoberstar.reckon:reckon-gradle:0.13.2") - // implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") + implementation("io.github.gradle-nexus:publish-plugin:1.3.0") + implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") } diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt index e263c96..d371285 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/DetektConfiguration.kt @@ -18,7 +18,7 @@ import org.gradle.kotlin.dsl.withType fun Project.configureDetekt() { apply() configure { - config = rootProject.files("detekt.yml") + config.from(rootProject.files("detekt.yml")) buildUponDefaultConfig = true } } diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt new file mode 100644 index 0000000..d480135 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt @@ -0,0 +1,65 @@ +/** + * Configure JaCoCo for code coverage calculation + */ + +@file:Suppress("FILE_WILDCARD_IMPORTS") + +package com.saveourtool.osv4k.buildutils + +import org.gradle.api.Project +import org.gradle.api.tasks.testing.Test +import org.gradle.kotlin.dsl.* +import org.gradle.testing.jacoco.plugins.JacocoPlugin +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension +import org.gradle.testing.jacoco.plugins.JacocoTaskExtension +import org.gradle.testing.jacoco.tasks.JacocoReport +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +/** + * Calculate code coverage from JVM test executions. + */ +fun Project.configureJacoco() { + apply() + + configure { + toolVersion = "0.8.8" + } + + val kotlin: KotlinMultiplatformExtension = extensions.getByType() + val jvmTestTask by tasks.named("jvmTest") { + configure { + // this is needed to generate jacoco/jvmTest.exec + isEnabled = true + } + } + + val configure: JacocoReport.() -> Unit = { + executionData(jvmTestTask.extensions.getByType(JacocoTaskExtension::class.java).destinationFile) + // todo: include platform-specific source sets + additionalSourceDirs( + kotlin.sourceSets["commonMain"].kotlin.sourceDirectories + + kotlin.sourceSets["commonNonJvmMain"].kotlin.sourceDirectories + ) + classDirectories.setFrom(fileTree("$buildDir/classes/kotlin/jvm/main").apply { + exclude("**/*\$\$serializer.class") + }) + reports { + xml.required.set(true) + html.required.set(true) + } + } + + // `application` plugin creates jacocoTestReport task in plugin section (this is definitely incorrect behavior) + // AFTER that in "com.saveourtool.save.buildutils.kotlin-library" we try to register this task once again and fail + // so the order of plugins in `apply` is critically important + val jacocoTestReportTask = if (project.name == "save-cli") { + val jacocoTestReportTask by tasks.named("jacocoTestReport", configure) + jacocoTestReportTask + } else { + val jacocoTestReportTask by tasks.register("jacocoTestReport", configure) + jacocoTestReportTask + } + + jvmTestTask.finalizedBy(jacocoTestReportTask) + jacocoTestReportTask.dependsOn(jvmTestTask) +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt new file mode 100644 index 0000000..cd76917 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt @@ -0,0 +1,162 @@ +/** + * Publishing configuration file. + */ + +package com.saveourtool.osv4k.buildutils + +import io.github.gradlenexus.publishplugin.NexusPublishExtension +import io.github.gradlenexus.publishplugin.NexusPublishPlugin +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin +import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven +import org.gradle.api.publish.maven.tasks.PublishToMavenRepository +import org.gradle.api.tasks.bundling.Jar +import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.extra +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform +import org.gradle.plugins.signing.Sign +import org.gradle.plugins.signing.SigningExtension +import org.gradle.plugins.signing.SigningPlugin + +@Suppress( + "MISSING_KDOC_ON_FUNCTION", + "MISSING_KDOC_TOP_LEVEL", + "TOO_LONG_FUNCTION" +) +fun Project.configurePublishing() { + // If present, set properties from env variables. If any are absent, release will fail. + System.getenv("OSSRH_USERNAME")?.let { + extra.set("sonatypeUsername", it) + } + System.getenv("OSSRH_PASSWORD")?.let { + extra.set("sonatypePassword", it) + } + System.getenv("GPG_SEC")?.let { + extra.set("signingKey", it) + } + System.getenv("GPG_PASSWORD")?.let { + extra.set("signingPassword", it) + } + + if (this == rootProject) { + apply() + if (hasProperty("sonatypeUsername")) { + configureNexusPublishing() + } + } + + apply() + apply() + + configurePublications() + + if (hasProperty("signingKey")) { + configureSigning() + } + + // https://kotlinlang.org/docs/mpp-publish-lib.html#avoid-duplicate-publications + afterEvaluate { + val publicationsFromMainHost = listOf( + "jvm", + "js", + "linuxX64", "mingwX64", "macosX64", + "kotlinMultiplatform", "metadata", + ) + configure { + publications.matching { it.name in publicationsFromMainHost }.all { + val targetPublication = this@all + tasks.withType() + .matching { it.publication == targetPublication } + .configureEach { + onlyIf { + // main publishing CI job is executed on Linux host + DefaultNativePlatform.getCurrentOperatingSystem().isLinux.apply { + if (!this) { + logger.lifecycle("Publication ${(it as AbstractPublishToMaven).publication.name} is skipped on current host") + } + } + } + } + } + } + } +} + +@Suppress("TOO_LONG_FUNCTION", "GENERIC_VARIABLE_WRONG_DECLARATION") +private fun Project.configurePublications() { + val dokkaJarProvider = tasks.register("dokkaJar") { + group = "documentation" + archiveClassifier.set("javadoc") + from(tasks.findByName("dokkaHtml")) + } + configure { + repositories { + mavenLocal() + } + publications.withType().forEach { publication -> + publication.artifact(dokkaJarProvider) + publication.pom { + name.set(project.name) + description.set(project.description ?: project.name) + url.set("https://github.com/saveourtool/save") + licenses { + license { + name.set("MIT License") + url.set("http://www.opensource.org/licenses/mit-license.php") + distribution.set("repo") + } + } + developers { + developer { + id.set("petertrr") + name.set("Petr Trifanov") + email.set("peter.trifanov@gmail.com") + } + developer { + id.set("akuleshov7") + name.set("Andrey Kuleshov") + email.set("andrewkuleshov7@gmail.com") + } + } + scm { + url.set("https://github.com/saveourtool/save") + connection.set("scm:git:git://github.com/saveourtool/save.git") + } + } + } + } +} + +private fun Project.configureSigning() { + configure { + useInMemoryPgpKeys(property("signingKey") as String?, property("signingPassword") as String?) + logger.lifecycle("The following publications are getting signed: ${extensions.getByType().publications.map { it.name }}") + sign(*extensions.getByType().publications.toTypedArray()) + } + + tasks.withType().configureEach { + // Workaround for the problem described at https://github.com/saveourtool/save-cli/pull/501#issuecomment-1439705340. + // We have a single Javadoc artifact shared by all platforms, hence all publications depend on signing of this artifact. + // This causes weird implicit dependencies, like `publishJsPublication...` depends on `signJvmPublication`. + dependsOn(tasks.withType()) + } +} + +private fun Project.configureNexusPublishing() { + configure { + repositories { + sonatype { + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + username.set(property("sonatypeUsername") as String) + password.set(property("sonatypePassword") as String) + } + } + } +} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt index 0c3e90e..b8f52b3 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/VersioningConfiguration.kt @@ -4,6 +4,8 @@ package com.saveourtool.osv4k.buildutils +import org.ajoberstar.reckon.core.Scope +import org.ajoberstar.reckon.gradle.ReckonExtension import org.ajoberstar.reckon.gradle.ReckonPlugin import org.eclipse.jgit.api.Git import org.eclipse.jgit.internal.storage.file.FileRepository @@ -11,6 +13,7 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.kotlin.dsl.apply +import org.gradle.kotlin.dsl.configure /** * Configures how project version is determined. @@ -19,6 +22,18 @@ import org.gradle.kotlin.dsl.apply */ fun Project.configureVersioning() { apply() + + configure { + setDefaultInferredScope(Scope.MINOR) + snapshots() + setScopeCalc(calcScopeFromProp()) + setStageCalc(calcStageFromProp()) + } + + val isRelease = hasProperty("reckon.stage") && property("reckon.stage") == "final" + if (isRelease) { + failOnUncleanTree() + } } private fun Project.failOnUncleanTree() { diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts index e118244..96497d0 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -7,7 +7,6 @@ package com.saveourtool.osv4k.buildutils -import org.gradle.kotlin.dsl.kotlin import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest @@ -112,7 +111,7 @@ kotlin { } // configureJacoco() -// configurePublishing() +configurePublishing() configureDiktat() configureDetekt() From 6223bca24be04467757333d4b56a66118e58acd4 Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 28 Jul 2023 12:43:06 +0300 Subject: [PATCH 16/18] took publishing-configuration.gradle.kts from kompiledb --- build.gradle.kts | 26 +- buildSrc/build.gradle.kts | 3 +- .../osv4k/buildutils/JacocoConfiguration.kt | 14 +- .../buildutils/PublishingConfiguration.kt | 162 ---------- .../buildutils/kotlin-library.gradle.kts | 95 +----- .../publishing-configuration.gradle.kts | 286 ++++++++++++++++++ gradle/libs.versions.toml | 4 + 7 files changed, 309 insertions(+), 281 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt create mode 100644 buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/publishing-configuration.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts index 0b4bf68..ef97a9e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,8 @@ -import com.saveourtool.osv4k.buildutils.configureDiktat -import com.saveourtool.osv4k.buildutils.configureVersioning import com.saveourtool.osv4k.buildutils.createDetektTask plugins { - // alias(libs.plugins.kotlin.multiplatform) - // alias(libs.plugins.kotlin.plugin.serialization) id("com.saveourtool.osv4k.buildutils.kotlin-library") + id("com.saveourtool.osv4k.buildutils.publishing-configuration") } group = "com.saveourtool.osv4k" @@ -14,11 +11,6 @@ repositories { mavenCentral() } -// version generation -configureVersioning() -// checks and validations - -configureDiktat() createDetektTask() kotlin { @@ -29,9 +21,11 @@ kotlin { kotlinOptions.jvmTarget = "1.8" } } - linuxX64() - mingwX64() - macosX64() + val nativeTargets = setOf( + linuxX64(), + mingwX64(), + macosX64(), + ) sourceSets { val commonMain by getting { dependencies { @@ -48,12 +42,8 @@ kotlin { val commonNonJvmMain by creating { dependsOn(commonMain) } - listOf( - "linuxX64", - "mingwX64", - "macosX64", - ).forEach { nonJvmTarget -> - getByName("${nonJvmTarget}Main").dependsOn(commonNonJvmMain) + nativeTargets.forEach { nativeTarget -> + getByName("${nativeTarget.name}Main").dependsOn(commonNonJvmMain) } @Suppress("UNUSED_VARIABLE") val jvmMain by getting { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 0d89dee..ef8d80e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { implementation(libs.diktat.gradle.plugin) implementation(libs.detekt.gradle.plugin) implementation(libs.kotlin.plugin.serialization) - implementation("io.github.gradle-nexus:publish-plugin:1.3.0") implementation("org.ajoberstar.reckon:reckon-gradle:0.18.0") + implementation(libs.dokka.gradle.plugin) + implementation(libs.gradle.nexus.publish.plugin) } diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt index d480135..3b5ae7e 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/JacocoConfiguration.kt @@ -22,7 +22,7 @@ fun Project.configureJacoco() { apply() configure { - toolVersion = "0.8.8" + toolVersion = JacocoPlugin.DEFAULT_JACOCO_VERSION } val kotlin: KotlinMultiplatformExtension = extensions.getByType() @@ -34,11 +34,10 @@ fun Project.configureJacoco() { } val configure: JacocoReport.() -> Unit = { + dependsOn(jvmTestTask) executionData(jvmTestTask.extensions.getByType(JacocoTaskExtension::class.java).destinationFile) - // todo: include platform-specific source sets additionalSourceDirs( - kotlin.sourceSets["commonMain"].kotlin.sourceDirectories + - kotlin.sourceSets["commonNonJvmMain"].kotlin.sourceDirectories + kotlin.sourceSets["commonMain"].kotlin.sourceDirectories ) classDirectories.setFrom(fileTree("$buildDir/classes/kotlin/jvm/main").apply { exclude("**/*\$\$serializer.class") @@ -50,10 +49,10 @@ fun Project.configureJacoco() { } // `application` plugin creates jacocoTestReport task in plugin section (this is definitely incorrect behavior) - // AFTER that in "com.saveourtool.save.buildutils.kotlin-library" we try to register this task once again and fail + // AFTER that in "com.saveourtool.osv4k.buildutils.kotlin-library" we try to register this task once again and fail // so the order of plugins in `apply` is critically important - val jacocoTestReportTask = if (project.name == "save-cli") { - val jacocoTestReportTask by tasks.named("jacocoTestReport", configure) + val jacocoTestReportTask = if (project.name == "osv4k") { + val jacocoTestReportTask by tasks.register("jacocoTestReport", configure) jacocoTestReportTask } else { val jacocoTestReportTask by tasks.register("jacocoTestReport", configure) @@ -61,5 +60,4 @@ fun Project.configureJacoco() { } jvmTestTask.finalizedBy(jacocoTestReportTask) - jacocoTestReportTask.dependsOn(jvmTestTask) } diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt deleted file mode 100644 index cd76917..0000000 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/PublishingConfiguration.kt +++ /dev/null @@ -1,162 +0,0 @@ -/** - * Publishing configuration file. - */ - -package com.saveourtool.osv4k.buildutils - -import io.github.gradlenexus.publishplugin.NexusPublishExtension -import io.github.gradlenexus.publishplugin.NexusPublishPlugin -import org.gradle.api.Project -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.publish.maven.plugins.MavenPublishPlugin -import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven -import org.gradle.api.publish.maven.tasks.PublishToMavenRepository -import org.gradle.api.tasks.bundling.Jar -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.configure -import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.getByType -import org.gradle.kotlin.dsl.register -import org.gradle.kotlin.dsl.withType -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform -import org.gradle.plugins.signing.Sign -import org.gradle.plugins.signing.SigningExtension -import org.gradle.plugins.signing.SigningPlugin - -@Suppress( - "MISSING_KDOC_ON_FUNCTION", - "MISSING_KDOC_TOP_LEVEL", - "TOO_LONG_FUNCTION" -) -fun Project.configurePublishing() { - // If present, set properties from env variables. If any are absent, release will fail. - System.getenv("OSSRH_USERNAME")?.let { - extra.set("sonatypeUsername", it) - } - System.getenv("OSSRH_PASSWORD")?.let { - extra.set("sonatypePassword", it) - } - System.getenv("GPG_SEC")?.let { - extra.set("signingKey", it) - } - System.getenv("GPG_PASSWORD")?.let { - extra.set("signingPassword", it) - } - - if (this == rootProject) { - apply() - if (hasProperty("sonatypeUsername")) { - configureNexusPublishing() - } - } - - apply() - apply() - - configurePublications() - - if (hasProperty("signingKey")) { - configureSigning() - } - - // https://kotlinlang.org/docs/mpp-publish-lib.html#avoid-duplicate-publications - afterEvaluate { - val publicationsFromMainHost = listOf( - "jvm", - "js", - "linuxX64", "mingwX64", "macosX64", - "kotlinMultiplatform", "metadata", - ) - configure { - publications.matching { it.name in publicationsFromMainHost }.all { - val targetPublication = this@all - tasks.withType() - .matching { it.publication == targetPublication } - .configureEach { - onlyIf { - // main publishing CI job is executed on Linux host - DefaultNativePlatform.getCurrentOperatingSystem().isLinux.apply { - if (!this) { - logger.lifecycle("Publication ${(it as AbstractPublishToMaven).publication.name} is skipped on current host") - } - } - } - } - } - } - } -} - -@Suppress("TOO_LONG_FUNCTION", "GENERIC_VARIABLE_WRONG_DECLARATION") -private fun Project.configurePublications() { - val dokkaJarProvider = tasks.register("dokkaJar") { - group = "documentation" - archiveClassifier.set("javadoc") - from(tasks.findByName("dokkaHtml")) - } - configure { - repositories { - mavenLocal() - } - publications.withType().forEach { publication -> - publication.artifact(dokkaJarProvider) - publication.pom { - name.set(project.name) - description.set(project.description ?: project.name) - url.set("https://github.com/saveourtool/save") - licenses { - license { - name.set("MIT License") - url.set("http://www.opensource.org/licenses/mit-license.php") - distribution.set("repo") - } - } - developers { - developer { - id.set("petertrr") - name.set("Petr Trifanov") - email.set("peter.trifanov@gmail.com") - } - developer { - id.set("akuleshov7") - name.set("Andrey Kuleshov") - email.set("andrewkuleshov7@gmail.com") - } - } - scm { - url.set("https://github.com/saveourtool/save") - connection.set("scm:git:git://github.com/saveourtool/save.git") - } - } - } - } -} - -private fun Project.configureSigning() { - configure { - useInMemoryPgpKeys(property("signingKey") as String?, property("signingPassword") as String?) - logger.lifecycle("The following publications are getting signed: ${extensions.getByType().publications.map { it.name }}") - sign(*extensions.getByType().publications.toTypedArray()) - } - - tasks.withType().configureEach { - // Workaround for the problem described at https://github.com/saveourtool/save-cli/pull/501#issuecomment-1439705340. - // We have a single Javadoc artifact shared by all platforms, hence all publications depend on signing of this artifact. - // This causes weird implicit dependencies, like `publishJsPublication...` depends on `signJvmPublication`. - dependsOn(tasks.withType()) - } -} - -private fun Project.configureNexusPublishing() { - configure { - repositories { - sonatype { - nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) - snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) - username.set(property("sonatypeUsername") as String) - password.set(property("sonatypePassword") as String) - } - } - } -} diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts index 96497d0..207274d 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -7,7 +7,6 @@ package com.saveourtool.osv4k.buildutils -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest plugins { @@ -17,101 +16,13 @@ plugins { kotlin { jvmToolchain { - this.languageVersion.set(JavaLanguageVersion.of("11")) - } - jvm { - compilations.all { - kotlinOptions { - jvmTarget = "11" - freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" - } - } - } - val nativeTargets = listOf(linuxX64(), mingwX64(), macosX64()) - if (project.name == "save-common") { - // additionally, save-common should be available for JS too - // fixme: shouldn't rely on hardcoded project name here - js(IR).browser() - - // store yarn.lock in the root directory - rootProject.extensions.configure { - lockFileDirectory = rootProject.projectDir - } - } - - if (hasProperty("disableRedundantTargets") && (property("disableRedundantTargets") as String?) != "false") { - // with this flag we exclude targets that are present on multiple OS to speed up build - val currentOs = DefaultNativePlatform.getCurrentOperatingSystem() - val redundantTarget: String? = when { - currentOs.isWindows -> "linuxX64" - currentOs.isMacOsX -> "linuxX64" - currentOs.isLinux -> null - else -> throw GradleException("Unknown operating system ${currentOs.name}") - } - tasks.matching { redundantTarget != null && it.name.contains(redundantTarget, ignoreCase = true) } - .configureEach { - logger.lifecycle("Disabling task :${project.name}:$name on host $currentOs") - enabled = false - } - } - - /* - * Common structure for MPP libraries: - * common - * | - * nonJs - * / \ - * native JVM - * / | \ - * linux mingw macos - */ - sourceSets { - all { - languageSettings.optIn("kotlin.RequiresOptIn") - } - val commonMain by getting - val commonTest by getting { - dependencies { - implementation("io.kotest:kotest-assertions-core:5.6.2") - } - } - val commonNonJsMain by creating { - dependsOn(commonMain) - } - val commonNonJsTest by creating { - dependsOn(commonTest) - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - } - } - val jvmMain by getting { - dependsOn(commonNonJsMain) - } - val jvmTest by getting { - dependsOn(commonNonJsTest) - dependencies { - implementation(kotlin("test-junit5")) - implementation("org.junit.jupiter:junit-jupiter-engine:5.10.0") - } - } - val nativeMain by creating { - dependsOn(commonNonJsMain) - } - val nativeTest by creating { - dependsOn(commonNonJsTest) - } - nativeTargets.forEach { - getByName("${it.name}Main").dependsOn(nativeMain) - } - nativeTargets.forEach { - getByName("${it.name}Test").dependsOn(nativeTest) - } + languageVersion.set(JavaLanguageVersion.of("17")) } } +configureVersioning() +// withJava() creates a task for jacoco // configureJacoco() -configurePublishing() configureDiktat() configureDetekt() diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/publishing-configuration.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/publishing-configuration.gradle.kts new file mode 100644 index 0000000..f5f2c74 --- /dev/null +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/publishing-configuration.gradle.kts @@ -0,0 +1,286 @@ +package com.saveourtool.osv4k.buildutils + +import io.github.gradlenexus.publishplugin.NexusPublishExtension +import io.github.gradlenexus.publishplugin.NexusPublishPlugin +import org.gradle.internal.logging.text.StyledTextOutput +import org.gradle.internal.logging.text.StyledTextOutput.Style.Failure +import org.gradle.internal.logging.text.StyledTextOutput.Style.Identifier +import org.gradle.internal.logging.text.StyledTextOutput.Style.Info +import org.gradle.internal.logging.text.StyledTextOutput.Style.Success +import org.gradle.internal.logging.text.StyledTextOutputFactory +import org.gradle.kotlin.dsl.support.serviceOf +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +plugins { + `maven-publish` + signing + id("org.jetbrains.dokka") +} + +group = rootProject.group +version = rootProject.version + +configurePublishing() + +/** + * Configures all aspects of the publishing process. + */ +fun Project.configurePublishing() { + createPublications() + configureNexusPublishing() + configureGitHubPublishing() + configurePublications() + configureSigning() + + // https://kotlinlang.org/docs/mpp-publish-lib.html#avoid-duplicate-publications + afterEvaluate { + val publicationsFromMainHost = listOf( + "jvm", + "js", + "linuxX64", "mingwX64", "macosX64", + "kotlinMultiplatform", "metadata", + ) + configure { + publications.matching { it.name in publicationsFromMainHost }.all { + val targetPublication = this@all + tasks.withType() + .matching { it.publication == targetPublication } + .configureEach { + onlyIf { + // main publishing CI job is executed on Linux host + DefaultNativePlatform.getCurrentOperatingSystem().isLinux.apply { + if (!this) { + logger.lifecycle("Publication ${(it as AbstractPublishToMaven).publication.name} is skipped on current host") + } + } + } + } + } + } + } +} + +/** + * Creates the publications. + */ +fun Project.createPublications() { + if (this == rootProject) { + return + } + + publishing { + publications { + create("maven") { + from(components["java"]) + suppressPomMetadataWarningsFor("testFixturesApiElements") + suppressPomMetadataWarningsFor("testFixturesRuntimeElements") + } + } + } +} + +/** + * Configures Maven Central as the publish destination. + */ +fun Project.configureNexusPublishing() { + if (this != rootProject) { + return + } + + if (!hasProperties("sonatypeUsername", "sonatypePassword")) { + styledOut(logCategory = "nexus") + .style(Info) + .text("Skipping Nexus publishing configuration as either ") + .style(Identifier) + .text("sonatypeUsername") + .style(Info) + .text(" or ") + .style(Identifier) + .text("sonatypePassword") + .style(Info) + .text(" are not set") + .println() + return + } + + apply() + + configure { + this@configure.repositories { + sonatype { + /* + * The default is https://oss.sonatype.org/service/local/. + */ + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + /* + * The default is https://oss.sonatype.org/content/repositories/snapshots/. + */ + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + username.set(property("sonatypeUsername") as String) + password.set(property("sonatypePassword") as String) + } + } + } +} + +/** + * Configures GitHub Packages as the publish destination. + */ +fun Project.configureGitHubPublishing(): Unit = + publishing { + repositories { + maven { + name = "GitHub" + url = uri("https://maven.pkg.github.com/saveourtool/osv4k") + credentials { + username = findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") + password = findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN") + } + } + } + } + +/** + * Configures all publications. The publications must already exist. + */ +@Suppress("TOO_LONG_FUNCTION") +fun Project.configurePublications() { + if (this == rootProject) { + return + } + + tasks.named("javadocJar").configure { + from(tasks.findByName("dokkaJavadoc")) + } + + configure { + publications.withType().configureEach { + pom { + val project = this@configurePublications + + name.set(project.name) + description.set(project.description ?: project.name) + url.set("https://github.com/saveourtool/osv4k") + licenses { + license { + name.set("MIT License") + url.set("https://opensource.org/license/MIT") + distribution.set("repo") + } + } + developers { + developer { + id.set("nulls") + name.set("Nariman Abdullin") + email.set("nulls.narik@gmail.com") + } + } + scm { + url.set("https://github.com/saveourtool/osv4k") + connection.set("scm:git:https://github.com/saveourtool/osv4k.git") + developerConnection.set("scm:git:git@github.com:saveourtool/osv4k.git") + } + } + } + } +} + +/** + * Enables signing of the artifacts if the `signingKey` project property is set. + * + * Should be explicitly called after each custom `publishing {}` section. + */ +fun Project.configureSigning() { + if (this == rootProject) { + return + } + + System.getenv("GPG_SEC")?.let { + extra.set("signingKey", it) + } + System.getenv("GPG_PASSWORD")?.let { + extra.set("signingPassword", it) + } + + if (hasProperty("signingKey")) { + /* + * GitHub Actions. + */ + configureSigningCommon { + useInMemoryPgpKeys(property("signingKey") as String?, findProperty("signingPassword") as String?) + } + } else if ( + hasProperties( + "signing.keyId", + "signing.password", + "signing.secretKeyRingFile", + ) + ) { + /*- + * Pure-Java signing mechanism via `org.bouncycastle.bcpg`. + * + * Requires an 8-digit (short form) PGP key id and a present `~/.gnupg/secring.gpg` + * (for gpg 2.1, run + * `gpg --keyring secring.gpg --export-secret-keys >~/.gnupg/secring.gpg` + * to generate one). + */ + configureSigningCommon() + } else if (hasProperty("signing.gnupg.keyName")) { + /*- + * Use an external `gpg` executable. + * + * On Windows, you may need to additionally specify the path to `gpg` via + * `signing.gnupg.executable`. + */ + configureSigningCommon { + useGpgCmd() + } + } +} + +/** + * @param useKeys the block which configures the PGP keys. Use either + * [SigningExtension.useInMemoryPgpKeys], [SigningExtension.useGpgCmd], or an + * empty lambda. + * @see SigningExtension.useInMemoryPgpKeys + * @see SigningExtension.useGpgCmd + */ +@Suppress( + "MaxLineLength", + "SpreadOperator", +) +fun Project.configureSigningCommon(useKeys: SigningExtension.() -> Unit = {}) { + require(this != rootProject) + + configure { + useKeys() + val publications = extensions.getByType().publications + val publicationCount = publications.size + val message = "The following $publicationCount publication(s) are getting signed: ${publications.map(Named::getName)}" + val style = when (publicationCount) { + 0 -> Failure + else -> Success + } + styledOut(logCategory = "signing").style(style).println(message) + sign(*publications.toTypedArray()) + } +} + +/** + * Creates a styled text output. + * + * @param logCategory + * @return [StyledTextOutput] + */ +fun Project.styledOut(logCategory: String): StyledTextOutput = + serviceOf().create(logCategory) + +/** + * Determines if this project has all the given properties. + * + * @param propertyNames the names of the properties to locate. + * @return `true` if this project has all the given properties, `false` otherwise. + * @see Project.hasProperty + */ +fun Project.hasProperties(vararg propertyNames: String): Boolean = + propertyNames.asSequence().all(this::hasProperty) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4664f4..1dcfff7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,6 +5,8 @@ kotlinx-datetime = "0.4.0" jackson = "2.15.2" diktat = "1.2.5" detekt = "1.23.0" +dokka = "1.8.20" +gradle-nexus-publish-plugin = "1.3.0" [plugins] kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } @@ -16,6 +18,8 @@ kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", v kotlin-plugin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } diktat-gradle-plugin = { module = "org.cqfn.diktat:diktat-gradle-plugin", version.ref = "diktat" } detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } +dokka-gradle-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" } +gradle-nexus-publish-plugin = { module = "io.github.gradle-nexus:publish-plugin", version.ref = "gradle-nexus-publish-plugin"} jetbrains-annotations = { module = "org.jetbrains:annotations", version = "24.0.1" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } From 71cb9db90da972dc1e28e2de437e0230beb42aae Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 28 Jul 2023 12:48:20 +0300 Subject: [PATCH 17/18] ugpraded JDK on github actions to 17 and copied release.yml from kompiledb --- .github/workflows/build_and_test.yml | 4 +- .github/workflows/detekt.yml | 4 +- .github/workflows/diktat.yml | 4 +- .github/workflows/release.yml | 71 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 32f3a85..072aabd 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -26,10 +26,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: 11 + java-version: 17 distribution: temurin - name: Retrieve Kotlin version shell: bash diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index 7cfcfe4..7b0dff7 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: 11 + java-version: 17 distribution: temurin - uses: gradle/gradle-build-action@v2 with: diff --git a/.github/workflows/diktat.yml b/.github/workflows/diktat.yml index 8bd86e4..b91f561 100644 --- a/.github/workflows/diktat.yml +++ b/.github/workflows/diktat.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: 11 + java-version: 17 distribution: temurin - uses: gradle/gradle-build-action@v2 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4254bae --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,71 @@ +name: 'Release' + +on: + push: + tags: + - 'v*' + +env: + GRADLE_OPTS: -Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.welcome=never + GPG_SEC: ${{ secrets.PGP_SEC }} + GPG_PASSWORD: ${{ secrets.PGP_PASSWORD }} + OSSRH_USERNAME: ${{ secrets.SONATYPE_USER }} + OSSRH_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + +jobs: + release: + name: 'Release' + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + # Fetch Git tags, so that semantic version can be calculated. + # Alternatively, run `git fetch --prune --unshallow --tags` as the + # next step, see + # https://github.com/actions/checkout/issues/206#issuecomment-607496604. + fetch-depth: 0 + + - name: 'Set up Java' + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + + - name: 'Publish a release to GitHub' + id: publish-github + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + -Preckon.stage= + publishAllPublicationsToGitHubRepository + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: 'Publish a release to Maven Central' + id: publish-sonatype + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + arguments: | + -Preckon.stage= + publishToSonatype + closeAndReleaseSonatypeStagingRepository + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + github_release: + needs: release + name: 'Github Release' + runs-on: ubuntu-latest + steps: + - name: 'Github Release' + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false \ No newline at end of file From 0aabc7e0ee891187e8b55e81af4a6c18d84d71db Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Fri, 28 Jul 2023 13:10:02 +0300 Subject: [PATCH 18/18] downgraded to jdk 11 --- .github/workflows/build_and_test.yml | 4 ++-- .github/workflows/detekt.yml | 4 ++-- .github/workflows/diktat.yml | 4 ++-- .github/workflows/release.yml | 2 +- build.gradle.kts | 1 - .../saveourtool/osv4k/buildutils/kotlin-library.gradle.kts | 4 +--- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 072aabd..32f3a85 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -26,10 +26,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 17 + - name: Set up JDK 11 uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 11 distribution: temurin - name: Retrieve Kotlin version shell: bash diff --git a/.github/workflows/detekt.yml b/.github/workflows/detekt.yml index 7b0dff7..7cfcfe4 100644 --- a/.github/workflows/detekt.yml +++ b/.github/workflows/detekt.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 17 + - name: Set up JDK 11 uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 11 distribution: temurin - uses: gradle/gradle-build-action@v2 with: diff --git a/.github/workflows/diktat.yml b/.github/workflows/diktat.yml index b91f561..8bd86e4 100644 --- a/.github/workflows/diktat.yml +++ b/.github/workflows/diktat.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 17 + - name: Set up JDK 11 uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 11 distribution: temurin - uses: gradle/gradle-build-action@v2 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4254bae..0aade44 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,7 +29,7 @@ jobs: - name: 'Set up Java' uses: actions/setup-java@v3 with: - java-version: 17 + java-version: 11 distribution: temurin - name: 'Publish a release to GitHub' diff --git a/build.gradle.kts b/build.gradle.kts index ef97a9e..917e3fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,6 @@ repositories { createDetektTask() kotlin { - jvmToolchain(11) jvm { withJava() compilations.all { diff --git a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts index 207274d..8a4500b 100644 --- a/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts +++ b/buildSrc/src/main/kotlin/com/saveourtool/osv4k/buildutils/kotlin-library.gradle.kts @@ -15,9 +15,7 @@ plugins { } kotlin { - jvmToolchain { - languageVersion.set(JavaLanguageVersion.of("17")) - } + jvmToolchain(11) } configureVersioning()