Module: Rigor::Environment::RbsCollectionDiscovery
- Defined in:
- lib/rigor/environment/rbs_collection_discovery.rb
Overview
rbs collection install awareness (O4 Layer 3 slice 2, implemented).
When the target project has been set up with rbs collection install (the standard RBS-ecosystem flow
for pulling community RBS from https://github.com/ruby/gem_rbs_collection), a
rbs_collection.lock.yaml records the resolved (gem, version, source) triples and
.gem_rbs_collection/<name>/ <version>/ carries the actual .rbs files. This module parses the
lockfile and returns the per-gem RBS directory paths so they can be appended to RbsLoader's
signature_paths:.
The discovery is intentionally a pure file-system + YAML walk — no Bundler API call, no network access. Failure modes (missing lockfile, malformed YAML, missing collection directory) silently degrade to an empty list.
Constant Summary collapse
- SKIPPED_SOURCE_TYPES =
stdlib-typed entries in the lockfile are loaded into the RBS environment by the standard library mechanism (rigor'sEnvironment::DEFAULT_LIBRARIESalready covers this surface). Including them assignature_paths:entries would riskRBS::DuplicatedDeclarationError(the same hazard O7's failure-memo handles). The other documented source types —git(the gem_rbs_collection repo),rubygems(sigs lifted from a gem's bundledsig/), andlocal(a user-managed RBS dir) — all produce a directory under the collection root and are admitted.The
source.typefilter alone is NOT sufficient: gems that were extracted from Ruby's stdlib into standalone default gems (e.g.cgi,logger,base64,csv,bigdecimal) are published inruby/gem_rbs_collectionunder agitsource type, yet rigor ALSO loads them from its bundled stdlib viaDEFAULT_LIBRARIES. Loading both copies triggers the veryRBS::DuplicatedDeclarationErrorthis module exists to avoid (observed on a Rails 8 app:.gem_rbs_collection/ cgi/0.5/vs the bundledstdlib/cgi). Theskip_gem_names:parameter lets the caller pass the set of library names rigor already loads so those gems are dropped regardless ofsource.type. Set["stdlib"].freeze
Class Method Summary collapse
-
.discover(lockfile_path:, project_root: Dir.pwd, auto_detect: true, skip_gem_names: []) ⇒ Array<Pathname>
Every
<collection_path>/<gem-name>/<gem-version>/directory listed in the lockfile whose entry has a non-skipped source type, whosenameis not inskip_gem_names:, and whose directory exists on disk. -
.resolve_lockfile_path(lockfile_path:, project_root: Dir.pwd, auto_detect: true) ⇒ Object
Returns the resolved lockfile path (
Pathname) ornilwhen neither explicit nor auto-detect produces one.
Class Method Details
.discover(lockfile_path:, project_root: Dir.pwd, auto_detect: true, skip_gem_names: []) ⇒ Array<Pathname>
Returns every <collection_path>/<gem-name>/<gem-version>/ directory listed in the
lockfile whose entry has a non-skipped source type, whose name is not in skip_gem_names:, and
whose directory exists on disk. Returns [] when no lockfile is resolvable, when the YAML is
unreadable, or when the collection path doesn't exist.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rigor/environment/rbs_collection_discovery.rb', line 54 def self.discover(lockfile_path:, project_root: Dir.pwd, auto_detect: true, skip_gem_names: []) resolved = resolve_lockfile_path( lockfile_path: lockfile_path, project_root: project_root, auto_detect: auto_detect ) return [] if resolved.nil? data = read_lockfile_yaml(resolved) return [] if data.nil? collection_root = resolve_collection_root(resolved, data) return [] unless collection_root.directory? gem_paths_from(collection_root, data, skip_gem_names.to_set) end |
.resolve_lockfile_path(lockfile_path:, project_root: Dir.pwd, auto_detect: true) ⇒ Object
Returns the resolved lockfile path (Pathname) or nil when neither explicit nor auto-detect
produces one. Public so the stats banner can surface what rigor found.
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/rigor/environment/rbs_collection_discovery.rb', line 73 def self.resolve_lockfile_path(lockfile_path:, project_root: Dir.pwd, auto_detect: true) if lockfile_path path = Pathname.new(File.(lockfile_path.to_s, project_root)) return path if path.file? return nil end return nil unless auto_detect candidate = Pathname.new(File.join(project_root, "rbs_collection.lock.yaml")) candidate.file? ? candidate : nil end |