rubycom 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +86 -5
- data/Rakefile +12 -6
- data/lib/rubycom/version.rb +1 -1
- data/lib/rubycom.rb +118 -175
- data/rubycom.gemspec +1 -1
- data/test/rubycom/test_rubycom.rb +100 -30
- data/test/rubycom/util_test_job.yaml +21 -0
- data/test/rubycom/util_test_module.rb +8 -1
- data/test/rubycom/util_test_no_singleton.rb +9 -9
- metadata +5 -3
data/README.md
CHANGED
@@ -21,6 +21,89 @@ by simply including Rubycom at the bottom.
|
|
21
21
|
* Command consoles can be built up by including other modules before including Rubycom.
|
22
22
|
* Included modules become commands, their public singleton methods become sub-commands.
|
23
23
|
|
24
|
+
Usage
|
25
|
+
---------------
|
26
|
+
|
27
|
+
Write your module of methods, document them as you normally would. `include Rubycom` at the bottom.
|
28
|
+
Optionally `#!/usr/bin/env ruby` at the top.
|
29
|
+
|
30
|
+
Now any singleton methods `def self.method_name` will be available to call from the terminal.
|
31
|
+
|
32
|
+
Calling `ruby ./path/to/module.rb <command_name>` will automatically discover and run your `<command_name>` singleton method.
|
33
|
+
If no method is found by the given name, a usage print out will be given including a summary of each command available
|
34
|
+
and it's description from the corresponding method's comments.
|
35
|
+
|
36
|
+
Calling a valid command with incorrect arguments will produce a usage print out for the matched method.
|
37
|
+
Rubycom will include as much documentation on the command line as you provide in your method comments. Currently Rubycom
|
38
|
+
only handles @param and @return annotation style comments for discovering the method comments regarding params and return values.
|
39
|
+
All other commentary will be included as part of the command description. In the absence of @param or @return comments,
|
40
|
+
Rubycom will also leave off the corresponding Param: and Return: markers in the usage output.
|
41
|
+
|
42
|
+
#####Special commands
|
43
|
+
|
44
|
+
| Command | Description | Options |
|
45
|
+
| ------- |:-----------:| -------:|
|
46
|
+
| `ruby ./path/to/module.rb help [command_name]` | Will print out usage for the module or optionally the specified command.||
|
47
|
+
| `ruby ./path/to/module.rb job </path/to/job.yaml>` | Runs the specified job file. See: "Jobs" below. | `--test` Prints the steps and context without running the commands. |
|
48
|
+
|
49
|
+
|
50
|
+
###Arguments
|
51
|
+
|
52
|
+
* Arguments are automatically parsed from the command line using Ruby's core Yaml module.
|
53
|
+
* Arguments will be passed to your method in order of their appearance on the command line.
|
54
|
+
* If you specify a default value for a parameter in your method, then Rubycom will look for a named argument matching
|
55
|
+
the parameter's name.
|
56
|
+
* Users may call out option parameters in any order using `--<param_name>=<value>` or `--<param_name> <value>`
|
57
|
+
* Currently Rubycom does not yet support sort names for optional parameters so specifying `-<param_name>`
|
58
|
+
is equivalent to `--<param_name>`
|
59
|
+
* In the absence of a named option, any optional parameters still unfilled will be filled by unnamed arguments in
|
60
|
+
order of appearance.
|
61
|
+
* Optional parameters which do not get overridden either by a named option specification or an available unnamed
|
62
|
+
argument will be filled by their default as usual.
|
63
|
+
* If a rest parameter `*param_name` is defined in the method being called, any remaining arguments will be passed to the
|
64
|
+
rest parameter after the required and optional parameters are filled.
|
65
|
+
|
66
|
+
###Jobs
|
67
|
+
|
68
|
+
Jobs are a higher order orchestration mechanism for command line utilities. Rubycom provides a simple job runner to every
|
69
|
+
command line utility. by calling `ruby ./path/to/module.rb job </path/to/job.yaml>` with a valid job yaml. Rubycom will
|
70
|
+
run your job.
|
71
|
+
|
72
|
+
* A valid job file is a Yaml file which specifies a `steps` node and any number of valid numbered child nodes
|
73
|
+
* Optionally, an `env` node may specified.
|
74
|
+
* If specified, `env` should include child nodes which are `key: value` pairs Ex: `working_dir: ./test/rubycom`
|
75
|
+
* If an `env` is specified, values may be inserted into commands in the `steps` node as such: `env['key']`
|
76
|
+
* Ex: `ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]`
|
77
|
+
* A valid `steps` child node is a numbered node `1:` with a `cmd:` child node and optionally several context `desc:`
|
78
|
+
child nodes.
|
79
|
+
* A `cmd:` node should specify the command string to run. Ex: `cmd: ls ./test_folder`
|
80
|
+
* A context node should specify some text to be placed with the node's key in a formatted
|
81
|
+
logging context Ex: `desc: Run test_composite_command`
|
82
|
+
|
83
|
+
Below is an example job file which demonstrates the format Rubycom supports.
|
84
|
+
|
85
|
+
---
|
86
|
+
env:
|
87
|
+
test_msg: Hello World
|
88
|
+
test_arg: 123
|
89
|
+
working_dir: ./test/rubycom
|
90
|
+
steps:
|
91
|
+
1:
|
92
|
+
desc: Run test_composite_command with environment variable
|
93
|
+
cmd: ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]
|
94
|
+
2:
|
95
|
+
Var: Run UtilTestModule/test_command_options_arr with environment variable
|
96
|
+
cmd: ruby env[working_dir]/util_test_composite.rb UtilTestModule test_command_options_arr '["Hello World", world2]'
|
97
|
+
3:
|
98
|
+
Context: Run test_command_with_args with environment variable
|
99
|
+
cmd: ruby env[working_dir]/util_test_module.rb test_command_with_args env[test_msg] env[test_arg]
|
100
|
+
4:
|
101
|
+
Cmd: Run ls for arbitrary command support
|
102
|
+
cmd: ls
|
103
|
+
5:
|
104
|
+
Arbitrary_Context: Run ls with environment variable
|
105
|
+
cmd: ls env[working_dir]
|
106
|
+
|
24
107
|
|
25
108
|
Raison d'etre
|
26
109
|
---------------
|
@@ -53,9 +136,7 @@ The result is a function library which can be consumed easily from other classes
|
|
53
136
|
|
54
137
|
Coming Soon
|
55
138
|
---------------
|
56
|
-
*
|
57
|
-
* Job help/usage output will include descriptions from command for each step
|
58
|
-
* Build a job yaml by running each command in sequence with a special option --job_add <path_to_yaml>
|
139
|
+
* Build a job yaml by running each command in sequence with a special option --job_add <path_to_yaml>[:step_number]
|
59
140
|
* Edit job files from the command line using special options.
|
60
|
-
* --job_update <path_to_yaml>
|
61
|
-
* --
|
141
|
+
* --job_update <path_to_yaml>[:step_number]
|
142
|
+
* --job_remove <path_to_yaml>[:step_number]
|
data/Rakefile
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
require "
|
2
|
-
require 'rake/testtask'
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/lib/rubycom/version.rb"
|
3
2
|
require 'yard'
|
4
3
|
|
5
|
-
task :default => [:
|
4
|
+
task :default => [:package]
|
5
|
+
|
6
|
+
task :clean do
|
7
|
+
FileUtils.rm_rf('./doc')
|
8
|
+
FileUtils.rm_rf('./.yardoc')
|
9
|
+
FileUtils.rm_rf('./pkg')
|
10
|
+
FileUtils.rm(Dir.glob('./rubycom-*.gem'))
|
11
|
+
end
|
6
12
|
|
7
13
|
task :test do
|
8
14
|
test_files = Dir.glob("**/test/*/test_*.rb")
|
@@ -14,7 +20,7 @@ end
|
|
14
20
|
|
15
21
|
YARD::Rake::YardocTask.new
|
16
22
|
|
17
|
-
task :package => [:test, :yard] do
|
23
|
+
task :package => [:clean, :test, :yard] do
|
18
24
|
gem_specs = Dir.glob("**/*.gemspec")
|
19
25
|
gem_specs.each { |gem_spec|
|
20
26
|
system("gem build #{gem_spec}")
|
@@ -23,9 +29,9 @@ task :package => [:test, :yard] do
|
|
23
29
|
end
|
24
30
|
|
25
31
|
task :install => :package do
|
26
|
-
system
|
32
|
+
system("gem install rubycom-#{Rubycom::VERSION}")
|
27
33
|
end
|
28
34
|
|
29
35
|
task :release => :package do
|
30
|
-
system
|
36
|
+
system("gem push ./rubycom-#{Rubycom::VERSION}.gem")
|
31
37
|
end
|
data/lib/rubycom/version.rb
CHANGED
data/lib/rubycom.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "#{File.expand_path(File.dirname(__FILE__))}/rubycom/version.rb"
|
2
2
|
require 'yaml'
|
3
|
+
require 'find'
|
3
4
|
require 'method_source'
|
4
5
|
|
5
6
|
# Upon inclusion in another Module, Rubycom will attempt to call a method in the including module by parsing
|
@@ -8,7 +9,8 @@ require 'method_source'
|
|
8
9
|
# If a Method match can not be made, Rubycom will print help instead by parsing source comments from the including
|
9
10
|
# module or it's included modules.
|
10
11
|
module Rubycom
|
11
|
-
class CLIError < StandardError;
|
12
|
+
class CLIError < StandardError;
|
13
|
+
end
|
12
14
|
|
13
15
|
# Detects that Rubycom was included in another module and calls Rubycom#run
|
14
16
|
#
|
@@ -44,6 +46,36 @@ module Rubycom
|
|
44
46
|
puts cmd_usage
|
45
47
|
return cmd_usage
|
46
48
|
end
|
49
|
+
elsif command == 'job'
|
50
|
+
begin
|
51
|
+
raise CLIError, 'No job specified' if arguments[0].nil? || arguments[0].empty?
|
52
|
+
job_hash = YAML.load_file(arguments[0])
|
53
|
+
STDOUT.sync = true
|
54
|
+
if arguments.delete('-test') || arguments.delete('--test')
|
55
|
+
puts "[Test Job #{arguments[0]}]"
|
56
|
+
job_hash['steps'].each { |step, step_hash|
|
57
|
+
step = "[Step: #{step}/#{job_hash['steps'].length}]"
|
58
|
+
context = step_hash.select{|key| key!="cmd"}.map{|key,val| "[#{key}: #{val}]"}.join(' ')
|
59
|
+
env = job_hash['env'] || {}
|
60
|
+
env.map { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") }
|
61
|
+
cmd = "[cmd: #{step_hash['cmd']}]"
|
62
|
+
puts "#{[step,context,cmd].join(' ')}"
|
63
|
+
}
|
64
|
+
else
|
65
|
+
puts "[Job #{arguments[0]}]"
|
66
|
+
job_hash['steps'].each { |step, step_hash|
|
67
|
+
step = "[Step: #{step}/#{job_hash['steps'].length}]"
|
68
|
+
context = step_hash.select{|key| key!="cmd"}.map{|key,val| "[#{key}: #{val}]"}.join(' ')
|
69
|
+
env = job_hash['env'] || {}
|
70
|
+
env.map { |key, val| step_hash['cmd'].gsub!("env[#{key}]", "#{((val.class == String)&&(val.match(/\w+/))) ? "\"#{val}\"" : val}") }
|
71
|
+
cmd = "[cmd: #{step_hash['cmd']}]"
|
72
|
+
puts "#{[step,context,cmd].join(' ')}"
|
73
|
+
system(step_hash['cmd'])
|
74
|
+
}
|
75
|
+
end
|
76
|
+
rescue CLIError => e
|
77
|
+
$stderr.puts e
|
78
|
+
end
|
47
79
|
else
|
48
80
|
output = self.run_command(base, command, arguments)
|
49
81
|
std_output = nil
|
@@ -53,7 +85,8 @@ module Rubycom
|
|
53
85
|
end
|
54
86
|
|
55
87
|
rescue CLIError => e
|
56
|
-
|
88
|
+
$stderr.puts e
|
89
|
+
$stderr.puts self.get_summary(base)
|
57
90
|
end
|
58
91
|
end
|
59
92
|
|
@@ -64,36 +97,20 @@ module Rubycom
|
|
64
97
|
# @param [Array] arguments a String Array representing the arguments for the given command
|
65
98
|
def self.run_command(base, command, arguments=[])
|
66
99
|
raise CLIError, 'No command specified.' if command.nil? || command.length == 0
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
self.run_command(eval(command), arguments[0], arguments[1..-1])
|
72
|
-
else
|
73
|
-
method = base.public_method(command_sym)
|
74
|
-
raise CLIError, "No public method found for symbol: #{command_sym}" if method.nil?
|
75
|
-
parameters = self.get_param_definitions(method)
|
76
|
-
params_hash = self.parse_arguments(parameters, arguments)
|
77
|
-
params = []
|
78
|
-
method.parameters.each { |type, name|
|
79
|
-
if type == :rest
|
80
|
-
if params_hash[name].class == Array
|
81
|
-
params_hash[name].each { |arg|
|
82
|
-
params << arg
|
83
|
-
}
|
84
|
-
else
|
85
|
-
params << params_hash[name]
|
86
|
-
end
|
87
|
-
else
|
88
|
-
params << params_hash[name]
|
89
|
-
end
|
90
|
-
}
|
91
|
-
if arguments.nil? || arguments.empty?
|
92
|
-
output = method.call
|
100
|
+
begin
|
101
|
+
raise CLIError, "Invalid Command: #{command}" unless self.get_top_level_commands(base).include? command.to_sym
|
102
|
+
if base.included_modules.map { |mod| mod.name.to_sym }.include?(command.to_sym)
|
103
|
+
self.run_command(eval(command), arguments[0], arguments[1..-1])
|
93
104
|
else
|
94
|
-
|
105
|
+
method = base.public_method(command.to_sym)
|
106
|
+
raise CLIError, "No public method found for symbol: #{command.to_sym}" if method.nil?
|
107
|
+
param_defs = self.get_param_definitions(method)
|
108
|
+
args = self.parse_arguments(param_defs, arguments)
|
109
|
+
(arguments.nil? || arguments.empty?) ? method.call : method.call(*method.parameters.map { |arr| args[arr[1]]}.flatten)
|
95
110
|
end
|
96
|
-
|
111
|
+
rescue CLIError => e
|
112
|
+
$stderr.puts e
|
113
|
+
$stderr.puts self.get_command_usage(base, command, arguments)
|
97
114
|
end
|
98
115
|
end
|
99
116
|
|
@@ -107,58 +124,32 @@ module Rubycom
|
|
107
124
|
# @param [Array] arguments an Array of Strings representing the arguments to be parsed
|
108
125
|
# @return [Hash] a Hash mapping the defined parameters to their matching argument values
|
109
126
|
def self.parse_arguments(parameters={}, arguments=[])
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
parameters.each_value { |def_hash|
|
116
|
-
req_l += 1 if def_hash[:type] == :req
|
117
|
-
opt_l += 1 if def_hash[:type] == :opt
|
118
|
-
has_rest_param = true if def_hash[:type] == :rest
|
119
|
-
def_hash[:default] = self.parse_arg(def_hash[:default])[:arg] unless def_hash[:default] == :nil_rubycom_required_param
|
120
|
-
}
|
121
|
-
raise CLIError, "Wrong number of arguments. Expected at least #{req_l}, received #{args_l}" if args_l < req_l
|
122
|
-
unless has_rest_param
|
123
|
-
raise CLIError, "Wrong number of arguments. Expected at most #{req_l + opt_l}, received #{args_l}" if args_l > (req_l + opt_l)
|
124
|
-
end
|
125
|
-
|
126
|
-
args = []
|
127
|
-
arguments.each { |arg|
|
128
|
-
args << self.parse_arg(arg)
|
129
|
-
}
|
127
|
+
raise CLIError, 'parameters may not be nil' if parameters.nil?
|
128
|
+
raise CLIError, 'arguments may not be nil' if arguments.nil?
|
129
|
+
types = parameters.values.group_by { |hsh| hsh[:type] }.map { |type, defs_arr| Hash[type, defs_arr.length] }.reduce(&:merge) || {}
|
130
|
+
raise CLIError, "Wrong number of arguments. Expected at least #{types[:req]}, received #{arguments.length}" if arguments.length < (types[:req]||0)
|
131
|
+
raise CLIError, "Wrong number of arguments. Expected at most #{(types[:req]||0) + (types[:opt]||0)}, received #{arguments.length}" if types[:rest].nil? && (arguments.length > ((types[:req]||0) + (types[:opt]||0)))
|
130
132
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
else
|
139
|
-
parsed_options[key]=val
|
140
|
-
end
|
141
|
-
}
|
133
|
+
sorted_args = arguments.map { |arg|
|
134
|
+
Rubycom.parse_arg(arg)
|
135
|
+
}.group_by { |hsh|
|
136
|
+
hsh.keys.first
|
137
|
+
}.map { |key, arr|
|
138
|
+
(key == :rubycom_non_opt_arg) ? Hash[key, arr.map { |hsh| hsh.values }.flatten] : Hash[key, arr.map { |hsh| hsh.values.first }.reduce(&:merge)]
|
139
|
+
}.reduce(&:merge) || {}
|
142
140
|
|
143
|
-
|
144
|
-
parameters.each { |param_name, def_hash|
|
141
|
+
parameters.map { |param_sym, def_hash|
|
145
142
|
if def_hash[:type] == :req
|
146
|
-
raise CLIError, "No argument available for #{
|
147
|
-
|
143
|
+
raise CLIError, "No argument available for #{param_sym}" if sorted_args[:rubycom_non_opt_arg].nil? || sorted_args[:rubycom_non_opt_arg].length == 0
|
144
|
+
Hash[param_sym, sorted_args[:rubycom_non_opt_arg].shift]
|
148
145
|
elsif def_hash[:type] == :opt
|
149
|
-
|
150
|
-
result_hash[param_name] = parsed_args.shift if result_hash[param_name].nil?
|
151
|
-
result_hash[param_name] = parameters[param_name][:default] if result_hash[param_name].nil?
|
146
|
+
Hash[param_sym, ((sorted_args[param_sym]) ? sorted_args[param_sym] : ((sorted_args[:rubycom_non_opt_arg].shift || parameters[param_sym][:default]) rescue parameters[param_sym][:default]))]
|
152
147
|
elsif def_hash[:type] == :rest
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
else
|
157
|
-
result_hash[param_name] = parsed_options[param_name]
|
158
|
-
end
|
148
|
+
ret = Hash[param_sym, ((sorted_args[param_sym]) ? sorted_args[param_sym] : sorted_args[:rubycom_non_opt_arg])]
|
149
|
+
sorted_args[:rubycom_non_opt_arg] = []
|
150
|
+
ret
|
159
151
|
end
|
160
|
-
}
|
161
|
-
result_hash
|
152
|
+
}.reduce(&:merge)
|
162
153
|
end
|
163
154
|
|
164
155
|
# Uses YAML.load to parse the given String
|
@@ -166,41 +157,19 @@ module Rubycom
|
|
166
157
|
# @param [String] arg a String representing the argument to be parsed
|
167
158
|
# @return [Object] the result of parsing the given arg with YAML.load
|
168
159
|
def self.parse_arg(arg)
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
if arg.match(/^--/) != nil
|
180
|
-
arg = arg.reverse.chomp('--').reverse
|
181
|
-
elsif arg.match(/^-/) != nil
|
182
|
-
arg = arg.reverse.chomp('-').reverse
|
183
|
-
end
|
184
|
-
|
185
|
-
if arg.match(/^\w+=/) != nil
|
186
|
-
arg_arr = arg.split('=')
|
187
|
-
param_name = arg_arr.shift.strip
|
188
|
-
arg_val = arg_arr.join('=').lstrip
|
189
|
-
elsif arg.match(/^\w+\s+\S+/) != nil
|
190
|
-
arg_arr = arg.split(' ')
|
191
|
-
param_name = arg_arr.shift
|
192
|
-
arg_val = arg_arr.join(' ')
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
val = YAML.load(arg_val) rescue nil
|
198
|
-
if val.nil?
|
199
|
-
result[param_name.to_sym] = "#{arg_val}"
|
160
|
+
return Hash[:rubycom_non_opt_arg, nil] if arg.nil?
|
161
|
+
if arg.is_a?(String) && ((arg.match(/^[-]{3,}\w+/) != nil) || ((arg.match(/^[-]{1,}\w+/) == nil) && (arg.match(/^\w+=/) != nil)))
|
162
|
+
raise CLIError, "Improper option specification, options must start with one or two dashes. Received: #{arg}"
|
163
|
+
elsif arg.is_a?(String) && arg.match(/^(-|--)\w+[=|\s]{1}/) != nil
|
164
|
+
k, v = arg.partition(/^(-|--)\w+[=|\s]{1}/).select { |part|
|
165
|
+
!part.empty?
|
166
|
+
}.each_with_index.map { |part, index|
|
167
|
+
index == 0 ? part.chomp('=').gsub(/^--/, '').gsub(/^-/, '').strip.to_sym : (YAML.load(part) rescue "#{part}")
|
168
|
+
}
|
169
|
+
Hash[k, v]
|
200
170
|
else
|
201
|
-
|
171
|
+
Hash[:rubycom_non_opt_arg, (YAML.load("#{arg}") rescue "#{arg}")]
|
202
172
|
end
|
203
|
-
result
|
204
173
|
end
|
205
174
|
|
206
175
|
# Retrieves the summary for each command method in the given Module
|
@@ -208,25 +177,13 @@ module Rubycom
|
|
208
177
|
# @param [Module] base the module which invoked 'include Rubycom'
|
209
178
|
# @return [String] the summary for each command method in the given Module
|
210
179
|
def self.get_summary(base)
|
211
|
-
longest_name_length = self.get_longest_command_name(base).length
|
212
180
|
self.get_top_level_commands(base).each_with_index.map { |sym, index|
|
213
|
-
|
214
|
-
if index == 0
|
215
|
-
"Commands:\n" << self.get_command_summary(base, sym, separator)
|
216
|
-
else
|
217
|
-
self.get_command_summary(base, sym, separator)
|
218
|
-
end
|
181
|
+
"#{"Commands:\n" if index == 0}" << self.get_command_summary(base, sym, self.get_separator(sym, self.get_longest_command_name(base).length))
|
219
182
|
}.reduce(:+) or "No Commands found for #{base}."
|
220
183
|
end
|
221
184
|
|
222
185
|
def self.get_separator(sym, spacer_length=0)
|
223
|
-
|
224
|
-
sep_length = spacer_length - cmd_name.length
|
225
|
-
separator = ""
|
226
|
-
sep_length.times {
|
227
|
-
separator << " "
|
228
|
-
}
|
229
|
-
separator << " - "
|
186
|
+
[].unshift(" " * (spacer_length - sym.to_s.length)).join << " - "
|
230
187
|
end
|
231
188
|
|
232
189
|
# Retrieves the summary for the given command_name
|
@@ -238,27 +195,23 @@ module Rubycom
|
|
238
195
|
raise CLIError, "Can not get usage for #{command_name} with base: #{base||"nil"}" if base.nil? || !base.respond_to?(:included_modules)
|
239
196
|
return 'No command specified.' if command_name.nil? || command_name.length == 0
|
240
197
|
if base.included_modules.map { |mod| mod.name.to_sym }.include?(command_name.to_sym)
|
241
|
-
|
198
|
+
mod_const = Kernel.const_get(command_name.to_sym)
|
199
|
+
desc = File.read(mod_const.public_method(mod_const.singleton_methods().first).source_location.first).split(//).reduce(""){|str,c|
|
200
|
+
unless str.gsub("\n",'').gsub(/\s+/,'').include?("module#{mod_const}")
|
201
|
+
str << c
|
202
|
+
end
|
203
|
+
str
|
204
|
+
}.split("\n").select{|line| line.strip.match(/^#/)}.map{|line| line.strip.gsub(/^#+/,'')}.join("\n")
|
242
205
|
else
|
243
206
|
raise CLIError, "Invalid command for #{base}, #{command_name}" unless base.public_methods.include?(command_name.to_sym)
|
244
|
-
|
245
|
-
method_doc = self.get_doc(m)
|
246
|
-
desc = method_doc[:desc].join("\n")
|
207
|
+
desc = self.get_doc(base.public_method(command_name.to_sym))[:desc].join("\n") rescue nil
|
247
208
|
end
|
248
209
|
(desc.nil?||desc=='nil'||desc.length==0) ? "#{command_name}\n" : self.get_formatted_summary(command_name, desc, separator)
|
249
210
|
end
|
250
211
|
|
251
212
|
def self.get_formatted_summary(command_name, command_description, separator = ' - ')
|
252
213
|
width = 95
|
253
|
-
|
254
|
-
command_name.to_s.split(//).each {
|
255
|
-
spacer << " "
|
256
|
-
}
|
257
|
-
sep_space = ""
|
258
|
-
separator.split(//).each {
|
259
|
-
sep_space << " "
|
260
|
-
}
|
261
|
-
prefix = "#{spacer}#{sep_space}"
|
214
|
+
prefix = command_name.to_s.split(//).map { " " }.join + separator.split(//).map { " " }.join
|
262
215
|
line_width = width - prefix.length
|
263
216
|
description_msg = command_description.gsub(/(.{1,#{line_width}})(?: +|$)\n?|(.{#{line_width}})/, "#{prefix}"+'\1\2'+"\n")
|
264
217
|
"#{command_name}#{separator}#{description_msg.lstrip}"
|
@@ -294,17 +247,17 @@ module Rubycom
|
|
294
247
|
m = base.public_method(command_name.to_sym)
|
295
248
|
method_doc = self.get_doc(m)
|
296
249
|
|
297
|
-
|
298
|
-
|
299
|
-
#{
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
END
|
250
|
+
msg = "Usage: #{m.name} #{self.get_param_usage(m)}\n"
|
251
|
+
msg << "#{"Parameters:"}\n" unless m.parameters.empty?
|
252
|
+
msg << "#{method_doc[:param].join("\n ")}\n" unless method_doc[:param].nil?
|
253
|
+
msg << "#{"Returns:"}\n" unless method_doc[:return].nil?
|
254
|
+
msg << "#{method_doc[:return].join("\n ")}\n" unless method_doc[:return].nil?
|
255
|
+
msg
|
304
256
|
end
|
305
257
|
end
|
306
258
|
|
307
259
|
def self.get_param_usage(method)
|
260
|
+
return "" if method.parameters.nil? || method.parameters.empty?
|
308
261
|
method.parameters.map { |type, param| {type => param}
|
309
262
|
}.group_by { |entry| entry.keys.first
|
310
263
|
}.map { |key, val| Hash[key, val.map { |param| param.values.first }]
|
@@ -327,35 +280,29 @@ module Rubycom
|
|
327
280
|
# @return [Hash] a Hash representing the given Method's parameters
|
328
281
|
def self.get_param_definitions(method)
|
329
282
|
raise CLIError, 'method must be an instance of the Method class' unless method.class == Method
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
param_definitions[name.to_sym][:default] = param_definitions[name.to_sym][:def].split('=')[1..-1].join('=')
|
346
|
-
else
|
347
|
-
param_definitions[name.to_sym][:default] = :nil_rubycom_required_param
|
348
|
-
end
|
349
|
-
}
|
350
|
-
param_definitions
|
283
|
+
method.parameters.map { |param|
|
284
|
+
param[1].to_s
|
285
|
+
}.map { |param_name|
|
286
|
+
{param_name.to_sym => method.source.split("\n").select { |line| line.include?(param_name) }.first}
|
287
|
+
}.map { |param_hash|
|
288
|
+
param_def = param_hash.flatten[1].gsub(/(def\s+self\.#{method.name.to_s}|def\s+#{method.name.to_s})/, '').lstrip.chomp.chomp(')').reverse.chomp('(').reverse.split(',').map { |param_n| param_n.lstrip }.select { |candidate| candidate.include?(param_hash.flatten[0].to_s) }.first
|
289
|
+
Hash[
|
290
|
+
param_hash.flatten[0],
|
291
|
+
Hash[
|
292
|
+
:def, param_def,
|
293
|
+
:type, method.parameters.select { |arr| arr[1] == param_hash.flatten[0] }.flatten[0],
|
294
|
+
:default, (param_def.include?('=') ? YAML.load(param_def.split('=')[1..-1].join('=')) : :nil_rubycom_required_param)
|
295
|
+
]
|
296
|
+
]
|
297
|
+
}.reduce(&:merge) || {}
|
351
298
|
end
|
352
299
|
|
353
300
|
# Retrieves the given method's documentation from it's source code.
|
354
301
|
#
|
355
302
|
# @param [Method] method the Method who's documentation should be retrieved
|
356
303
|
# @return [Hash] a Hash representing the given Method's documentation, documentation parsed as follows:
|
357
|
-
# :desc = the first general method comment
|
358
|
-
# :
|
304
|
+
# :desc = the first general method comment lines,
|
305
|
+
# :word = each @word comment (i.e.- a line starting with @param will be saved as :param => ["line"])
|
359
306
|
def self.get_doc(method)
|
360
307
|
method.comment.split("\n").map { |line|
|
361
308
|
line.gsub(/#\s*/, '') }.group_by { |doc|
|
@@ -382,17 +329,13 @@ module Rubycom
|
|
382
329
|
# @return [Hash] a Hash of Symbols representing the command methods in the given base and it's included modules (if all=true)
|
383
330
|
def self.get_commands(base, all=true)
|
384
331
|
return {} if base.nil? || !base.respond_to?(:singleton_methods) || !base.respond_to?(:included_modules)
|
385
|
-
excluded_commands = [:included, :extended]
|
386
|
-
excluded_modules = [:Rubycom]
|
387
332
|
{
|
388
333
|
base.name.to_sym => {
|
389
|
-
commands: base.singleton_methods(true).select { |sym| !
|
390
|
-
inclusions: base.included_modules.select { |mod|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
mod.name.to_sym
|
395
|
-
end
|
334
|
+
commands: base.singleton_methods(true).select { |sym| ![:included, :extended].include?(sym) },
|
335
|
+
inclusions: base.included_modules.select { |mod|
|
336
|
+
![:Rubycom].include?(mod.name.to_sym)
|
337
|
+
}.map { |mod|
|
338
|
+
all ? self.get_commands(mod) : mod.name.to_sym
|
396
339
|
}
|
397
340
|
}
|
398
341
|
}
|
data/rubycom.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "rubycom"
|
8
8
|
spec.version = Rubycom::VERSION
|
9
9
|
spec.authors = ["Danny Purcell"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["d.purcell.jr+rubycom@gmail.com"]
|
11
11
|
spec.description = %q{Allows command-line access for all singleton methods in an including class. Reads Yard style documentation for command line help output. Uses Yaml for parsing options. Allows the user to make a command-line tool by simply including Rubycom at the bottom.}
|
12
12
|
spec.summary = %q{Converts singleton methods to command-line functions upon inclusion.}
|
13
13
|
spec.homepage = "http://dannypurcell.github.io/Rubycom"
|
@@ -113,19 +113,20 @@ class TestRubycom < Test::Unit::TestCase
|
|
113
113
|
UtilTestModule <command> [args]
|
114
114
|
|
115
115
|
Commands:
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
116
|
+
test_command - A basic test command
|
117
|
+
test_command_with_arg - A test_command with one arg
|
118
|
+
test_command_arg_named_arg - A test_command with an arg named arg
|
119
|
+
test_command_with_args - A test_command with two args
|
120
|
+
test_command_with_options - A test_command with an optional argument
|
121
|
+
test_command_all_options - A test_command with all optional arguments
|
122
|
+
test_command_options_arr - A test_command with an options array
|
123
|
+
test_command_with_return - A test_command with a return argument
|
124
|
+
test_command_arg_timestamp - A test_command with a Timestamp argument and an unnecessarily
|
125
|
+
long description which should overflow when
|
126
|
+
it tries to line up with other descriptions.
|
127
|
+
test_command_arg_false - A test_command with a Boolean argument
|
128
|
+
test_command_arg_arr - A test_command with an array argument
|
129
|
+
test_command_arg_hash - A test_command with an Hash argument
|
129
130
|
|
130
131
|
END
|
131
132
|
assert_equal(expected.gsub(/\n|\r|\s/, ''), result.gsub(/\n|\r|\s/, ''))
|
@@ -150,14 +151,15 @@ class TestRubycom < Test::Unit::TestCase
|
|
150
151
|
Commands:
|
151
152
|
test_command - A basic test command
|
152
153
|
test_command_with_arg - A test_command with one arg
|
154
|
+
test_command_arg_named_arg - A test_command with an arg named arg
|
153
155
|
test_command_with_args - A test_command with two args
|
154
156
|
test_command_with_options - A test_command with an optional argument
|
155
157
|
test_command_all_options - A test_command with all optional arguments
|
156
158
|
test_command_options_arr - A test_command with an options array
|
157
159
|
test_command_with_return - A test_command with a return argument
|
158
160
|
test_command_arg_timestamp - A test_command with a Timestamp argument and an unnecessarily
|
159
|
-
long description which should overflow when
|
160
|
-
with other descriptions.
|
161
|
+
long description which should overflow when
|
162
|
+
it tries to line up with other descriptions.
|
161
163
|
test_command_arg_false - A test_command with a Boolean argument
|
162
164
|
test_command_arg_arr - A test_command with an array argument
|
163
165
|
test_command_arg_hash - A test_command with an Hash argument
|
@@ -178,7 +180,7 @@ class TestRubycom < Test::Unit::TestCase
|
|
178
180
|
end
|
179
181
|
|
180
182
|
def test_get_top_level_commands
|
181
|
-
test_command_list = [:test_command, :test_command_with_arg, :test_command_with_args, :test_command_with_options,
|
183
|
+
test_command_list = [:test_command, :test_command_with_arg, :test_command_arg_named_arg, :test_command_with_args, :test_command_with_options,
|
182
184
|
:test_command_all_options, :test_command_options_arr, :test_command_with_return,
|
183
185
|
:test_command_arg_timestamp, :test_command_arg_false, :test_command_arg_arr,
|
184
186
|
:test_command_arg_hash]
|
@@ -219,21 +221,21 @@ class TestRubycom < Test::Unit::TestCase
|
|
219
221
|
def test_parse_arg_string
|
220
222
|
test_arg = "test_arg"
|
221
223
|
result = Rubycom.parse_arg(test_arg)
|
222
|
-
expected = {
|
224
|
+
expected = {rubycom_non_opt_arg: "test_arg"}
|
223
225
|
assert_equal(expected, result)
|
224
226
|
end
|
225
227
|
|
226
228
|
def test_parse_arg_fixnum
|
227
229
|
test_arg = "1234512415435"
|
228
230
|
result = Rubycom.parse_arg(test_arg)
|
229
|
-
expected = {
|
231
|
+
expected = {rubycom_non_opt_arg: 1234512415435}
|
230
232
|
assert_equal(expected, result)
|
231
233
|
end
|
232
234
|
|
233
235
|
def test_parse_arg_float
|
234
236
|
test_arg = "12345.67890"
|
235
237
|
result = Rubycom.parse_arg(test_arg)
|
236
|
-
expected = {
|
238
|
+
expected = {rubycom_non_opt_arg: 12345.67890}
|
237
239
|
assert_equal(expected, result)
|
238
240
|
end
|
239
241
|
|
@@ -241,8 +243,8 @@ class TestRubycom < Test::Unit::TestCase
|
|
241
243
|
time = Time.new
|
242
244
|
test_arg = time.to_s
|
243
245
|
result = Rubycom.parse_arg(test_arg)
|
244
|
-
expected = {
|
245
|
-
assert_equal(expected[:
|
246
|
+
expected = {rubycom_non_opt_arg: time}
|
247
|
+
assert_equal(expected[:rubycom_non_opt_arg].to_i, result[:rubycom_non_opt_arg].to_i)
|
246
248
|
end
|
247
249
|
|
248
250
|
def test_parse_arg_datetime
|
@@ -250,14 +252,14 @@ class TestRubycom < Test::Unit::TestCase
|
|
250
252
|
date = Date.new(time.year, time.month, time.day)
|
251
253
|
test_arg = date.to_s
|
252
254
|
result = Rubycom.parse_arg(test_arg)
|
253
|
-
expected = {
|
255
|
+
expected = {rubycom_non_opt_arg: date}
|
254
256
|
assert_equal(expected, result)
|
255
257
|
end
|
256
258
|
|
257
259
|
def test_parse_arg_array
|
258
260
|
test_arg = ["1", 2, "a", 'b']
|
259
261
|
result = Rubycom.parse_arg(test_arg.to_s)
|
260
|
-
expected = {
|
262
|
+
expected = {rubycom_non_opt_arg: test_arg}
|
261
263
|
assert_equal(expected, result)
|
262
264
|
end
|
263
265
|
|
@@ -265,28 +267,91 @@ class TestRubycom < Test::Unit::TestCase
|
|
265
267
|
time = Time.new.to_s
|
266
268
|
test_arg = ":a: \"#{time}\""
|
267
269
|
result = Rubycom.parse_arg(test_arg.to_s)
|
268
|
-
expected = {
|
270
|
+
expected = {rubycom_non_opt_arg: {a: time}}
|
269
271
|
assert_equal(expected, result)
|
270
272
|
end
|
271
273
|
|
272
274
|
def test_parse_arg_hash_group
|
273
275
|
test_arg = ":a: [1,2]\n:b: 1\n:c: test\n:d: 1.0\n:e: \"2013-05-08 23:21:52 -0500\"\n"
|
274
276
|
result = Rubycom.parse_arg(test_arg.to_s)
|
275
|
-
expected = {
|
277
|
+
expected = {rubycom_non_opt_arg: {:a => [1, 2], :b => 1, :c => "test", :d => 1.0, :e => "2013-05-08 23:21:52 -0500"}}
|
276
278
|
assert_equal(expected, result)
|
277
279
|
end
|
278
280
|
|
279
281
|
def test_parse_arg_yaml
|
280
282
|
test_arg = {:a => ["1", 2, "a", 'b'], :b => 1, :c => "test", :d => "#{Time.now.to_s}"}
|
281
283
|
result = Rubycom.parse_arg(test_arg.to_yaml)
|
282
|
-
expected = {
|
284
|
+
expected = {rubycom_non_opt_arg: test_arg}
|
283
285
|
assert_equal(expected, result)
|
284
286
|
end
|
285
287
|
|
286
288
|
def test_parse_arg_code
|
287
289
|
test_arg = 'def self.test_code_method; raise "Fail - test_parse_arg_code";end'
|
288
290
|
result = Rubycom.parse_arg(test_arg.to_s)
|
289
|
-
expected = {
|
291
|
+
expected = {rubycom_non_opt_arg: 'def self.test_code_method; raise "Fail - test_parse_arg_code";end'}
|
292
|
+
assert_equal(expected, result)
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_parse_opt_string_eq
|
296
|
+
test_arg = "-test_arg=\"test\""
|
297
|
+
result = Rubycom.parse_arg(test_arg)
|
298
|
+
expected = {test_arg: "test"}
|
299
|
+
assert_equal(expected, result)
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_parse_opt_string_sp
|
303
|
+
test_arg = "-test_arg \"test\""
|
304
|
+
result = Rubycom.parse_arg(test_arg)
|
305
|
+
expected = {test_arg: "test"}
|
306
|
+
assert_equal(expected, result)
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_parse_opt_long_string_eq
|
310
|
+
test_arg = "--test_arg=\"test\""
|
311
|
+
result = Rubycom.parse_arg(test_arg)
|
312
|
+
expected = {test_arg: "test"}
|
313
|
+
assert_equal(expected, result)
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_parse_opt_long_string_sp
|
317
|
+
test_arg = "--test_arg \"test\""
|
318
|
+
result = Rubycom.parse_arg(test_arg)
|
319
|
+
expected = {test_arg: "test"}
|
320
|
+
assert_equal(expected, result)
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_get_param_definitions
|
324
|
+
test_method = UtilTestModule.public_method('test_command_with_args')
|
325
|
+
expected = {:test_arg=>{:def=>"test_arg", :type=>:req, :default=>:nil_rubycom_required_param}, :another_test_arg=>{:def=>"another_test_arg", :type=>:req, :default=>:nil_rubycom_required_param}}
|
326
|
+
result = Rubycom.get_param_definitions(test_method)
|
327
|
+
assert_equal(expected, result)
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_get_param_definitions_no_args
|
331
|
+
test_method = UtilTestModule.public_method('test_command')
|
332
|
+
expected = {}
|
333
|
+
result = Rubycom.get_param_definitions(test_method)
|
334
|
+
assert_equal(expected, result)
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_get_param_definitions_arr_param
|
338
|
+
test_method = UtilTestModule.public_method('test_command_options_arr')
|
339
|
+
expected = {:test_option=>{:def=>"test_option=\"test_option_default\"", :type=>:opt, :default=>"test_option_default"}, :test_options=>{:def=>"*test_options", :type=>:rest, :default=>:nil_rubycom_required_param}}
|
340
|
+
result = Rubycom.get_param_definitions(test_method)
|
341
|
+
assert_equal(expected, result)
|
342
|
+
end
|
343
|
+
|
344
|
+
def test_get_param_definitions_all_options
|
345
|
+
test_method = UtilTestModule.public_method('test_command_all_options')
|
346
|
+
expected = {:test_arg=>{:def=>"test_arg='test_arg_default'", :type=>:opt, :default=>"test_arg_default"}, :test_option=>{:def=>"test_option='test_option_default'", :type=>:opt, :default=>"test_option_default"}}
|
347
|
+
result = Rubycom.get_param_definitions(test_method)
|
348
|
+
assert_equal(expected, result)
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_get_param_definitions_mixed
|
352
|
+
test_method = UtilTestModule.public_method('test_command_with_options')
|
353
|
+
expected = {:test_arg=>{:def=>"test_arg", :type=>:req, :default=>:nil_rubycom_required_param}, :test_option=>{:def=>"test_option='option_default'", :type=>:opt, :default=>"option_default"}}
|
354
|
+
result = Rubycom.get_param_definitions(test_method)
|
290
355
|
assert_equal(expected, result)
|
291
356
|
end
|
292
357
|
|
@@ -334,6 +399,7 @@ class TestRubycom < Test::Unit::TestCase
|
|
334
399
|
Commands:
|
335
400
|
test_command - A basic test command
|
336
401
|
test_command_with_arg - A test_command with one arg
|
402
|
+
test_command_arg_named_arg - A test_command with an arg named arg
|
337
403
|
test_command_with_args - A test_command with two args
|
338
404
|
test_command_with_options - A test_command with an optional argument
|
339
405
|
test_command_all_options - A test_command with all optional arguments
|
@@ -347,7 +413,7 @@ class TestRubycom < Test::Unit::TestCase
|
|
347
413
|
test_command_arg_hash - A test_command with an Hash argument
|
348
414
|
END
|
349
415
|
expected_out = expected
|
350
|
-
assert_equal(expected, result)
|
416
|
+
assert_equal(expected.gsub(/\n|\r|\s/, ''), result.gsub(/\n|\r|\s/, ''))
|
351
417
|
assert_equal(expected_out.gsub(/\n|\r|\s/, ''), tst_out.gsub(/\n|\r|\s/, ''))
|
352
418
|
ensure
|
353
419
|
$stdout = o_stdout
|
@@ -596,9 +662,13 @@ class TestRubycom < Test::Unit::TestCase
|
|
596
662
|
result = Rubycom.run(base, args)
|
597
663
|
|
598
664
|
expected = nil
|
599
|
-
expected_out = "No argument available for test_arg"
|
665
|
+
expected_out = "No argument available for test_arg\n"
|
666
|
+
|
600
667
|
assert_equal(expected, result)
|
601
|
-
assert_equal(expected_out, tst_out.
|
668
|
+
assert_equal(expected_out, tst_out.lines.first)
|
669
|
+
Rubycom.get_command_usage(base,args[0],args[1..-1]).each_line{|expected_line|
|
670
|
+
assert_equal(true, tst_out.lines.include?(expected_line))
|
671
|
+
}
|
602
672
|
ensure
|
603
673
|
$stdout = o_stdout
|
604
674
|
$stderr = o_stderr
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
env:
|
3
|
+
test_msg: Hello World
|
4
|
+
test_arg: 123
|
5
|
+
working_dir: ./test/rubycom
|
6
|
+
steps:
|
7
|
+
1:
|
8
|
+
desc: Run test_composite_command with environment variable
|
9
|
+
cmd: ruby env[working_dir]/util_test_composite.rb test_composite_command env[test_msg]
|
10
|
+
2:
|
11
|
+
Var: Run UtilTestModule/test_command_options_arr with environment variable
|
12
|
+
cmd: ruby env[working_dir]/util_test_composite.rb UtilTestModule test_command_options_arr '["Hello World 1", world2]'
|
13
|
+
3:
|
14
|
+
Cntxt: Run test_command_with_args with environment variable
|
15
|
+
cmd: ruby env[working_dir]/util_test_module.rb test_command_with_args env[test_msg] env[test_arg]
|
16
|
+
4:
|
17
|
+
Cmd: Run ls for arbitrary command support
|
18
|
+
cmd: ls
|
19
|
+
5:
|
20
|
+
Arbitrary_Context: Run ls with environment variable
|
21
|
+
cmd: ls env[working_dir]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
|
2
|
-
|
2
|
+
# A command module used for testing
|
3
3
|
module UtilTestModule
|
4
4
|
|
5
5
|
# A test non-command method
|
@@ -19,6 +19,13 @@ module UtilTestModule
|
|
19
19
|
"test_arg=#{test_arg}"
|
20
20
|
end
|
21
21
|
|
22
|
+
# A test_command with an arg named arg
|
23
|
+
#
|
24
|
+
# @param [String] arg a test argument whose parameter name is arg
|
25
|
+
def self.test_command_arg_named_arg(arg)
|
26
|
+
"arg=#{arg}"
|
27
|
+
end
|
28
|
+
|
22
29
|
# A test_command with two args
|
23
30
|
# @param [String] test_arg a test argument
|
24
31
|
# @param [String] another_test_arg another test argument
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
|
2
|
-
require "#{File.expand_path(File.dirname(__FILE__))}/util_test_composite.rb"
|
3
|
-
|
4
|
-
module UtilTestNoSingleton
|
5
|
-
def test_method
|
6
|
-
"TEST_NON_SINGLETON_METHOD"
|
7
|
-
end
|
8
|
-
|
9
|
-
include Rubycom
|
1
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
|
2
|
+
require "#{File.expand_path(File.dirname(__FILE__))}/util_test_composite.rb"
|
3
|
+
|
4
|
+
module UtilTestNoSingleton
|
5
|
+
def test_method
|
6
|
+
"TEST_NON_SINGLETON_METHOD"
|
7
|
+
end
|
8
|
+
|
9
|
+
include Rubycom
|
10
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubycom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -96,7 +96,7 @@ description: Allows command-line access for all singleton methods in an includin
|
|
96
96
|
parsing options. Allows the user to make a command-line tool by simply including
|
97
97
|
Rubycom at the bottom.
|
98
98
|
email:
|
99
|
-
-
|
99
|
+
- d.purcell.jr+rubycom@gmail.com
|
100
100
|
executables: []
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- rubycom.gemspec
|
112
112
|
- test/rubycom/test_rubycom.rb
|
113
113
|
- test/rubycom/util_test_composite.rb
|
114
|
+
- test/rubycom/util_test_job.yaml
|
114
115
|
- test/rubycom/util_test_module.rb
|
115
116
|
- test/rubycom/util_test_no_singleton.rb
|
116
117
|
- test/rubycom/utility_tester.rb
|
@@ -142,6 +143,7 @@ summary: Converts singleton methods to command-line functions upon inclusion.
|
|
142
143
|
test_files:
|
143
144
|
- test/rubycom/test_rubycom.rb
|
144
145
|
- test/rubycom/util_test_composite.rb
|
146
|
+
- test/rubycom/util_test_job.yaml
|
145
147
|
- test/rubycom/util_test_module.rb
|
146
148
|
- test/rubycom/util_test_no_singleton.rb
|
147
149
|
- test/rubycom/utility_tester.rb
|