143 lines
4.8 KiB
Kotlin
143 lines
4.8 KiB
Kotlin
package dorkbox.license
|
|
|
|
import org.gradle.api.DefaultTask
|
|
import org.gradle.api.GradleException
|
|
import org.gradle.api.tasks.Input
|
|
import org.gradle.api.tasks.InputDirectory
|
|
import org.gradle.api.tasks.OutputDirectory
|
|
import org.gradle.api.tasks.TaskAction
|
|
import java.io.File
|
|
import java.io.FileOutputStream
|
|
import java.io.ObjectOutputStream
|
|
import javax.inject.Inject
|
|
|
|
|
|
|
|
internal open class LicenseInjector @Inject constructor(val extension: Licensing) : DefaultTask() {
|
|
// only want to build these files once
|
|
private var alreadyBuilt = false
|
|
|
|
companion object {
|
|
const val LICENSE_FILE = "LICENSE"
|
|
const val LICENSE_BLOB = "LICENSE.blob"
|
|
}
|
|
|
|
@Input lateinit var licenses: MutableList<LicenseData>
|
|
@OutputDirectory lateinit var outputDir: File
|
|
@InputDirectory lateinit var rootDir: File
|
|
|
|
init {
|
|
outputs.upToDateWhen {
|
|
alreadyBuilt || !(checkLicenseFiles(outputDir, licenses) && checkLicenseFiles(rootDir, licenses))
|
|
}
|
|
}
|
|
|
|
@TaskAction
|
|
fun doTask() {
|
|
if (alreadyBuilt) {
|
|
return
|
|
}
|
|
alreadyBuilt = true
|
|
|
|
// now we want to add license information that we know about from our dependencies to our list
|
|
// just to make it clear, license information CAN CHANGE BETWEEN VERSIONS! For example, JNA changed from GPL to Apache in version 4+
|
|
// we associate the artifact group + id + (start) version as a license.
|
|
// if a license for a dependency is UNKNOWN, then we emit a warning to the user to add it as a pull request
|
|
// if a license version is not specified, then we use the default
|
|
DependencyScanner(project, extension).scanForLicenseData()
|
|
|
|
// true if there was any work done
|
|
didWork = buildLicenseFiles(outputDir, licenses) && buildLicenseFiles(rootDir, licenses)
|
|
}
|
|
|
|
/**
|
|
* @return true when there is work that needs to be done
|
|
*/
|
|
private fun checkLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>): Boolean {
|
|
var needsToDoWork = false
|
|
if (!outputDir.exists()) outputDir.mkdirs()
|
|
|
|
val licenseText = LicenseData.buildString(licenses)
|
|
val licenseFile = File(outputDir, LICENSE_FILE)
|
|
|
|
if (fileIsNotSame(licenseFile, licenseText)) {
|
|
// write out the LICENSE and various license files
|
|
needsToDoWork = true
|
|
}
|
|
|
|
if (!needsToDoWork) {
|
|
licenses.forEach {
|
|
val license = it.license
|
|
val file = File(outputDir, license.licenseFile)
|
|
val sourceText = license.licenseText
|
|
|
|
if (fileIsNotSame(file, sourceText)) {
|
|
needsToDoWork = true
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return needsToDoWork
|
|
}
|
|
|
|
/**
|
|
* @return true when there is work that has be done
|
|
*/
|
|
private fun buildLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>): Boolean {
|
|
var hasDoneWork = false
|
|
|
|
if (!outputDir.exists()) outputDir.mkdirs()
|
|
|
|
val licenseText = LicenseData.buildString(licenses)
|
|
if (licenseText.isEmpty()) {
|
|
println("\tNo License information defined in the project. Unable to build license data")
|
|
} else {
|
|
val licenseFile = File(outputDir, LICENSE_FILE)
|
|
val licenseBlob = File(outputDir, LICENSE_BLOB)
|
|
|
|
if (fileIsNotSame(licenseFile, licenseText)) {
|
|
// write out the LICENSE files
|
|
licenseFile.writeText(licenseText)
|
|
|
|
// save off the blob, so we can check when reading dependencies if we can
|
|
// import this license info as extra license info for the project
|
|
ObjectOutputStream(FileOutputStream(licenseBlob)).use { oos ->
|
|
oos.writeInt(licenses.size)
|
|
|
|
licenses.forEach {
|
|
it.writeObject(oos)
|
|
}
|
|
}
|
|
|
|
hasDoneWork = true
|
|
}
|
|
|
|
licenses.forEach {
|
|
val license = it.license
|
|
val file = File(outputDir, license.licenseFile)
|
|
val sourceText = license.licenseText
|
|
|
|
if (fileIsNotSame(file, sourceText)) {
|
|
// write out the various license text files
|
|
file.writeText(sourceText)
|
|
|
|
hasDoneWork = true
|
|
}
|
|
}
|
|
}
|
|
|
|
return hasDoneWork
|
|
}
|
|
|
|
/**
|
|
* this is so we can check if we need to re-write the file. This is done to
|
|
* save write cycles on low-end drives where write frequency is an issue
|
|
*
|
|
* @return TRUE if the file IS NOT THE SAME, FALSE if the file IS THE SAME
|
|
*/
|
|
private fun fileIsNotSame(outputFile: File, sourceText: String): Boolean {
|
|
return !(outputFile.canRead() && sourceText.toByteArray() contentEquals outputFile.readBytes())
|
|
}
|
|
}
|