rubycom 0.3.2 → 0.4.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.
Files changed (43) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +162 -146
  3. data/Rakefile +12 -12
  4. data/lib/rubycom.rb +156 -226
  5. data/lib/rubycom/arg_parse.rb +252 -0
  6. data/lib/rubycom/command_interface.rb +97 -0
  7. data/lib/rubycom/completions.rb +62 -0
  8. data/lib/rubycom/error_handler.rb +15 -0
  9. data/lib/rubycom/executor.rb +23 -0
  10. data/lib/rubycom/helpers.rb +98 -0
  11. data/lib/rubycom/output_handler.rb +15 -0
  12. data/lib/rubycom/parameter_extract.rb +262 -0
  13. data/lib/rubycom/singleton_commands.rb +78 -0
  14. data/lib/rubycom/sources.rb +99 -0
  15. data/lib/rubycom/version.rb +1 -1
  16. data/lib/rubycom/yard_doc.rb +146 -0
  17. data/rubycom.gemspec +14 -16
  18. data/test/rubycom/arg_parse_test.rb +247 -0
  19. data/test/rubycom/command_interface_test.rb +293 -0
  20. data/test/rubycom/completions_test.rb +94 -0
  21. data/test/rubycom/error_handler_test.rb +72 -0
  22. data/test/rubycom/executor_test.rb +64 -0
  23. data/test/rubycom/helpers_test.rb +467 -0
  24. data/test/rubycom/output_handler_test.rb +76 -0
  25. data/test/rubycom/parameter_extract_test.rb +141 -0
  26. data/test/rubycom/rubycom_test.rb +290 -548
  27. data/test/rubycom/singleton_commands_test.rb +122 -0
  28. data/test/rubycom/sources_test.rb +59 -0
  29. data/test/rubycom/util_test_bin.rb +8 -0
  30. data/test/rubycom/util_test_composite.rb +23 -20
  31. data/test/rubycom/util_test_module.rb +142 -112
  32. data/test/rubycom/util_test_no_singleton.rb +2 -2
  33. data/test/rubycom/util_test_sub_module.rb +13 -0
  34. data/test/rubycom/yard_doc_test.rb +165 -0
  35. metadata +61 -24
  36. data/lib/rubycom/arguments.rb +0 -133
  37. data/lib/rubycom/commands.rb +0 -63
  38. data/lib/rubycom/documentation.rb +0 -212
  39. data/test/rubycom/arguments_test.rb +0 -289
  40. data/test/rubycom/commands_test.rb +0 -51
  41. data/test/rubycom/documentation_test.rb +0 -186
  42. data/test/rubycom/util_test_job.yaml +0 -21
  43. data/test/rubycom/utility_tester.rb +0 -17
@@ -2,8 +2,8 @@ require "#{File.expand_path(File.dirname(__FILE__))}/../../lib/rubycom.rb"
2
2
 
3
3
  module UtilTestNoSingleton
4
4
  def test_method
5
- "TEST_NON_SINGLETON_METHOD"
5
+ 'TEST_NON_SINGLETON_METHOD'
6
6
  end
7
7
 
8
8
  include Rubycom
9
- end
9
+ end
@@ -0,0 +1,13 @@
1
+ module UtilTestComposite
2
+ # Sub-Module in UtilTestComposite
3
+ module UtilTestSubModule
4
+
5
+ # Test command in a sub-module as part of UtilTestComposite
6
+ #
7
+ # @param [String] test the testing parameter to output
8
+ # @return [String] a String representation of the input parameter
9
+ def self.sub_module_command(test)
10
+ "test = #{test}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,165 @@
1
+ require "#{File.dirname(__FILE__)}/../../lib/rubycom/yard_doc.rb"
2
+
3
+ require "#{File.dirname(__FILE__)}/../../lib/rubycom/sources.rb"
4
+ require "#{File.dirname(__FILE__)}/util_test_module.rb"
5
+ require "#{File.dirname(__FILE__)}/util_test_composite.rb"
6
+ require "#{File.dirname(__FILE__)}/util_test_no_singleton.rb"
7
+
8
+ require 'test/unit'
9
+
10
+ class YardDocTest < Test::Unit::TestCase
11
+
12
+ def test_document_commands
13
+ test_commands = [
14
+ UtilTestComposite,
15
+ UtilTestModule,
16
+ UtilTestModule.public_method(:test_command),
17
+ "test_extra_arg"
18
+ ]
19
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
20
+ result = Rubycom::YardDoc.document_commands(test_commands, test_source_fn)
21
+ assert(result.class == Array, "result should be an array")
22
+ result.each{|h|
23
+ assert(h.class == Hash, "each command in the result should be a Hash. #{h}")
24
+ assert(h.has_key?(:command), "each command hash should respond to :command. #{h}")
25
+ assert([Module, Method, String].include?(h[:command].class),"each command should be a Module | Method | String. #{h[:command]}")
26
+ assert(h.has_key?(:doc), "each command hash should respond to :doc. #{h}")
27
+ assert(h[:doc].has_key?(:full_doc), "each doc hash should respond to :full_doc. #{h[:doc]}")
28
+ assert(h[:doc].has_key?(:short_doc), "each doc hash should respond to :short_doc. #{h[:doc]}")
29
+ if h[:command].class == Module
30
+ assert(h[:doc].has_key?(:sub_command_docs), "if the command is a module then the :doc has should respond to :sub_command_docs #{h[:doc]}")
31
+ assert(h[:doc][:sub_command_docs].class == Hash, "sub_command_docs should be a Hash. #{h[:doc][:sub_command_docs]}")
32
+ h[:doc][:sub_command_docs].each{|k,v|
33
+ assert(k.class == Symbol, "each sub_command_doc key should be a symbol. k: #{k}, k.class #{k.class}")
34
+ assert(v.class == String, "each sub_command_doc value should be a string. k: #{k}, v: #{v}, v.class: #{v.class}")
35
+ }
36
+ elsif h[:command].class == Method
37
+ assert(h[:doc].has_key?(:parameters), "if the command is a method then the :doc has should respond to :parameters. #{h[:doc]}")
38
+ assert(h[:doc].has_key?(:tags), "if the command is a method then the :doc has should respond to :tags. #{h[:doc]}")
39
+ assert(h[:doc][:parameters].class == Array, "parameters should be a Hash. #{h[:doc][:parameters]}")
40
+ assert(h[:doc][:tags].class == Array, "parameters should be a Hash. #{h[:doc][:tags]}")
41
+ h[:doc][:parameters].each{|ph|
42
+ assert(ph.class == Hash, "each parameter should be a Hash. #{ph}")
43
+ assert(ph.class == Hash, "each parameter should be a Hash. #{ph}")
44
+ assert(ph.has_key?(:default), "each parameter should respond to :default. #{ph}")
45
+ assert(ph.has_key?(:doc), "each parameter should respond to :doc. #{ph}")
46
+ assert(ph.has_key?(:doc_type), "each parameter should respond to :doc_type. #{ph}")
47
+ assert(ph.has_key?(:type), "each parameter should respond to :type. #{ph}")
48
+ }
49
+ h[:doc][:tags].each{|th|
50
+ assert(th.class == Hash, "each tag should be a Hash")
51
+ assert(th.has_key?(:name), "each tag should respond to :name. #{th}")
52
+ assert(th.has_key?(:tag_name), "each tag should respond to :tag_name. #{th}")
53
+ assert(th.has_key?(:text), "each tag should respond to :text. #{th}")
54
+ assert(th.has_key?(:types), "each tag should respond to :types. #{th}")
55
+ }
56
+ else
57
+ assert(([:full_doc, :short_doc] - h[:doc].keys).length == 0, "if the command is a String then :doc should only respond to :short_doc and :full_doc. #{h[:doc]}")
58
+ end
59
+ }
60
+ end
61
+
62
+ def test_document_command_command_run
63
+ test_command = UtilTestModule.public_method(:test_command_with_return)
64
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
65
+ result = Rubycom::YardDoc.document_command(test_command, test_source_fn)
66
+ assert(result.has_key?(:full_doc), "each doc hash should respond to :full_doc. #{result}")
67
+ assert(result.has_key?(:short_doc), "each doc hash should respond to :short_doc. #{result}")
68
+ assert(result.has_key?(:parameters), "if the command is a method then the :doc has should respond to :parameters. #{result}")
69
+ assert(result.has_key?(:tags), "if the command is a method then the :doc has should respond to :tags. #{result}")
70
+ assert(result[:parameters].class == Array, "parameters should be a Hash. #{result[:parameters]}")
71
+ assert(result[:tags].class == Array, "parameters should be a Hash. #{result[:tags]}")
72
+ result[:parameters].each{|ph|
73
+ assert(ph.class == Hash, "each parameter should be a Hash. #{ph}")
74
+ assert(ph.has_key?(:default), "each parameter should respond to :default. #{ph}")
75
+ assert(ph.has_key?(:doc), "each parameter should respond to :doc. #{ph}")
76
+ assert(ph.has_key?(:doc_type), "each parameter should respond to :doc_type. #{ph}")
77
+ assert(ph.has_key?(:type), "each parameter should respond to :type. #{ph}")
78
+ }
79
+ result[:tags].each{|th|
80
+ assert(th.class == Hash, "each tag should be a Hash")
81
+ assert(th.has_key?(:name), "each tag should respond to :name. #{th}")
82
+ assert(th.has_key?(:tag_name), "each tag should respond to :tag_name. #{th}")
83
+ assert(th.has_key?(:text), "each tag should respond to :text. #{th}")
84
+ assert(th.has_key?(:types), "each tag should respond to :types. #{th}")
85
+ }
86
+ end
87
+
88
+ def test_document_command_command_run_rest
89
+ test_command = UtilTestModule.public_method(:test_command_mixed_options)
90
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
91
+ result = Rubycom::YardDoc.document_command(test_command, test_source_fn)
92
+ assert(result.has_key?(:full_doc), "each doc hash should respond to :full_doc. #{result}")
93
+ assert(result.has_key?(:short_doc), "each doc hash should respond to :short_doc. #{result}")
94
+ assert(result.has_key?(:parameters), "if the command is a method then the :doc has should respond to :parameters. #{result}")
95
+ assert(result.has_key?(:tags), "if the command is a method then the :doc has should respond to :tags. #{result}")
96
+ assert(result[:parameters].class == Array, "parameters should be a Hash. #{result[:parameters]}")
97
+ assert(result[:tags].class == Array, "parameters should be a Hash. #{result[:tags]}")
98
+ result[:parameters].each{|ph|
99
+ assert(ph.class == Hash, "each parameter should be a Hash. #{ph}")
100
+ assert(ph.has_key?(:default), "each parameter should respond to :default. #{ph}")
101
+ assert(ph.has_key?(:doc), "each parameter should respond to :doc. #{ph}")
102
+ assert(ph.has_key?(:doc_type), "each parameter should respond to :doc_type. #{ph}")
103
+ assert(ph.has_key?(:type), "each parameter should respond to :type. #{ph}")
104
+ if ph[:type] == :rest
105
+ assert(ph[:param_name].start_with?("*"), "a rest parameter's name should start with a star")
106
+ end
107
+ }
108
+ result[:tags].each{|th|
109
+ assert(th.class == Hash, "each tag should be a Hash")
110
+ assert(th.has_key?(:name), "each tag should respond to :name. #{th}")
111
+ assert(th.has_key?(:tag_name), "each tag should respond to :tag_name. #{th}")
112
+ assert(th.has_key?(:text), "each tag should respond to :text. #{th}")
113
+ assert(th.has_key?(:types), "each tag should respond to :types. #{th}")
114
+ }
115
+ end
116
+
117
+ def test_document_command_run_module
118
+ test_command = UtilTestModule
119
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
120
+ result = Rubycom::YardDoc.document_command(test_command, test_source_fn)
121
+ assert(result.has_key?(:sub_command_docs), "if the command is a module then the :doc has should respond to :sub_command_docs #{result}")
122
+ assert(result[:sub_command_docs].class == Hash, "sub_command_docs should be a Hash. #{result[:sub_command_docs]}")
123
+ result[:sub_command_docs].each{|k,v|
124
+ assert(k.class == Symbol, "each sub_command_doc key should be a symbol. k: #{k}, k.class #{k.class}")
125
+ assert(v.class == String, "each sub_command_doc value should be a string. k: #{k}, v: #{v}, v.class: #{v.class}")
126
+ }
127
+ end
128
+
129
+ def test_document_command_run_composite
130
+ test_command = UtilTestComposite
131
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
132
+ result = Rubycom::YardDoc.document_command(test_command, test_source_fn)
133
+ result_sub_command_doc = result[:sub_command_docs]
134
+ result_sub_command_doc_keys = result_sub_command_doc.keys.map{|sub_mod|sub_mod.to_s}
135
+ test_command.included_modules.reject{|mod|mod.to_s=="Rubycom"}.map{|mod|mod.to_s}.each{|mod|
136
+ assert(result_sub_command_doc_keys.include?(mod.split("::").last), "result_sub_command_doc_keys #{result_sub_command_doc_keys} should include #{mod.split("::").last}")
137
+ }
138
+ result_sub_command_doc.each{|k,v|
139
+ if k.to_s == "UtilTestNoSingleton"
140
+ assert_equal(v, '')
141
+ else
142
+ assert(v != '', "sub_command_doc for #{k} should not be empty")
143
+ end
144
+ }
145
+ end
146
+
147
+ def test_document_command_run_composite_command
148
+ test_command = UtilTestComposite.public_method(:test_composite_command)
149
+ test_source_fn = Rubycom::Sources.public_method(:source_command)
150
+ result = Rubycom::YardDoc.document_command(test_command, test_source_fn)
151
+ expected = {
152
+ :full_doc => "A test_command in a composite console",
153
+ :parameters => [
154
+ {:default => nil, :doc => "a test argument", :doc_type => "String", :param_name => "test_arg", :type => :req}
155
+ ],
156
+ :short_doc => "A test_command in a composite console.",
157
+ :tags => [
158
+ {:name => "test_arg", :tag_name => "param", :text => "a test argument", :types => ["String"]},
159
+ {:name => nil, :tag_name => "return", :text => "the test arg", :types => ["String"]}
160
+ ]
161
+ }
162
+ assert_equal(expected, result)
163
+ end
164
+
165
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubycom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Purcell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-20 00:00:00.000000000 Z
11
+ date: 2013-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: test-unit
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,10 +80,23 @@ dependencies:
80
80
  - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: Allows command-line access for all singleton methods in an including
84
- class. Reads Yard style documentation for command line help output. Uses Yaml for
85
- parsing options. Allows the user to make a command-line tool by simply including
86
- Rubycom at the bottom.
83
+ - !ruby/object:Gem::Dependency
84
+ name: parslet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Enables command-line access for methods in an including module. Reads
98
+ method documentation for command line help output. Parses command line options and
99
+ flags. Turn your library into a command-line app by simply including Rubycom.
87
100
  email:
88
101
  - d.purcell.jr+rubycom@gmail.com
89
102
  executables: []
@@ -96,20 +109,36 @@ files:
96
109
  - README.md
97
110
  - Rakefile
98
111
  - lib/rubycom.rb
99
- - lib/rubycom/arguments.rb
100
- - lib/rubycom/commands.rb
101
- - lib/rubycom/documentation.rb
112
+ - lib/rubycom/arg_parse.rb
113
+ - lib/rubycom/command_interface.rb
114
+ - lib/rubycom/completions.rb
115
+ - lib/rubycom/error_handler.rb
116
+ - lib/rubycom/executor.rb
117
+ - lib/rubycom/helpers.rb
118
+ - lib/rubycom/output_handler.rb
119
+ - lib/rubycom/parameter_extract.rb
120
+ - lib/rubycom/singleton_commands.rb
121
+ - lib/rubycom/sources.rb
102
122
  - lib/rubycom/version.rb
123
+ - lib/rubycom/yard_doc.rb
103
124
  - rubycom.gemspec
104
- - test/rubycom/arguments_test.rb
105
- - test/rubycom/commands_test.rb
106
- - test/rubycom/documentation_test.rb
125
+ - test/rubycom/arg_parse_test.rb
126
+ - test/rubycom/command_interface_test.rb
127
+ - test/rubycom/completions_test.rb
128
+ - test/rubycom/error_handler_test.rb
129
+ - test/rubycom/executor_test.rb
130
+ - test/rubycom/helpers_test.rb
131
+ - test/rubycom/output_handler_test.rb
132
+ - test/rubycom/parameter_extract_test.rb
107
133
  - test/rubycom/rubycom_test.rb
134
+ - test/rubycom/singleton_commands_test.rb
135
+ - test/rubycom/sources_test.rb
136
+ - test/rubycom/util_test_bin.rb
108
137
  - test/rubycom/util_test_composite.rb
109
- - test/rubycom/util_test_job.yaml
110
138
  - test/rubycom/util_test_module.rb
111
139
  - test/rubycom/util_test_no_singleton.rb
112
- - test/rubycom/utility_tester.rb
140
+ - test/rubycom/util_test_sub_module.rb
141
+ - test/rubycom/yard_doc_test.rb
113
142
  homepage: http://dannypurcell.github.io/rubycom
114
143
  licenses:
115
144
  - MIT
@@ -133,15 +162,23 @@ rubyforge_project:
133
162
  rubygems_version: 2.0.3
134
163
  signing_key:
135
164
  specification_version: 4
136
- summary: Converts singleton methods to command-line functions upon inclusion.
165
+ summary: Turn your library into a command-line app by simply including Rubycom.
137
166
  test_files:
138
- - test/rubycom/arguments_test.rb
139
- - test/rubycom/commands_test.rb
140
- - test/rubycom/documentation_test.rb
167
+ - test/rubycom/arg_parse_test.rb
168
+ - test/rubycom/command_interface_test.rb
169
+ - test/rubycom/completions_test.rb
170
+ - test/rubycom/error_handler_test.rb
171
+ - test/rubycom/executor_test.rb
172
+ - test/rubycom/helpers_test.rb
173
+ - test/rubycom/output_handler_test.rb
174
+ - test/rubycom/parameter_extract_test.rb
141
175
  - test/rubycom/rubycom_test.rb
176
+ - test/rubycom/singleton_commands_test.rb
177
+ - test/rubycom/sources_test.rb
178
+ - test/rubycom/util_test_bin.rb
142
179
  - test/rubycom/util_test_composite.rb
143
- - test/rubycom/util_test_job.yaml
144
180
  - test/rubycom/util_test_module.rb
145
181
  - test/rubycom/util_test_no_singleton.rb
146
- - test/rubycom/utility_tester.rb
182
+ - test/rubycom/util_test_sub_module.rb
183
+ - test/rubycom/yard_doc_test.rb
147
184
  has_rdoc:
@@ -1,133 +0,0 @@
1
- require 'yaml'
2
- require 'method_source'
3
-
4
- module Rubycom
5
- module Arguments
6
-
7
- # Parses the given arguments and matches them to the given parameters
8
- #
9
- # @param [Hash] parameters a Hash representing the parameters to match.
10
- # Entries should match :param_name => { type: :req||:opt||:rest,
11
- # def:(source_definition),
12
- # default:(default_value || :nil_rubycom_required_param)
13
- # }
14
- # @param [Array] arguments an Array of Strings representing the arguments to be parsed
15
- # @return [Hash] a Hash mapping the defined parameters to their matching argument values
16
- def self.resolve(parameters={}, arguments=[])
17
- raise CLIError, 'parameters may not be nil' if parameters.nil?
18
- raise CLIError, 'arguments may not be nil' if arguments.nil?
19
- parsed_args = self.parse_args(arguments)
20
-
21
- args = parsed_args[:rubycom_non_opt_arg] || []
22
- options = parsed_args.select{|key,_| key != :rubycom_non_opt_arg } || {}
23
- parsed_arg_count = args.length + options.length
24
- types = parameters.values.group_by { |hsh| hsh[:type] }.map { |type, defs_arr| Hash[type, defs_arr.length] }.reduce(&:merge) || {}
25
- raise CLIError, "Wrong number of arguments. Expected at least #{types[:req]}, received #{parsed_arg_count}" if parsed_arg_count < (types[:req]||0)
26
- raise CLIError, "Wrong number of arguments. Expected at most #{(types[:req]||0) + (types[:opt]||0)}, received #{parsed_arg_count}" if types[:rest].nil? && (parsed_arg_count > ((types[:req]||0) + (types[:opt]||0)))
27
-
28
- self.merge_params(parameters, parsed_args)
29
- end
30
-
31
- # Matches the given parameters to the given pre-parsed arguments
32
- #
33
- # @param [Hash] parameters a Hash representing the parameters to match.
34
- # Entries should match :param_name => { type: :req||:opt||:rest,
35
- # def:(source_definition),
36
- # default:(default_value || :nil_rubycom_required_param)
37
- # }
38
- # @param [Hash] parsed_args a Hash of parsed arguments where the keys are either the name of the optional argument
39
- # the value to designated for or :rubycom_non_opt_arg if the argument was not sent for a specified optional parameter
40
- # @return [Hash] a Hash mapping the defined parameters to their matching argument values
41
- def self.merge_params(parameters={}, parsed_args={})
42
- parameters.map { |param_sym, def_hash|
43
- if def_hash[:type] == :req
44
- raise CLIError, "No argument available for #{param_sym}" if parsed_args[:rubycom_non_opt_arg].nil? || parsed_args[:rubycom_non_opt_arg].length == 0
45
- Hash[param_sym, parsed_args[:rubycom_non_opt_arg].shift]
46
- elsif def_hash[:type] == :opt
47
- if parsed_args[param_sym].nil?
48
- arg = (parsed_args[:rubycom_non_opt_arg].nil? || parsed_args[:rubycom_non_opt_arg].empty?) ? parameters[param_sym][:default] : parsed_args[:rubycom_non_opt_arg].shift
49
- else
50
- arg = parsed_args[param_sym]
51
- end
52
- Hash[param_sym, arg]
53
- elsif def_hash[:type] == :rest
54
- ret = Hash[param_sym, ((!parsed_args[param_sym].nil?) ? parsed_args[param_sym] : parsed_args[:rubycom_non_opt_arg])]
55
- parsed_args[:rubycom_non_opt_arg] = []
56
- ret
57
- end
58
- }.reduce(&:merge)
59
- end
60
-
61
- def self.parse_args(arguments)
62
- arguments.map { |arg|
63
- self.parse_arg(arg)
64
- }.group_by { |hsh|
65
- hsh.keys.first
66
- }.map { |key, arr|
67
- (key == :rubycom_non_opt_arg) ? Hash[key, arr.map { |hsh| hsh.values }.flatten(1)] : Hash[key, arr.map { |hsh| hsh.values.first }.reduce(&:merge)]
68
- }.reduce(&:merge) || {}
69
- end
70
-
71
- # Uses YAML.load to parse the given String
72
- #
73
- # @param [String] arg a String representing the argument to be parsed
74
- # @return [Object] the result of parsing the given arg with YAML.load
75
- def self.parse_arg(arg)
76
- return Hash[:rubycom_non_opt_arg, nil] if arg.nil?
77
- if arg.is_a?(String) && ((arg.match(/^[-]{3,}\w+/) != nil) || ((arg.match(/^[-]{1,}\w+/) == nil) && (arg.match(/^\w+=/) != nil)))
78
- raise CLIError, "Improper option specification, options must start with one or two dashes. Received: #{arg}"
79
- elsif arg.is_a?(String) && arg.match(/^(-|--)\w+[=|\s]{1}/) != nil
80
- k, v = arg.partition(/^(-|--)\w+[=|\s]{1}/).select { |part|
81
- !part.empty?
82
- }.each_with_index.map { |part, index|
83
- if index == 0
84
- part.chomp('=').gsub(/^--/, '').gsub(/^-/, '').strip.to_sym
85
- else
86
- if part.start_with?("#") || part.start_with?("!")
87
- "#{part}"
88
- else
89
- (YAML.load(part) rescue "#{part}")
90
- end
91
- end
92
- }
93
- Hash[k, v]
94
- else
95
- begin
96
- parsed_arg = "#{arg}"
97
- unless arg.start_with?("#") || arg.start_with?("!")
98
- parsed_arg = YAML.load("#{arg}")
99
- end
100
- rescue Exception
101
- parsed_arg = "#{arg}"
102
- end
103
- Hash[:rubycom_non_opt_arg, parsed_arg]
104
- end
105
- end
106
-
107
- # Builds a hash mapping parameter names (as symbols) to their
108
- # :type (:req,:opt,:rest), :def (source_definition), :default (default_value || :nil_rubycom_required_param)
109
- # for each parameter defined by the given method.
110
- #
111
- # @param [Method] method the Method who's parameter hash should be built
112
- # @return [Hash] a Hash representing the given Method's parameters
113
- def self.get_param_definitions(method)
114
- raise CLIError, 'method must be an instance of the Method class' unless method.class == Method
115
- method.parameters.map { |param|
116
- param[1].to_s
117
- }.map { |param_name|
118
- {param_name.to_sym => method.source.split("\n").select { |line| line.include?(param_name) }.first}
119
- }.map { |param_hash|
120
- 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
121
- Hash[
122
- param_hash.flatten[0],
123
- Hash[
124
- :def, param_def,
125
- :type, method.parameters.select { |arr| arr[1] == param_hash.flatten[0] }.flatten[0],
126
- :default, (param_def.include?('=') ? YAML.load(param_def.split('=')[1..-1].join('=')) : :nil_rubycom_required_param)
127
- ]
128
- ]
129
- }.reduce(&:merge) || {}
130
- end
131
-
132
- end
133
- end