Skip to content

Commit

Permalink
model: Introduce a new copyright holder field to data model
Browse files Browse the repository at this point in the history
In German law, the author and the copyright holder can be two seperate
legal entities and therefore also need to be treated separately.

Introduce a new copyright holder field that is now the primary source
for copyright holder information. Authors are still only used as
copyright holders if the `addAuthorsToCopyrights` option is enabled.

For now, all package manager implementations set empty copyright
holders. Filling the copyright holder field is left as an exercise for
future actions. Right now, the only way to add copyright holders is via
curations.

This change resolves oss-review-toolkit#4519.

Signed-off-by: Rainer Bieniek <[email protected]>
  • Loading branch information
porsche-rbieniek committed Jul 12, 2022
1 parent 285f018 commit 7632134
Show file tree
Hide file tree
Showing 34 changed files with 181 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class SpdxDocumentFileFunTest : WordSpec({
cpe = "cpe:2.3:a:http:curl:7.70.0:*:*:*:*:*:*:*",
definitionFilePath = vcsDir.getPathToRoot(curlPackageFile),
authors = sortedSetOf("Daniel Stenberg ([email protected])"),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf("curl"),
vcs = VcsInfo(
type = VcsType.GIT,
Expand All @@ -120,6 +121,7 @@ class SpdxDocumentFileFunTest : WordSpec({
cpe = "cpe:2.3:a:a-name:openssl:1.1.1g:*:*:*:*:*:*:*",
definitionFilePath = vcsDir.getPathToRoot(opensslPackageFile),
authors = sortedSetOf("OpenSSL Development Team"),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf("Apache-2.0"),
vcs = VcsInfo(
type = VcsType.GIT,
Expand All @@ -141,6 +143,7 @@ class SpdxDocumentFileFunTest : WordSpec({
cpe = "cpe:/a:compress:zlib:1.2.11:::en-us",
definitionFilePath = vcsDir.getPathToRoot(zlibPackageFile),
authors = sortedSetOf("Jean-loup Gailly", "Mark Adler"),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf("Zlib"),
vcs = VcsInfo(
type = VcsType.GIT,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Bower.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class Bower(
Package(
id = parsePackageId(node),
authors = parseAuthors(node),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(node),
description = node["pkgMeta"]["description"].textValueOrEmpty(),
homepageUrl = node["pkgMeta"]["homepage"].textValueOrEmpty(),
Expand Down Expand Up @@ -252,6 +253,7 @@ class Bower(
id = projectPackage.id,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = projectPackage.authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = projectPackage.declaredLicenses,
vcs = projectPackage.vcs,
vcsProcessed = processProjectVcs(workingDir, projectPackage.vcs, projectPackage.homepageUrl),
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Bundler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class Bundler(
id = projectId,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses.toSortedSet(),
vcs = VcsInfo.EMPTY,
vcsProcessed = processProjectVcs(workingDir, VcsInfo.EMPTY, homepageUrl),
Expand Down Expand Up @@ -264,6 +265,7 @@ class Bundler(
return Package(
id = gemId,
authors = gemSpec.authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = gemSpec.declaredLicenses,
description = gemSpec.description,
homepageUrl = gemSpec.homepageUrl,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Cargo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class Cargo(
id = projectPkg.id,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = projectPkg.declaredLicenses,
declaredLicensesProcessed = processDeclaredLicenses(projectPkg.declaredLicenses),
vcs = projectPkg.vcs,
Expand Down Expand Up @@ -272,6 +273,7 @@ private fun parsePackage(node: JsonNode, hashes: Map<String, String>): Package {
return Package(
id = parsePackageId(node),
authors = parseAuthors(node["authors"]),
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
declaredLicensesProcessed = declaredLicensesProcessed,
description = node["description"].textValueOrEmpty(),
Expand Down
4 changes: 4 additions & 0 deletions analyzer/src/main/kotlin/managers/Carthage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Carthage(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
vcs = VcsInfo.EMPTY,
vcsProcessed = processProjectVcs(workingDir, VcsInfo.EMPTY),
Expand Down Expand Up @@ -190,6 +191,7 @@ class Carthage(
version = revision
),
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
description = "",
homepageUrl = projectUrl.removeSuffix(".git"),
Expand All @@ -214,6 +216,7 @@ class Carthage(
version = revision
),
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
description = "",
homepageUrl = "",
Expand All @@ -232,6 +235,7 @@ class Carthage(
version = revision
),
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
description = "",
homepageUrl = "",
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/CocoaPods.kt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class CocoaPods(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
vcs = VcsInfo.EMPTY,
vcsProcessed = processProjectVcs(workingDir),
Expand Down Expand Up @@ -186,6 +187,7 @@ class CocoaPods(
return Package(
id = id,
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = podspec.license.takeUnless { it.isEmpty() }?.let { sortedSetOf(it) } ?: sortedSetOf(),
description = podspec.summary,
homepageUrl = podspec.homepage,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Composer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class Composer(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = parseAuthors(json),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(json),
vcs = vcs,
vcsProcessed = processProjectVcs(definitionFile.parentFile, vcs, homepageUrl),
Expand Down Expand Up @@ -265,6 +266,7 @@ class Composer(
version = version
),
authors = parseAuthors(pkgInfo),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(pkgInfo),
description = pkgInfo["description"].textValueOrEmpty(),
homepageUrl = homepageUrl,
Expand Down
4 changes: 4 additions & 0 deletions analyzer/src/main/kotlin/managers/Conan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ class Conan(
id = projectPackage.id,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = projectPackage.authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = projectPackage.declaredLicenses,
vcs = projectPackage.vcs,
vcsProcessed = processProjectVcs(
Expand Down Expand Up @@ -288,6 +289,7 @@ class Conan(
return Package(
id = id,
authors = parseAuthors(node),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(node),
description = parsePackageField(node, workingDir, "description"),
homepageUrl = homepageUrl,
Expand Down Expand Up @@ -427,6 +429,7 @@ class Conan(
version = inspectField(definitionFile.name, workingDir, "version")
),
authors = parseAuthors(node),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(node),
description = inspectField(definitionFile.name, workingDir, "description"),
homepageUrl = node["homepage"].textValueOrEmpty(),
Expand All @@ -447,6 +450,7 @@ class Conan(
version = ""
),
authors = parseAuthors(node),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseDeclaredLicenses(node),
description = "",
homepageUrl = node["homepage"].textValueOrEmpty(),
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/GoDep.kt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class GoDep(
val pkg = Package(
id = Identifier(managerName, "", name, version),
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
description = "",
homepageUrl = "",
Expand Down Expand Up @@ -171,6 +172,7 @@ class GoDep(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
vcs = VcsInfo.EMPTY,
vcsProcessed = projectVcs,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/GoMod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class GoMod(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = sortedSetOf(), // Go mod doesn't support author information.
copyrightHolders = sortedSetOf(), // Go mod doesn't support copyright holders.
declaredLicenses = sortedSetOf(), // Go mod doesn't support declared licenses.
vcs = projectVcs,
vcsProcessed = projectVcs,
Expand Down Expand Up @@ -274,6 +275,7 @@ class GoMod(
return Package(
id = Identifier(managerName, "", id.name, id.version),
authors = sortedSetOf(), // Go mod doesn't support author information.
copyrightHolders = sortedSetOf(), // Go mod doesn't support copyright holders
declaredLicenses = sortedSetOf(), // Go mod doesn't support declared licenses.
description = "",
homepageUrl = "",
Expand Down
1 change: 1 addition & 0 deletions analyzer/src/main/kotlin/managers/Gradle.kt
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class Gradle(
id = projectId,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = sortedSetOf(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(),
vcs = VcsInfo.EMPTY,
vcsProcessed = processProjectVcs(definitionFile.parentFile),
Expand Down
1 change: 1 addition & 0 deletions analyzer/src/main/kotlin/managers/Maven.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class Maven(
id = projectId,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = MavenSupport.parseAuthors(mavenProject),
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
declaredLicensesProcessed = declaredLicensesProcessed,
vcs = vcsFromPackage,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Npm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ open class Npm(
val module = Package(
id = id,
authors = authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
description = description,
homepageUrl = homepageUrl,
Expand Down Expand Up @@ -623,6 +624,7 @@ open class Npm(
),
definitionFilePath = VersionControlSystem.getPathInfo(packageJson).path,
authors = authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
vcs = vcsFromPackage,
vcsProcessed = processProjectVcs(projectDir, vcsFromPackage, homepageUrl),
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Pip.kt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ class Pip(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
vcs = VcsInfo.EMPTY,
vcsProcessed = processProjectVcs(workingDir, VcsInfo.EMPTY, setupHomepage),
Expand Down Expand Up @@ -737,6 +738,7 @@ private fun Package.enrichWith(other: Package?): Package =
homepageUrl = homepageUrl.takeUnless { it.isBlank() } ?: other.homepageUrl,
description = description.takeUnless { it.isBlank() } ?: other.description,
authors = authors.takeUnless { it.isEmpty() } ?: other.authors,
copyrightHolders = copyrightHolders.takeUnless { it.isEmpty() } ?: other.copyrightHolders,
declaredLicenses = declaredLicenses.takeUnless { it.isEmpty() } ?: other.declaredLicenses,
declaredLicensesProcessed = declaredLicensesProcessed.takeUnless { declaredLicenses.isEmpty() }
?: other.declaredLicensesProcessed,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Pub.kt
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ class Pub(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = authors,
copyrightHolders = sortedSetOf(),
// Pub does not declare any licenses in the pubspec files, therefore we keep this empty.
declaredLicenses = sortedSetOf(),
vcs = vcs,
Expand Down Expand Up @@ -530,6 +531,7 @@ class Pub(
packages[id] = Package(
id,
authors = authors,
copyrightHolders = sortedSetOf(),
// Pub does not declare any licenses in the pubspec files, therefore we keep this empty.
declaredLicenses = sortedSetOf(),
description = description,
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/SpdxDocumentFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ class SpdxDocumentFile(
purl = locateExternalReference(SpdxExternalReference.Type.Purl) ?: id.toPurl(),
cpe = locateCpe(),
authors = originator.wrapPresentInSortedSet(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(licenseDeclared),
concludedLicense = getConcludedLicense(),
description = packageDescription,
Expand Down Expand Up @@ -467,6 +468,7 @@ class SpdxDocumentFile(
cpe = projectPackage.locateCpe(),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = projectPackage.originator.wrapPresentInSortedSet(),
copyrightHolders = sortedSetOf(),
declaredLicenses = sortedSetOf(projectPackage.licenseDeclared),
vcs = processProjectVcs(definitionFile.parentFile, VcsInfo.EMPTY),
homepageUrl = projectPackage.homepage.mapNotPresentToEmpty(),
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/Stack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class Stack(
id = projectId,
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = projectPackage.authors,
copyrightHolders = sortedSetOf(),
declaredLicenses = projectPackage.declaredLicenses,
vcs = projectPackage.vcs,
vcsProcessed = processProjectVcs(workingDir, projectPackage.vcs, projectPackage.homepageUrl),
Expand Down Expand Up @@ -334,6 +335,7 @@ class Stack(
.map(String::trim)
.filter(String::isNotEmpty)
.mapTo(sortedSetOf(), ::parseAuthorString),
copyrightHolders = sortedSetOf(),
declaredLicenses = map["license"]?.let { sortedSetOf(it) } ?: sortedSetOf(),
description = map["description"].orEmpty(),
homepageUrl = homepageUrl,
Expand Down
1 change: 1 addition & 0 deletions analyzer/src/main/kotlin/managers/utils/MavenSupport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ class MavenSupport(private val workspaceReader: WorkspaceReader) {
version = mavenProject.version
),
authors = parseAuthors(mavenProject),
copyrightHolders = sortedSetOf(),
declaredLicenses = declaredLicenses,
declaredLicensesProcessed = declaredLicensesProcessed,
description = mavenProject.description.orEmpty(),
Expand Down
2 changes: 2 additions & 0 deletions analyzer/src/main/kotlin/managers/utils/NuGetSupport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ class NuGetSupport(serviceIndexUrls: List<String> = listOf(DEFAULT_SERVICE_INDEX
Package(
id = getIdentifier(id, version),
authors = parseAuthors(all.spec),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseLicenses(all.spec),
description = description.orEmpty(),
homepageUrl = homepageUrl,
Expand Down Expand Up @@ -370,6 +371,7 @@ private fun PackageManager.getProject(
),
definitionFilePath = VersionControlSystem.getPathInfo(definitionFile).path,
authors = parseAuthors(spec),
copyrightHolders = sortedSetOf(),
declaredLicenses = parseLicenses(spec),
vcs = VcsInfo.EMPTY,
vcsProcessed = PackageManager.processProjectVcs(workingDir),
Expand Down
8 changes: 8 additions & 0 deletions analyzer/src/test/kotlin/managers/CarthageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class CarthageTest : WordSpec() {
id.type shouldBe "Carthage"
vcs.url shouldBe "https://github.com/Alamofire/AlamofireImage.git"
vcs.revision shouldBe "3.2.0"
authors shouldBe emptySet()
copyrightHolders shouldBe emptySet()
}
}
}
Expand All @@ -67,6 +69,8 @@ class CarthageTest : WordSpec() {
vcs.type shouldBe VcsType.GIT
vcs.url shouldBe "https://host.tld/path/to/project.git"
vcs.revision shouldBe "1.0.0"
authors shouldBe emptySet()
copyrightHolders shouldBe emptySet()
}
}
}
Expand All @@ -85,6 +89,8 @@ class CarthageTest : WordSpec() {
id.type shouldBe "Carthage"
id.name shouldBe "spec"
binaryArtifact.url shouldBe "https://host.tld/path/to/binary/dependency.zip"
authors shouldBe emptySet()
copyrightHolders shouldBe emptySet()
}
}
}
Expand All @@ -102,6 +108,8 @@ class CarthageTest : WordSpec() {
size shouldBe 3
forEach {
it.id.type shouldBe "Carthage"
it.authors shouldBe emptySet()
it.copyrightHolders shouldBe emptySet()
}
count { "user/project" in it.vcs.url } shouldBe 1
count { "user-2/project_2" in it.vcs.url } shouldBe 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class NpmDependencyHandlerTest : StringSpec({
id shouldBe Identifier("NPM", "", "bonjour", "3.5.0")
declaredLicenses should containExactly("MIT")
authors should containExactly("Thomas Watson Steen")
copyrightHolders shouldBe emptySet<String>()
homepageUrl shouldBe "https://github.com/watson/bonjour/local"
description shouldBe "A Bonjour/Zeroconf implementation in pure JavaScript (local)"
}
Expand Down

0 comments on commit 7632134

Please sign in to comment.