Skip to content

feat: populate component.authors #648

Open

Description

@fkleon

Relating to the (upcoming) 4.0.0 release:

The author field is currently missing in the resulting SBOM but could be populated from the project.authors field in pyproject.toml (although pyproject allows multiple authors).

See:

Activity

  1. jkowalleck commented on Jan 10, 2024

    @jkowalleck
    Member

    need to reflect:

  2. jkowalleck commented on Jan 10, 2024

    @jkowalleck
    Member

    the "authors" feature was removed in v4 for the fact thast some things were just uncertain.
    CycloneDX allows exactly one author. Python projects may have multiple ...

    to be clarified: which parts of the "author" should be used? there are multiples:

    • name
    • email-address

    to be clarified: how to describe multiple authors? see CycloneDX/specification#335

    • concatenate multiple with a & or |?
    • just use the first author and thats is it
    • just use the first author and add a "et al."(Latin "and others", commonly practice in legal area) - ala Jane Doe <jd@acme.org> et al.

    need to clarify with CycloneDX core team and specification partners.

  3. changed the title [-] feat: populate component metadata author information from pyproject.toml[/-] [+] feat: `populate component.author`[/+] on Jan 10, 2024
  4. changed the title [-] feat: `populate component.author`[/-] [+] feat: populate `component.author`[/+] on Jan 10, 2024
  5. jkowalleck commented on Feb 2, 2024

    @jkowalleck
    Member

    since v4 was published and released (:tada:), this feature request is open for contributors. Feel free to discuss solutions or open pull requests. Please see the existing requirements and spec descriptions above.

  6. jkowalleck commented on May 3, 2024

    @jkowalleck
    Member

    further: CycloneDX 1.6 got versatile support for $.components[].authors (deprecating $.components[].author)

    expected result could be: Populate $.components[].authors with a structure, and, additionally, populate $.components[].author with a derived string.

  7. changed the title [-] feat: populate `component.author`[/-] [+] feat: populate `component.authors`[/+] on May 3, 2024
  8. changed the title [-] feat: populate `component.authors`[/-] [+]feat: populate `component.authors`[/+] on Jan 29, 2025
  9. SemyonAndreyev commented on Sep 25, 2026

    @SemyonAndreyev

    Thanks for the review, moving the discussion here as asked. Went through all three, tested the actual behavior before replying rather than arguing from memory.

    1. Custom parsing vs email.utils.parseaddr

    Tested both against a wider set of inputs, including the ones I wrote the custom matcher for:

    'jd@acme.org'                          parseaddr-guard: ('', 'jd@acme.org')   mine: ('jd@acme.org', None)  <- mine is wrong here
    'Jane Doe <>'                          parseaddr-guard: ('Jane Doe <>', '')    mine: ('Jane Doe', None)     <- guard is wrong here
    'Jane Doe <jd@acme.org> <extra@x.org>' parseaddr-guard: ('Jane Doe', 'jd@acme.org')  mine: rejected, no usable data
    'A, B <a@x.com>, C <b@y.com>'          parseaddr-guard: ('', 'Multiple')       mine: rejected, no usable data
    

    So it's not one-sided: your guard correctly classifies a bare email as an email, and my matcher gets that wrong (real bug, will fix regardless of how this discussion ends). But the guard also silently mis-parses malformed multi-address strings (getaddresses/parseaddr doesn't validate there's only one address — it just grabs the first plausible fragment and drops the rest, no error). Given pyproject.toml authors/maintainers fields are free text some tooling fills in a "Name, Name " shape by mistake, I'd rather not silently emit a wrong contact for that input.

    Proposal: keep parseaddr as the actual parser (drop my hand-rolled regex, you're right it's not needed for the core case), but validate first that the string doesn't itself look like more than one address before handing it off — that fixes the bare-email bug you're pointing at without reintroducing the multi-address footgun. Small diff, happy to push it once we agree on the three points here.

    2. Leniency in pep621.py

    Agreed, dropping the fallback. You're right that the file's own docstring scopes it to the spec, and the "in the wild" string form belongs with Poetry/packaging handling (which already have their own free-text parsing), not here. Will remove it from project2authors().

    3. Joining multiple authors with ' & '

    Agreed to implement it as you suggested, with one adjustment — Contact objects don't need an isinstance(x, str) filter (they're never anything else here), but I'll filter out any contact with no usable name/email before joining, so an author entry with only, say, an empty string doesn't produce a stray ' & '. Something like:

    ' & '.join(c.name or c.email for c in contacts if c.name or c.email)

    Wanted to flag: this reopens the exact ambiguity you called out yourself in the issue two years ago (#648, your 2024-01-10 comment — "need to clarify with CycloneDX core team and specification partners", referencing specification#335, which is still open/unresolved upstream). I don't have a stake in that spec discussion — just noting it so it's a deliberate choice, not an oversight, if ' & ' ends up needing to change later when the spec does resolve it.

    Will hold off touching #1096 until you've had a look at this — didn't want to push changes and have you re-review the same disagreement twice.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions