Module: Rubycom
- Defined in:
- lib/rubycom.rb,
lib/rubycom/version.rb,
lib/rubycom/commands.rb,
lib/rubycom/arguments.rb,
lib/rubycom/documentation.rb
Overview
Upon inclusion in another Module, Rubycom will attempt to call a method in the including module by parsing ARGV for a method name and a list of arguments. If found Rubycom will call the method specified in ARGV with the parameters parsed from the remaining arguments If a Method match can not be made, Rubycom will print help instead by parsing source comments from the including module or it’s included modules.
Defined Under Namespace
Modules: Arguments, Commands, Documentation Classes: CLIError
Constant Summary collapse
- VERSION =
"0.3.0"
Class Method Summary collapse
-
.included(base) ⇒ Object
Detects that Rubycom was included in another module and calls Rubycom#run.
-
.register_completions(base) ⇒ String
Inserts a tab completion into the current user’s .bash_profile with a command entry to register the function for the current running ruby file.
-
.run(base, args = []) ⇒ Object
Looks up the command specified in the first arg and executes with the rest of the args.
-
.run_command(base, command, arguments = []) ⇒ Object
Calls the given Method#name on the given Module after parsing the given Array of arguments.
-
.tab_complete(base, arguments) ⇒ Array
Discovers a list of possible matches to the given arguments Intended for use with bash tab completion.
Class Method Details
.included(base) ⇒ Object
Detects that Rubycom was included in another module and calls Rubycom#run
20 21 22 23 24 25 26 27 28 |
# File 'lib/rubycom.rb', line 20 def self.included(base) raise CLIError, 'base must be a module' if base.class != Module base_file_path = caller.first.gsub(/:\d+:.+/, '') if base_file_path == $0 base.module_eval { Rubycom.run(base, ARGV) } end end |
.register_completions(base) ⇒ String
Inserts a tab completion into the current user’s .bash_profile with a command entry to register the function for the current running ruby file
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/rubycom.rb', line 151 def self.register_completions(base) completion_function = "\n _\#{base}_complete() {\n COMPREPLY=()\n local completions=\"$(ruby \#{File.absolute_path($0)} tab_complete ${COMP_WORDS[*]} 2>/dev/null)\"\n COMPREPLY=( $(compgen -W \"$completions\") )\n }\n complete -o bashdefault -o default -o nospace -F _\#{base}_complete \#{$0.split('/').last}\n END\n\n already_registered = File.readlines(\"\#{Dir.home}/.bash_profile\").map { |line| line.include?(\"_\#{base}_complete()\") }.reduce(:|) rescue false\n if already_registered\n \"Completion function for \#{base} already registered.\"\n else\n File.open(\"\#{Dir.home}/.bash_profile\", 'a+') { |file|\n file.write(completion_function)\n }\n \"Registration complete, run 'source \#{Dir.home}/.bash_profile' to enable auto-completion.\"\n end\nend\n".gsub(/^ {4}/, '') |
.run(base, args = []) ⇒ Object
Looks up the command specified in the first arg and executes with the rest of the args
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/rubycom.rb', line 34 def self.run(base, args=[]) begin raise CLIError, "Invalid base class invocation: #{base}" if base.nil? command = args[0] || nil arguments = args[1..-1] || [] case command when 'register_completions' puts self.register_completions(base) when 'tab_complete' puts self.tab_complete(base, args) when 'help' help_topic = arguments[0] if help_topic.nil? usage = Documentation.get_usage(base) default_usage = Documentation.get_default_commands_usage puts usage puts default_usage return usage+"\n"+default_usage elsif help_topic == 'job' usage = Documentation.get_job_usage(base) puts usage return usage elsif help_topic == 'register_completions' usage = Documentation.get_register_completions_usage(base) puts usage return usage elsif help_topic == 'tab_complete' usage = Documentation.get_tab_complete_usage(base) puts usage return usage else cmd_usage = Documentation.get_command_usage(base, help_topic, arguments[1..-1]) puts cmd_usage return cmd_usage end when 'job' begin raise CLIError, 'No job specified' if arguments[0].nil? || arguments[0].empty? job_hash = YAML.load_file(arguments[0]) job_hash = {} if job_hash.nil? STDOUT.sync = true if arguments.delete('-test') || arguments.delete('--test') puts "[Test Job #{arguments[0]}]" job_hash['steps'].each { |step, step_hash| step = "[Step: #{step}/#{job_hash['steps'].length}]" context = step_hash.select { |key| key!="cmd" }.map { |key, val| "[#{key}: #{val}]" }.join(' ') env = job_hash['env'] || {} env.each { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") } cmd = "[cmd: #{step_hash['cmd']}]" puts "#{[step, context, cmd].join(' ')}" } else puts "[Job #{arguments[0]}]" job_hash['steps'].each { |step, step_hash| step = "[Step: #{step}/#{job_hash['steps'].length}]" context = step_hash.select { |key| key!="cmd" }.map { |key, val| "[#{key}: #{val}]" }.join(' ') env = job_hash['env'] || {} env.each { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") } cmd = "[cmd: #{step_hash['cmd']}]" puts "#{[step, context, cmd].join(' ')}" system(step_hash['cmd']) } end rescue CLIError => e $stderr.puts e end else output = self.run_command(base, command, arguments) std_output = nil std_output = output.to_yaml unless [String, NilClass, TrueClass, FalseClass, Fixnum, Float, Symbol].include?(output.class) puts std_output || output return output end rescue CLIError => e $stderr.puts e $stderr.puts Documentation.get_summary(base) end end |
.run_command(base, command, arguments = []) ⇒ Object
Calls the given Method#name on the given Module after parsing the given Array of arguments
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/rubycom.rb', line 120 def self.run_command(base, command, arguments=[]) arguments = [] if arguments.nil? raise CLIError, 'No command specified.' if command.nil? || command.length == 0 begin raise CLIError, "Invalid Command: #{command}" unless Commands.get_top_level_commands(base).include? command.to_sym if base.included_modules.map { |mod| mod.name.to_sym }.include?(command.to_sym) self.run_command(eval(command), arguments[0], arguments[1..-1]) else method = base.public_method(command.to_sym) raise CLIError, "No public method found for symbol: #{command.to_sym}" if method.nil? param_defs = Arguments.get_param_definitions(method) args = Arguments.parse_arguments(param_defs, arguments) flatten = false params = method.parameters.map { |arr| flatten = true if arr[0]==:rest; args[arr[1]] } if flatten rest_arr = params.delete_at(-1) rest_arr.each { |arg| params << arg } end (arguments.nil? || arguments.empty?) ? method.call : method.call(*params) end rescue CLIError => e $stderr.puts e $stderr.puts Documentation.get_command_usage(base, command, arguments) end end |
.tab_complete(base, arguments) ⇒ Array
Discovers a list of possible matches to the given arguments Intended for use with bash tab completion
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rubycom.rb', line 179 def self.tab_complete(base, arguments) arguments = [] if arguments.nil? args = (arguments.include?("tab_complete")) ? arguments[2..-1] : arguments matches = [''] if args.nil? || args.empty? matches = Rubycom::Commands.get_top_level_commands(base).map { |sym| sym.to_s } elsif args.length == 1 matches = Rubycom::Commands.get_top_level_commands(base).map { |sym| sym.to_s }.select { |word| !word.match(/^#{args[0]}/).nil? } if matches.size == 1 && matches[0] == args[0] matches = self.tab_complete(Kernel.const_get(args[0].to_sym), args[1..-1]) end elsif args.length > 1 begin matches = self.tab_complete(Kernel.const_get(args[0].to_sym), args[1..-1]) rescue Exception matches = [''] end end unless base.nil? matches = [''] if matches.nil? || matches.include?(args[0]) matches end |