Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependencies {
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-android:3.9.0'
testImplementation 'org.mockito:mockito-core:3.9.0'
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
testImplementation "com.google.truth:truth:1.1.2"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.cookpad.android.plugin.license.extension

import com.cookpad.android.plugin.license.data.LibraryInfo

internal fun LibraryInfo.generateLibraryInfoText(): String {
val text = StringBuffer()
text.append("- artifact: ${artifactId.withWildcardVersion()}\n")
text.append(" name: ${name ?: "#NAME#"}\n")
text.append(" copyrightHolder: ${copyrightHolder ?: "#COPYRIGHT_HOLDER#"}\n")
text.append(" license: ${license ?: "#LICENSE#"}\n")
if (licenseUrl?.isNotBlank() == true) {
text.append(" licenseUrl: ${licenseUrl}\n")
}
if (url?.isNotBlank() == true) {
text.append(" url: ${url}\n")
}
return text.toString().trim()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ import com.cookpad.android.plugin.license.data.ArtifactId
import com.cookpad.android.plugin.license.data.LibraryInfo
import com.cookpad.android.plugin.license.data.LibraryPom
import com.cookpad.android.plugin.license.extension.duplicatedArtifacts
import com.cookpad.android.plugin.license.extension.generateLibraryInfoText
import com.cookpad.android.plugin.license.extension.licensesUnMatched
import com.cookpad.android.plugin.license.extension.notListedIn
import com.cookpad.android.plugin.license.extension.resolvedArtifacts
import com.cookpad.android.plugin.license.extension.toFormattedText
import com.cookpad.android.plugin.license.util.YamlUtils
import java.io.File
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesting
import org.simpleframework.xml.Serializer
import org.simpleframework.xml.core.Persister
import java.io.File

object CheckLicenses {
fun register(project: Project): Task {
Expand Down Expand Up @@ -62,10 +63,7 @@ object CheckLicenses {
.distinctBy { it.artifactId.withWildcardVersion() }
.sortedBy { it.artifactId.withWildcardVersion() }
.forEach { libraryInfo ->
val text =
generateLibraryInfoText(
libraryInfo
)
val text = libraryInfo.generateLibraryInfoText()
project.logger.warn(text)
}
}
Expand Down Expand Up @@ -101,22 +99,6 @@ object CheckLicenses {
}
}

@VisibleForTesting
fun generateLibraryInfoText(libraryInfo: LibraryInfo): String {
val text = StringBuffer()
text.append("- artifact: ${libraryInfo.artifactId.withWildcardVersion()}\n")
text.append(" name: ${libraryInfo.name ?: "#NAME#"}\n")
text.append(" copyrightHolder: ${libraryInfo.copyrightHolder ?: "#COPYRIGHT_HOLDER#"}\n")
text.append(" license: ${libraryInfo.license ?: "#LICENSE#"}\n")
if (libraryInfo.licenseUrl?.isNotBlank() == true) {
text.append(" licenseUrl: ${libraryInfo.licenseUrl}\n")
}
if (libraryInfo.url?.isNotBlank() == true) {
text.append(" url: ${libraryInfo.url}\n")
}
return text.toString().trim()
}

@VisibleForTesting
fun loadDependencyLicenses(
project: Project,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@ package com.cookpad.android.plugin.license.task

import com.cookpad.android.plugin.license.LicenseToolsPluginExtension
import com.cookpad.android.plugin.license.data.LibraryInfo
import com.cookpad.android.plugin.license.extension.notListedIn
import com.cookpad.android.plugin.license.extension.writeLicenseYaml
import com.cookpad.android.plugin.license.util.YamlUtils
import com.cookpad.android.plugin.license.extension.generateLibraryInfoText
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesting
import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml
import java.nio.charset.Charset

object UpdateLicenses {
fun register(project: Project): Task {
Expand All @@ -23,30 +18,28 @@ object UpdateLicenses {
CheckLicenses.resolveProjectDependencies(project, ext.ignoredProjects)
val dependencyLicenses =
CheckLicenses.loadDependencyLicenses(project, resolvedArtifacts, ext.ignoredGroups)
val librariesYaml = YamlUtils.loadToLibraryInfo(project.file(ext.licensesYaml))
val notDocumented = dependencyLicenses.notListedIn(librariesYaml)

notDocumented.forEach {
val text = generateLibraryInfoText(it)
project.file(ext.licensesYaml).appendText("${text}\n")
}
updateLicensesYaml(project, ext.licensesYaml, dependencyLicenses)
}
}

@VisibleForTesting
fun generateLibraryInfoText(libraryInfo: LibraryInfo): String {
val text = StringBuffer()
text.append("- artifact: ${libraryInfo.artifactId.withWildcardVersion()}\n")
text.append(" name: ${libraryInfo.name ?: "#NAME#"}\n")
text.append(" copyrightHolder: ${libraryInfo.copyrightHolder ?: "#COPYRIGHT_HOLDER#"}\n")
text.append(" license: ${libraryInfo.license ?: "#LICENSE#"}\n")
if (libraryInfo.licenseUrl?.isNotBlank() == true) {
text.append(" licenseUrl: ${libraryInfo.licenseUrl}\n")
}
if (libraryInfo.url?.isNotBlank() == true) {
text.append(" url: ${libraryInfo.url}\n")
internal fun updateLicensesYaml(
project: Project,
licensesYaml: String,
dependencyLicenses: List<LibraryInfo>
) {
// Dedup and sort dependencies
val sortedDependencies = dependencyLicenses.associateBy { it.artifactId.withWildcardVersion() }
.toSortedMap { o1, o2 ->
o1.compareTo(o2, ignoreCase = true)
}.values

project.file(licensesYaml).apply {
// Clean content
writeText("")
for (libraryInfo in sortedDependencies) {
appendText("${libraryInfo.generateLibraryInfoText()}\n")
}
}
return text.toString().trim()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.cookpad.android.plugin.license.task

import com.cookpad.android.plugin.license.loadYamlFromResources
import com.cookpad.android.plugin.license.util.YamlUtils
import com.google.common.truth.Truth.assertThat
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.whenever
import org.gradle.api.Project
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import java.io.File

@RunWith(MockitoJUnitRunner::class)
class UpdateLicensesTest {

@get:Rule
val tempFolder = TemporaryFolder()
private lateinit var licensesYamlFile: File

@Mock
lateinit var project: Project

@Before
fun setUp() {
licensesYamlFile = tempFolder.newFile()
whenever(project.file(FILENAME_LICENSES_YAML)) doReturn licensesYamlFile
}

@After
fun tearDown() {
licensesYamlFile.delete()
}

@Test
fun updateLicensesYaml_duplicatedDependencies_dedupsAndSortsDependencies() {
val licenses = loadYamlFromResources("yaml/duplicated_unsorted_licenses.yml")
assertThat(licenses.size).isEqualTo(4)
UpdateLicenses.updateLicensesYaml(project, FILENAME_LICENSES_YAML, licenses)

val result = YamlUtils.loadToLibraryInfo(licensesYamlFile)

val expected = loadYamlFromResources("yaml/dedup_sorted_licenses.yml")
assertThat(result.size).isEqualTo(expected.size)
for ((index, info) in result.withIndex()) {
assertThat(info).isEqualTo(expected[index])
}
}

companion object {
private const val FILENAME_LICENSES_YAML = "licenses.yml"
}
}
17 changes: 17 additions & 0 deletions plugin/src/test/resources/yaml/dedup_sorted_licenses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
- artifact: com.google.android.play:core:+
name: core
copyrightHolder: Google Inc.
license: Play Core Software Development Kit Terms of Service
licenseUrl: https://developer.android.com/guide/playcore/license
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-android:+
name: kotlinx-coroutines-android
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-core-common:+
name: kotlinx-coroutines-core-common
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines
24 changes: 24 additions & 0 deletions plugin/src/test/resources/yaml/duplicated_unsorted_licenses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-android:+
name: kotlinx-coroutines-android
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines
- artifact: com.google.android.play:core:+
name: core
copyrightHolder: Google Inc.
license: Play Core Software Development Kit Terms of Service
licenseUrl: https://developer.android.com/guide/playcore/license
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-core-common:+
name: kotlinx-coroutines-core-common
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines
# Duplicated artifact id
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-core-common:+
name: kotlinx-coroutines-core-common
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines