class Chef::Knife::SubcommandLoader::GemGlobLoader

Public Instance Methods

find_subcommands_via_dirglob() click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 48
def find_subcommands_via_dirglob
  # The "require paths" of the core knife subcommands bundled with chef
  files = Dir[File.join(Chef::Util::PathHelper.escape_glob_dir(File.expand_path("../../../knife", __FILE__)), "*.rb")]
  subcommand_files = {}
  files.each do |knife_file|
    rel_path = knife_file[/#{CHEF_ROOT}#{Regexp.escape(File::SEPARATOR)}(.*)\.rb/, 1]
    subcommand_files[rel_path] = knife_file
  end
  subcommand_files
end
find_subcommands_via_rubygems() click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 59
def find_subcommands_via_rubygems
  files = find_files_latest_gems "chef/knife/*.rb"
  subcommand_files = {}
  files.each do |file|
    rel_path = file[/(#{Regexp.escape File.join('chef', 'knife', '')}.*)\.rb/, 1]

    # When not installed as a gem (ChefDK/appbundler in particular), AND
    # a different version of Chef is installed via gems, `files` will
    # include some files from the 'other' Chef install. If this contains
    # a knife command that doesn't exist in this version of Chef, we will
    # get a LoadError later when we try to require it.
    next if from_different_chef_version?(file)

    subcommand_files[rel_path] = file
  end

  subcommand_files.merge(find_subcommands_via_dirglob)
end
gem_and_builtin_subcommands() click to toggle source

Returns a Hash of paths to knife commands built-in to chef, or installed via gem. If rubygems is not installed, falls back to globbing the knife directory. The Hash is of the form {“relative/path” => “/absolute/path”}

# File lib/chef/knife/core/gem_glob_loader.rb, line 41
def gem_and_builtin_subcommands
  require "rubygems" unless defined?(Gem)
  find_subcommands_via_rubygems
rescue LoadError
  find_subcommands_via_dirglob
end
subcommand_files() click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 28
def subcommand_files
  @subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq
end

Private Instance Methods

check_spec_for_glob(spec, glob) click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 112
def check_spec_for_glob(spec, glob)
  dirs = if spec.require_paths.size > 1
           "{#{spec.require_paths.join(',')}}"
         else
           spec.require_paths.first
         end

  glob = File.join(Chef::Util::PathHelper.escape_glob_dir(spec.full_gem_path, dirs), glob)

  Dir[glob].map { |f| f.untaint }
end
find_files_latest_gems(glob, check_load_path = true) click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 80
def find_files_latest_gems(glob, check_load_path = true)
  files = []

  if check_load_path
    files = $LOAD_PATH.map do |load_path|
      Dir["#{File.expand_path glob, Chef::Util::PathHelper.escape_glob_dir(load_path)}#{Gem.suffix_pattern}"]
    end.flatten.select { |file| File.file? file.untaint }
  end

  gem_files = latest_gem_specs.map do |spec|
    # Gem::Specification#matches_for_glob wasn't added until RubyGems 1.8
    if spec.respond_to? :matches_for_glob
      spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
    else
      check_spec_for_glob(spec, glob)
    end
  end.flatten

  files.concat gem_files
  files.uniq! if check_load_path

  files
end
from_different_chef_version?(path) click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 124
def from_different_chef_version?(path)
  matches_any_chef_gem?(path) && !matches_this_chef_gem?(path)
end
latest_gem_specs() click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 104
def latest_gem_specs
  @latest_gem_specs ||= if Gem::Specification.respond_to? :latest_specs
                          Gem::Specification.latest_specs(true) # find prerelease gems
                        else
                          Gem.source_index.latest_specs(true)
                        end
end
matches_any_chef_gem?(path) click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 128
def matches_any_chef_gem?(path)
  path =~ MATCHES_CHEF_GEM
end
matches_this_chef_gem?(path) click to toggle source
# File lib/chef/knife/core/gem_glob_loader.rb, line 132
def matches_this_chef_gem?(path)
  path =~ MATCHES_THIS_CHEF_GEM
end