Class: Decidim::DependencyResolver
- Inherits:
-
Object
- Object
- Decidim::DependencyResolver
- Includes:
- Singleton
- Defined in:
- decidim-core/lib/decidim/dependency_resolver.rb
Overview
The dependency resolver provides information about the Decidim module dependencies. For instance, it can be used to check if a particular Decidim module is needed by the instance or not.
This is a singleton utility in order to make it perform better when it is called from different places throughout the application.
Defined Under Namespace
Classes: Lookup
Instance Method Summary collapse
-
#available?(spec) ⇒ Boolean
Resolves whether the module for the gem specification defines the main load file.
-
#initialize ⇒ DependencyResolver
constructor
A new instance of DependencyResolver.
-
#loaded?(spec) ⇒ Boolean
Checks if the module for the gem speficiation has been loaded through ‘require “decidim/foo”`.
-
#lookup(gem) ⇒ Gem::Specification?
Finds a gem specification for the gem with the name provided as the argument.
-
#module_path(spec) ⇒ String
Resolves the main load file path for module defined by the gem specification.
-
#needed?(spec) ⇒ Boolean
Resolves whether the target gem is needed or not, i.e.
Constructor Details
#initialize ⇒ DependencyResolver
Returns a new instance of DependencyResolver.
16 17 18 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 16 def initialize @cache = [] end |
Instance Method Details
#available?(spec) ⇒ Boolean
Resolves whether the module for the gem specification defines the main load file.
82 83 84 85 86 87 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 82 def available?(spec) path = module_path(spec) return false unless path File.exist?(path) end |
#loaded?(spec) ⇒ Boolean
Checks if the module for the gem speficiation has been loaded through ‘require “decidim/foo”`.
96 97 98 99 100 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 96 def loaded?(spec) return false unless available?(spec) $LOADED_FEATURES.include?(module_path(spec)) end |
#lookup(gem) ⇒ Gem::Specification?
Finds a gem specification for the gem with the name provided as the argument.
When bundler is available, searches whether the gem is listed in the Gemfile or required as a dependency for one of the gems in the Gemfile or their dependencies.
When bundler is not available, gets the gem specification from the loaded specs which means any gems available in the gem install folder.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 34 def lookup(gem) # In case the lookup method is called with a spec definition, return the # definition itself. return gem unless gem.is_a?(String) if bundler? lookup = Lookup.new return lookup.spec(gem) if cache.include?(gem) # Keep a local cache of the already processed gems in order to avoid # double lookups. lookup.find(Bundler.definition.dependencies, gem) do |dependency| if potential_module?(dependency.name) cache_miss = cache.exclude?(dependency.name) cache << dependency.name if cache_miss cache_miss else false end end else return unless potential_module?(gem) Gem.loaded_specs[gem] end end |
#module_path(spec) ⇒ String
Resolves the main load file path for module defined by the gem specification.
68 69 70 71 72 73 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 68 def module_path(spec) spec = lookup(spec) return unless spec "#{spec.full_gem_path}/lib/#{spec.name.gsub("-", "/")}.rb" end |
#needed?(spec) ⇒ Boolean
Resolves whether the target gem is needed or not, i.e. does it need to be loaded.
When bundler is available, the dependencies are resolved based on the modules defined in the Gemfile which means that the gem is always needed when it is reported as available by the resolver (i.e. defined as a dependency in the Gemfile itself or one of those gems depend on it).
When bundler is not available, this will check whether the Decidim module provided by the gem has been already required/loaded or not. In this situation, it is impossible to know whether the implementer has intended the gem to be used or not, so we assume in these situations implementers will load all the gems they want before running any initializers. This means that the ‘require “decidim/foo”` statements have to be listed for all modules before the initialization process.
122 123 124 125 126 127 128 129 130 131 |
# File 'decidim-core/lib/decidim/dependency_resolver.rb', line 122 def needed?(spec) spec = lookup(spec) return false unless spec if bundler? available?(spec) else loaded?(spec) end end |