Module: Cinnabar::GemPathCore
- Defined in:
- lib/cinnabar/gem_path.rb
Overview
These functions may perform disk I/O and can be slow.
Low-level helpers for resolving RubyGems load paths.
This module provides the "expensive" operations: loading RubyGems, locating gem specs, and optionally installing missing gems.
Design goals
- Lazy-load RubyGems: do not
require 'rubygems'at file load time. - Return full require paths: use RubyGems’ resolved paths rather than hand-joining.
- Be usable by higher-level caches: see GemPath.
Class Method Summary collapse
-
.ensure_rubygems! ⇒ void
Ensures RubyGems is loaded.
-
.find_lib_paths(gem_name) ⇒ Array<String>
Returns full load paths for a gem's require paths.
-
.find_or_install_lib_paths(gem_name) ⇒ Array<String>
Returns the gem's load paths; installs the gem when missing.
-
.init_gem_dir_hash(gems, install_gem: true) ⇒ Hash{(String)=>Array<String>}
Builds a mapping from gem name to resolved load paths.
Class Method Details
.ensure_rubygems! ⇒ void
If Ruby was not started with --disable=gems option, this function is unnecessary.
This function must be called only at the point where RubyGems is actually needed (lazy loading).
Do not call require 'rubygems' outside this method.
This method returns an undefined value.
Ensures RubyGems is loaded.
Behavior
- If RubyGems is already available (
::GemandGem::Specification), this is a no-op. - Otherwise, it calls
require 'rubygems'.
65 66 67 68 69 |
# File 'lib/cinnabar/gem_path.rb', line 65 def ensure_rubygems! return if defined?(::Gem) && ::Gem.respond_to?(:Specification) Kernel.require 'rubygems' end |
.find_lib_paths(gem_name) ⇒ Array<String>
Returns full load paths for a gem's require paths.
This uses Gem::Specification#full_require_paths, which returns absolute
directories that should be added to $LOAD_PATH to require files from the gem.
82 83 84 85 86 |
# File 'lib/cinnabar/gem_path.rb', line 82 def find_lib_paths(gem_name) ensure_rubygems! Gem::Specification.find_by_name(gem_name).full_require_paths end |
.find_or_install_lib_paths(gem_name) ⇒ Array<String>
Returns the gem's load paths; installs the gem when missing.
This method is intended for low-level bootstrap scenarios:
- Try to resolve require paths via RubyGems.
- If it fails, warn to stderr and attempt
Gem.install(gem). - Re-resolve paths after successful installation.
Notes
- This method intentionally prints warnings via Kernel.warn.
- Avoid using "advanced" loggers here, because this method may run before other dependencies are available.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/cinnabar/gem_path.rb', line 111 def find_or_install_lib_paths(gem_name) ensure_rubygems! gem = gem_name.to_s begin find_lib_paths(gem) # NOTE: Intentionally rescuing `Exception` here (see original intent). rescue Exception => e # rubocop:disable Lint/RescueException Kernel.warn "[WARN] #{e}; Try installing #{gem}" # Attempt to install; raise if installation fails. specs = Gem.install(gem) Kernel.raise "Failed to install #{gem}" if specs.nil? || specs.empty? find_lib_paths(gem) end end |
.init_gem_dir_hash(gems, install_gem: true) ⇒ Hash{(String)=>Array<String>}
Builds a mapping from gem name to resolved load paths.
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/cinnabar/gem_path.rb', line 138 def init_gem_dir_hash(gems, install_gem: true) gems.map { |name| paths = if install_gem find_or_install_lib_paths(name) else find_lib_paths(name) end [name, paths] }.to_h end |