Class: Decidim::DependencyResolver::Lookup

Inherits:
Object
  • Object
show all
Defined in:
lib/decidim/dependency_resolver.rb

Overview

The lookup class takes care of the individual recursive lookups over a dependency tree.

Instance Method Summary collapse

Constructor Details

#initialize(debug: false) ⇒ Lookup

Returns a new instance of Lookup.

Parameters:

  • debug (Boolean) (defaults to: false)

    A boolean indicating if the debug mode is enabled or not. False by default.



159
160
161
162
163
164
165
166
167
168
# File 'lib/decidim/dependency_resolver.rb', line 159

def initialize(debug: false)
  @current_level = 0
  return unless debug

  formatter = proc do |_severity, _datetime, _progname, msg|
    "#{msg}\n"
  end
  @logger = Logger.new($stdout, formatter:)
  logger.debug!
end

Instance Method Details

#find(dependencies, gem) {|dependency| ... } ⇒ Bundler::LazySpecification?

Iterates recursively through the runtime dependencies array and their sub-dependencies to find whether the provided gem is included. This always iterates through the whole dependency tree even when the gem is already found in order not to process the same dependencies multiple times and to make the cache work correctly when calling this.

Parameters:

  • dependencies (Array)

    An array of the dependencies to iterate through.

  • gem (String)

    The name of the gem to find.

Yields:

  • (dependency)

    Yields each dependency to be processed to the provided block to check if that dependency needs to be processed or not.

Returns:

  • (Bundler::LazySpecification, nil)

    The specification for the gem or nil when it is not found.



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/decidim/dependency_resolver.rb', line 188

def find(dependencies, gem, &)
  found = nil
  dependencies.each do |dependency|
    next unless process?(dependency, &)

    spec = spec(dependency.name)
    next unless spec # E.g. the "bundler" gem is not in the locked gems

    log(dependency)

    found ||= spec if spec.name == gem

    @current_level += 1
    # Do not se the found value directly here because otherwise the
    # recursive call would not be made if the target gem is already found.
    sub_spec = find(spec.dependencies, gem, &)
    @current_level -= 1
    found ||= sub_spec
  end

  found
end

#spec(name) ⇒ Gem::Specification?

Finds a gem specification from the locked gems of the instance.

Note that this does not resolve if the module is needed or not. This may also return the gem specification even when it is not listed in the Gemfile, e.g. when the Decidim gems are installed through git.

Parameters:

  • name (String)

    The name of the gem to find.

Returns:

  • (Gem::Specification, nil)

    The specification for the gem or nil if the gem is not listed in the locked gems or nil when the returned spec is not installed in the current gem environment.



221
222
223
224
225
226
227
228
229
230
# File 'lib/decidim/dependency_resolver.rb', line 221

def spec(name)
  sp = Bundler.definition.locked_gems.specs.find { |s| s.name == name }

  # Fetching the gem through Gem.loaded_specs ensures we are not returning
  # a lazy specification which does not respond to `#full_gem_path` which
  # is needed for the resolver.
  return Gem.loaded_specs[sp.name] if sp

  nil
end