13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/otto/optional_dependency.rb', line 13
def require!(gem_name, requirement, require_path:, feature:, alternative: nil)
version_requirement = Gem::Requirement.new(requirement)
guidance = "Add `gem '#{gem_name}', '#{requirement}'` to your Gemfile."
guidance = "#{guidance} #{alternative}" if alternative
installed_specs = Gem::Specification.find_all_by_name(gem_name)
active_spec = Gem.loaded_specs[gem_name]
compatible_spec = if active_spec && version_requirement.satisfied_by?(active_spec.version)
active_spec
else
installed_specs
.select { |spec| version_requirement.satisfied_by?(spec.version) }
.max_by(&:version)
end
unless compatible_spec
installed = installed_specs.map(&:version).sort.join(', ')
reason = installed.empty? ? 'it is not installed' : "installed version(s) #{installed} are incompatible"
raise OptionalDependencyError,
"#{feature} requires optional dependency '#{gem_name}' (#{version_requirement}), but #{reason}. #{guidance}"
end
load_error = begin
compatible_spec.activate
require require_path
nil
rescue LoadError => e
e
end
raise_load_error!(feature, gem_name, version_requirement, guidance, load_error) if load_error
compatible_spec
end
|