feat(gem,maven): extend multi-platform release patching to RubyGems + Maven#91
Merged
Mikola Lysenko (mikolalysenko) merged 1 commit intoMay 28, 2026
Merged
Conversation
… Maven Generalizes the PyPI multi-release machinery (release-variant qualifiers, narrow/broad download, base-PURL remove/rollback) to the other ecosystems that ship multiple platform/release artifacts per package@version: * RubyGems — platform gems (`?platform=x86_64-linux`, `?platform=arm64-darwin`) * Maven — classifier jars (`?classifier=linux-x86_64&ext=jar`) NuGet/npm/Cargo/Go/Composer/Deno are unaffected: they ship one artifact per version (platform splits live under separate package names), so they keep the 1:1 PURL match path. Shared generalization: - Ecosystem::supports_release_variants() (Pypi | Gem | Maven) replaces the scattered `== Ecosystem::Pypi` gates in apply/get/dispatch. - ecosystem_dispatch: rename pypi-specific dedup_pypi_purls/merge_pypi_qualified to dedup_qualified_purls/merge_qualified and apply them to the gem and maven scan blocks. The crawler is queried with base PURLs and the installed variant is resolved by hashing on-disk files — the same model PyPI uses. - select_installed_variant -> plural select_installed_variants returning ALL present-and-matching variants. PyPI/RubyGems install exactly one distribution per environment (≤1 match, unchanged), but Maven classifier jars coexist in one version dir, so several may match. apply.rs applies every matching variant (no early `break`); the get narrow-filter and rollback dedupe keep all matches. RubyGems: - RubyCrawler::parse_dir_name_version now splits at the first dash-digit and drops the trailing `-<platform>` suffix, fixing a misparse that folded the platform into the version (`nokogiri-1.16.5-x86_64-linux` -> version `1.16.5-x86_64-linux`). New locate_gem_dir resolves a base name/version to the installed platform-suffixed gem directory. Maven needs no crawler change: find_by_purls already emits the base PURL keyed to the version directory, and each classifier variant is hash-resolved against its jar file. Maven stays behind SOCKET_EXPERIMENTAL_MAVEN and still leaves `.jar.sha1` sidecars stale (no fixup — unchanged). Tests: - in_process_gem_multi_platform.rs: synthetic platform gem (no `gem` binary) + wiremock — narrow keeps the installed platform, broad keeps all, remove base PURL clears all variants and rolls back, rollback-all exits 0. - in_process_remote_ecosystems_apply.rs: maven_multi_classifier test proving the plural selector patches every coexisting classifier jar. - Unit tests for gem dir-name platform parsing (incl. the regression case and a trailing-OS-version platform) and the supports_release_variants predicate. Full workspace suite: 1580 passed, 0 failed; clippy clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wenxin Jiang (Wenxin-Jiang)
approved these changes
May 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Generalizes the PyPI multi-release machinery from #90 (release-variant qualifiers, narrow/broad download, base-PURL
remove/rollback) to the other ecosystems that ship multiple platform/release artifacts perpackage@version:?platform=x86_64-linux?classifier=linux-x86_64&ext=jarNuGet / npm / Cargo / Go / Composer / Deno are unaffected — they ship one artifact per version (platform splits live under separate package names), so they keep the 1:1 PURL-match path.
Shared generalization
Ecosystem::supports_release_variants()(Pypi | Gem | Maven) replaces the scattered== Ecosystem::Pypigates in apply / get / dispatch.dedup_pypi_purls/merge_pypi_qualified→ genericdedup_qualified_purls/merge_qualified, now applied to the gem and maven scan blocks. The crawler is queried with base PURLs and the installed variant is resolved by hashing on-disk files — the same model PyPI uses.select_installed_variant→select_installed_variantsreturning all present-and-matching variants. PyPI/RubyGems install exactly one distribution per env (≤1 match — unchanged), but Maven classifier jars coexist, so several may match.apply.rsapplies every matching variant (no earlybreak); the get narrow-filter and rollback dedupe keep all matches.RubyGems
RubyCrawler::parse_dir_name_versionnow splits at the first dash-digit and drops the trailing-<platform>suffix, fixing a misparse that folded the platform into the version (nokogiri-1.16.5-x86_64-linux→ version1.16.5-x86_64-linux).locate_gem_dirresolves a base name/version to the installed platform-suffixed gem directory.Maven
find_by_purlsalready emits the base PURL keyed to the version dir; each classifier variant is hash-resolved against its jar file. Stays behindSOCKET_EXPERIMENTAL_MAVEN; still leaves.jar.sha1sidecars stale (no fixup — unchanged, out of scope).Tests
in_process_gem_multi_platform.rs— synthetic platform gem (nogembinary) + wiremock: narrow keeps the installed platform, broad keeps all,removebase PURL clears all variants and rolls back, rollback-all exits 0.in_process_remote_ecosystems_apply.rs—maven_multi_classifiertest proving the plural selector patches every coexisting classifier jar.supports_release_variantspredicate.Full workspace suite: 1580 passed, 0 failed; clippy gate clean.
Companion backend change (separate, depscan repo)
The patch API must emit qualified PURLs for gem/maven. In depscan,
orgs/patches/{by-package,batch}.tsdrop the&& type===PYPIgate (normalizeArtifactPURLalready converts a non-PyPIartifact_idinto qualifiers). Per-platform gemartifactrows already exist; note the autopatch pipeline currently authors gem patches against the canonicalplatform=rubyartifact, so full per-platform patch authoring is a separate pipeline change.Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com