Fixed issues with copyright (Now following USC 17.4)
This commit is contained in:
parent
116ee8d1ea
commit
439016cb6b
23
LICENSE
23
LICENSE
|
@ -1,4 +1,25 @@
|
||||||
- Licensing - License definitions and legal management plugin for the Gradle build system
|
- Licensing - License definitions and legal management plugin for the Gradle build system
|
||||||
|
[The Apache Software License, Version 2.0]
|
||||||
https://git.dorkbox.com/dorkbox/Licensing
|
https://git.dorkbox.com/dorkbox/Licensing
|
||||||
Copyright 2020 - The Apache Software License, Version 2.0
|
Copyright 2020
|
||||||
Dorkbox LLC
|
Dorkbox LLC
|
||||||
|
|
||||||
|
Extra license information
|
||||||
|
- Kotlin -
|
||||||
|
[The Apache Software License, Version 2.0]
|
||||||
|
https://github.com/JetBrains/kotlin
|
||||||
|
Copyright 2020
|
||||||
|
JetBrains s.r.o. and Kotlin Programming Language contributors
|
||||||
|
Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply
|
||||||
|
See: https://github.com/JetBrains/kotlin/blob/master/license/README.md
|
||||||
|
|
||||||
|
- Version - Java Semantic Versioning with exceptions. Minor/Patch number optional and build-after-final-dot (minor/patch) permitted.
|
||||||
|
[MIT License]
|
||||||
|
https://git.dorkbox.com/dorkbox/Version
|
||||||
|
Copyright 2020
|
||||||
|
Dorkbox LLC
|
||||||
|
G. Richard Bellamy
|
||||||
|
Kenduck
|
||||||
|
Larry Bordowitz <lbordowitz@yahoo-inc.com>
|
||||||
|
Martin Rüegg <martin.rueegg@bristolpound.org> <martin.rueegg@metaworx.ch>
|
||||||
|
Zafar Khaja <zafarkhaja@gmail.com>
|
||||||
|
|
21
LICENSE.MIT
Normal file
21
LICENSE.MIT
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -16,13 +16,18 @@
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show the stacktrace!
|
||||||
|
gradle.startParameter.warningMode = WarningMode.All
|
||||||
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
`java-gradle-plugin`
|
`java-gradle-plugin`
|
||||||
|
|
||||||
id("com.gradle.plugin-publish") version "0.12.0"
|
id("com.gradle.plugin-publish") version "0.12.0"
|
||||||
|
|
||||||
id("com.dorkbox.VersionUpdate") version "1.7"
|
id("com.dorkbox.Licensing") version "2.1"
|
||||||
|
id("com.dorkbox.VersionUpdate") version "1.8"
|
||||||
id("com.dorkbox.GradleUtils") version "1.8"
|
id("com.dorkbox.GradleUtils") version "1.8"
|
||||||
|
|
||||||
kotlin("jvm") version "1.3.72"
|
kotlin("jvm") version "1.3.72"
|
||||||
|
@ -33,7 +38,7 @@ object Extras {
|
||||||
// set for the project
|
// set for the project
|
||||||
const val description = "License definitions and legal management plugin for the Gradle build system"
|
const val description = "License definitions and legal management plugin for the Gradle build system"
|
||||||
const val group = "com.dorkbox"
|
const val group = "com.dorkbox"
|
||||||
const val version = "2.0"
|
const val version = "2.1"
|
||||||
|
|
||||||
// set as project.ext
|
// set as project.ext
|
||||||
const val name = "Gradle Licensing Plugin"
|
const val name = "Gradle Licensing Plugin"
|
||||||
|
@ -53,6 +58,15 @@ object Extras {
|
||||||
GradleUtils.load("$projectDir/../../gradle.properties", Extras)
|
GradleUtils.load("$projectDir/../../gradle.properties", Extras)
|
||||||
GradleUtils.fixIntellijPaths()
|
GradleUtils.fixIntellijPaths()
|
||||||
|
|
||||||
|
|
||||||
|
licensing {
|
||||||
|
license(License.APACHE_2) {
|
||||||
|
description(Extras.description)
|
||||||
|
author(Extras.vendor)
|
||||||
|
url(Extras.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
java {
|
java {
|
||||||
|
@ -83,7 +97,7 @@ dependencies {
|
||||||
// the kotlin version is taken from the plugin, so it is not necessary to set it here
|
// the kotlin version is taken from the plugin, so it is not necessary to set it here
|
||||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
||||||
|
|
||||||
implementation("com.dorkbox:Version:1.2")
|
implementation("com.dorkbox:Version:2.4")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|
|
@ -43,7 +43,6 @@ object AppLicensing {
|
||||||
private val map = listOf(
|
private val map = listOf(
|
||||||
LicenseChain("org.jetbrains.kotlin",
|
LicenseChain("org.jetbrains.kotlin",
|
||||||
LicenseData("Kotlin", License.APACHE_2).apply {
|
LicenseData("Kotlin", License.APACHE_2).apply {
|
||||||
copyright(2000)
|
|
||||||
author("JetBrains s.r.o. and Kotlin Programming Language contributors")
|
author("JetBrains s.r.o. and Kotlin Programming Language contributors")
|
||||||
url("https://github.com/JetBrains/kotlin")
|
url("https://github.com/JetBrains/kotlin")
|
||||||
note("Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply")
|
note("Kotlin Compiler, Test Data+Libraries, and Tools repository contain third-party code, to which different licenses may apply")
|
||||||
|
@ -54,7 +53,6 @@ object AppLicensing {
|
||||||
LicenseData("Java Annotations", License.APACHE_2).apply {
|
LicenseData("Java Annotations", License.APACHE_2).apply {
|
||||||
description("Annotations for JVM-based languages")
|
description("Annotations for JVM-based languages")
|
||||||
url("https://github.com/JetBrains/java-annotations")
|
url("https://github.com/JetBrains/java-annotations")
|
||||||
copyright(2000)
|
|
||||||
author("JetBrains s.r.o.")
|
author("JetBrains s.r.o.")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -62,7 +60,6 @@ object AppLicensing {
|
||||||
LicenseData("kotlinx.coroutines", License.APACHE_2).apply {
|
LicenseData("kotlinx.coroutines", License.APACHE_2).apply {
|
||||||
description("Library support for Kotlin coroutines with multiplatform support")
|
description("Library support for Kotlin coroutines with multiplatform support")
|
||||||
url("https://github.com/Kotlin/kotlinx.coroutines")
|
url("https://github.com/Kotlin/kotlinx.coroutines")
|
||||||
copyright(2000)
|
|
||||||
author("JetBrains s.r.o.")
|
author("JetBrains s.r.o.")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -70,7 +67,6 @@ object AppLicensing {
|
||||||
LicenseData("kotlin-logging", License.APACHE_2).apply {
|
LicenseData("kotlin-logging", License.APACHE_2).apply {
|
||||||
description("Lightweight logging framework for Kotlin")
|
description("Lightweight logging framework for Kotlin")
|
||||||
url("https://github.com/MicroUtils/kotlin-logging")
|
url("https://github.com/MicroUtils/kotlin-logging")
|
||||||
copyright(2016)
|
|
||||||
author("Ohad Shai")
|
author("Ohad Shai")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -78,7 +74,6 @@ object AppLicensing {
|
||||||
LicenseData("SLF4J", License.MIT).apply {
|
LicenseData("SLF4J", License.MIT).apply {
|
||||||
description("Simple facade or abstraction for various logging frameworks")
|
description("Simple facade or abstraction for various logging frameworks")
|
||||||
url("http://www.slf4j.org")
|
url("http://www.slf4j.org")
|
||||||
copyright(2004)
|
|
||||||
author("QOS.ch")
|
author("QOS.ch")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -86,7 +81,6 @@ object AppLicensing {
|
||||||
LicenseData("JNA", License.LGPLv2_1).apply {
|
LicenseData("JNA", License.LGPLv2_1).apply {
|
||||||
description("Simplified native library access for Java.")
|
description("Simplified native library access for Java.")
|
||||||
url("https://github.com/twall/jna")
|
url("https://github.com/twall/jna")
|
||||||
copyright(2004)
|
|
||||||
author("Timothy Wall")
|
author("Timothy Wall")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -94,7 +88,6 @@ object AppLicensing {
|
||||||
LicenseData("JNA", License.APACHE_2).apply {
|
LicenseData("JNA", License.APACHE_2).apply {
|
||||||
description("Simplified native library access for Java.")
|
description("Simplified native library access for Java.")
|
||||||
url("https://github.com/twall/jna")
|
url("https://github.com/twall/jna")
|
||||||
copyright(2013)
|
|
||||||
author("Timothy Wall")
|
author("Timothy Wall")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -103,7 +96,6 @@ object AppLicensing {
|
||||||
LicenseData("JNA-Platform", License.LGPLv2_1).apply {
|
LicenseData("JNA-Platform", License.LGPLv2_1).apply {
|
||||||
description("Mappings for a number of commonly used platform functions")
|
description("Mappings for a number of commonly used platform functions")
|
||||||
url("https://github.com/twall/jna")
|
url("https://github.com/twall/jna")
|
||||||
copyright(2013)
|
|
||||||
author("Timothy Wall")
|
author("Timothy Wall")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -111,7 +103,6 @@ object AppLicensing {
|
||||||
LicenseData("JNA-Platform", License.APACHE_2).apply {
|
LicenseData("JNA-Platform", License.APACHE_2).apply {
|
||||||
description("Mappings for a number of commonly used platform functions")
|
description("Mappings for a number of commonly used platform functions")
|
||||||
url("https://github.com/twall/jna")
|
url("https://github.com/twall/jna")
|
||||||
copyright(2013)
|
|
||||||
author("Timothy Wall")
|
author("Timothy Wall")
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -120,29 +111,24 @@ object AppLicensing {
|
||||||
LicenseData("SSHJ", License.APACHE_2).apply {
|
LicenseData("SSHJ", License.APACHE_2).apply {
|
||||||
description("SSHv2 library for Java")
|
description("SSHv2 library for Java")
|
||||||
url("https://github.com/hierynomus/sshj")
|
url("https://github.com/hierynomus/sshj")
|
||||||
copyright(2009)
|
|
||||||
author("Jeroen van Erp")
|
author("Jeroen van Erp")
|
||||||
author("SSHJ Contributors")
|
author("SSHJ Contributors")
|
||||||
|
|
||||||
extra("Apache MINA", License.APACHE_2) {
|
extra("Apache MINA", License.APACHE_2) {
|
||||||
it.url("https://mina.apache.org/sshd-project/")
|
it.url("https://mina.apache.org/sshd-project/")
|
||||||
it.copyright(2003).to(2017)
|
|
||||||
it.author("The Apache Software Foundation")
|
it.author("The Apache Software Foundation")
|
||||||
}
|
}
|
||||||
extra("Apache Commons-Net", License.APACHE_2) {
|
extra("Apache Commons-Net", License.APACHE_2) {
|
||||||
it.url("https://commons.apache.org/proper/commons-net/")
|
it.url("https://commons.apache.org/proper/commons-net/")
|
||||||
it.copyright(2001).to(2017)
|
|
||||||
it.author("The Apache Software Foundation")
|
it.author("The Apache Software Foundation")
|
||||||
}
|
}
|
||||||
extra("JZlib", License.APACHE_2) {
|
extra("JZlib", License.APACHE_2) {
|
||||||
it.url("http://www.jcraft.com/jzlib")
|
it.url("http://www.jcraft.com/jzlib")
|
||||||
it.copyright(2002).to(2008)
|
|
||||||
it.author("Atsuhiko Yamanaka")
|
it.author("Atsuhiko Yamanaka")
|
||||||
it.author("JCraft, Inc.")
|
it.author("JCraft, Inc.")
|
||||||
}
|
}
|
||||||
extra("Bouncy Castle Crypto", License.APACHE_2) {
|
extra("Bouncy Castle Crypto", License.APACHE_2) {
|
||||||
it.url("http://www.bouncycastle.org")
|
it.url("http://www.bouncycastle.org")
|
||||||
it.copyright(2000).to(2006)
|
|
||||||
it.author("The Legion of the Bouncy Castle Inc")
|
it.author("The Legion of the Bouncy Castle Inc")
|
||||||
}
|
}
|
||||||
extra("ed25519-java", License.CC0) {
|
extra("ed25519-java", License.CC0) {
|
||||||
|
@ -155,7 +141,6 @@ object AppLicensing {
|
||||||
LicenseChain("org.bouncycastle",
|
LicenseChain("org.bouncycastle",
|
||||||
LicenseData("Bouncy Castle Crypto", License.APACHE_2).apply {
|
LicenseData("Bouncy Castle Crypto", License.APACHE_2).apply {
|
||||||
description("Lightweight cryptography API and JCE Extension")
|
description("Lightweight cryptography API and JCE Extension")
|
||||||
copyright(2000)
|
|
||||||
author("The Legion of the Bouncy Castle Inc")
|
author("The Legion of the Bouncy Castle Inc")
|
||||||
url("http://www.bouncycastle.org")
|
url("http://www.bouncycastle.org")
|
||||||
}
|
}
|
||||||
|
@ -164,7 +149,6 @@ object AppLicensing {
|
||||||
LicenseChain("com.fasterxml.uuid:java-uuid-generator",
|
LicenseChain("com.fasterxml.uuid:java-uuid-generator",
|
||||||
LicenseData("Java Uuid Generator", License.APACHE_2).apply {
|
LicenseData("Java Uuid Generator", License.APACHE_2).apply {
|
||||||
description("A set of Java classes for working with UUIDs")
|
description("A set of Java classes for working with UUIDs")
|
||||||
copyright(2002)
|
|
||||||
author("Tatu Saloranta (tatu.saloranta@iki.fi)")
|
author("Tatu Saloranta (tatu.saloranta@iki.fi)")
|
||||||
author("Contributors. See source release-notes/CREDITS")
|
author("Contributors. See source release-notes/CREDITS")
|
||||||
url("https://github.com/cowtowncoder/java-uuid-generator")
|
url("https://github.com/cowtowncoder/java-uuid-generator")
|
||||||
|
@ -181,7 +165,6 @@ object AppLicensing {
|
||||||
LicenseChain("io.netty",
|
LicenseChain("io.netty",
|
||||||
LicenseData("Netty", License.APACHE_2).apply {
|
LicenseData("Netty", License.APACHE_2).apply {
|
||||||
description("An event-driven asynchronous network application framework")
|
description("An event-driven asynchronous network application framework")
|
||||||
copyright(2014)
|
|
||||||
author("The Netty Project")
|
author("The Netty Project")
|
||||||
author("Contributors. See source NOTICE")
|
author("Contributors. See source NOTICE")
|
||||||
url("https://netty.io")
|
url("https://netty.io")
|
||||||
|
@ -190,7 +173,6 @@ object AppLicensing {
|
||||||
LicenseChain("org.lwjgl:lwjgl-xxhash",
|
LicenseChain("org.lwjgl:lwjgl-xxhash",
|
||||||
LicenseData("Lightweight Java Game Library", License.BSD_3).apply {
|
LicenseData("Lightweight Java Game Library", License.BSD_3).apply {
|
||||||
description("Java library that enables cross-platform access to popular native APIs")
|
description("Java library that enables cross-platform access to popular native APIs")
|
||||||
copyright(2012)
|
|
||||||
author("Lightweight Java Game Library")
|
author("Lightweight Java Game Library")
|
||||||
url("https://github.com/LWJGL/lwjgl3")
|
url("https://github.com/LWJGL/lwjgl3")
|
||||||
}
|
}
|
||||||
|
@ -199,7 +181,6 @@ object AppLicensing {
|
||||||
LicenseChain("com.github.ben-manes:gradle-versions-plugin",
|
LicenseChain("com.github.ben-manes:gradle-versions-plugin",
|
||||||
LicenseData("Gradle Versions Plugin", License.APACHE_2).apply {
|
LicenseData("Gradle Versions Plugin", License.APACHE_2).apply {
|
||||||
description("This plugin provides a task to determine which dependencies have updates")
|
description("This plugin provides a task to determine which dependencies have updates")
|
||||||
copyright(2012)
|
|
||||||
author("Ben Manes")
|
author("Ben Manes")
|
||||||
url("https://github.com/ben-manes/gradle-versions-plugin")
|
url("https://github.com/ben-manes/gradle-versions-plugin")
|
||||||
}
|
}
|
||||||
|
@ -208,7 +189,6 @@ object AppLicensing {
|
||||||
LicenseChain("org.json:json",
|
LicenseChain("org.json:json",
|
||||||
LicenseData("JSON in Java", License.JSON).apply {
|
LicenseData("JSON in Java", License.JSON).apply {
|
||||||
description("A light-weight language independent data interchange format.")
|
description("A light-weight language independent data interchange format.")
|
||||||
copyright(2002)
|
|
||||||
author("JSON.org")
|
author("JSON.org")
|
||||||
url("https://github.com/stleary/JSON-java")
|
url("https://github.com/stleary/JSON-java")
|
||||||
url("https://www.json.org/json-en.html")
|
url("https://www.json.org/json-en.html")
|
||||||
|
@ -218,7 +198,6 @@ object AppLicensing {
|
||||||
LicenseChain("net.jodah:typetools",
|
LicenseChain("net.jodah:typetools",
|
||||||
LicenseData("TypeTools", License.APACHE_2).apply {
|
LicenseData("TypeTools", License.APACHE_2).apply {
|
||||||
description("A simple, zero-dependency library for working with types. Supports Java 1.6+ and Android.")
|
description("A simple, zero-dependency library for working with types. Supports Java 1.6+ and Android.")
|
||||||
copyright(2010)
|
|
||||||
author("Jonathan Halterman and friends")
|
author("Jonathan Halterman and friends")
|
||||||
url("https://github.com/jhalterman/typetools")
|
url("https://github.com/jhalterman/typetools")
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,17 +40,16 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val missingLicenseInfo = mutableListOf<Dependency>()
|
val missingLicenseInfo = mutableSetOf<Dependency>()
|
||||||
val actuallyMissingLicenseInfo = mutableListOf<Dependency>()
|
val actuallyMissingLicenseInfo = mutableSetOf<Dependency>()
|
||||||
|
|
||||||
if (extension.licenses.isNotEmpty()) {
|
if (extension.licenses.isNotEmpty()) {
|
||||||
// when we scan, we ONLY want to scan a SINGLE LAYER (if we have license info for module ID, then we don't need license info for it's children)
|
// when we scan, we ONLY want to scan a SINGLE LAYER (if we have license info for module ID, then we don't need license info for it's children)
|
||||||
println("\tLicense Detection")
|
println("\t\tScanning for preloaded license data...")
|
||||||
print("\t\tScanning for preloaded license data...")
|
|
||||||
|
|
||||||
val primaryLicense = extension.licenses.first()
|
val primaryLicense = extension.licenses.first()
|
||||||
var found = false
|
|
||||||
|
|
||||||
|
// scan to see if we have in our predefined section
|
||||||
projectDependencies.forEach { info: Dependency ->
|
projectDependencies.forEach { info: Dependency ->
|
||||||
val license: LicenseData? = try {
|
val license: LicenseData? = try {
|
||||||
AppLicensing.getLicense(info.mavenId())
|
AppLicensing.getLicense(info.mavenId())
|
||||||
|
@ -64,6 +63,8 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
missingLicenseInfo.add(info)
|
missingLicenseInfo.add(info)
|
||||||
} else {
|
} else {
|
||||||
if (!primaryLicense.extras.contains(license)) {
|
if (!primaryLicense.extras.contains(license)) {
|
||||||
|
println("\t\t\t${info.mavenId()}")
|
||||||
|
|
||||||
// get the OLDEST date from the artifacts and use that as the copyright date
|
// get the OLDEST date from the artifacts and use that as the copyright date
|
||||||
var oldestDate = 0L
|
var oldestDate = 0L
|
||||||
info.artifacts.forEach { artifact ->
|
info.artifacts.forEach { artifact ->
|
||||||
|
@ -77,35 +78,22 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
oldestDate = Instant.now().toEpochMilli()
|
oldestDate = Instant.now().toEpochMilli()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// as per US Code Title 17, Chapter 4; for "visually perceptive copies" (which includes software).
|
||||||
|
// http://www.copyright.gov/title17/92chap4.html
|
||||||
|
// it is ONLY... © year name
|
||||||
val year = Date(oldestDate).toInstant().atZone(ZoneId.systemDefault()).toLocalDate().year
|
val year = Date(oldestDate).toInstant().atZone(ZoneId.systemDefault()).toLocalDate().year
|
||||||
if (license.copyrights.size == 1) {
|
license.copyright = year
|
||||||
if (year > license.copyrights.first()) {
|
|
||||||
// only do this if we have copyright greater than our specified (it can be the SAME, so don't want to do this!)
|
|
||||||
try {
|
|
||||||
CopyrightRange(license, license.copyrights.first(), license.copyrights).to(year)
|
|
||||||
} catch (e: GradleException) {
|
|
||||||
throw GradleException("Error assigning internal copyright for ${info.mavenId()}", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
license.copyright(year)
|
|
||||||
}
|
|
||||||
|
|
||||||
primaryLicense.extras.add(license)
|
primaryLicense.extras.add(license)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
|
||||||
found = false
|
|
||||||
println(" found")
|
|
||||||
} else {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
print("\t\tScanning for embedded license data...")
|
println("\t\tScanning for embedded license data...")
|
||||||
|
|
||||||
|
// now scan to see if the jar has a license blob in it
|
||||||
if (missingLicenseInfo.isNotEmpty()) {
|
if (missingLicenseInfo.isNotEmpty()) {
|
||||||
missingLicenseInfo.forEach { info ->
|
missingLicenseInfo.forEach { info ->
|
||||||
// see if we have it in the dependency jar
|
// see if we have it in the dependency jar
|
||||||
|
@ -114,12 +102,12 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
info.artifacts.forEach search@{ artifact ->
|
info.artifacts.forEach search@{ artifact ->
|
||||||
ZipFile(artifact.file).use {
|
ZipFile(artifact.file).use {
|
||||||
try {
|
try {
|
||||||
|
// read the license blob information
|
||||||
val ze = it.getEntry(LicenseInjector.LICENSE_BLOB)
|
val ze = it.getEntry(LicenseInjector.LICENSE_BLOB)
|
||||||
if (ze != null) {
|
if (ze != null) {
|
||||||
it.getInputStream(ze).use { licenseStream ->
|
it.getInputStream(ze).use { licenseStream ->
|
||||||
licenseStream.copyTo(output)
|
licenseStream.copyTo(output)
|
||||||
missingFound = true
|
missingFound = true
|
||||||
found = true
|
|
||||||
return@search
|
return@search
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +120,7 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
if (!missingFound) {
|
if (!missingFound) {
|
||||||
actuallyMissingLicenseInfo.add(info)
|
actuallyMissingLicenseInfo.add(info)
|
||||||
} else {
|
} else {
|
||||||
// println("Found license info in: $info")
|
println("\t\t\t$info")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ObjectInputStream(ByteArrayInputStream(output.toByteArray())).use { ois ->
|
ObjectInputStream(ByteArrayInputStream(output.toByteArray())).use { ois ->
|
||||||
|
@ -141,7 +129,11 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
val license = LicenseData("", License.CUSTOM)
|
val license = LicenseData("", License.CUSTOM)
|
||||||
license.readObject(ois)
|
license.readObject(ois)
|
||||||
|
|
||||||
// println("Adding license: $license")
|
// as per US Code Title 17, Chapter 4; for "visually perceptive copies" (which includes software).
|
||||||
|
// http://www.copyright.gov/title17/92chap4.html
|
||||||
|
// it is ONLY... © year name
|
||||||
|
//
|
||||||
|
// this is correctly saved in the license blob
|
||||||
if (!primaryLicense.extras.contains(license)) {
|
if (!primaryLicense.extras.contains(license)) {
|
||||||
primaryLicense.extras.add(license)
|
primaryLicense.extras.add(license)
|
||||||
}
|
}
|
||||||
|
@ -154,23 +146,23 @@ class DependencyScanner(private val project: Project, private val extension: Lic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
found = false
|
|
||||||
println(" found")
|
|
||||||
} else {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actuallyMissingLicenseInfo.isNotEmpty()) {
|
if (actuallyMissingLicenseInfo.isNotEmpty()) {
|
||||||
println("\t\tLicense information is missing for the following. Please submit an issue with this information to include it in future license scans\n")
|
println("\t\tLicense information is missing for the following. Please submit an issue with this information to include it in future license scans")
|
||||||
|
|
||||||
actuallyMissingLicenseInfo.forEach { missingDep ->
|
actuallyMissingLicenseInfo.forEach { missingDep ->
|
||||||
val flatDependencies = mutableSetOf<Dependency>()
|
val flatDependencies = mutableSetOf<Dependency>()
|
||||||
missingDep.children.forEach {
|
missingDep.children.forEach {
|
||||||
flattenDep(it, flatDependencies)
|
flattenDep(it, flatDependencies)
|
||||||
}
|
}
|
||||||
println("\t\t ${missingDep.mavenId()} ${flatDependencies.map { it.mavenId() }}")
|
|
||||||
|
val flat = flatDependencies.map { it.mavenId() }
|
||||||
|
val extras = if (flat.isEmpty()) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
flat.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
println("\t\t ${missingDep.mavenId()} $extras")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,17 +38,33 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright
|
* The Berne Convention leaves "implementation details" up to individual countries.
|
||||||
|
*
|
||||||
|
* In the US (which is the relevant country for FSF documents), copyright notices are defined by Title 17, Chapter 4;
|
||||||
|
* for "visually perceptive copies" (which includes software). http://www.copyright.gov/title17/92chap4.html
|
||||||
|
*
|
||||||
|
* These take the form :
|
||||||
|
*
|
||||||
|
* © year name
|
||||||
|
*
|
||||||
|
* where
|
||||||
|
*
|
||||||
|
* `©` is specifically that symbol (not "(c)", which has no legal value), and can be replaced by "Copyright" or "Copr." (§ 401(b)(1))
|
||||||
|
*
|
||||||
|
* `year` is the year of first publication of the work, or the year of first publication of the compilation or derivative work if relevant
|
||||||
|
*
|
||||||
|
* `name` is the name of the owner of the copyright.
|
||||||
|
*
|
||||||
|
* What counts is years of publication; for software this is generally considered years in which the software is released.
|
||||||
|
*
|
||||||
|
* So if you release a piece of software in 2014, and release it again in 2016 without making changes in 2015, the years of publication
|
||||||
|
* would be 2014 and 2016, and the copyright notices would be "© 2014" in the first release and "© 2016" in the second release.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* When scanning for license copyright dates, we use the date of publication (the date of the manifest file, within the published jar)
|
||||||
*/
|
*/
|
||||||
val copyrights = mutableListOf<Int>()
|
var copyright = LocalDate.now().year
|
||||||
|
|
||||||
/**
|
|
||||||
* If not specified, will use the current year
|
|
||||||
*/
|
|
||||||
fun copyright(copyright: Int = LocalDate.now().year): CopyrightRange {
|
|
||||||
copyrights.add(copyright)
|
|
||||||
return CopyrightRange(this, copyright, copyrights)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL
|
* URL
|
||||||
|
@ -129,7 +145,7 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
if (name != other.name) return false
|
if (name != other.name) return false
|
||||||
if (license != other.license) return false
|
if (license != other.license) return false
|
||||||
if (description != other.description) return false
|
if (description != other.description) return false
|
||||||
if (copyrights != other.copyrights) return false
|
if (copyright != other.copyright) return false
|
||||||
if (urls != other.urls) return false
|
if (urls != other.urls) return false
|
||||||
if (notes != other.notes) return false
|
if (notes != other.notes) return false
|
||||||
if (authors != other.authors) return false
|
if (authors != other.authors) return false
|
||||||
|
@ -142,7 +158,7 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
var result = name.hashCode()
|
var result = name.hashCode()
|
||||||
result = 31 * result + license.hashCode()
|
result = 31 * result + license.hashCode()
|
||||||
result = 31 * result + description.hashCode()
|
result = 31 * result + description.hashCode()
|
||||||
result = 31 * result + copyrights.hashCode()
|
result = 31 * result + copyright
|
||||||
result = 31 * result + urls.hashCode()
|
result = 31 * result + urls.hashCode()
|
||||||
result = 31 * result + notes.hashCode()
|
result = 31 * result + notes.hashCode()
|
||||||
result = 31 * result + authors.hashCode()
|
result = 31 * result + authors.hashCode()
|
||||||
|
@ -156,10 +172,7 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
s.writeUTF(license.name)
|
s.writeUTF(license.name)
|
||||||
s.writeUTF(description)
|
s.writeUTF(description)
|
||||||
|
|
||||||
s.writeInt(copyrights.size)
|
s.writeInt(copyright)
|
||||||
copyrights.forEach {
|
|
||||||
s.writeInt(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.writeInt(urls.size)
|
s.writeInt(urls.size)
|
||||||
urls.forEach {
|
urls.forEach {
|
||||||
|
@ -184,18 +197,14 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gradle only needs to serialize objects, so this isn't strictly needed
|
// this is used to load license data from supported dependencies
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun readObject(s: ObjectInputStream) {
|
fun readObject(s: ObjectInputStream) {
|
||||||
name = s.readUTF()
|
name = s.readUTF()
|
||||||
license = License.valueOfLicenseName(s.readUTF())
|
license = License.valueOfLicenseName(s.readUTF())
|
||||||
description = s.readUTF()
|
description = s.readUTF()
|
||||||
|
|
||||||
|
copyright = s.readInt()
|
||||||
val copyrightsSize = s.readInt()
|
|
||||||
for (i in 1..copyrightsSize) {
|
|
||||||
copyrights.add(s.readInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
val urlsSize = s.readInt()
|
val urlsSize = s.readInt()
|
||||||
for (i in 1..urlsSize) {
|
for (i in 1..urlsSize) {
|
||||||
|
@ -225,10 +234,9 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
|
|
||||||
// NOTE: we ALWAYS use unix line endings!
|
// NOTE: we ALWAYS use unix line endings!
|
||||||
private const val NL = "\n"
|
private const val NL = "\n"
|
||||||
private const val HEADER = " - "
|
private const val HEADER1 = " - "
|
||||||
private const val HEADR4 = " ---- "
|
private const val HEADER4 = " ---- "
|
||||||
private const val SPACER3 = " "
|
private const val SPACER3 = " "
|
||||||
private const val SPACER4 = " "
|
|
||||||
|
|
||||||
private fun prefix(prefix: Int, builder: StringBuilder): StringBuilder {
|
private fun prefix(prefix: Int, builder: StringBuilder): StringBuilder {
|
||||||
if (prefix == 0) {
|
if (prefix == 0) {
|
||||||
|
@ -279,43 +287,25 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
|
|
||||||
// NOTE: we ALWAYS use unix line endings!
|
// NOTE: we ALWAYS use unix line endings!
|
||||||
private fun buildLicenseString(b: StringBuilder, license: LicenseData, prefixOffset: Int) {
|
private fun buildLicenseString(b: StringBuilder, license: LicenseData, prefixOffset: Int) {
|
||||||
line(prefixOffset, b, HEADER, license.name, " - ", license.description)
|
line(prefixOffset, b, HEADER1, license.name, " - ", license.description)
|
||||||
|
|
||||||
|
line(prefixOffset, b, SPACER3, "[", license.license.preferedName, "]")
|
||||||
|
|
||||||
license.urls.forEach {
|
license.urls.forEach {
|
||||||
line(prefixOffset, b, SPACER3, it)
|
line(prefixOffset, b, SPACER3, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix(prefixOffset, b).append(SPACER3).append("Copyright")
|
// as per US Code Title 17, Chapter 4; for "visually perceptive copies" (which includes software).
|
||||||
if (license.copyrights.isEmpty()) {
|
// http://www.copyright.gov/title17/92chap4.html
|
||||||
// append the current year
|
// it is ONLY... © year name (or Copyright year name)
|
||||||
b.append(" ").append(LocalDate.now().year)
|
// authors go on a separate line
|
||||||
}
|
line(prefixOffset, b, SPACER3, "Copyright ", license.copyright)
|
||||||
else if (license.copyrights.size == 1) {
|
|
||||||
// this is 2001
|
|
||||||
b.append(" ").append(license.copyrights.first())
|
|
||||||
} else {
|
|
||||||
// is this 2001,2002,2004,2014 <OR> 2001-2014
|
|
||||||
val sumA = license.copyrights.sum()
|
|
||||||
val sumB = license.copyrights.first().rangeTo(license.copyrights.last()).sum()
|
|
||||||
if (sumA == sumB) {
|
|
||||||
// this is 2001-2004
|
|
||||||
b.append(" ").append(license.copyrights.first()).append("-").append(license.copyrights.last())
|
|
||||||
} else {
|
|
||||||
// this is 2001,2002,2004
|
|
||||||
license.copyrights.forEach {
|
|
||||||
b.append(" ").append(it).append(",")
|
|
||||||
}
|
|
||||||
b.deleteCharAt(b.length-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.append(HEADER).append(license.license.preferedName).append(NL)
|
|
||||||
|
|
||||||
license.authors.forEach {
|
license.authors.forEach {
|
||||||
line(prefixOffset, b, SPACER4, it)
|
line(prefixOffset, b, SPACER3, " ", it)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (license.license === License.CUSTOM) {
|
if (license.license === License.CUSTOM) {
|
||||||
line(prefixOffset, b, HEADR4)
|
line(prefixOffset, b, HEADER4)
|
||||||
}
|
}
|
||||||
|
|
||||||
license.notes.forEach {
|
license.notes.forEach {
|
||||||
|
@ -371,26 +361,3 @@ class LicenseData(var name: String, var license: License) : java.io.Serializable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CopyrightRange internal constructor(private val license: LicenseData,
|
|
||||||
private val start: Int,
|
|
||||||
private val copyrights: MutableList<Int>) {
|
|
||||||
fun to(copyRight: Int) {
|
|
||||||
if (start >= copyRight) {
|
|
||||||
throw GradleException("Cannot have a start copyright date that is equal or greater than the `to` copyright date for ${license.name}")
|
|
||||||
}
|
|
||||||
|
|
||||||
val newStart = start+1
|
|
||||||
if (newStart < copyRight) {
|
|
||||||
// increment by 1, since the first part of the range is already added
|
|
||||||
copyrights.addAll((newStart).rangeTo(copyRight))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toNow() {
|
|
||||||
val nowYear = LocalDate.now().year
|
|
||||||
if (start < nowYear) {
|
|
||||||
to(nowYear)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,40 +2,49 @@ package dorkbox.license
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.ObjectOutputStream
|
import java.io.ObjectOutputStream
|
||||||
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal open class LicenseInjector @Inject constructor(@Internal val extension: Licensing) : DefaultTask() {
|
internal open class LicenseInjector @Inject constructor(project: Project, @Internal val extension: Licensing) : DefaultTask() {
|
||||||
// only want to build these files once
|
|
||||||
private var alreadyBuilt = false
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val LICENSE_FILE = "LICENSE"
|
const val LICENSE_FILE = "LICENSE"
|
||||||
const val LICENSE_BLOB = "LICENSE.blob"
|
const val LICENSE_BLOB = "LICENSE.blob"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input lateinit var licenses: MutableList<LicenseData>
|
@Input val licenses = extension.licenses
|
||||||
@OutputDirectory lateinit var outputDir: File
|
|
||||||
@InputDirectory lateinit var rootDir: File
|
@Internal private val outputBuildDir = File(project.buildDir, "licensing")
|
||||||
|
@OutputFiles val outputFiles = mutableListOf<File>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
/// outputBuildDir
|
||||||
|
outputFiles.add(File(outputBuildDir, LICENSE_FILE))
|
||||||
|
outputFiles.add(File(outputBuildDir, LICENSE_BLOB))
|
||||||
|
licenses.forEach {
|
||||||
|
outputFiles.add(File(outputBuildDir, it.license.licenseFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// root dir
|
||||||
|
outputFiles.add(File(project.rootDir, LICENSE_FILE))
|
||||||
|
outputFiles.add(File(project.rootDir, LICENSE_BLOB))
|
||||||
|
licenses.forEach {
|
||||||
|
outputFiles.add(File(project.rootDir, it.license.licenseFile))
|
||||||
|
}
|
||||||
|
|
||||||
outputs.upToDateWhen {
|
outputs.upToDateWhen {
|
||||||
alreadyBuilt || !(checkLicenseFiles(outputDir, licenses) && checkLicenseFiles(rootDir, licenses))
|
!(checkLicenseFiles(outputBuildDir, licenses) && checkLicenseFiles(project.rootDir, licenses))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun doTask() {
|
fun doTask() {
|
||||||
if (alreadyBuilt) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
alreadyBuilt = true
|
|
||||||
|
|
||||||
// now we want to add license information that we know about from our dependencies to our list
|
// 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+
|
// 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.
|
// we associate the artifact group + id + (start) version as a license.
|
||||||
|
@ -44,14 +53,13 @@ internal open class LicenseInjector @Inject constructor(@Internal val extension:
|
||||||
DependencyScanner(project, extension).scanForLicenseData()
|
DependencyScanner(project, extension).scanForLicenseData()
|
||||||
|
|
||||||
// true if there was any work done
|
// true if there was any work done
|
||||||
didWork = buildLicenseFiles(outputDir, licenses) && buildLicenseFiles(rootDir, licenses)
|
didWork = buildLicenseFiles(outputBuildDir, licenses, true) && buildLicenseFiles(project.rootDir, licenses, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true when there is work that needs to be done
|
* @return true when there is work that needs to be done
|
||||||
*/
|
*/
|
||||||
private fun checkLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>): Boolean {
|
private fun checkLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>): Boolean {
|
||||||
var needsToDoWork = false
|
|
||||||
if (!outputDir.exists()) outputDir.mkdirs()
|
if (!outputDir.exists()) outputDir.mkdirs()
|
||||||
|
|
||||||
val licenseText = LicenseData.buildString(licenses)
|
val licenseText = LicenseData.buildString(licenses)
|
||||||
|
@ -59,29 +67,26 @@ internal open class LicenseInjector @Inject constructor(@Internal val extension:
|
||||||
|
|
||||||
if (fileIsNotSame(licenseFile, licenseText)) {
|
if (fileIsNotSame(licenseFile, licenseText)) {
|
||||||
// write out the LICENSE and various license files
|
// write out the LICENSE and various license files
|
||||||
needsToDoWork = true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needsToDoWork) {
|
licenses.forEach {
|
||||||
licenses.forEach {
|
val license = it.license
|
||||||
val license = it.license
|
val file = File(outputDir, license.licenseFile)
|
||||||
val file = File(outputDir, license.licenseFile)
|
val sourceText = license.licenseText
|
||||||
val sourceText = license.licenseText
|
|
||||||
|
|
||||||
if (fileIsNotSame(file, sourceText)) {
|
if (fileIsNotSame(file, sourceText)) {
|
||||||
needsToDoWork = true
|
return true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
return needsToDoWork
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true when there is work that has be done
|
* @return true when there is work that has be done
|
||||||
*/
|
*/
|
||||||
private fun buildLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>): Boolean {
|
private fun buildLicenseFiles(outputDir: File, licenses: MutableList<LicenseData>, buildLicenseBlob: Boolean): Boolean {
|
||||||
var hasDoneWork = false
|
var hasDoneWork = false
|
||||||
|
|
||||||
if (!outputDir.exists()) outputDir.mkdirs()
|
if (!outputDir.exists()) outputDir.mkdirs()
|
||||||
|
@ -97,20 +102,36 @@ internal open class LicenseInjector @Inject constructor(@Internal val extension:
|
||||||
// write out the LICENSE files
|
// write out the LICENSE files
|
||||||
licenseFile.writeText(licenseText)
|
licenseFile.writeText(licenseText)
|
||||||
|
|
||||||
// save off the blob, so we can check when reading dependencies if we can
|
if (buildLicenseBlob) {
|
||||||
// import this license info as extra license info for the project
|
// save off the blob, so we can check when reading dependencies if we can
|
||||||
ObjectOutputStream(FileOutputStream(licenseBlob)).use { oos ->
|
// import this license info as extra license info for the project
|
||||||
oos.writeInt(licenses.size)
|
ObjectOutputStream(FileOutputStream(licenseBlob)).use { oos ->
|
||||||
|
oos.writeInt(licenses.size)
|
||||||
|
|
||||||
licenses.forEach {
|
licenses.forEach {
|
||||||
it.writeObject(oos)
|
it.writeObject(oos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasDoneWork = true
|
hasDoneWork = true
|
||||||
}
|
}
|
||||||
|
|
||||||
licenses.forEach {
|
// for the license files, we have to FLATTEN the list of licenses!
|
||||||
|
val flattenedLicenses = mutableSetOf<LicenseData>()
|
||||||
|
val scanningLicenses: LinkedList<LicenseData> = LinkedList<LicenseData>()
|
||||||
|
scanningLicenses.addAll(licenses)
|
||||||
|
|
||||||
|
while(scanningLicenses.isNotEmpty()) {
|
||||||
|
val license = scanningLicenses.remove()
|
||||||
|
val wasAdded = flattenedLicenses.add(license)
|
||||||
|
if (wasAdded) {
|
||||||
|
// should always be added, but MAYBE there is a loop somewhere. this hopefully prevents that
|
||||||
|
scanningLicenses.addAll(license.extras)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedLicenses.forEach {
|
||||||
val license = it.license
|
val license = it.license
|
||||||
val file = File(outputDir, license.licenseFile)
|
val file = File(outputDir, license.licenseFile)
|
||||||
val sourceText = license.licenseText
|
val sourceText = license.licenseText
|
||||||
|
|
|
@ -19,6 +19,7 @@ import License
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.ResolvedArtifact
|
import org.gradle.api.artifacts.ResolvedArtifact
|
||||||
import org.gradle.api.artifacts.ResolvedDependency
|
import org.gradle.api.artifacts.ResolvedDependency
|
||||||
import org.gradle.api.plugins.JavaPlugin
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
|
@ -41,21 +42,14 @@ import java.util.zip.ZipInputStream
|
||||||
class LicensePlugin : Plugin<Project> {
|
class LicensePlugin : Plugin<Project> {
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
val outputDir = File(project.buildDir, "licensing")
|
|
||||||
|
|
||||||
// Create the Plugin extension object (for users to configure our execution).
|
// Create the Plugin extension object (for users to configure our execution).
|
||||||
val extension: Licensing = project.extensions.create(Licensing.NAME, Licensing::class.java, project, outputDir)
|
val extension: Licensing = project.extensions.create(Licensing.NAME, Licensing::class.java, project)
|
||||||
|
|
||||||
val licenseInjector = project.tasks.create("generateLicenseFiles", LicenseInjector::class.java, extension).apply {
|
val licenseInjector = project.tasks.create("generateLicenseFiles", LicenseInjector::class.java, project, extension).apply {
|
||||||
group = "other"
|
group = "other"
|
||||||
}
|
}
|
||||||
|
|
||||||
licenseInjector.outputDir = outputDir
|
|
||||||
licenseInjector.rootDir = project.rootDir
|
|
||||||
licenseInjector.licenses = extension.licenses
|
|
||||||
|
|
||||||
project.afterEvaluate { prj ->
|
project.afterEvaluate { prj ->
|
||||||
|
|
||||||
// the task will only build files that it needs to (and will only run once)
|
// the task will only build files that it needs to (and will only run once)
|
||||||
prj.tasks.forEach {
|
prj.tasks.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -64,6 +58,16 @@ class LicensePlugin : Plugin<Project> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure to cleanup the generated license files on clean
|
||||||
|
project.tasks.getByName("clean").apply {
|
||||||
|
// delete the license info
|
||||||
|
extension.output().forEach {
|
||||||
|
if (it.exists()) {
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prj.configurations.asIterable().forEach { extension.projectDependencies.addAll(it.dependencies) }
|
prj.configurations.asIterable().forEach { extension.projectDependencies.addAll(it.dependencies) }
|
||||||
|
|
||||||
val licensing = extension.licenses
|
val licensing = extension.licenses
|
||||||
|
@ -82,7 +86,7 @@ class LicensePlugin : Plugin<Project> {
|
||||||
if (MavenPublication::class.java.isAssignableFrom(it.javaClass)) {
|
if (MavenPublication::class.java.isAssignableFrom(it.javaClass)) {
|
||||||
it as MavenPublication
|
it as MavenPublication
|
||||||
|
|
||||||
// add the license information. ONLY THE FIRST ONE!
|
// get the license information. ONLY FROM THE FIRST ONE! (which is the license for our project)
|
||||||
val licenseData = extension.licenses.first()
|
val licenseData = extension.licenses.first()
|
||||||
val license = licenseData.license
|
val license = licenseData.license
|
||||||
it.pom.licenses { licSpec ->
|
it.pom.licenses { licSpec ->
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.gradle.api.Project
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
open class Licensing(project: Project, private val outputDir: File) {
|
open class Licensing(private val project: Project) {
|
||||||
private val projectName = project.name
|
private val projectName = project.name
|
||||||
|
|
||||||
val projectDependencies = mutableListOf<Dependency>()
|
val projectDependencies = mutableListOf<Dependency>()
|
||||||
|
@ -32,13 +32,15 @@ open class Licensing(project: Project, private val outputDir: File) {
|
||||||
* Gets a list of files, representing the on-disk location of each generated license file
|
* Gets a list of files, representing the on-disk location of each generated license file
|
||||||
*/
|
*/
|
||||||
fun output() : List<File> {
|
fun output() : List<File> {
|
||||||
|
val outputBuilDir = File(project.buildDir, "licensing")
|
||||||
|
|
||||||
val files = mutableSetOf<File>()
|
val files = mutableSetOf<File>()
|
||||||
|
|
||||||
files.add(File(outputDir, LicenseInjector.LICENSE_FILE))
|
files.add(File(outputBuilDir, LicenseInjector.LICENSE_FILE))
|
||||||
files.add(File(outputDir, LicenseInjector.LICENSE_BLOB))
|
files.add(File(outputBuilDir, LicenseInjector.LICENSE_BLOB))
|
||||||
|
|
||||||
licenses.forEach {
|
licenses.forEach {
|
||||||
files.add(File(outputDir, it.license.licenseFile))
|
files.add(File(outputBuilDir, it.license.licenseFile))
|
||||||
}
|
}
|
||||||
|
|
||||||
return files.toList()
|
return files.toList()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user