Class: Chef::Knife::SubcommandLoader
- Inherits:
-
Object
- Object
- Chef::Knife::SubcommandLoader
- Defined in:
- lib/chef/knife/core/subcommand_loader.rb
Constant Summary collapse
- MATCHES_CHEF_GEM =
%r{/chef-[\d]+\.[\d]+\.[\d]+}.freeze
- MATCHES_THIS_CHEF_GEM =
%r{/chef-#{Chef::VERSION}/}.freeze
Instance Attribute Summary collapse
-
#chef_config_dir ⇒ Object
readonly
Returns the value of attribute chef_config_dir.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
Instance Method Summary collapse
- #find_subcommands_via_dirglob ⇒ Object
-
#find_subcommands_via_manifest ⇒ Object
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.
- #find_subcommands_via_rubygems ⇒ Object
-
#gem_and_builtin_subcommands ⇒ Object
Returns a Hash of paths to knife commands built-in to chef, or installed via gem.
- #have_plugin_manifest? ⇒ Boolean
-
#initialize(chef_config_dir, env = nil) ⇒ SubcommandLoader
constructor
A new instance of SubcommandLoader.
-
#load_commands ⇒ Object
Load all the sub-commands.
- #plugin_manifest ⇒ Object
- #plugin_manifest_path ⇒ Object
-
#site_subcommands ⇒ Object
Returns an Array of paths to knife commands located in chef_config_dir/plugins/knife/ and ~/.chef/plugins/knife/.
- #subcommand_files ⇒ Object
Constructor Details
#initialize(chef_config_dir, env = nil) ⇒ SubcommandLoader
Returns a new instance of SubcommandLoader.
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 31 def initialize(chef_config_dir, env=nil) @chef_config_dir = chef_config_dir @forced_activate = {} # Deprecated and un-used instance variable. @env = env unless env.nil? Chef::Log.deprecation("The env argument to Chef::Knife::SubcommandLoader is deprecated. If you are using env to inject/mock HOME, consider mocking Chef::Util::PathHelper.home instead.") end end |
Instance Attribute Details
#chef_config_dir ⇒ Object (readonly)
Returns the value of attribute chef_config_dir.
28 29 30 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 28 def chef_config_dir @chef_config_dir end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
29 30 31 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 29 def env @env end |
Instance Method Details
#find_subcommands_via_dirglob ⇒ Object
120 121 122 123 124 125 126 127 128 129 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 120 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(File.('../../../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_manifest ⇒ Object
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.
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 107 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 ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 131 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 ⇒ Object
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 => “/absolute/path” – Note: the “right” way to load the plugins is to require the relative path, i.e.,
require 'chef/knife/command'
but we’re getting frustrated by bugs at every turn, and it’s slow besides. So subcommand loader has been modified to load the plugins by using Kernel.load with the absolute path.
74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 74 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? ⇒ Boolean
150 151 152 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 150 def have_plugin_manifest? plugin_manifest_path && File.exist?(plugin_manifest_path) end |
#load_commands ⇒ Object
Load all the sub-commands
43 44 45 46 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 43 def load_commands subcommand_files.each { |subcommand| Kernel.load subcommand } true end |
#plugin_manifest ⇒ Object
154 155 156 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 154 def plugin_manifest Chef::JSONCompat.from_json(File.read(plugin_manifest_path)) end |
#plugin_manifest_path ⇒ Object
158 159 160 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 158 def plugin_manifest_path Chef::Util::PathHelper.home('.chef', 'plugin_manifest.json') end |
#site_subcommands ⇒ Object
Returns an Array of paths to knife commands located in chef_config_dir/plugins/knife/ and ~/.chef/plugins/knife/
50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 50 def site_subcommands user_specific_files = [] if chef_config_dir user_specific_files.concat Dir.glob(File.("plugins/knife/*.rb", Chef::Util::PathHelper.escape_glob(chef_config_dir))) end # finally search ~/.chef/plugins/knife/*.rb Chef::Util::PathHelper.home('.chef', 'plugins', 'knife') do |p| user_specific_files.concat Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(p), '*.rb')) end user_specific_files end |
#subcommand_files ⇒ Object
86 87 88 |
# File 'lib/chef/knife/core/subcommand_loader.rb', line 86 def subcommand_files @subcommand_files ||= (gem_and_builtin_subcommands.values + site_subcommands).flatten.uniq end |