Skip to content

chore(utils): Ignore also NOASSERTION contained in declared licenses - #12465

Draft
fviernau wants to merge 1 commit into
mainfrom
dlp-filter-noassertion
Draft

fviernau wants to merge 1 commit into
mainfrom
dlp-filter-noassertion

Conversation

@fviernau

@fviernau fviernau commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

Related to #11459.

@fviernau
fviernau requested a review from a team as a code owner September 16, 2026 07:20
@fviernau
fviernau force-pushed the dlp-filter-noassertion branch from a12d7f3 to eed9a61 Compare September 16, 2026 07:21

val spdxExpression = processedLicenses.values.toSet().filter {
it.toString() != SpdxConstants.NONE
val spdxExpression = processedLicenses.values.toSet().filterNot {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this say filter {} to keep isPresent?

And while at it, how about simplifying this to .filterTo(mutableSetOf())?

@fviernau
fviernau force-pushed the dlp-filter-noassertion branch from eed9a61 to 2c24fc1 Compare September 16, 2026 07:45
@fviernau
fviernau requested a review from sschuberth September 16, 2026 07:45
@fviernau
fviernau enabled auto-merge (rebase) September 16, 2026 07:45
sschuberth
sschuberth previously approved these changes Sep 16, 2026
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.21%. Comparing base (be83dc7) to head (2de6736).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main   #12465   +/-   ##
=========================================
  Coverage     59.21%   59.21%           
  Complexity     1892     1892           
=========================================
  Files           366      366           
  Lines         13839    13839           
  Branches       1462     1462           
=========================================
  Hits           8195     8195           
  Misses         5114     5114           
  Partials        530      530           
Flag Coverage Δ
test-ubuntu-26.04 42.61% <ø> (ø)
test-windows-2025 42.59% <ø> (ø)

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.
It does not make sense to include `NOASSERTION` into the declared
license. So, adjust the filter condition for clarity. `NOASSERTION` in
detected licenses have only been observed for Cargo, see also the
updated test expectations.

While at it, simplify and clarify the deduplication by using
`filterTo()`.

Signed-off-by: Frank Viernau <frank.viernau@gmail.com>
- "NOASSERTION"
declared_licenses_processed:
spdx_expression: "Apache-2.0 OR MIT OR NOASSERTION"
spdx_expression: "Apache-2.0 OR MIT"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. This required test change made me think about this again:

I agree that it's highly unlikely for someone to declare a license of NOASSERTION, and that it's not very meaningful to do so.

But if someone still does it, maybe to express "there is some license without an SPDX ID" (due to that someone being unaware of the LicenseRef mechanism), is it then really correct for us to omit that information?

I guess it's better to play safe and not omit this after all.

@fviernau fviernau Sep 16, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test failure also made me look into the code again.
I found that NOASSERTION and NONE can have two sources:

  1. Written in the definition file (I haven't seen this myself)
  2. Added by an ORT package manager, for the sake of indicating something.

Examples for 2 are:

  • // an unknown declared license to indicate that there is a declared license, but we cannot know which it is at this
    // point.
    // See: https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields
    if (licenseFile.orEmpty().isNotBlank()) {
    declaredLicenses += SpdxConstants.NOASSERTION
    }
    return declaredLicenses
    }
  • // NPM does not mean https://unlicense.org/ here, but the wish to not "grant others the right to use
    // a private or unpublished package under any terms", which corresponds to SPDX's "NONE".
    declaredLicense == "UNLICENSED" -> SpdxConstants.NONE
    // NPM allows declaring non-SPDX licenses only by referencing a license file. Avoid reporting an
    // [Issue] by mapping this to a valid license identifier.
    declaredLicense.startsWith("SEE LICENSE IN ") -> SpdxConstants.NOASSERTION
    else -> declaredLicense.takeUnless { it.isBlank() }

Given that my commit does not make sense.
However, this seemed to uncover an are for improvement / clean-up.

Simply from reading the code, the following should not have any effect

// NPM does not mean https://unlicense.org/ here, but the wish to not "grant others the right to use
            // a private or unpublished package under any terms", which corresponds to SPDX's "NONE".
            declaredLicense == "UNLICENSED" -> SpdxConstants.NONE

as NONE gets filtered out by the DeclaredLicenseProcessor.

This has to do with NONE being also use as means for discarding a declared license, see
#3038.

@fviernau fviernau Sep 16, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While mapping UNLICENSED to NONE makes sense to me,
mapping to NOASSERTION could be changed to keep the original string.
For node a single file is referenced, for example

  • SEE LICENSE IN LICENSE
  • SEE LICENSE IN Readme.md
    For Cargo also a single file can be referenced.

I wonder if it would be cleaner to introduce dedicated fields and use them in Package.kt

data class RawDeclaredLicense(
    val licenses: List<String>,
    val fileReferences: List<String>,
    val operator: SpdxOperator = SpdxOperator.AND
)

This would have clearer semantics, but it would require means to map a file reference to a license using a curation (which should not be hard to do). Furthermore, adding the operator would allow to re-compute the
processed license without this hack:

// Preserve an existing top-level operator from the base SPDX expression.
val declaredLicensesProcessed = when (val expression = base.declaredLicensesProcessed.spdxExpression) {
is SpdxCompoundExpression -> DeclaredLicenseProcessor.process(
base.declaredLicenses,
declaredLicenseMapping,
expression.operator
)
else -> DeclaredLicenseProcessor.process(
base.declaredLicenses,
declaredLicenseMapping
)
}

What do you think about this @sschuberth ?

Or instead of fileReferences we could by convention use the current List<String> approach and
use the from SEE LICENSE IN $filepath, to not introduce a new mechanism. Benefit is, that it is obvious what it is about while NOASSERTION is unclear.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NONE gets filtered out by the DeclaredLicenseProcessor.

But isn't that exactly what we want for the "NPM does not mean https://unlicense.org/" case? Because that makes declaredLicensesProcessed empty, i.e. no declared license, which is exactly what "unlicensed" is supposed to mean.

While mapping UNLICENSED to NONE makes sense to me

Ok, seems we're on the same page here.

mapping to NOASSERTION could be changed to keep the original string.

One problem we had with this is in past is that users then need to deal with each original string separately, instead of e.g. just disregarding everything that is "NOASSERTION" / not a concrete license.

@fviernau
fviernau requested a review from sschuberth September 16, 2026 10:06
@fviernau fviernau added the on hold Pull requests that cannot currently be merged label Sep 16, 2026
@fviernau
fviernau marked this pull request as draft September 16, 2026 10:21
auto-merge was automatically disabled September 16, 2026 10:21

Pull request was converted to draft

This branch has not been deployed

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

Labels

on hold Pull requests that cannot currently be merged

2 participants