Module: Solargraph::Yardoc

Defined in:
lib/solargraph/yardoc.rb

Overview

Methods for caching and loading YARD documentation for gems.

Class Method Summary collapse

Class Method Details

.cache(yard_plugins, gemspec) ⇒ String

Build and cache a gem’s yardoc and return the path. If the cache already exists, do nothing and return the path.

Parameters:

  • yard_plugins (Array<String>)

    The names of YARD plugins to use.

  • gemspec (Gem::Specification)

Returns:

  • (String)

    The path to the cached yardoc.



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
# File 'lib/solargraph/yardoc.rb', line 17

def cache yard_plugins, gemspec
  path = PinCache.yardoc_path gemspec
  return path if cached?(gemspec)

  unless Dir.exist? gemspec.gem_dir
    # Can happen in at least some (old?) RubyGems versions when we
    # have a gemspec describing a standard library like bundler.
    #
    # https://github.com/apiology/solargraph/actions/runs/17650140201/job/50158676842?pr=10
    Solargraph.logger.info { "Bad info from gemspec - #{gemspec.gem_dir} does not exist" }
    return path
  end

  Solargraph.logger.info "Caching yardoc for #{gemspec.name} #{gemspec.version}"
  cmd = "yardoc --db #{path} --no-output --plugin solargraph"
  yard_plugins.each { |plugin| cmd << " --plugin #{plugin}" }
  Solargraph.logger.debug { "Running: #{cmd}" }
  # @todo set these up to run in parallel
  # @todo Is the chdir argument being used here?
  # @sg-ignore Unrecognized keyword argument chdir to Open3.capture2e
  stdout_and_stderr_str, status = Open3.capture2e(current_bundle_env_tweaks, cmd, chdir: gemspec.gem_dir)
  unless status.success?
    Solargraph.logger.warn { "YARD failed running #{cmd.inspect} in #{gemspec.gem_dir}" }
    Solargraph.logger.info stdout_and_stderr_str
  end
  path
end

.cached?(gemspec) ⇒ Boolean

True if the gem yardoc is cached.

Parameters:

  • gemspec (Gem::Specification)

Returns:

  • (Boolean)


48
49
50
51
# File 'lib/solargraph/yardoc.rb', line 48

def cached? gemspec
  yardoc = File.join(PinCache.yardoc_path(gemspec), 'complete')
  File.exist?(yardoc)
end

.current_bundle_env_tweaksHash{String => String}

If the BUNDLE_GEMFILE environment variable is set, we need to make sure it’s an absolute path, as we’ll be changing directories.

‘bundle exec’ sets an absolute path here, but at least the overcommit gem does not, breaking on-the-fly documention with a spawned yardoc command from our current bundle

Returns:

  • (Hash{String => String})

    a hash of environment variables to override



81
82
83
84
85
86
87
88
# File 'lib/solargraph/yardoc.rb', line 81

def current_bundle_env_tweaks
  tweaks = {}
  # @sg-ignore Unresolved call to empty? on String, nil
  if ENV['BUNDLE_GEMFILE'] && !ENV['BUNDLE_GEMFILE'].empty?
    tweaks['BUNDLE_GEMFILE'] = File.expand_path(ENV['BUNDLE_GEMFILE'])
  end
  tweaks
end

.load!(gemspec) ⇒ Array<YARD::CodeObjects::Base>

Note:

This method modifies the global YARD registry.

Load a gem’s yardoc and return its code objects.

Parameters:

  • gemspec (Gem::Specification)

Returns:

  • (Array<YARD::CodeObjects::Base>)


67
68
69
70
# File 'lib/solargraph/yardoc.rb', line 67

def load! gemspec
  YARD::Registry.load! PinCache.yardoc_path gemspec
  YARD::Registry.all
end

.processing?(gemspec) ⇒ Boolean

True if another process is currently building the yardoc cache.

Parameters:

  • gemspec (Gem::Specification)

Returns:

  • (Boolean)


56
57
58
59
# File 'lib/solargraph/yardoc.rb', line 56

def processing? gemspec
  yardoc = File.join(PinCache.yardoc_path(gemspec), 'processing')
  File.exist?(yardoc)
end