Skip to content

Commit

Permalink
(puppetlabsGH-121) Add Puppet Strings helper methods
Browse files Browse the repository at this point in the history
The Puppet Strings gem uses YARD to parse the relevant files, however this is
not useful for the Sidecar as we need access to the ruby objects, not a markdown
or JSON file being created.  This commit:

* Adds a PuppetStringsHelper which can configure and execute YARD in the same
  way Puppet Strings does and then allow the Sidecar to extract the information
  it needs later.
* Later commits will modify the helper to understand the various metadata the
  Sidecar needs.
* Adds a caching layer to the results of running YARD. This means that if a
  file is queried more than once, YARD will only be executed once as running
  YARD is an expensive exercise.
* Monkey patches YARD to suppress ALL output.  By default the command line
  parameters still emit text of STDOUT, STDERR which breaks the STDIO transport
  for the Sidecar.
  • Loading branch information
glennsarti committed May 22, 2019
1 parent 3214177 commit 33abbde
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
95 changes: 95 additions & 0 deletions lib/puppet-languageserver-sidecar/puppet_strings_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# frozen_string_literal: true

module PuppetLanguageServerSidecar
module PuppetStringsHelper
# Returns a FileDocumentation object for a given path
#
# @param [String] path The absolute path to the file that will be documented
# @return [FileDocumentation, nil] Returns the documentation for the path, or nil if it cannot be extracted
def self.file_documentation(path)
return nil unless require_puppet_strings
@helper_cache = FileDocumentationCache.new if @helper_cache.nil?
return @helper_cache.document(path) if @helper_cache.path_exists?(path)
PuppetLanguageServerSidecar.log_message(:debug, "[PuppetStringsHelper::file_documentation] Fetching documentation for #{path}")

setup_yard!

# For now, assume a single file path
search_patterns = [path]

# Format the arguments to YARD
args = ['doc']
args << '--no-output'
args << '--quiet'
args << '--no-stats'
args << '--no-progress'
args << '--no-save'
args << '--api public'
args << '--api private'
args << '--no-api'
args += search_patterns

# Run YARD
::YARD::CLI::Yardoc.run(*args)

# Populate the documentation cache from the YARD information
@helper_cache.populate_from_yard_registry!

# Return the documentation details
@helper_cache.document(path)
end

def self.require_puppet_strings
return @puppet_strings_loaded unless @puppet_strings_loaded.nil?
begin
require 'puppet-strings'
require 'puppet-strings/yard'
require 'puppet-strings/json'
@puppet_strings_loaded = true
rescue LoadError => e
PuppetLanguageServerSidecar.log_message(:error, "[PuppetStringsHelper::require_puppet_strings] Unable to load puppet-strings gem: #{e}")
@puppet_strings_loaded = false
end
@puppet_strings_loaded
end
private_class_method :require_puppet_strings

def self.setup_yard!
unless @yard_setup # rubocop:disable Style/GuardClause
::PuppetStrings::Yard.setup!
@yard_setup = true
end
end
private_class_method :setup_yard!
end

class FileDocumentationCache
def initialize
# Hash of <[String] path, FileDocumentation> objects
@cache = {}
end

def path_exists?(path)
@cache.key?(path)
end

def document(path)
@cache[path]
end

def populate_from_yard_registry!
# Extract all of the information
# Ref - https://github.com/puppetlabs/puppet-strings/blob/87a8e10f45bfeb7b6b8e766324bfb126de59f791/lib/puppet-strings/json.rb#L10-L16
end

private

class FileDocumentation
# The path to file that has been documented
attr_reader :path

def initialize(path)
@path = path
end
end
end
16 changes: 16 additions & 0 deletions lib/puppet-languageserver-sidecar/puppet_strings_monkey_patches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

require 'yard/logging'
module YARD
class Logger < ::Logger
# Suppress ANY output
def self.instance(_pipe = STDOUT)
@logger ||= new(nil)
end

# Suppress ANY progress indicators
def show_progress
false
end
end
end

0 comments on commit 33abbde

Please sign in to comment.