# class Chef::Knife::SubcommandLoader

### Attributes

chef_config_dir[R]
env[R]

### Public Class Methods

new(chef_config_dir, env=ENV) click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 27
    def initialize(chef_config_dir, env=ENV)
      @chef_config_dir, @env = chef_config_dir, env
      @forced_activate = {}
    end

### Public Instance Methods

find_subcommands_via_dirglob() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 108
    def find_subcommands_via_dirglob
      # The "require paths" of the core knife subcommands bundled with chef
      files = Dir[File.expand_path('../../../knife/*.rb', __FILE__)]
      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_manifest() click to toggle source

If the user has created a ~/.chef/plugin_manifest.json file, we’ll use that instead of inspecting the on-system gems to find the plugins. The file format is expected to look like:

    { "plugins": {
        "knife-ec2": {
          "paths": [
            "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_create.rb",
            "/home/alice/.rubymanagerthing/gems/knife-ec2-x.y.z/lib/chef/knife/ec2_server_delete.rb"
          ]
        }
      }
    }

Extraneous content in this file is ignored. This intentional so that we can adapt the file format for potential behavior changes to knife in the future.

    # File lib/chef/knife/core/subcommand_loader.rb, line 95
    def find_subcommands_via_manifest
      # Format of subcommand_files is "relative_path" (something you can
      # Kernel.require()) => full_path. The relative path isn't used
      # currently, so we just map full_path => full_path.
      subcommand_files = {}
      plugin_manifest["plugins"].each do |plugin_name, plugin_manifest|
        plugin_manifest["paths"].each do |cmd_path|
          subcommand_files[cmd_path] = cmd_path
        end
      end
      subcommand_files.merge(find_subcommands_via_dirglob)
    end

find_subcommands_via_rubygems() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 119
    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]
        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/subcommand_loader.rb, line 62
    def gem_and_builtin_subcommands
      if have_plugin_manifest?
        find_subcommands_via_manifest
      else
        # search all gems for chef/knife/*.rb
        require 'rubygems'
        find_subcommands_via_rubygems
      end
    rescue LoadError
      find_subcommands_via_dirglob
    end

have_plugin_manifest?() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 130
    def have_plugin_manifest?
      ENV["HOME"] && File.exist?(plugin_manifest_path)
    end

load_commands() click to toggle source

Load all the sub-commands

    # File lib/chef/knife/core/subcommand_loader.rb, line 33
    def load_commands
      subcommand_files.each { |subcommand| Kernel.load subcommand }
      true
    end

plugin_manifest() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 134
    def plugin_manifest
      Chef::JSONCompat.from_json(File.read(plugin_manifest_path))
    end

plugin_manifest_path() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 138
    def plugin_manifest_path
      File.join(ENV['HOME'], '.chef', 'plugin_manifest.json')
    end

site_subcommands() click to toggle source

Returns an Array of paths to knife commands located in chef_config_dir/plugins/knife/ and ~/.chef/plugins/knife/

    # File lib/chef/knife/core/subcommand_loader.rb, line 40
    def site_subcommands
      user_specific_files = []

      if chef_config_dir
        user_specific_files.concat Dir.glob(File.expand_path("plugins/knife/*.rb", chef_config_dir))
      end

      # finally search ~/.chef/plugins/knife/*.rb
      user_specific_files.concat Dir.glob(File.join(env['HOME'], '.chef', 'plugins', 'knife', '*.rb')) if env['HOME']

      user_specific_files
    end

subcommand_files() click to toggle source

    # File lib/chef/knife/core/subcommand_loader.rb, line 74
    def subcommand_files
      @subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq
    end