Module: Conify::Command
Defined Under Namespace
Classes: AbstractCommand, Global
Constant Summary collapse
- CMD_BLACKLIST =
[]
Instance Method Summary collapse
- #command_description(command_info_module) ⇒ Object
-
#command_file_paths ⇒ Object
Feturn an array of all command file paths, with the exception of abstract_command.rb.
- #command_valid_args(command_info_module) ⇒ Object
- #commands ⇒ Object
-
#create_commands_map ⇒ Object
Create a commands map to respond to ‘conify help` with.
- #error_no_command ⇒ Object
-
#file_for_command(command) ⇒ Object
Create a command file path from the name of a command.
-
#find_command(cmd, args = []) ⇒ Object
Finds file/method for command.
-
#get_basename_from_file(file) ⇒ Object
Return just the basename for a file, no extensions.
-
#handle_invalid_args(command_info_module) ⇒ Object
Respond to the user in the instance of invalid arguments.
-
#klass_for_file(file) ⇒ Object
Get a command klass back from a file path: Example I/O: ‘command/bundles’ –> Conify::Command::Bundles.
-
#klass_has_method?(klass, method) ⇒ Boolean
Check to see if user-defined method exists on a klass.
-
#register_command(basename, action, command_class, global: false) ⇒ Object
register a command’s info to the @@commands map - utilized when calling ‘conify help`.
-
#respond_with_command_help(command_info_module) ⇒ Object
Respond to command-specific help.
- #respond_with_help ⇒ Object
- #respond_with_version ⇒ Object
-
#run(klass, method) ⇒ Object
Call a method on a klass with certain arguments.
-
#seeking_command_help?(args) ⇒ Boolean
Seeking command-specific help.
-
#seeking_help? ⇒ Boolean
stdin is ‘conify help` or `conify -h`.
-
#seeking_version? ⇒ Boolean
stdin is ‘conify –version` or `conify -v`.
-
#usage_info(map) ⇒ Object
Format a map of commands into help output format.
-
#valid_args?(accepted_arg_formats) ⇒ Boolean
Check if passed-in arguments are valid for a specific format.
Methods included from Helpers
allow_user_response, ask_for_conflux_creds, ask_for_password, ask_for_password_on_windows, camelize, display, echo_off, echo_on, error, exclusive_deep_merge, format_with_bang, host, host_url, kensa_manifest_name, kensa_manifest_path, manifest_content, manifest_filename, manifest_path, manually_added_methods, open_url, running_on_a_mac?, running_on_windows?, site_url, to_table, with_tty
Instance Method Details
#command_description(command_info_module) ⇒ Object
170 171 172 |
# File 'lib/conify/command.rb', line 170 def command_description(command_info_module) command_info_module.const_defined?('DESCRIPTION') ? command_info_module::DESCRIPTION : '' end |
#command_file_paths ⇒ Object
Feturn an array of all command file paths, with the exception of abstract_command.rb
267 268 269 270 |
# File 'lib/conify/command.rb', line 267 def command_file_paths abstract_file = File.join(File.dirname(__FILE__), 'command', 'abstract_command.rb') Dir[File.join(File.dirname(__FILE__), 'command', '*.rb')] - [abstract_file] end |
#command_valid_args(command_info_module) ⇒ Object
166 167 168 |
# File 'lib/conify/command.rb', line 166 def command_valid_args(command_info_module) command_info_module.const_defined?('VALID_ARGS') ? command_info_module::VALID_ARGS : [] end |
#commands ⇒ Object
272 273 274 |
# File 'lib/conify/command.rb', line 272 def commands @@commands ||= {} end |
#create_commands_map ⇒ Object
Create a commands map to respond to ‘conify help` with.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/conify/command.rb', line 196 def create_commands_map # Require all the ruby command files command_file_paths.each do |file| require file # Get basename for the file without the extension basename = get_basename_from_file(file) # Camelcase the basename to be the klass name klass_name = camelize(basename) # return the command klass for this klass_name command_klass = Conify::Command.const_get(klass_name) # For each of the user-defined methods inside this class, create a command for it manually_added_methods(command_klass).each { |method| register_command(basename, method.to_s, command_klass, global: basename == 'global') } end end |
#error_no_command ⇒ Object
120 121 122 123 124 125 |
# File 'lib/conify/command.rb', line 120 def error_no_command error([ "`#{@current_cmd}` is not a conify command.", "Type `conify help` for a list of available commands." ].compact.join("\n")) end |
#file_for_command(command) ⇒ Object
Create a command file path from the name of a command
111 112 113 |
# File 'lib/conify/command.rb', line 111 def file_for_command(command) File.join(File.dirname(__FILE__), 'command', "#{command}.rb") end |
#find_command(cmd, args = []) ⇒ Object
Finds file/method for command
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/conify/command.rb', line 14 def find_command(cmd, args = []) @current_cmd = cmd @current_args = args respond_with_help if seeking_help? respond_with_version if seeking_version? # Separate out primary/secondary commands based on if command was namespaced # e.g. `conify services vs. conify services:add` primary_cmd, secondary_cmd = @current_cmd.split(':') # Get the command file path (string) for the primary command primary_cmd_file = file_for_command(primary_cmd) # If the primary command has it's own file, require it primary_cmd_file_exists = File.exists?(primary_cmd_file) require primary_cmd_file if primary_cmd_file_exists # If a secondary command exists, the primary_cmd_file must be where our command method lies if !secondary_cmd.nil? error_no_command if !primary_cmd_file_exists # Get command_klass for file path. Example response --> Conify::Command::Services command_klass = klass_for_file(primary_cmd_file) # Error out if the command klass doesn't have a method named <secondary_cmd> error_no_command if !klass_has_method?(command_klass, secondary_cmd) run(command_klass, secondary_cmd) # If there's no secondary command, there are 2 options for where the command method could be (in order of priority): # (1) Inside the primary command file as the 'index' method # (2) Inside the global command file, as a method named <primary_cmd> else # Store lambda for later try_global = lambda { require 'conify/command/global' command_klass = Conify::Command::Global error_no_command if !klass_has_method?(command_klass, primary_cmd) run(command_klass, primary_cmd) } # Number 1 above. If primary_cmd file exists, call the index method on it if it exists. # If index method doens't exist, check to see if method is a global command. if primary_cmd_file_exists # Get command_klass for file path. Example response --> Conify::Command::Services command_klass = klass_for_file(primary_cmd_file) klass_has_method?(command_klass, 'index') ? run(command_klass, 'index') : try_global.call # Number 2 above. Check to see if method is a global command inside command/global.rb else try_global.call end end end |
#get_basename_from_file(file) ⇒ Object
Return just the basename for a file, no extensions.
261 262 263 264 |
# File 'lib/conify/command.rb', line 261 def get_basename_from_file(file) basename = Pathname.new(file).basename.to_s basename[0..(basename.rindex('.') - 1)] end |
#handle_invalid_args(command_info_module) ⇒ Object
Respond to the user in the instance of invalid arguments.
152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/conify/command.rb', line 152 def handle_invalid_args(command_info_module) if !@invalid_args.empty? = 'Invalid argument' += 's' if @invalid_args.length > 1 args = @invalid_args.map { |arg| "\"#{arg}\"" }.join(', ') puts " ! #{}: #{args}" else puts " ! Invalid command usage" end respond_with_command_help(command_info_module) end |
#klass_for_file(file) ⇒ Object
Get a command klass back from a file path: Example I/O: ‘command/bundles’ –> Conify::Command::Bundles
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/conify/command.rb', line 99 def klass_for_file(file) # Get basename for the file without the extension basename = get_basename_from_file(file) # Camelcase the basename to be the klass name klass_name = camelize(basename) # return the command klass for this klass_name Conify::Command.const_get(klass_name) end |
#klass_has_method?(klass, method) ⇒ Boolean
Check to see if user-defined method exists on a klass
116 117 118 |
# File 'lib/conify/command.rb', line 116 def klass_has_method?(klass, method) manually_added_methods(klass).include?(method.to_sym) end |
#register_command(basename, action, command_class, global: false) ⇒ Object
register a command’s info to the @@commands map - utilized when calling ‘conify help`
277 278 279 280 281 282 283 |
# File 'lib/conify/command.rb', line 277 def register_command(basename, action, command_class, global: false) command = global ? action : (action == 'index' ? basename : "#{basename}:#{action}") command_info_module = command_class::CommandInfo.const_get(camelize(action)) commands[command] = { description: command_description(command_info_module) } end |
#respond_with_command_help(command_info_module) ⇒ Object
Respond to command-specific help
240 241 242 243 244 245 246 247 248 |
# File 'lib/conify/command.rb', line 240 def respond_with_command_help(command_info_module) help = "\nValid Command Formats:\n\n" command_valid_args(command_info_module).each { |format| help += "# conify #{@current_cmd} #{format.join(' ')}\n" } puts "#{help}\n" end |
#respond_with_help ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/conify/command.rb', line 179 def respond_with_help create_commands_map header = [ 'Usage: conify COMMAND [command-specific-arguments]', 'Type "conify COMMAND --help" for more details about each command', 'Commands:' ].join("\n\n") commands_info = usage_info(commands) puts "\n#{header}" puts "\n#{commands_info}\n\n" exit(0) end |
#respond_with_version ⇒ Object
255 256 257 258 |
# File 'lib/conify/command.rb', line 255 def respond_with_version display "conify #{Conify::VERSION}" exit(0) end |
#run(klass, method) ⇒ Object
Call a method on a klass with certain arguments. Will validate arguments first before calling method.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/conify/command.rb', line 73 def run(klass, method) # Get the command info for this method on this klass command_info_module = klass::CommandInfo.const_get(camelize(method)) # If seeking help for this command with --help or -h if seeking_command_help?(@current_args) puts "\nPurpose: #{command_description(command_info_module)}\n" # respond with command-specific help respond_with_command_help(command_info_module) return end # get the valid arguments defined for this comand valid_args = command_valid_args(command_info_module) if !valid_args?(valid_args) handle_invalid_args(command_info_module) return end klass.new(@current_args.dup).send(method) end |
#seeking_command_help?(args) ⇒ Boolean
Seeking command-specific help. e.g. ‘conify bundles –help`
235 236 237 |
# File 'lib/conify/command.rb', line 235 def seeking_command_help?(args) args.include?('-h') || args.include?('--help') end |
#seeking_help? ⇒ Boolean
stdin is ‘conify help` or `conify -h`
175 176 177 |
# File 'lib/conify/command.rb', line 175 def seeking_help? @current_args.length == 0 && (@current_cmd.empty? || ['help', '--help', '-h'].include?(@current_cmd)) end |
#seeking_version? ⇒ Boolean
stdin is ‘conify –version` or `conify -v`
251 252 253 |
# File 'lib/conify/command.rb', line 251 def seeking_version? @current_args.length == 0 && (@current_cmd == '--version' || @current_cmd == '-v') end |
#usage_info(map) ⇒ Object
Format a map of commands into help output format
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/conify/command.rb', line 218 def usage_info(map) keys = map.keys commands_column_width = keys.max_by(&:length).length + 1 commands_column_width += 2 if commands_column_width < 12 # iterate through each of the commands, create an array # of strings in a `<command> # <description>` format. Sort # them alphabetically, and then join them with new lines. keys.map { |key| command = " #{key}" command += (' ' * (commands_column_width - key.length + 1)) command += "# #{map[key][:description]}" command }.sort_by{ |k| k.downcase }.join("\n") end |
#valid_args?(accepted_arg_formats) ⇒ Boolean
Check if passed-in arguments are valid for a specific format
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/conify/command.rb', line 128 def valid_args?(accepted_arg_formats) valid_args = false accepted_arg_formats.each { |format| # if no arguments exist, and no arguments is an accepted format, args are valid. if format.empty? && @current_args.empty? valid_args = true else passed_in_args = @current_args.clone format.each_with_index { |arg, i| passed_in_args[i] = arg if CMD_BLACKLIST.include?(arg) } @invalid_args = passed_in_args - format - [nil] valid_args = true if passed_in_args == format end } valid_args end |