class Fauxhai::Mocker

def data

def data
  @fauxhai_data ||= lambda do
    # If a path option was specified, use it
    if @options[:path]
      filepath = File.expand_path(@options[:path])
      unless File.exist?(filepath)
        raise Fauxhai::Exception::InvalidPlatform.new("You specified a path to a JSON file on the local system that does not exist: '#{filepath}'")
      end
    else
      filepath = File.join(platform_path, "#{version}.json")
    end
    if File.exist?(filepath)
      parse_and_validate(File.read(filepath))
    elsif @options[:github_fetching]
      # Try loading from github (in case someone submitted a PR with a new file, but we haven't
      # yet updated the gem version). Cache the response locally so it's faster next time.
      require "open-uri" unless defined?(OpenURI)
      begin
        response = URI.open("#{RAW_BASE}/lib/fauxhai/platforms/#{platform}/#{version}.json")
      rescue OpenURI::HTTPError
        raise Fauxhai::Exception::InvalidPlatform.new("Could not find platform '#{platform}/#{version}' on the local disk and an HTTP error was encountered when fetching from Github. #{PLATFORM_LIST_MESSAGE}")
      end
      if response.status.first.to_i == 200
        response_body = response.read
        path = Pathname.new(filepath)
        FileUtils.mkdir_p(path.dirname)
        begin
          File.open(filepath, "w") { |f| f.write(response_body) }
        rescue Errno::EACCES # a pretty common problem in CI systems
          puts "Fetched '#{platform}/#{version}' from GitHub, but could not write to the local path: #{filepath}. Fix the local file permissions to avoid downloading this file every run."
        end
        return parse_and_validate(response_body)
      else
        raise Fauxhai::Exception::InvalidPlatform.new("Could not find platform '#{platform}/#{version}' on the local disk and an Github fetching returned http error code #{response.status.first.to_i}! #{PLATFORM_LIST_MESSAGE}")
      end
    else
      raise Fauxhai::Exception::InvalidPlatform.new("Could not find platform '#{platform}/#{version}' on the local disk and Github fetching is disabled! #{PLATFORM_LIST_MESSAGE}")
    end
  end.call
end

def initialize(options = {}, &override_attributes)

Options Hash: (**options)
  • :github_fetching (Bool) --
  • :path (String) --
  • :version (String) --
  • :platform (String) --

Parameters:
  • options (Hash) --
def initialize(options = {}, &override_attributes)
  @options = { github_fetching: true }.merge(options)
  yield(data) if block_given?
end

def parse_and_validate(unparsed_data)

and eventually remove them while giving end users ample warning.
to regenerate all fauxhai data. This allows us to deprecate old releases
As major releases of Ohai ship it's difficult and sometimes impossible
def parse_and_validate(unparsed_data)
  parsed_data = JSON.parse(unparsed_data)
  if parsed_data["deprecated"]
    STDERR.puts "WARNING: Fauxhai platform data for #{parsed_data["platform"]} #{parsed_data["platform_version"]} is deprecated and will be removed in the 10.0 release 3/2022. #{PLATFORM_LIST_MESSAGE}"
  end
  parsed_data
end

def platform

def platform
  @options[:platform] ||= begin
                            STDERR.puts "WARNING: you must specify a 'platform' and optionally a 'version' for your ChefSpec Runner and/or Fauxhai constructor, in the future omitting the platform will become a hard error. #{PLATFORM_LIST_MESSAGE}"
                            "chefspec"
                          end
end

def platform_path

def platform_path
  File.join(Fauxhai.root, "lib", "fauxhai", "platforms", platform)
end

def version

def version
  @version ||= begin
    if File.exist?("#{platform_path}/#{@options[:version]}.json")
      # Whole version, use it as-is.
      @options[:version]
    else
      # Check if it's a prefix of an existing version.
      versions = Dir["#{platform_path}/*.json"].map { |path| File.basename(path, ".json") }
      unless @options[:version].to_s == ""
        # If the provided version is nil or '', that means take anything,
        # otherwise run the prefix match with an extra \D to avoid the
        # case where "7.1" matches "7.10.0".
        prefix_re = /^#{Regexp.escape(@options[:version])}\D/
        versions.select! { |ver| ver =~ prefix_re }
      end
      if versions.empty?
        # No versions available, either an unknown platform or nothing matched
        # the prefix check. Pass through the option as given so we can try
        # github fetching.
        @options[:version]
      else
        # Take the highest version available, trying to use rules that should
        # probably mostly work on all OSes. Famous last words. The idea of
        # the regex is to split on any punctuation (the common case) and
        # also any single letter with digit on either side (2012r2). This
        # leaves any long runs of letters intact (4.2-RELEASE). Then convert
        # any run of digits to an integer to get version-ish comparison.
        # This is basically a more flexible version of Gem::Version.
        versions.max_by do |ver|
          ver.split(/[^a-z0-9]|(?<=\d)[a-z](?=\d)/i).map do |part|
            if part =~ /^\d+$/
              part.to_i
            else
              part
            end
          end
        end
      end
    end
  end
end