subcommand-optparse 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: