Skip to content

Add Maintainers and FundingLinks to core.Package - #110

Merged
andrew merged 1 commit into
git-pkgs:mainfrom
abhinavgautam01:feat/package-maintainers-funding-links
Oct 19, 2026
Merged

andrew merged 1 commit into
git-pkgs:mainfrom
abhinavgautam01:feat/package-maintainers-funding-links

Conversation

@abhinavgautam01

Copy link
Copy Markdown
Contributor

Closes #34

Problem

enrichment exposes PackageInfo.Maintainers and PackageInfo.FundingLinks, but only the ecosyste.ms backend fills them in. The direct-registry backend can't, because core.Package has neither field. Maintainers were only available through a separate FetchMaintainers call per package. That means N extra requests for BulkFetchPackages callers. Funding links weren't normalized at all: npm and RubyGems left them in registry-specific Metadata.

Change

core.Package gets two new fields:

// Maintainers is populated when the package endpoint already returns
// maintainer data. It is nil otherwise; use FetchMaintainers instead.
Maintainers []Maintainer

// FundingLinks lists funding or sponsorship URLs declared for the
// package. It is nil when the registry exposes none.
FundingLinks []string

Both are filled only from data the package endpoint already returns, so FetchPackage makes no extra requests.

Registry Maintainers FundingLinks source
npm packument maintainers funding (string, object or array)
hex package owners meta.links entries labelled Sponsor, Funding, Donate, etc.
rubygems nil (needs owners.json) funding_uri
pypi nil (not exposed) project_urls entries labelled Funding, Sponsor, Donate, etc.

Every other registry leaves both fields nil.

Details

  • New helpers in internal/core/funding.go:
    • IsFundingLabel matches labels containing "fund", "sponsor" or "donat", ignoring case.
    • FundingLinksFromLabels returns matching URLs sorted and deduplicated, so results don't depend on map iteration order.
    • AppendFundingLink trims whitespace, skips empty values and drops duplicates.
  • npm funding can be a URL string, an object with a url or an array of either. Links keep their declared order, since npm treats the first entry as primary.
  • Maintainer conversion in npm and hex now lives in shared helpers, so FetchPackage and FetchMaintainers build core.Maintainer the same way. FetchMaintainers returns exactly what it did before.
  • Existing Metadata["funding"] (npm) and Metadata["funding_uri"] (rubygems) entries are kept for compatibility.
  • Cargo is left out. crates.io returns owners from a separate endpoint and doesn't expose funding.
  • The README Package section documents the new fields and which registries fill them.

Follow-up

Once this is released, enrichment.RegistriesClient.BulkLookup can copy both fields straight into PackageInfo (git-pkgs/enrichment#83). That gives the hybrid client parity with ecosyste.ms for packages routed to direct registries.

Tests

  • internal/core/funding_test.go: label matching, sorting, deduplication, whitespace and empty handling.
  • npm: maintainers plus mixed array funding, a package with neither, and a table test covering each funding form (string, object, object without url, array with duplicates and empties, null, unexpected type).
  • hex: owners plus a Sponsor link, and a package with neither.
  • rubygems and pypi: packages with and without funding.
  • Locally, gofmt -l . is clean. go vet ./..., go test -race ./... and golangci-lint run ./... pass, as do the js and wasip1 wasm builds and the tinygo-tagged tests.

@andrew
andrew merged commit 4d31fcf into git-pkgs:main Oct 19, 2026
3 checks passed
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.

Include Maintainers and FundingLinks in core.Package

2 participants