subcommand-optparse 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33646b64e094a13d9df10e21dd7efec280b109f8
4
- data.tar.gz: f9f9c33ecadc11ecd51de2d8750963e35f518cec
3
+ metadata.gz: 634e18a8f111dd35ab12a98897abb16db057d351
4
+ data.tar.gz: 63beca167bd690d821b878f3265f6e1f876b62ca
5
5
  SHA512:
6
- metadata.gz: 8c36a320be9f2f72c1d71766aaf0762e1b58ecd0bf016bb3e588617637dcf2df14c0ae91e8beb310b4f1c055aa0fa84002962278017d1036a1ae905d55d076ae
7
- data.tar.gz: f2e289deb6723de5d741fe9ea8136c054d79b8be4ba7973b042d20861c0475e15e3110e5a7454ba9cc2e26a3f071fe40a5299b7825cd53df3319be3495939106
6
+ metadata.gz: aed83c4d4aa0a5abad231e614c7c41e66827353695d19faa91dc3d771635c480330cdd2720a068920f205796091e62518278cc5db90e2efddc874e5133a01179
7
+ data.tar.gz: cf9879e2f5d5fc11b900ffd169b14d12937950fb23dfea2feda4796c483c8a9f3537addec92d7ce97545681fbaf130f535a7e127ff03031a5a5bc5cacd414b7d
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Subcommand::Optparse
1
+ # subcommand-optparse
2
2
 
3
3
  Option parser for a command with subcommands, which is parsed by library 'optparse'
4
4
 
@@ -18,7 +18,11 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- Please see the files in the directory 'examples'
21
+ For now, please see the files in the directory 'examples' and source codes.
22
+
23
+ ## License
24
+
25
+ GPLv3
22
26
 
23
27
  ## Contributing
24
28
 
@@ -4,18 +4,22 @@ require "subcommand_optparse"
4
4
  options = {}
5
5
 
6
6
  parser = SubCmdOptParser.new(:help_command => true) do |sc|
7
+ sc.program_name = "sample_command.rb"
8
+ sc.version = "0.0.1"
9
+ sc.release = "hello world"
10
+
7
11
  sc.global_option do |opt|
8
12
  opt.on("--global-option", "Banner of global option") do |v|
9
13
  options[:global_option] = true
10
14
  end
11
15
  end
12
- sc.subcommand("foo", "Banner of foo") do |opt|
16
+ sc.subcommand("foo", "Description of foo") do |opt|
13
17
  opt.on("--foo-option", "Foo option") do |v|
14
18
  options[:foo] = true
15
19
  end
16
20
  end
17
21
  sc.subcommand("bar") do |opt|
18
- opt.on("--bar-option", "Bar option") do |v|
22
+ opt.on("--bar-option", "Description of bar") do |v|
19
23
  options[:bar] = true
20
24
  end
21
25
  end
@@ -1,3 +1,3 @@
1
1
  class SubCmdOptParser
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -5,31 +5,59 @@ require "active_support/core_ext/array/extract_options"
5
5
  class SubCmdOptParser
6
6
  class OptionParserForSubCmd < OptionParser
7
7
  attr_accessor :subcommand_name
8
+ attr_accessor :description
9
+
10
+ def initialize(subcmd, description, width, indent)
11
+ @subcommand_name = subcmd
12
+ @description = description
13
+ super(nil, width, indent)
14
+ end
8
15
 
9
16
  def banner
10
17
  unless @banner
11
18
  @banner = "Usage: #{program_name} #{@subcommand_name || '<command>'} [options]"
19
+ if @description
20
+ @banner << "\n\n#{@description}"
21
+ end
12
22
  visit(:add_banner, @banner)
13
23
  end
14
24
  @banner
15
25
  end
16
26
  end
17
27
 
18
- # @overload initialize(banner = nil, width = 32, indent = ' ' * 4, opts = {})
19
- # @param [String,nil] banner An argument of OptionParser
20
- # @param [Fixnum] width An argument of OptionParser
21
- # @param [String] indent An argument of OptionParser
28
+ attr_accessor :program_name
29
+ attr_accessor :summary_width
30
+ attr_accessor :summary_indent
31
+ attr_accessor :version
32
+ attr_accessor :release
33
+ alias set_program_name program_name=
34
+ alias set_summary_width summary_width=
35
+ alias set_summary_indent summary_indent=
36
+
37
+ # @overload initialize(width = 32, indent = ' ' * 4, opts = {})
38
+ # @param [Fixnum] width Width of summary
39
+ # @param [String] indent Indent of summary
22
40
  # @param [Hash] opts Options hash
23
- # @option opts [boolean] :help_command If the value is false then subcommand help is not set automatically
41
+ # @option opts [boolean] :help_command
42
+ # If the value is false then command "help" is not set automatically. Default is true
43
+ # @option opts [boolean] :version_command
44
+ # If the value is false then command "version" is not set automatically. Default is true
45
+ # @option opts [boolean] :accept_undefined_command
46
+ # If the value is false then show help for undefined commands. Default is false
47
+ # @option opts [boolean] :parse_only
48
+ # Commands (help and version) do not exit with printing messages and just parse options
24
49
  # @yield [sc]
25
50
  # @yieldparam [SubCmdOptParser] sc Option parser
26
51
  def initialize(*args, &block)
27
52
  opts = args.extract_options!
28
- @default_banner = args.shift
29
- @args_option_parser = args
53
+ @summary_width = args[0] || 32
54
+ @summary_indent = args[1] || ' ' * 4
30
55
  @global_option_setting = nil
31
56
  @subcommand = []
32
57
  @help_subcommand_use_p = (!opts.has_key?(:help_command) || opts[:help_command])
58
+ @version_subcommand_use_p = (!opts.has_key?(:version_command) || opts[:version_command])
59
+ @accept_undefined_command = opts[:accept_undefined_command]
60
+ @parse_only = opts[:parse_only]
33
61
  if block_given?
34
62
  yield(self)
35
63
  end
@@ -42,24 +70,36 @@ class SubCmdOptParser
42
70
  @global_option_setting = block
43
71
  end
44
72
 
45
- # @overload subcommand(name, banner = nil, opts = {})
73
+ def subcommand_defined?(subcmd)
74
+ !!@subcommand.assoc(subcmd)
75
+ end
76
+
77
+ # @overload subcommand(name, description = nil, opts = {})
46
78
  # @param [String] name Name of subcommand
79
+ # @param [String] description Description of subcommand whose first line is shows in list of subcommands
47
80
  # @param [Hash] opts Options hash
48
81
  # @option opts [boolean] :load_global_options If the value is false then global options are not loaded
49
82
  # @yield [opt]
50
83
  # @yieldparam [OptionParserForSubCmd] opt Option parser for the subcommand
51
84
  def subcommand(name, *args, &block)
85
+ if subcommand_defined?(name)
86
+ raise ArgumentError, "Command '#{name}' has been already defined"
87
+ end
52
88
  opts = args.extract_options!
53
- banner = args.shift
54
- h = { :banner => banner, :setting => block }
89
+ description = args.shift
90
+ if args.size > 0
91
+ raise ArgumentError, "Too many arguments"
92
+ end
93
+ h = { :description => description, :setting => block }
55
94
  h[:load_global_options] = !(opts.has_key?(:load_global_options) && !opts[:load_global_options])
56
95
  @subcommand << [name, h]
57
96
  end
58
97
 
59
- def get_banner(subcmd_data)
60
- (subcmd_data && subcmd_data[:banner]) || @default_banner
98
+ def subcommand_clear(name)
99
+ @subcommand.delete_if do |subcmd, data|
100
+ subcmd == name
101
+ end
61
102
  end
62
- private :get_banner
63
103
 
64
104
  def get_subcmd_data(subcmd)
65
105
  subcmd_data = nil
@@ -71,11 +111,12 @@ class SubCmdOptParser
71
111
  private :get_subcmd_data
72
112
 
73
113
  def get_option_parser(subcmd, subcmd_data)
74
- opt = OptionParserForSubCmd.new(get_banner(subcmd_data), *@args_option_parser)
75
- opt.subcommand_name = subcmd
76
- if subcmd_data && subcmd_data[:setting]
77
- subcmd_data[:setting].call(opt)
78
- end
114
+ desc = subcmd_data && subcmd_data[:description]
115
+ opt = OptionParserForSubCmd.new(subcmd, desc, @summary_width, @summary_indent)
116
+ opt.program_name = program_name if @program_name
117
+ opt.version = version if @version
118
+ opt.release = release if @release
119
+ subcmd_data[:setting].call(opt) if subcmd_data && subcmd_data[:setting]
79
120
  if @global_option_setting && (!subcmd_data || subcmd_data[:load_global_options])
80
121
  @global_option_setting.call(opt)
81
122
  end
@@ -83,35 +124,80 @@ class SubCmdOptParser
83
124
  end
84
125
  private :get_option_parser
85
126
 
86
- def message_list_subcommands(opt)
87
- mes = "Subcommands of #{opt.program_name}:\n"
127
+ def message_list_subcommands
128
+ mes = "Commands are:\n"
129
+ max_size_subcmd = (@subcommand.map { |name, val| name.size }).max
130
+ str_size = (max_size_subcmd.even? ? max_size_subcmd : max_size_subcmd + 1) + 4
88
131
  @subcommand.each do |name, val|
89
- mes << " " << name << "\n"
132
+ desc = ((val && val[:description]) ? val[:description].each_line.first.strip : "")
133
+ mes << (" %-#{str_size}s" % name) << desc << "\n"
90
134
  end
91
135
  mes
92
136
  end
93
137
  private :message_list_subcommands
94
138
 
95
- def parse!(argv = ARGV)
139
+ def get_banner_help(opt)
140
+ "Usage: #{opt.program_name} <command> [options]\n\n" + message_list_subcommands
141
+ end
142
+ private :get_banner_help
143
+
144
+ def define_prepared_command
96
145
  if @help_subcommand_use_p
97
- subcommand("help", :load_global_options => false)
146
+ unless subcommand_defined?("help")
147
+ subcommand("help", "Show help message", :load_global_options => false) do |opt|
148
+ opt.banner = get_banner_help(opt)
149
+ end
150
+ end
98
151
  end
152
+ if @version_subcommand_use_p
153
+ unless subcommand_defined?("version")
154
+ subcommand("version", "Show version", :load_global_options => false)
155
+ end
156
+ end
157
+ end
158
+ private :define_prepared_command
159
+
160
+ def exec_prepared_command(opt, argv)
161
+ unless @parse_only
162
+ case opt.subcommand_name
163
+ when "help"
164
+ if !argv.empty?
165
+ if !subcommand_defined?(argv[0])
166
+ puts "Unknown command: #{argv[0].inspect}"
167
+ else
168
+ opt = get_option_parser(argv[0], get_subcmd_data(argv[0]))
169
+ end
170
+ end
171
+ print opt.to_s
172
+ return true
173
+ when "version"
174
+ puts opt.ver || "Unknown version"
175
+ return true
176
+ end
177
+ end
178
+ nil
179
+ end
180
+ private :exec_prepared_command
99
181
 
182
+ def parse!(argv = ARGV)
183
+ define_prepared_command
100
184
  subcmd = argv[0]
101
185
  if subcmd_data = get_subcmd_data(subcmd)
102
186
  argv.shift
103
187
  else
104
188
  subcmd = nil
189
+ unless @accept_undefined_command
190
+ subcmd = "help"
191
+ unless subcmd_data = get_subcmd_data(subcmd)
192
+ raise "Unknown command #{subcmd.inspect}"
193
+ end
194
+ end
105
195
  end
106
196
  opt = get_option_parser(subcmd, subcmd_data)
107
- opt.parse!(argv)
108
-
109
- if @help_subcommand_use_p && subcmd == "help"
110
- print opt.to_s + "\n"
111
- puts message_list_subcommands(opt)
112
- exit
197
+ if exec_prepared_command(opt, argv)
198
+ exit(0)
113
199
  end
114
-
200
+ opt.parse!(argv)
115
201
  subcmd
116
202
  end
117
203
  end
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH << File.expand_path(File.join(__dir__, "../lib"))
2
+
3
+ require "subcommand_optparse"
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # Require this file using `require "spec_helper"` to ensure that it is only
8
+ # loaded once.
9
+ #
10
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
+ RSpec.configure do |config|
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus => true
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ describe SubCmdOptParser do
4
+ it "should raise error" do
5
+ opt = SubCmdOptParser.new do |opt_subcmd|
6
+ opt_subcmd.subcommand("hello")
7
+ expect do
8
+ opt_subcmd.subcommand("hello")
9
+ end.to raise_error
10
+ end
11
+ end
12
+
13
+ context "when executing prepared commands" do
14
+ before(:each) do
15
+ $stdout = StringIO.new
16
+ end
17
+
18
+ it "should exit in help command" do
19
+ opt = SubCmdOptParser.new
20
+ expect do
21
+ opt.parse!(["help"])
22
+ end.to raise_error(SystemExit)
23
+ end
24
+
25
+ it "should exit in version command" do
26
+ opt = SubCmdOptParser.new
27
+ expect do
28
+ opt.parse!(["version"])
29
+ end.to raise_error(SystemExit)
30
+ end
31
+
32
+ it "should not exit in help command" do
33
+ opt = SubCmdOptParser.new(:parse_only => true)
34
+ expect do
35
+ opt.parse!(["help"])
36
+ end.not_to raise_error
37
+ end
38
+
39
+ it "should not exit in version command" do
40
+ opt = SubCmdOptParser.new(:parse_only => true)
41
+ expect do
42
+ opt.parse!(["version"])
43
+ end.not_to raise_error
44
+ end
45
+
46
+ after(:each) do
47
+ $stdout = STDOUT
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subcommand-optparse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takayuki YAMAGUCHI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-05 00:00:00.000000000 Z
11
+ date: 2014-01-31 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
19
  version: '1.3'
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
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: Option parser for subcommands
@@ -87,7 +87,8 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - .gitignore
90
+ - ".gitignore"
91
+ - ".rspec"
91
92
  - Gemfile
92
93
  - LICENSE.txt
93
94
  - README.md
@@ -95,6 +96,8 @@ files:
95
96
  - examples/sample_command.rb
96
97
  - lib/subcommand_optparse.rb
97
98
  - lib/subcommand_optparse/version.rb
99
+ - spec/spec_helper.rb
100
+ - spec/subcommand_optparse_spec.rb
98
101
  - subcommand-optparse.gemspec
99
102
  homepage: ''
100
103
  licenses:
@@ -106,20 +109,22 @@ require_paths:
106
109
  - lib
107
110
  required_ruby_version: !ruby/object:Gem::Requirement
108
111
  requirements:
109
- - - '>='
112
+ - - ">="
110
113
  - !ruby/object:Gem::Version
111
114
  version: '0'
112
115
  required_rubygems_version: !ruby/object:Gem::Requirement
113
116
  requirements:
114
- - - '>='
117
+ - - ">="
115
118
  - !ruby/object:Gem::Version
116
119
  version: '0'
117
120
  requirements: []
118
121
  rubyforge_project:
119
- rubygems_version: 2.0.3
122
+ rubygems_version: 2.1.11
120
123
  signing_key:
121
124
  specification_version: 4
122
125
  summary: Option parser for a command with subcommands, which is parsed by library
123
126
  'optparse'
124
- test_files: []
127
+ test_files:
128
+ - spec/spec_helper.rb
129
+ - spec/subcommand_optparse_spec.rb
125
130
  has_rdoc: