Skip to content

License text curations PoC#12084

Closed
fviernau wants to merge 8 commits into
mainfrom
license-text-curations-poc
Closed

License text curations PoC#12084
fviernau wants to merge 8 commits into
mainfrom
license-text-curations-poc

Conversation

@fviernau

@fviernau fviernau commented Jun 30, 2026

Copy link
Copy Markdown
Member

Initial PoC implementation, to be used as a basis for moving to a consensus on how the
final implementation should look like.

It should include all needed functionality wrt the output notice file.
It does not yet cover how the license fact provider is injected / configured.

See also the ort-config part: oss-review-toolkit/ort-config#446

fviernau added 8 commits June 29, 2026 16:03
Allow to configure multiple instances of the same provider type. This
flexibility can be used to organize the upcoming identifier-specific
license text in a directory separate from the identifier-agnostic custom
license texts.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
For the upcoming license text curations feature it makes more sense to
match the curations against `SpdxSingleLicenseExpression`s, compared to
matching the IDs of license and expression separately, to not limit the
flexibility of the curations without need.

Use more speaking parameter names in the `LicenseFactProvider` interface
to further clarify the meaning of `licenseId`. Furthermore, re-write the
`getLicenseText(String, Identifier)` to interpret the first parameter as
`SpdxSingleLicenseExpression`, to prepare for using it from the FTL
template.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Allow multiple license text variants to be provided for a single
`licenseId` instead of a single concatenated string.

Rationale: Some packages include more than one distinct text for the
same licenseId; forcing a single text required curators to concatenate
variants, which is inflexible. Returning a set enables additive
curation semantics (append/merge) rather than overwrite semantics,
which is more powerful for future tooling. Each text entry can carr
 its own metadata (e.g., comment or source), improving traceability.

The signature now returns a set of license text entries for a given
`licenseId` and the helper getLicenseText(licenseId, id) is removed,
since integrations (for example NOTICE template generation) need to
distinguish between single and multiple texts and will need to call
both functions anyway.

Note: The `JvmName` has to be changed to avoid a clash due to the now
      equal return type of `Set`.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Prepare for an upcoming change.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Prepare for re-use in an upcoming change.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
Enhance `licensesNotInLicenseFiles()` to optionally keep licenses with
text curations. This allows for ensuring, to always include curated texts
in the NOTICE files.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
appendLine()
append(exceptionText.text)
}


override fun getLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<LicenseText> =
getCurationsForId(id).mapNotNullTo(mutableSetOf()) { curation ->
curation.licenseText.takeIf { curation.licenseId.toString() == singleLicenseExpression }?.let { LicenseText(it) }

override fun getLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<LicenseText> =
getCurationsForId(id).mapNotNullTo(mutableSetOf()) { curation ->
curation.licenseText.takeIf { curation.licenseId.toString() == singleLicenseExpression }?.let { LicenseText(it) }

override fun getLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<LicenseText> =
getCurationsForId(id).mapNotNullTo(mutableSetOf()) { curation ->
curation.licenseText.takeIf { curation.licenseId.toString() == singleLicenseExpression }?.let { LicenseText(it) }

override fun getLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<LicenseText> =
getCurationsForId(id).mapNotNullTo(mutableSetOf()) { curation ->
curation.licenseText.takeIf { curation.licenseId.toString() == singleLicenseExpression }?.let { LicenseText(it) }

override fun getLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<LicenseText> =
getCurationsForId(id).mapNotNullTo(mutableSetOf()) { curation ->
curation.licenseText.takeIf { curation.licenseId.toString() == singleLicenseExpression }?.let { LicenseText(it) }
val outputFileLicenses = licenseFiles.files.flatMap { it.licenses }
return resolvedLicenses.filter { it !in outputFileLicenses }
return resolvedLicenses.filter { resolvedLicense ->
val hasCurations = input.licenseFactProvider.hasLicenseTextsForId(resolvedLicense.license.toString(), id)
*/
fun hasLicenseText(licenseId: String, id: Identifier): Boolean =
hasLicenseText(licenseId, id) || hasLicenseText(licenseId)
fun hasLicenseTexts(singleLicenseExpression: String, id: Identifier): Boolean {
fun getNonBlankLicenseText(licenseOrExceptionId: String): String? = getLicenseText(licenseOrExceptionId)?.text

@JvmName("getLicenseTextsStringForId")
fun getNonBlankLicenseTextsForId(singleLicenseExpression: String, id: Identifier): Set<String> =
@JvmName("getLicenseText")
fun getNonBlankLicenseText(licenseId: String, id: Identifier): String? = getLicenseText(licenseId, id)?.text
@JvmName("getLicenseTextsString")
fun getNonBlankLicenseTexts(singleLicenseExpression: String, id: Identifier): Set<String> =
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.62%. Comparing base (f014881) to head (88712d8).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main   #12084   +/-   ##
=========================================
  Coverage     58.62%   58.62%           
  Complexity     1825     1825           
=========================================
  Files           361      361           
  Lines         13572    13572           
  Branches       1400     1400           
=========================================
  Hits           7956     7956           
  Misses         5114     5114           
  Partials        502      502           
Flag Coverage Δ
test-windows-2025 42.22% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@fviernau fviernau closed this Jul 3, 2026
@fviernau fviernau deleted the license-text-curations-poc branch July 3, 2026 07:35
@fviernau

fviernau commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

PoC now more needed, real impl has been done.

@sschuberth

Copy link
Copy Markdown
Member

PoC now more needed, real impl has been done.

See #12086 for the concluding PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants