Skip to content

fix: surface license text for clarified LicenseRef-* identifiers#303

Open
ruffsl wants to merge 1 commit into
EmbarkStudios:mainfrom
ruffsl:fix/licenseref-license-files
Open

fix: surface license text for clarified LicenseRef-* identifiers#303
ruffsl wants to merge 1 commit into
EmbarkStudios:mainfrom
ruffsl:fix/licenseref-license-files

Conversation

@ruffsl
Copy link
Copy Markdown

@ruffsl ruffsl commented May 6, 2026

Disclosure: I used LLMs to trace, fix, and check this patch while debugging semi-related warnings when using slint.

Perhaps we could also expand this if theirs interest in any REUSE-aware filename heuristic development as well.


Checklist

  • I have read the Contributor Guide
  • I have read and agree to the Code of Conduct
  • I have added a description of my changes and why I'd like them included in the section below

Description of Changes

generate.rs's per-license iteration treated the two LicenseItem variants asymmetrically. The Spdx { id, .. } arm filters krate_license.license_files for entries whose recorded expression matches the SPDX id and uses the file's text. The Other(..) arm unconditionally emitted log::warn!("{license} has no license file for crate '{}'") and never looked at license_files at all.

That meant clarifications targeting a LicenseRef-* identifier (e.g. [<crate>.clarify] with license = "LicenseRef-Slint-Royalty-free-2.0" and a [[<crate>.clarify.files]] pointing at the bundled license file) ran successfully — apply_ clarification populated license_files correctly, the DEBUG log confirmed applying clarification expression '...' — but the generated bundle had an empty section header for the LicenseRef license and the warning still surfaced. There was no way to make the bundle complete without falling back to a Handlebars-side template hack.

The Other arm now mirrors the Spdx arm's filter:

  • Iterate license_files, keep entries whose license_expr contains a LicenseItem::Other matching the outer LicenseRef (compared via LicenseRef::PartialEq, which honors both the optional doc_ref and the lic_ref).
  • For text-bearing files, push a License entry using the LicenseRef's Display form for both name and id.
  • Emit the existing warning only when no match is found. There's no canonical-text fallback for project-specific LicenseRefs (no equivalent of LicenseId::text()), so behavior in the no-match case is unchanged from before.

The surrounding match license.license becomes match &license.license so the new arm can bind license_ref: &Box<LicenseRef> without moving out of the LicenseReq. The Spdx arm's id binding becomes a reference too; the only adjustment is dereferencing *id inside evaluate's closure.

Concrete real-world impact: bundlers consuming Slint can now clarify their LicenseRef-Slint-Royalty-free-2.0 election and get the actual license text in their generated attribution, instead of a textless section + per-crate warning. The same applies to any project using a LicenseRef-* identifier (REUSE-compliant projects hosted in non-SPDX-blessed corners of the ecosystem; Embark's own about.toml example for ring only happens to work today because ring's clarified license is OpenSSL — a real SPDX id).

Related Issues

`generate.rs`'s per-license iteration treated the two `LicenseItem`
variants asymmetrically. The `Spdx { id, .. }` arm filters
`krate_license.license_files` for entries whose recorded expression
matches the SPDX id and uses the file's text. The `Other(..)` arm
unconditionally emitted `log::warn!("{license} has no license file
for crate '{}'")` and never looked at `license_files` at all.

That meant clarifications targeting a `LicenseRef-*` identifier
(e.g. `[<crate>.clarify]` with `license =
"LicenseRef-Slint-Royalty-free-2.0"` and a `[[<crate>.clarify.files]]`
pointing at the bundled license file) ran successfully — `apply_
clarification` populated `license_files` correctly, the DEBUG log
confirmed `applying clarification expression '...'` — but the
generated bundle had an empty section header for the LicenseRef
license and the warning still surfaced. There was no way to make
the bundle complete without falling back to a Handlebars-side
template hack.

The `Other` arm now mirrors the `Spdx` arm's filter:

  - Iterate `license_files`, keep entries whose `license_expr`
    contains a `LicenseItem::Other` matching the outer LicenseRef
    (compared via `LicenseRef::PartialEq`, which honors both the
    optional `doc_ref` and the `lic_ref`).
  - For text-bearing files, push a `License` entry using the
    LicenseRef's `Display` form for both `name` and `id`.
  - Emit the existing warning only when no match is found. There's
    no canonical-text fallback for project-specific LicenseRefs
    (no equivalent of `LicenseId::text()`), so behavior in the
    no-match case is unchanged from before.

The surrounding `match license.license` becomes `match
&license.license` so the new arm can bind `license_ref:
&Box<LicenseRef>` without moving out of the `LicenseReq`. The
`Spdx` arm's `id` binding becomes a reference too; the only
adjustment is dereferencing `*id` inside `evaluate`'s closure.

Concrete real-world impact: bundlers consuming Slint can now
clarify their LicenseRef-Slint-Royalty-free-2.0 election and get
the actual license text in their generated attribution, instead of
a textless section + per-crate warning. The same applies to any
project using a LicenseRef-* identifier (REUSE-compliant projects
hosted in non-SPDX-blessed corners of the ecosystem; Embark's own
about.toml example for `ring` only happens to work today because
ring's clarified license is `OpenSSL` — a real SPDX id).
@ruffsl ruffsl requested a review from Jake-Shadle as a code owner May 6, 2026 03:03
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.

1 participant