Skip to content

Replace OTHER with a LicenseRef#926

Merged
dangoor merged 4 commits intoactions:mainfrom
dangoor:dangoor/replace-other
May 7, 2025
Merged

Replace OTHER with a LicenseRef#926
dangoor merged 4 commits intoactions:mainfrom
dangoor:dangoor/replace-other

Conversation

@dangoor
Copy link
Contributor

@dangoor dangoor commented May 5, 2025

Purpose

ClearlyDefined uses the string OTHER for the declared license when
a human has reviewed NOASSERTION text and found it to be a valid
license, but one without an SPDX identifier. OTHER, unlike
NOASSERTION, is not valid. With this change, when OTHER appears
in a license string, we'll replace it with
LicenseRef-clearlydefined-OTHER, which is valid and will allow
the expressions to parse.

Related Issues

N/A

Copilot AI review requested due to automatic review settings May 5, 2025 19:53
@dangoor dangoor requested a review from a team as a code owner May 5, 2025 19:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR ensures that the invalid OTHER token in license expressions is replaced with a valid LicenseRef-clearlydefined-OTHER before parsing or satisfiability checks.

  • Sanitizes input expressions in satisfies, satisfiesAny, satisfiesAll, and isValid by calling removeInvalidSPDX.
  • Introduces removeInvalidSPDX (with a regex) to transform OTHER into LicenseRef-clearlydefined-OTHER.
  • Expands unit tests to cover the new replacement behavior.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/spdx.ts Preprocess SPDX strings by replacing OTHER with LicenseRef-clearlydefined-OTHER.
tests/spdx.test.ts Adds test cases for OTHER in various positions and a new removeInvalidSPDX suite.
Comments suppressed due to low confidence (1)

tests/spdx.test.ts:290

  • Add a test case for multiple occurrences of OTHER (e.g., 'OTHER AND OTHER') to verify that all instances are correctly replaced.
const units = [

src/spdx.ts Outdated
candidateExpr: string,
constraintExpr: string
): boolean {
candidateExpr = removeInvalidSPDX(candidateExpr)
Copy link

Copilot AI May 5, 2025

Choose a reason for hiding this comment

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

Constraint expressions are not sanitized in satisfies. Consider also calling removeInvalidSPDX on constraintExpr to ensure OTHER in constraints is handled.

Suggested change
candidateExpr = removeInvalidSPDX(candidateExpr)
candidateExpr = removeInvalidSPDX(candidateExpr)
constraintExpr = removeInvalidSPDX(constraintExpr)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is probably unnecessary since the constraint expressions are written by the users and OTHER is invalid already. Users should write LicenseRef-clearlydefined-OTHER. That does bring to mind an issue with the approach in this PR: when an invalid license message is shown, it would still say OTHER instead of LicenseRef-clearlydefined-OTHER, so it wouldn't give users a clue about what they'd need to add to their license list. (Generally speaking, they shouldn't be adding OTHER in any form to their allowed license list because they can't know what the terms of that license are!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I spoke with @ahpook about this particular UX nit and he wasn't worried about it in the context of all of the good this change does in general. (Plus, from a compliance perspective, people really should not be adding LicenseRef-clearlydefined-OTHER to their allow lists because you can't be sure what the terms you're agreeing to are.)

Ahmed3lmallah
Ahmed3lmallah previously approved these changes May 5, 2025
Copy link
Contributor

@Ahmed3lmallah Ahmed3lmallah left a comment

Choose a reason for hiding this comment

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

LGTM besides minor comments. The dist needs to be regenerated too.

licenses: ['MIT'],
expected: true
},
// TODO(dangoor): this does not seem correct to me: the only license is Apache-2.0 and it's on the list
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that this tests satisfiesAll, I'm assuming that the candidate should satisfy all entries in the licenses list, which seems to be correctly not the case here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I understand. I don't see why someone would want that, but 🤷 . I'm tempted to just remove this function, since we don't use it.

@@ -130,6 +141,16 @@ describe('satisfiesAll', () => {
candidate: 'MIT OR ISC',
licenses: ['MiT'],
Copy link
Contributor

Choose a reason for hiding this comment

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

Not related to this PR, but here is another case where I would have expected the result to be true but it's likely not because it's case sensitive. Does the matching here need to be case sensitive?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, so the official spec says that license identifiers are case-insensitive.

This, then, is not actually the correct behavior as per the spec, but is the behavior expected of the library we're using. Definitely out of scope for this PR.

src/spdx.ts Outdated

// adjusts license expressions to not include the invalid `OTHER`
// which ClearlyDefined adds to license strings
export function removeInvalidSPDX(spdxExpr: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

The method name initially threw me off. I thought we are removing an entry from a list, but after looking at the data types I realized I was wrong. Perhaps something like cleanInvalidSPDX would be more clear?

@dangoor
Copy link
Contributor Author

dangoor commented May 6, 2025

I'm going to need to revise this a little based on #927.

dangoor added 2 commits May 6, 2025 11:22
ClearlyDefined uses the string `OTHER` for the declared license when
a human has reviewed `NOASSERTION` text and found it to be a valid
license, but one without an SPDX identifier. `OTHER`, unlike
`NOASSERTION`, is not valid. With this change, when `OTHER` appears
in a license string, we'll replace it with
`LicenseRef-clearlydefined-OTHER`, which _is_ valid and will allow
the expressions to parse.
@dangoor
Copy link
Contributor Author

dangoor commented May 6, 2025

Oof, I didn't realize I had been working from a fork and not a branch. I pushed a change that is rebased on #927.

@dangoor
Copy link
Contributor Author

dangoor commented May 7, 2025

This is ready for review again, now that #927 has landed.

@dangoor dangoor merged commit 69d2faa into actions:main May 7, 2025
6 checks passed
@dangoor dangoor deleted the dangoor/replace-other branch May 7, 2025 17:25
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