From 250105b95a80e93736a0ab7e0395888c68130ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 13 Nov 2023 19:52:46 +0100 Subject: [PATCH 1/5] Add core module + setup publishing --- gradle/libs.versions.toml | 2 + .../src/main/kotlin/PublishingPlugin.kt | 5 +++ .../api/licensee-for-android-core.api | 45 +++++++++++++++++++ licensee-for-android-core/build.gradle | 22 +++++++++ .../io/github/usefulness/licensee/Artifact.kt | 30 +++++++++++++ .../io/github/usefulness/licensee/Licensee.kt | 6 +++ licensee-for-android/build.gradle | 2 +- settings.gradle | 1 + 8 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 licensee-for-android-core/api/licensee-for-android-core.api create mode 100644 licensee-for-android-core/build.gradle create mode 100644 licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt create mode 100644 licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Licensee.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 921a9c7..28331a2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,6 +9,7 @@ maven-junit = "5.10.1" maven-assertj = "3.24.2" maven-binarycompatiblity = "0.13.2" maven-dokka = "1.9.10" +maven-poko = "0.15.0" [libraries] junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "maven-junit" } @@ -31,4 +32,5 @@ starter-library-android = { id = "com.starter.library.android", version.ref = "g gradle-pluginpublish = { id = "com.gradle.plugin-publish", version.ref = "gradle-pluginpublish" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "maven-kotlin" } kotlinx-binarycompatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "maven-binarycompatiblity" } +drewhamilton-poko = { id = "dev.drewhamilton.poko", version.ref = "maven-poko" } osacky-doctor = { id = "com.osacky.doctor", version.ref = "gradle-doctor" } diff --git a/gradle/plugins/src/main/kotlin/PublishingPlugin.kt b/gradle/plugins/src/main/kotlin/PublishingPlugin.kt index 0ce8a6a..42904cb 100644 --- a/gradle/plugins/src/main/kotlin/PublishingPlugin.kt +++ b/gradle/plugins/src/main/kotlin/PublishingPlugin.kt @@ -77,6 +77,11 @@ class PublishingPlugin : Plugin { } extensions.configure { + if(!pluginManager.hasPlugin("com.gradle.plugin-publish")) { + publications.register("mavenJava", MavenPublication::class.java) { publication -> + publication.from(components.getByName("java")) + } + } publications.configureEach { publication -> (publication as? MavenPublication)?.pom { pom -> pom.name.set("${project.group}:${project.name}") diff --git a/licensee-for-android-core/api/licensee-for-android-core.api b/licensee-for-android-core/api/licensee-for-android-core.api new file mode 100644 index 0000000..35662a4 --- /dev/null +++ b/licensee-for-android-core/api/licensee-for-android-core.api @@ -0,0 +1,45 @@ +public final class io/github/usefulness/licensee/Artifact { + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lio/github/usefulness/licensee/Scm;Ljava/util/List;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getArtifactId ()Ljava/lang/String; + public final fun getGroupId ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getScm ()Lio/github/usefulness/licensee/Scm; + public final fun getSpdxLicenses ()Ljava/util/List; + public final fun getUnknownLicenses ()Ljava/util/List; + public final fun getVersion ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class io/github/usefulness/licensee/Licensee { + public abstract fun getArtifacts ()Ljava/util/List; +} + +public final class io/github/usefulness/licensee/Scm { + public fun (Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class io/github/usefulness/licensee/SpdxLicense { + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getIdentifier ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class io/github/usefulness/licensee/UnknownLicense { + public fun (Ljava/lang/String;Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getName ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + diff --git a/licensee-for-android-core/build.gradle b/licensee-for-android-core/build.gradle new file mode 100644 index 0000000..1cab7ce --- /dev/null +++ b/licensee-for-android-core/build.gradle @@ -0,0 +1,22 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + alias(libs.plugins.starter.library.kotlin) + alias(libs.plugins.kotlinx.binarycompatibility) + alias(libs.plugins.drewhamilton.poko) + id("com.starter.publishing") +} + +kotlin { + explicitApi() +} + +tasks.withType(KotlinCompile).configureEach { + kotlinOptions { + apiVersion = "1.8" + languageVersion = "1.8" + } +} +tasks.withType(Test).configureEach { + useJUnitPlatform() +} diff --git a/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt new file mode 100644 index 0000000..5f35caa --- /dev/null +++ b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt @@ -0,0 +1,30 @@ +package io.github.usefulness.licensee + +import dev.drewhamilton.poko.Poko + +@Poko +public class SpdxLicenses( + public val identifier: String, + public val name: String, + public val url: String, +) + +@Poko +public class Scm(public val url: String) + +@Poko +public class UnknownLicenses( + public val name: String, + public val url: String, +) + +@Poko +public class Artifact( + public val groupId: String, + public val artifactId: String, + public val version: String, + public val name: String?, + public val spdxLicenses: List, + public val scm: Scm?, + public val unknownLicenses: List, +) diff --git a/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Licensee.kt b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Licensee.kt new file mode 100644 index 0000000..efe2ab1 --- /dev/null +++ b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Licensee.kt @@ -0,0 +1,6 @@ +package io.github.usefulness.licensee + +public interface Licensee { + + public val artifacts: List +} diff --git a/licensee-for-android/build.gradle b/licensee-for-android/build.gradle index d6ace0a..2d825e8 100644 --- a/licensee-for-android/build.gradle +++ b/licensee-for-android/build.gradle @@ -45,7 +45,7 @@ description = "A plugin that generates a list of open source licenses you depend gradlePlugin { plugins { - create("gross") { + register("licenseeForAndroid") { id = "io.github.usefulness.licensee-for-android" displayName = "`cashapp/licensee` helper for Android" description = project.description diff --git a/settings.gradle b/settings.gradle index 1149132..0b35922 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,4 +23,5 @@ dependencyResolutionManagement { rootProject.name = "io.github.usefulness" include("licensee-for-android") +include("licensee-for-android-core") includeBuild("gradle/plugins") From b5ea86cc9d9d577fa463240ed452432178f34f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 13 Nov 2023 20:08:52 +0100 Subject: [PATCH 2/5] Update code-generator --- licensee-for-android-core/build.gradle | 8 ++ .../io/github/usefulness/licensee/Artifact.kt | 26 ++-- .../api/licensee-for-android.api | 1 + licensee-for-android/build.gradle | 33 +++++ .../licensee/ArtifactCodeGenerator.kt | 30 ++-- .../usefulness/licensee/CodeGenerationTask.kt | 32 ++--- .../licensee/LicenseeForAndroidExtension.kt | 6 + .../licensee/LicenseeForAndroidPlugin.kt | 16 +++ .../licensee/LicenseeTypesGenerator.kt | 132 ------------------ .../licensee/ArtifactGeneratorTest.kt | 35 ++--- .../licensee/LicenseeTypesGeneratorTest.kt | 65 --------- 11 files changed, 116 insertions(+), 268 deletions(-) delete mode 100644 licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeTypesGenerator.kt delete mode 100644 licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/LicenseeTypesGeneratorTest.kt diff --git a/licensee-for-android-core/build.gradle b/licensee-for-android-core/build.gradle index 1cab7ce..7790820 100644 --- a/licensee-for-android-core/build.gradle +++ b/licensee-for-android-core/build.gradle @@ -11,6 +11,14 @@ kotlin { explicitApi() } +def targetVersion = JavaVersion.VERSION_1_8 +tasks.withType(KotlinCompile).configureEach { + it.kotlinOptions.jvmTarget = targetVersion.toString() +} +tasks.withType(JavaCompile).configureEach { + it.options.release.set(targetVersion.majorVersion.toInteger()) +} + tasks.withType(KotlinCompile).configureEach { kotlinOptions { apiVersion = "1.8" diff --git a/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt index 5f35caa..7e3d24d 100644 --- a/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt +++ b/licensee-for-android-core/src/main/kotlin/io/github/usefulness/licensee/Artifact.kt @@ -3,7 +3,18 @@ package io.github.usefulness.licensee import dev.drewhamilton.poko.Poko @Poko -public class SpdxLicenses( +public class Artifact( + public val groupId: String, + public val artifactId: String, + public val version: String, + public val name: String?, + public val spdxLicenses: List, + public val scm: Scm?, + public val unknownLicenses: List, +) + +@Poko +public class SpdxLicense( public val identifier: String, public val name: String, public val url: String, @@ -13,18 +24,7 @@ public class SpdxLicenses( public class Scm(public val url: String) @Poko -public class UnknownLicenses( +public class UnknownLicense( public val name: String, public val url: String, ) - -@Poko -public class Artifact( - public val groupId: String, - public val artifactId: String, - public val version: String, - public val name: String?, - public val spdxLicenses: List, - public val scm: Scm?, - public val unknownLicenses: List, -) diff --git a/licensee-for-android/api/licensee-for-android.api b/licensee-for-android/api/licensee-for-android.api index 6c05b4b..0d266c1 100644 --- a/licensee-for-android/api/licensee-for-android.api +++ b/licensee-for-android/api/licensee-for-android.api @@ -16,6 +16,7 @@ public abstract class io/github/usefulness/licensee/LicenseeFileCopyTask : org/g public class io/github/usefulness/licensee/LicenseeForAndroidExtension { public fun (Lorg/gradle/api/model/ObjectFactory;)V + public final fun getAutomaticCoreDependencyManagement ()Lorg/gradle/api/provider/Property; public final fun getEnableKotlinCodeGeneration ()Lorg/gradle/api/provider/Property; public final fun getEnableResourceGeneration ()Lorg/gradle/api/provider/Property; public final fun getGeneratedPackageName ()Lorg/gradle/api/provider/Property; diff --git a/licensee-for-android/build.gradle b/licensee-for-android/build.gradle index 2d825e8..b2897a8 100644 --- a/licensee-for-android/build.gradle +++ b/licensee-for-android/build.gradle @@ -55,4 +55,37 @@ gradlePlugin { } } +final GENERATED_PACKAGE_NAME = "io.github.usefulness.licensee.generated" +final GENERATED_BUILD_DIR = layout.buildDirectory.map { it.dir("generated/config/${GENERATED_PACKAGE_NAME.replace('.', '/')}")} +tasks.register("generateBuildConfig") { + final version = project.version + doLast { + def generatedDir = GENERATED_BUILD_DIR.get().asFile + generatedDir.deleteDir() + generatedDir.mkdirs() + + final className = "LicenseeForAndroidBuildConfig" + final configClass = new File(generatedDir, "${className}.kt") + BufferedWriter writer = configClass.newWriter() + try { + writer.writeLine("package $GENERATED_PACKAGE_NAME") + writer.writeLine("") + writer.writeLine("internal object $className { internal const val VERSION: String = \"${version.toString()}\" }") + writer.flush() + } finally { + writer.close() + } + } +} + +tasks.named("compileKotlin") { + dependsOn("generateBuildConfig") + sourceSets.named("main") { + kotlin.srcDir(GENERATED_BUILD_DIR) + } +} + +tasks.named('clean') { + delete GENERATED_BUILD_DIR +} diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/ArtifactCodeGenerator.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/ArtifactCodeGenerator.kt index 11c611c..e10ae24 100644 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/ArtifactCodeGenerator.kt +++ b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/ArtifactCodeGenerator.kt @@ -2,21 +2,20 @@ package io.github.usefulness.licensee import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.LIST import com.squareup.kotlinpoet.MemberName -import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.withIndent -import io.github.usefulness.licensee.core.Artifact +import io.github.usefulness.licensee.serialization.Artifact -internal class ArtifactCodeGenerator( - private val packageName: String, - private val spdxLicensesTypeSpec: TypeSpec, - private val scmTypeSpec: TypeSpec, - private val unknownLicensesTypeSpec: TypeSpec, -) { +internal object ArtifactCodeGenerator { + + val entrypointType = coreClassName("Licensee") + val artifactListType = LIST.parameterizedBy(coreClassName("Artifact")) fun artifactCodeBlock(artifact: Artifact) = CodeBlock.builder() .withIndent { - addStatement("Artifact(") + addStatement("%T(", ARTIFACT_KCLASS_NAME) withIndent { addStatement("groupId = %S,", artifact.groupId) addStatement("artifactId = %S,", artifact.artifactId) @@ -29,7 +28,7 @@ internal class ArtifactCodeGenerator( addStatement("spdxLicenses = %M(", MemberName("kotlin.collections", "listOf")) withIndent { artifact.spdxLicenses.forEach { license -> - addStatement("%T(", ClassName(packageName, spdxLicensesTypeSpec.name!!)) + addStatement("%T(", SPDX_LICENSE_KCLASS_NAME) withIndent { addStatement("identifier = %S,", license.identifier) addStatement("name = %S,", license.name) @@ -44,7 +43,7 @@ internal class ArtifactCodeGenerator( if (artifact.scm == null) { addStatement("scm = null,") } else { - addStatement("scm = %T(url = %S),", ClassName(packageName, scmTypeSpec.name!!), artifact.scm.url) + addStatement("scm = %T(url = %S),", SCM_KCLASS_NAME, artifact.scm.url) } if (artifact.unknownLicenses.isNullOrEmpty()) { @@ -53,7 +52,7 @@ internal class ArtifactCodeGenerator( addStatement("unknownLicenses = %M(", MemberName("kotlin.collections", "listOf")) withIndent { artifact.unknownLicenses.forEach { license -> - addStatement("%T(", ClassName(packageName, unknownLicensesTypeSpec.name!!)) + addStatement("%T(", UNKNOWN_LICENSE_KCLASS_NAME) withIndent { addStatement("name = %S,", license.name) addStatement("url = %S,", license.url) @@ -67,4 +66,11 @@ internal class ArtifactCodeGenerator( addStatement("),") } .build() + + private fun coreClassName(name: String) = ClassName("io.github.usefulness.licensee", name) + + private val SPDX_LICENSE_KCLASS_NAME = coreClassName("SpdxLicense") + private val SCM_KCLASS_NAME = coreClassName("Scm") + private val UNKNOWN_LICENSE_KCLASS_NAME = coreClassName("UnknownLicense") + private val ARTIFACT_KCLASS_NAME = coreClassName("Artifact") } diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/CodeGenerationTask.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/CodeGenerationTask.kt index 1d5eb86..cb48637 100644 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/CodeGenerationTask.kt +++ b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/CodeGenerationTask.kt @@ -2,10 +2,11 @@ package io.github.usefulness.licensee import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.KModifier import com.squareup.kotlinpoet.MemberName import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.TypeSpec -import io.github.usefulness.licensee.core.Artifact +import io.github.usefulness.licensee.serialization.Artifact import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.okio.decodeFromBufferedSource @@ -39,42 +40,27 @@ public abstract class CodeGenerationTask : DefaultTask() { @TaskAction @ExperimentalSerializationApi public fun action() { - val packageName = packageName.get() - val licenseeTypesGenerator = LicenseeTypesGenerator(packageName) - - FileSpec.builder(packageName, "Artifact") - .addType(licenseeTypesGenerator.spdxLicensesTypeSpec) - .addType(licenseeTypesGenerator.scmTypeSpec) - .addType(licenseeTypesGenerator.unknownLicensesTypeSpec) - .addType(licenseeTypesGenerator.artifactTypeSpec) - .build().writeTo(outputDirectory.asFile.get()) - val artifacts = Json.decodeFromBufferedSource>(inputFile.asFile.get().source().buffer()) - val artifactCodeGenerator = ArtifactCodeGenerator( - packageName = packageName, - spdxLicensesTypeSpec = licenseeTypesGenerator.spdxLicensesTypeSpec, - scmTypeSpec = licenseeTypesGenerator.scmTypeSpec, - unknownLicensesTypeSpec = licenseeTypesGenerator.unknownLicensesTypeSpec, - ) - val artifactList = CodeBlock.builder().apply { addStatement("%M(", MemberName("kotlin.collections", "listOf")) artifacts.forEach { artifact -> - add(artifactCodeGenerator.artifactCodeBlock(artifact)) + add(ArtifactCodeGenerator.artifactCodeBlock(artifact)) } addStatement(")") }.build() - val grossType = TypeSpec.objectBuilder("Licensee") + val licenseeType = TypeSpec.objectBuilder("LicenseeForAndroid") + .addSuperinterface(ArtifactCodeGenerator.entrypointType) .addProperty( - PropertySpec.builder("artifacts", licenseeTypesGenerator.artifactListType) + PropertySpec.builder("artifacts", ArtifactCodeGenerator.artifactListType) + .addModifiers(KModifier.OVERRIDE) .initializer(artifactList).build(), ) .build() - FileSpec.builder(packageName, "Licensee") - .addType(grossType) + FileSpec.builder(packageName.get(), "LicenseeForAndroid") + .addType(licenseeType) .build().writeTo(outputDirectory.asFile.get()) } } diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidExtension.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidExtension.kt index dfb37d7..f62140b 100644 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidExtension.kt +++ b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidExtension.kt @@ -34,6 +34,12 @@ public open class LicenseeForAndroidExtension(objectFactory: ObjectFactory) { */ @Incubating public val singularVariantName: Property = objectFactory.property(default = null) + + /** + * Automatically add `licensee-for-android-core` core artifact as an implementation dependency for the generated code. + * The idea is to use the core artifact in a consumer project, and wire generated implementation via DI mechanism + */ + public val automaticCoreDependencyManagement: Property = objectFactory.property(default = true) } internal inline fun ObjectFactory.property(default: T? = null): Property = property(T::class.java).apply { diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidPlugin.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidPlugin.kt index d55772a..6517dfc 100644 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidPlugin.kt +++ b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeForAndroidPlugin.kt @@ -1,6 +1,7 @@ package io.github.usefulness.licensee import com.android.build.api.variant.AndroidComponentsExtension +import io.github.usefulness.licensee.generated.LicenseeForAndroidBuildConfig import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.reporting.ReportingExtension @@ -79,6 +80,10 @@ public class LicenseeForAndroidPlugin : Plugin { ) codeGenerationTask.configure { it.dependsOn(licenseeTaskName) } + + if (extension.automaticCoreDependencyManagement.get()) { + addCoreDependency() + } } } } @@ -124,6 +129,17 @@ public class LicenseeForAndroidPlugin : Plugin { } codeGenerationTask.configure { it.dependsOn(licenseeTaskName) } + + if (extension.automaticCoreDependencyManagement.get()) { + addCoreDependency() + } } } + + private fun Project.addCoreDependency() { + dependencies.add( + "implementation", + "io.github.usefulness:licensee-for-android-core:${LicenseeForAndroidBuildConfig.VERSION}", + ) + } } diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeTypesGenerator.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeTypesGenerator.kt deleted file mode 100644 index e43f38c..0000000 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/LicenseeTypesGenerator.kt +++ /dev/null @@ -1,132 +0,0 @@ -package io.github.usefulness.licensee - -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.LIST -import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeSpec -import com.squareup.kotlinpoet.asTypeName - -internal class LicenseeTypesGenerator(packageName: String) { - - val spdxLicensesTypeSpec: TypeSpec = - TypeSpec.classBuilder("SpdxLicenses") - .addModifiers(KModifier.DATA) - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("identifier", String::class) - .addParameter("name", String::class) - .addParameter("url", String::class) - .build(), - ).addProperty( - PropertySpec.builder("identifier", String::class) - .initializer("identifier") - .build(), - ) - .addProperty( - PropertySpec.builder("name", String::class) - .initializer("name") - .build(), - ) - .addProperty( - PropertySpec.builder("url", String::class) - .initializer("url") - .build(), - ) - .build() - - val scmTypeSpec = TypeSpec.classBuilder("Scm") - .addModifiers(KModifier.DATA) - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("url", String::class) - .build(), - ).addProperty( - PropertySpec.builder("url", String::class) - .initializer("url") - .build(), - ) - .build() - - val unknownLicensesTypeSpec = TypeSpec.classBuilder("UnknownLicenses") - .addModifiers(KModifier.DATA) - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("name", String::class) - .addParameter("url", String::class) - .build(), - ).addProperty( - PropertySpec.builder("name", String::class) - .initializer("name") - .build(), - ) - .addProperty( - PropertySpec.builder("url", String::class) - .initializer("url") - .build(), - ) - .build() - - private val spdxListType = - LIST.parameterizedBy(ClassName(packageName, spdxLicensesTypeSpec.name!!)) - - private val scmType = ClassName(packageName, scmTypeSpec.name!!).copy(nullable = true) - - private val unknownLicensesType = - LIST.parameterizedBy(ClassName(packageName, unknownLicensesTypeSpec.name!!)) - - val artifactTypeSpec = TypeSpec.classBuilder("Artifact") - .addModifiers(KModifier.DATA) - .primaryConstructor( - FunSpec.constructorBuilder() - .addParameter("groupId", String::class) - .addParameter("artifactId", String::class) - .addParameter("version", String::class) - .addParameter("name", String::class.asTypeName().copy(nullable = true)) - .addParameter("spdxLicenses", spdxListType) - .addParameter("scm", scmType) - .addParameter("unknownLicenses", unknownLicensesType) - .build(), - ).addProperty( - PropertySpec.builder("groupId", String::class) - .initializer("groupId") - .build(), - ).addProperty( - PropertySpec.builder("artifactId", String::class) - .initializer("artifactId") - .build(), - ).addProperty( - PropertySpec.builder("version", String::class) - .initializer("version") - .build(), - ).addProperty( - PropertySpec.builder( - "name", - String::class.asTypeName().copy(nullable = true), - ) - .initializer("name") - .build(), - ).addProperty( - PropertySpec.builder("spdxLicenses", spdxListType) - .initializer("spdxLicenses") - .build(), - ).addProperty( - PropertySpec.builder("scm", scmType.copy(nullable = true)) - .initializer("scm") - .build(), - ).addProperty( - PropertySpec.builder("unknownLicenses", unknownLicensesType) - .initializer("unknownLicenses") - .build(), - ) - .build() - - val artifactListType = LIST.parameterizedBy( - ClassName( - packageName, - artifactTypeSpec.name!!, - ), - ) -} diff --git a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt b/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt index a11cc2e..f79307b 100644 --- a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt +++ b/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt @@ -9,20 +9,9 @@ import org.junit.jupiter.api.Test class ArtifactGeneratorTest { - private val packageName = "io.github.usefulness.licensee" - - private val licenseeTypesGenerator = LicenseeTypesGenerator(packageName = packageName) - - private val artifactCodeGenerator = ArtifactCodeGenerator( - packageName = packageName, - licenseeTypesGenerator.unknownLicensesTypeSpec, - licenseeTypesGenerator.spdxLicensesTypeSpec, - licenseeTypesGenerator.scmTypeSpec, - ) - @Test fun `test all nullables are null`() { - val artifactCodeBlock = artifactCodeGenerator.artifactCodeBlock( + val artifactCodeBlock = ArtifactCodeGenerator.artifactCodeBlock( Artifact( groupId = "testGroup", artifactId = "testArtifact", @@ -36,7 +25,7 @@ class ArtifactGeneratorTest { // language val expected = """ - Artifact( + io.github.usefulness.licensee.Artifact( groupId = "testGroup", artifactId = "testArtifact", version = "testVersion", @@ -52,7 +41,7 @@ class ArtifactGeneratorTest { @Test fun `test all lists are empty`() { - val artifactCodeBlock = artifactCodeGenerator.artifactCodeBlock( + val artifactCodeBlock = ArtifactCodeGenerator.artifactCodeBlock( Artifact( groupId = "testGroup", artifactId = "testArtifact", @@ -64,13 +53,13 @@ class ArtifactGeneratorTest { ), ) val expected = """ - Artifact( + io.github.usefulness.licensee.Artifact( groupId = "testGroup", artifactId = "testArtifact", version = "testVersion", name = "testName", spdxLicenses = kotlin.collections.emptyList(), - scm = io.github.usefulness.licensee.SpdxLicenses(url = "testUrl"), + scm = io.github.usefulness.licensee.Scm(url = "testUrl"), unknownLicenses = kotlin.collections.emptyList(), ), @@ -80,7 +69,7 @@ class ArtifactGeneratorTest { @Test fun `test all lists have items`() { - val artifactCodeBlock = artifactCodeGenerator.artifactCodeBlock( + val artifactCodeBlock = ArtifactCodeGenerator.artifactCodeBlock( Artifact( groupId = "testGroup", artifactId = "testArtifact", @@ -98,30 +87,30 @@ class ArtifactGeneratorTest { ), ) val expected = """ - Artifact( + io.github.usefulness.licensee.Artifact( groupId = "testGroup", artifactId = "testArtifact", version = "testVersion", name = "testName", spdxLicenses = kotlin.collections.listOf( - io.github.usefulness.licensee.UnknownLicenses( + io.github.usefulness.licensee.SpdxLicense( identifier = "spdxId1", name = "spdxName1", url = "spdxUrl1", ), - io.github.usefulness.licensee.UnknownLicenses( + io.github.usefulness.licensee.SpdxLicense( identifier = "spdxId2", name = "spdxName2", url = "spdxUrl2", ), ), - scm = io.github.usefulness.licensee.SpdxLicenses(url = "testUrl"), + scm = io.github.usefulness.licensee.Scm(url = "testUrl"), unknownLicenses = kotlin.collections.listOf( - io.github.usefulness.licensee.Scm( + io.github.usefulness.licensee.UnknownLicense( name = "unknown1", url = "unknown1", ), - io.github.usefulness.licensee.Scm( + io.github.usefulness.licensee.UnknownLicense( name = "unknown2", url = "unknown2", ), diff --git a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/LicenseeTypesGeneratorTest.kt b/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/LicenseeTypesGeneratorTest.kt deleted file mode 100644 index f69b901..0000000 --- a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/LicenseeTypesGeneratorTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -package io.github.usefulness.licensee - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class LicenseeTypesGeneratorTest { - - private val packageName = "io.github.usefulness.licensee" - - @Test - fun testSpdxLicenses() { - val licenseeTypesGenerator = LicenseeTypesGenerator(packageName) - - val spdxDefinition = """public data class SpdxLicenses( - public val identifier: kotlin.String, - public val name: kotlin.String, - public val url: kotlin.String, -) -""" - - assertThat(licenseeTypesGenerator.spdxLicensesTypeSpec.toString()).isEqualTo(spdxDefinition) - } - - @Test - fun testScm() { - val licenseeTypesGenerator = LicenseeTypesGenerator(packageName) - - val spdxDefinition = """public data class Scm( - public val url: kotlin.String, -) -""" - - assertThat(licenseeTypesGenerator.scmTypeSpec.toString()).isEqualTo(spdxDefinition) - } - - @Test - fun testUnknownLicenses() { - val licenseeTypesGenerator = LicenseeTypesGenerator(packageName) - - val unknownLicensesDefinition = """public data class UnknownLicenses( - public val name: kotlin.String, - public val url: kotlin.String, -) -""" - - assertThat(licenseeTypesGenerator.unknownLicensesTypeSpec.toString()).isEqualTo(unknownLicensesDefinition) - } - - @Test - fun testArtifact() { - val licenseeTypesGenerator = LicenseeTypesGenerator(packageName) - - val artifactDefinition = """public data class Artifact( - public val groupId: kotlin.String, - public val artifactId: kotlin.String, - public val version: kotlin.String, - public val name: kotlin.String?, - public val spdxLicenses: kotlin.collections.List, - public val scm: io.github.usefulness.licensee.Scm?, - public val unknownLicenses: kotlin.collections.List, -) -""" - assertThat(licenseeTypesGenerator.artifactTypeSpec.toString()).isEqualTo(artifactDefinition) - } -} From 47b9d8b52ca7c26a7feedaba5c295aef95d079ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 13 Nov 2023 20:54:02 +0100 Subject: [PATCH 3/5] Update sample --- .../{core => serialization}/Artifact.kt | 2 +- .../licensee/ArtifactGeneratorTest.kt | 8 ++-- .../se/premex/gross/OssKotlinCodeView.kt | 32 +------------- .../licensee/PluginIntegrationTest.kt | 2 +- .../github/usefulness/licensee/TestUtils.kt | 2 +- sample/{core => serialization}/.gitignore | 0 sample/{core => serialization}/build.gradle | 0 .../licensee/serialization}/LicenseeParser.kt | 2 +- .../serialization/SerializationArtifact.kt} | 2 +- .../serialization}/PluginIntegrationTest.kt | 6 +-- .../serialization}/ResourcesLoader.kt | 2 +- sample/settings.gradle | 10 +++-- sample/ui/build.gradle | 3 +- sample/ui/config/baseline.xml | 2 +- .../se/premex/gross/ui/AssetLicenseeParser.kt | 42 +++++++++++++------ .../main/kotlin/se/premex/gross/ui/OssView.kt | 28 +++++++++---- .../kotlin/se/premex/gross/ui/OssViewModel.kt | 12 +----- .../licensee/LibraryIntegrationTest.kt | 6 +-- 18 files changed, 78 insertions(+), 83 deletions(-) rename licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/{core => serialization}/Artifact.kt (92%) rename sample/{core => serialization}/.gitignore (100%) rename sample/{core => serialization}/build.gradle (100%) rename sample/{core/src/main/kotlin/io/github/usefulness/licensee/core => serialization/src/main/kotlin/io/github/usefulness/licensee/serialization}/LicenseeParser.kt (87%) rename sample/{core/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt => serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/SerializationArtifact.kt} (91%) rename sample/{core/src/test/kotlin/io/github/usefulness/licensee/core => serialization/src/test/kotlin/io/github/usefulness/licensee/serialization}/PluginIntegrationTest.kt (79%) rename sample/{core/src/test/kotlin/io/github/usefulness/licensee/core => serialization/src/test/kotlin/io/github/usefulness/licensee/serialization}/ResourcesLoader.kt (89%) diff --git a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/serialization/Artifact.kt similarity index 92% rename from licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt rename to licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/serialization/Artifact.kt index e17bc8b..27f8f5b 100644 --- a/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt +++ b/licensee-for-android/src/main/kotlin/io/github/usefulness/licensee/serialization/Artifact.kt @@ -1,4 +1,4 @@ -package io.github.usefulness.licensee.core +package io.github.usefulness.licensee.serialization import kotlinx.serialization.Serializable diff --git a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt b/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt index f79307b..a52a7b3 100644 --- a/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt +++ b/licensee-for-android/src/test/kotlin/io/github/usefulness/licensee/ArtifactGeneratorTest.kt @@ -1,9 +1,9 @@ package io.github.usefulness.licensee -import io.github.usefulness.licensee.core.Artifact -import io.github.usefulness.licensee.core.Scm -import io.github.usefulness.licensee.core.SpdxLicenses -import io.github.usefulness.licensee.core.UnknownLicenses +import io.github.usefulness.licensee.serialization.Artifact +import io.github.usefulness.licensee.serialization.Scm +import io.github.usefulness.licensee.serialization.SpdxLicenses +import io.github.usefulness.licensee.serialization.UnknownLicenses import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test diff --git a/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt b/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt index f2b0f7f..bf61816 100644 --- a/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt +++ b/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt @@ -5,41 +5,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import io.githhub.usefulness.licensee.android.app.R -import io.github.usefulness.licensee.Licensee -import io.github.usefulness.licensee.core.Artifact -import io.github.usefulness.licensee.core.Scm -import io.github.usefulness.licensee.core.SpdxLicenses -import io.github.usefulness.licensee.core.UnknownLicenses +import io.github.usefulness.licensee.LicenseeForAndroid import se.premex.gross.ui.OssView @Composable fun ProgrammaticOssView() { Column { Text(text = stringResource(id = R.string.programmatic)) - OssView( - Licensee.artifacts.map { artifact -> - Artifact( - name = artifact.name, - groupId = artifact.groupId, - artifactId = artifact.artifactId, - version = artifact.version, - scm = if (artifact.scm?.url != null) { - Scm(artifact.scm.url) - } else { - null - }, - spdxLicenses = artifact.spdxLicenses.map { - SpdxLicenses( - identifier = it.identifier, - name = it.name, - url = it.url, - ) - }, - unknownLicenses = artifact.unknownLicenses.map { - UnknownLicenses(name = it.name, url = it.url) - }, - ) - }, - ) + OssView(LicenseeForAndroid.artifacts) } } diff --git a/sample/app/src/test/kotlin/io/github/usefulness/licensee/PluginIntegrationTest.kt b/sample/app/src/test/kotlin/io/github/usefulness/licensee/PluginIntegrationTest.kt index c1ce494..0adc141 100644 --- a/sample/app/src/test/kotlin/io/github/usefulness/licensee/PluginIntegrationTest.kt +++ b/sample/app/src/test/kotlin/io/github/usefulness/licensee/PluginIntegrationTest.kt @@ -14,7 +14,7 @@ class PluginIntegrationTest { @Test fun checkGeneratedCode() { checkLoadedArtifacts( - artifacts = Licensee.artifacts, + artifacts = LicenseeForAndroid.artifacts, isViewPager2Dependency = { groupId == "androidx.viewpager2" && artifactId == "viewpager2" }, ) } diff --git a/sample/app/src/test/kotlin/io/github/usefulness/licensee/TestUtils.kt b/sample/app/src/test/kotlin/io/github/usefulness/licensee/TestUtils.kt index 3736d08..f06b760 100644 --- a/sample/app/src/test/kotlin/io/github/usefulness/licensee/TestUtils.kt +++ b/sample/app/src/test/kotlin/io/github/usefulness/licensee/TestUtils.kt @@ -17,7 +17,7 @@ internal fun checkLoadedArtifacts(artifacts: List, isViewPager2Dependency version = "1.0.0", name = "AndroidX Widget ViewPager2", spdxLicenses = listOf( - SpdxLicenses( + SpdxLicense( identifier = "Apache-2.0", name = "Apache License 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0", diff --git a/sample/core/.gitignore b/sample/serialization/.gitignore similarity index 100% rename from sample/core/.gitignore rename to sample/serialization/.gitignore diff --git a/sample/core/build.gradle b/sample/serialization/build.gradle similarity index 100% rename from sample/core/build.gradle rename to sample/serialization/build.gradle diff --git a/sample/core/src/main/kotlin/io/github/usefulness/licensee/core/LicenseeParser.kt b/sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/LicenseeParser.kt similarity index 87% rename from sample/core/src/main/kotlin/io/github/usefulness/licensee/core/LicenseeParser.kt rename to sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/LicenseeParser.kt index 034584c..d6bb27b 100644 --- a/sample/core/src/main/kotlin/io/github/usefulness/licensee/core/LicenseeParser.kt +++ b/sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/LicenseeParser.kt @@ -1,4 +1,4 @@ -package io.github.usefulness.licensee.core +package io.github.usefulness.licensee.serialization import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json diff --git a/sample/core/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt b/sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/SerializationArtifact.kt similarity index 91% rename from sample/core/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt rename to sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/SerializationArtifact.kt index ca443d2..bfdcf76 100644 --- a/sample/core/src/main/kotlin/io/github/usefulness/licensee/core/Artifact.kt +++ b/sample/serialization/src/main/kotlin/io/github/usefulness/licensee/serialization/SerializationArtifact.kt @@ -1,4 +1,4 @@ -package io.github.usefulness.licensee.core +package io.github.usefulness.licensee.serialization import kotlinx.serialization.Serializable diff --git a/sample/core/src/test/kotlin/io/github/usefulness/licensee/core/PluginIntegrationTest.kt b/sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/PluginIntegrationTest.kt similarity index 79% rename from sample/core/src/test/kotlin/io/github/usefulness/licensee/core/PluginIntegrationTest.kt rename to sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/PluginIntegrationTest.kt index d1ba623..3811937 100644 --- a/sample/core/src/test/kotlin/io/github/usefulness/licensee/core/PluginIntegrationTest.kt +++ b/sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/PluginIntegrationTest.kt @@ -1,8 +1,8 @@ -package io.github.usefulness.licensee.core +package io.github.usefulness.licensee.serialization -import example.generated.from.kotlin.library.Licensee as LibraryLicensee +import example.generated.from.kotlin.library.LicenseeForAndroid as LibraryLicensee import org.junit.jupiter.api.Test -import example.generated.app_rules.from.kotlin.library.Licensee as AppLicensee +import example.generated.app_rules.from.kotlin.library.LicenseeForAndroid as AppLicensee import org.assertj.core.api.Assertions.assertThat class PluginIntegrationTest { diff --git a/sample/core/src/test/kotlin/io/github/usefulness/licensee/core/ResourcesLoader.kt b/sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/ResourcesLoader.kt similarity index 89% rename from sample/core/src/test/kotlin/io/github/usefulness/licensee/core/ResourcesLoader.kt rename to sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/ResourcesLoader.kt index 5c6bdc5..0f8e2ea 100644 --- a/sample/core/src/test/kotlin/io/github/usefulness/licensee/core/ResourcesLoader.kt +++ b/sample/serialization/src/test/kotlin/io/github/usefulness/licensee/serialization/ResourcesLoader.kt @@ -1,4 +1,4 @@ -package io.github.usefulness.licensee.core +package io.github.usefulness.licensee.serialization import java.io.ByteArrayOutputStream diff --git a/sample/settings.gradle b/sample/settings.gradle index e3f7d6b..c433d3b 100644 --- a/sample/settings.gradle +++ b/sample/settings.gradle @@ -1,7 +1,6 @@ import org.gradle.api.initialization.resolve.RepositoriesMode pluginManagement { - includeBuild("..") repositories { google { content { @@ -32,11 +31,16 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() - mavenCentral() + mavenCentral { + content { + excludeModule("io.github.usefulness", "lincensee-for-android-core") + } + } } } rootProject.name = "io.github.usefulness.sample" -include(":core") +includeBuild("..") +include(':serialization') include("app") include(":ui") diff --git a/sample/ui/build.gradle b/sample/ui/build.gradle index c0b57d7..5e6142c 100644 --- a/sample/ui/build.gradle +++ b/sample/ui/build.gradle @@ -38,7 +38,8 @@ tasks.withType(Test).configureEach { } dependencies { - api(project(":core")) + api("io.github.usefulness:licensee-for-android-core") + api(project(":serialization")) implementation(platform(libs.androidx.compose.bom)) implementation(libs.androidx.compose.runtime) implementation(libs.androidx.compose.ui) diff --git a/sample/ui/config/baseline.xml b/sample/ui/config/baseline.xml index 3869c16..feab6bf 100644 --- a/sample/ui/config/baseline.xml +++ b/sample/ui/config/baseline.xml @@ -9,8 +9,8 @@ FunctionNaming:LoadingView.kt$@Composable fun LoadingView(modifier: Modifier = Modifier, content: @Composable () -> Unit = {}) FunctionNaming:LoadingView.kt$@Preview @Composable private fun PreviewLoadingView() FunctionNaming:OssView.kt$@Composable fun CharacterHeader(initial: String, modifier: Modifier = Modifier) - FunctionNaming:OssView.kt$@Composable fun LicenseSelector(title: String, licenses: List<License>, close: () -> Unit) FunctionNaming:OssView.kt$@Composable fun OssView(artifacts: List<Artifact>, modifier: Modifier = Modifier) + FunctionNaming:OssView.kt$@Composable private fun LicenseSelector(title: String, licenses: List<ViewLicense>, close: () -> Unit) FunctionNaming:OssView.kt$@Preview(showSystemUi = true) @Composable private fun LicenseSelectorPreview() UnusedPrivateMember:ErrorView.kt$@Preview @Composable private fun ErrorViewPreview() UnusedPrivateMember:LoadingView.kt$@Preview @Composable private fun PreviewLoadingView() diff --git a/sample/ui/src/main/kotlin/se/premex/gross/ui/AssetLicenseeParser.kt b/sample/ui/src/main/kotlin/se/premex/gross/ui/AssetLicenseeParser.kt index 80c6bad..1d63422 100644 --- a/sample/ui/src/main/kotlin/se/premex/gross/ui/AssetLicenseeParser.kt +++ b/sample/ui/src/main/kotlin/se/premex/gross/ui/AssetLicenseeParser.kt @@ -1,10 +1,11 @@ package se.premex.gross.ui import android.content.res.AssetManager -import io.github.usefulness.licensee.core.Artifact -import io.github.usefulness.licensee.core.LicenseeParser -import io.github.usefulness.licensee.core.SpdxLicenses -import io.github.usefulness.licensee.core.UnknownLicenses +import io.github.usefulness.licensee.Artifact +import io.github.usefulness.licensee.Scm +import io.github.usefulness.licensee.SpdxLicense +import io.github.usefulness.licensee.UnknownLicense +import io.github.usefulness.licensee.serialization.LicenseeParser import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okio.buffer @@ -13,14 +14,29 @@ import okio.source class AssetLicenseeParser(private val assetManager: AssetManager) { suspend fun readFromAssets(): List = withContext(Dispatchers.IO) { val source = assetManager.open("licensee_artifacts.json").source().buffer() - LicenseeParser.decode(source) + val serialized = LicenseeParser.decode(source) + + serialized.map { artifact -> + Artifact( + groupId = artifact.groupId, + artifactId = artifact.artifactId, + version = artifact.version, + name = artifact.name, + spdxLicenses = artifact.spdxLicenses.map { license -> + SpdxLicense( + identifier = license.identifier, + name = license.name, + url = license.url, + ) + }, + scm = artifact.scm?.let { scm -> Scm(url = scm.url) }, + unknownLicenses = artifact.unknownLicenses.map { license -> + UnknownLicense( + name = license.name, + url = license.url, + ) + }, + ) + } } } - -internal fun List?.unknownToLicenses(): List = orEmpty().map { unknown -> unknown.asLicense() } - -internal fun UnknownLicenses.asLicense(): License = License(name, url) - -internal fun List?.spdxToLicenses(): List = orEmpty().map { spdx -> spdx.asLicense() } - -internal fun SpdxLicenses.asLicense() = License(title = name, url = url) diff --git a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt index f2fc4ca..561c50a 100644 --- a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt +++ b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt @@ -32,20 +32,23 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.githhub.usefulness.licensee.android.ui.R -import io.github.usefulness.licensee.core.Artifact +import io.github.usefulness.licensee.Artifact @Composable fun OssView(artifacts: List, modifier: Modifier = Modifier) { val viewData = artifacts.map { artifact -> - val licenses = - artifact.spdxLicenses.spdxToLicenses() + artifact.unknownLicenses.unknownToLicenses() + val spdxViewLicenses = artifact.spdxLicenses.map { ViewLicense(title = it.name, url = it.url) } + val unknown = artifact.unknownLicenses.map { ViewLicense(title = it.name, url = it.url) } val nameOrPackage = ("${artifact.name}\n(${artifact.groupId}:${artifact.artifactId}:${artifact.version})".trim()) - ViewArtifact(nameOrPackage, licenses) - }.sortedBy { it.title } + ViewArtifact( + title = nameOrPackage, + licenses = spdxViewLicenses + unknown, + ) + }.sortedBy { (nameOrPackage, _) -> nameOrPackage } - val licenses: SnapshotStateList = remember { mutableStateListOf() } + val licenses: SnapshotStateList = remember { mutableStateListOf() } var alertTitle by remember { mutableStateOf("") } LicenseSelector(alertTitle, licenses) { licenses.clear() @@ -93,6 +96,15 @@ fun OssView(artifacts: List, modifier: Modifier = Modifier) { } } +private data class ViewArtifact( + val title: String, + val licenses: List, +) +private data class ViewLicense( + val title: String, + val url: String, +) + @Composable fun CharacterHeader(initial: String, modifier: Modifier = Modifier) { Text( @@ -110,13 +122,13 @@ fun CharacterHeader(initial: String, modifier: Modifier = Modifier) { @Composable private fun LicenseSelectorPreview() { Column(Modifier.fillMaxSize()) { - LicenseSelector("Licenses", listOf(License("aaa", "http://google.se"))) { + LicenseSelector("Licenses", listOf(ViewLicense("aaa", "http://google.se"))) { } } } @Composable -fun LicenseSelector(title: String, licenses: List, close: () -> Unit) { +private fun LicenseSelector(title: String, licenses: List, close: () -> Unit) { val uriHandler = LocalUriHandler.current if (licenses.isNotEmpty()) { diff --git a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt index 4ade3f9..f73babd 100644 --- a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt +++ b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt @@ -1,6 +1,6 @@ package se.premex.gross.ui -import io.github.usefulness.licensee.core.Artifact +import io.github.usefulness.licensee.Artifact sealed class State { class Loading : State() @@ -9,13 +9,3 @@ sealed class State { } data class OssViewState(val viewState: State> = State.Loading()) - -data class ViewArtifact( - val title: String, - val licenses: List, -) - -data class License( - val title: String, - val url: String, -) diff --git a/sample/ui/src/test/kotlin/io/github/usefulness/licensee/LibraryIntegrationTest.kt b/sample/ui/src/test/kotlin/io/github/usefulness/licensee/LibraryIntegrationTest.kt index 7c90c56..88648af 100644 --- a/sample/ui/src/test/kotlin/io/github/usefulness/licensee/LibraryIntegrationTest.kt +++ b/sample/ui/src/test/kotlin/io/github/usefulness/licensee/LibraryIntegrationTest.kt @@ -2,8 +2,8 @@ package io.github.usefulness.licensee import android.content.Context import androidx.test.core.app.ApplicationProvider -import example.generated.from.android.library.Licensee -import io.github.usefulness.licensee.core.LicenseeParser +import example.generated.from.kotlin.library.LicenseeForAndroid +import io.github.usefulness.licensee.serialization.LicenseeParser import okio.buffer import okio.source import org.assertj.core.api.Assertions.assertThat @@ -16,7 +16,7 @@ class LibraryIntegrationTest { @Test fun checkGeneratedCode() { - assertThat(Licensee.artifacts).isNotEmpty() + assertThat(LicenseeForAndroid.artifacts).isNotEmpty() } @Test From 67ff407dae9d4d8b9cfc63bd96523f2a6ff259f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 13 Nov 2023 21:00:35 +0100 Subject: [PATCH 4/5] Update readme --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index a901467..100190b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ licenseeForAndroid { enableResourceGeneration = false resourceFileName = "licensee_artifacts.json" singularVariantName = null + automaticCoreDependencyManagement = true } ``` @@ -49,6 +50,7 @@ licenseeForAndroid { - `enableResourceGeneration` - Enables copying _licensee_ report to asset(Android)/resource(JVM) directory, making it available under 'resourceFileName' name. - `resourceFileName` - The name of the asset/resource file the licensee report gets copied to. - `singularVariantName` - The name of the build variant that all variants will use to have always the same licensed, regardless of app variant. (i.e. `"paidRelease"`) +- `automaticCoreDependencyManagement` - Automatically add `licensee-for-android-core` core artifact as an implementation dependency for the generated code. The idea is to use the core artifact in a consumer project, and wire generated implementation via DI mechanism ### Common recipes @@ -72,6 +74,7 @@ licenseeForAndroid { ``` #### Generate Kotlin code in Kotlin-only module using licensee output from a different module +###### Gradle based approach ```groovy plugins { id("org.jetbrains.kotlin.jvm") // or any other module type @@ -102,5 +105,32 @@ tasks.named("compileKotlin") { } ``` +###### DI based approach + +`app/build.gradle`: + +```groovy +plugins { + id("com.android.application") + id("app.cash.licensee") + id("io.github.usefulness.licensee-for-android") +} +licenseeForAndroid { + enableKotlinCodeGeneration = true +} +``` +\+ provide `LicenseeForAndroid` object as `Licensee` interface + +`consumer/build.gradle`: +```groovy +plugins { + id("org.jetbrains.kotlin.jvm") // or any other module type +} + +dependencies +``` +\+ inject `Licensee` interface + + ### Credits Huge thanks to [premex-ab/gross](https://github.com/premex-ab/gross) which this plugin forked from. From 5c3b1be5598652fff8c8f49be696b358b9842572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 13 Nov 2023 21:06:27 +0100 Subject: [PATCH 5/5] Bump starter to avoid running ktlint over generated code --- gradle/libs.versions.toml | 2 +- sample/build.gradle | 1 - sample/gradle/libs.versions.toml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 28331a2..2b98c01 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -gradle-starter = "0.65.0" +gradle-starter = "0.66.0" gradle-pluginpublish = "1.2.1" gradle-doctor = "0.9.0" google-agp = "8.1.3" diff --git a/sample/build.gradle b/sample/build.gradle index 203c44e..49954eb 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -3,7 +3,6 @@ plugins { alias(libs.plugins.starter.application.android) apply false alias(libs.plugins.starter.library.android) apply false alias(libs.plugins.starter.library.kotlin) apply false - id("io.github.usefulness.ktlint-gradle-plugin") version "0.7.0" apply(false) } commonConfig { diff --git a/sample/gradle/libs.versions.toml b/sample/gradle/libs.versions.toml index f61598f..8f9dbe5 100644 --- a/sample/gradle/libs.versions.toml +++ b/sample/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -gradle-starter = "0.65.0" +gradle-starter = "0.66.0" maven-kotlin-serialization = "1.6.0" maven-kotlin = "1.9.20" maven-junit = "5.10.1"