class Yoda::Store::Project::LibraryDocLoader

Attributes

errors[R]

@param errors [Array<BaseError>]

gem_specs[R]

@param gem_specs [Array<Objects::ProjectStatus::GemStatus, Bundler::LazySpecification>]

registry[R]

@return [Registry]

Public Class Methods

build_for(project) click to toggle source

@param project [Project] @return [LibraryDocLoader]

# File lib/yoda/store/project/library_doc_loader.rb, line 17
def build_for(project)
  new(registry: project.registry, gem_specs: gem_specs(project))
end
new(registry:, gem_specs:) click to toggle source

@param registry [Registry] @param gem_specs [Array<Objects::ProjectStatus::GemStatus, Bundler::LazySpecification>]

# File lib/yoda/store/project/library_doc_loader.rb, line 41
def initialize(registry:, gem_specs:)
  @registry = registry
  @gem_specs = gem_specs
  @errors = []
end

Private Class Methods

gem_specs(project) click to toggle source
# File lib/yoda/store/project/library_doc_loader.rb, line 31
def gem_specs(project)
  lockfile_parser = parse_gemfile_lock(project.root_path, Cache.gemfile_lock_path(project.root_path))
  (lockfile_parser&.specs || []).reject do |spec|
    spec.source.is_a?(Bundler::Source::Path) && (File.expand_path(spec.source.path) == File.expand_path(project.root_path))
  end
end
parse_gemfile_lock(root_path, gemfile_lock_path) click to toggle source

@return [Bundler::LockfileParser, nil]

# File lib/yoda/store/project/library_doc_loader.rb, line 24
def parse_gemfile_lock(root_path, gemfile_lock_path)
  return if !gemfile_lock_path || !File.exists?(gemfile_lock_path)
  Dir.chdir(root_path) do
    Bundler::LockfileParser.new(File.read(gemfile_lock_path))
  end
end

Public Instance Methods

run() click to toggle source
# File lib/yoda/store/project/library_doc_loader.rb, line 47
def run
  project_status = registry.project_status || Objects::ProjectStatus.initial_build(specs: gem_specs)
  new_bundle_status = update_bundle(project_status.bundle)
  registry.save_project_status(project_status.derive(bundle: new_bundle_status))
end

Private Instance Methods

import_core(bundle_status) click to toggle source

@param bundle_status [Objects::ProjectStatus::BundleStatus] @return [Objects::ProjectStatus::BundleStatus]

# File lib/yoda/store/project/library_doc_loader.rb, line 79
def import_core(bundle_status)
  result = Actions::ImportCoreLibrary.run(registry)
  errors.push(CoreImportError.new('core')) unless result
  bundle_status.derive(std_status: bundle_status.std_status.derive(core_present: !!result))
end
import_deps(bundle_status) click to toggle source

Try to import missing gems and core libraries. @param bundle_status [Objects::ProjectStatus::BundleStatus] @return [Objects::ProjectStatus::BundleStatus]

# File lib/yoda/store/project/library_doc_loader.rb, line 70
def import_deps(bundle_status)
  Instrument.instance.initialization_progress(phase: :load_core, message: 'Loading core index')
  bundle_status = import_core(bundle_status) unless bundle_status.std_status.core_present?
  bundle_status = import_std(bundle_status) unless bundle_status.std_status.std_present?
  import_gems(bundle_status)
end
import_gems(bundle_status) click to toggle source

@param bundle_status [Objects::ProjectStatus::BundleStatus] @return [Objects::ProjectStatus::BundleStatus]

# File lib/yoda/store/project/library_doc_loader.rb, line 95
def import_gems(bundle_status)
  present_gem_statuses, absent_gem_statuses = bundle_status.gem_statuses.partition { |gem_status| gem_status.present? }

  progress = Instrument::Progress.new(absent_gem_statuses.length) do |index:, length:|
    Instrument.instance.initialization_progress(phase: :load_gems, message: "Loading gems (#{index} / #{length})", index: index, length: length)
  end

  new_gem_statuses = absent_gem_statuses.map do |gem_status|
    result = Actions::ImportGem.run(registry: registry, gem_name: gem_status.name, gem_version: gem_status.version)
    progress.increment
    errors.push(GemImportError.new(name: gem_status.name, version: gem_status.version)) unless result
    gem_status.derive(present: result)
  end

  bundle_status.derive(gem_statuses: present_gem_statuses + new_gem_statuses)
end
import_std(bundle_status) click to toggle source

@param bundle_status [Objects::ProjectStatus::BundleStatus] @return [Objects::ProjectStatus::BundleStatus]

# File lib/yoda/store/project/library_doc_loader.rb, line 87
def import_std(bundle_status)
  result = Actions::ImportStdLibrary.run(registry)
  errors.push(CoreImportError.new('std')) unless result
  bundle_status.derive(std_status: bundle_status.std_status.derive(std_present: !!result))
end
update_bundle(bundle_status) click to toggle source

@param bundle_status [Objects::ProjectStatus::BundleStatus] @return [Objects::ProjectStatus::BundleStatus]

# File lib/yoda/store/project/library_doc_loader.rb, line 57
def update_bundle(bundle_status)
  unless bundle_status.all_present?
    Logger.info 'Constructing database for the current project.'
    bundle_status = import_deps(bundle_status)
    Instrument.instance.initialization_progress(phase: :save, message: 'Saving registry')
    registry.compress_and_save
  end
  bundle_status
end