subcommand 1.0.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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rahul Kumar
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,108 @@
1
+ = subcommand
2
+
3
+ A tiny wrapper over ruby's awesome OptionParser (standard) which gives easy facility of subcommands.
4
+ It has a similar interface to git and prints subcommands summary as well.
5
+
6
+ == Features:
7
+
8
+ 1. subcommands using all of OptionParser's features
9
+ 2. aliases for subcommands
10
+
11
+
12
+ e.g
13
+ Assuming a program "prog" with subcommands "del" and "add"
14
+
15
+ prog help
16
+ prog --help
17
+
18
+ prog help del
19
+ prog del --help
20
+
21
+ prog del --force file.a
22
+ prog --verbose del --force file.a
23
+
24
+ == Examples
25
+
26
+ if a program has subcommands foo and baz
27
+
28
+ ruby subcommand.rb help
29
+ ruby subcommand.rb --help
30
+ ruby subcommand.rb help foo
31
+ ruby subcommand.rb foo --help
32
+ ruby subcommand.rb baz --quiet "some text"
33
+ ruby subcommand.rb --verbose foo --force file.zzz
34
+
35
+ == STEPS
36
+
37
+ 1. define global_options (optional)
38
+
39
+ global_options do |opts|
40
+ opts.banner = "Usage: subcommand.rb [options] [subcommand [options]]"
41
+ opts.description = "Stupid program that does something"
42
+ opts.separator ""
43
+ opts.separator "Global options are:"
44
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
45
+ options[:verbose] = v
46
+ end
47
+ end
48
+
49
+ 2. define commands using command(). Send multiple names for aliases.
50
+
51
+ command :foo do |opts|
52
+ opts.banner = "Usage: foo [options]"
53
+ opts.description = "desc for foo"
54
+ opts.on("-f", "--[no-]force", "force action") do |v|
55
+ options[:force] = v
56
+ end
57
+ end
58
+
59
+ # aliases init and create
60
+ command :init, :create do |opts| ...
61
+
62
+ 3. call opt_parse()
63
+
64
+ == Sample Output
65
+
66
+ $ ruby subcommand.rb help
67
+
68
+ Usage: subcommand.rb [options] [subcommand [options]]
69
+ Stupid program that does something
70
+
71
+ Global options are:
72
+ -v, --[no-]verbose Run verbosely
73
+
74
+ Commands are:
75
+ foo : desc for foo
76
+ baz : desc for baz
77
+
78
+ Aliases:
79
+ goo - foo
80
+
81
+ See 'subcommand.rb help COMMAND' for more information on a specific command.
82
+
83
+
84
+ $ ruby subcommand.rb help foo
85
+
86
+ Usage: foo [options]
87
+ desc for foo
88
+ -f, --[no-]force force action
89
+
90
+ == Install
91
+
92
+ sudo gem install subcommand
93
+
94
+ Or, copy into your lib directory and require (see source for sample usage)
95
+
96
+ == Note on Patches/Pull Requests
97
+
98
+ * Fork the project.
99
+ * Make your feature addition or bug fix.
100
+ * Add tests for it. This is important so I don't break it in a
101
+ future version unintentionally.
102
+ * Commit, do not mess with rakefile, version, or history.
103
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
104
+ * Send me a pull request. Bonus points for topic branches.
105
+
106
+ == Copyright
107
+
108
+ Copyright (c) 2010 Rahul Kumar. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "subcommand"
8
+ gem.summary = %Q{A tiny wrapper over OptionParser giving simple, elegant subcommand facility}
9
+ gem.description = %Q{Subcommand and alias facility for command line programs with elegant help printing}
10
+ gem.email = "sentinel.1879@gmail.com"
11
+ gem.homepage = "http://github.com/rkumar/subcommand"
12
+ gem.authors = ["Rahul Kumar"]
13
+ #gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ begin
47
+ require 'yard'
48
+ YARD::Rake::YardocTask.new
49
+ rescue LoadError
50
+ task :yardoc do
51
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
52
+ end
53
+ end
data/TODO ADDED
@@ -0,0 +1 @@
1
+ Add aliases
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/lib/subcommand.rb ADDED
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env ruby -w
2
+ ######################################
3
+ # A tiny wrapper over optparse that gives easy subcommand facility.
4
+ # It also neatly prints help for global and subcommands
5
+ # as well as summarizes subcommands in global help.
6
+ #
7
+ # Thanks to Robert Klemme for his idea on lazy loading the subcommand option parsers.
8
+ #
9
+ # @author Rahul Kumar, Jun 2010
10
+ # @date 2010-06-20 22:33
11
+ #
12
+ # @examples
13
+ # if a program has subcommands foo and baz
14
+ #
15
+ # ruby opt.rb help
16
+ # ruby opt.rb --help
17
+ # ruby opt.rb help foo
18
+ # ruby opt.rb foo --help
19
+ # ruby opt.rb baz --quiet "some text"
20
+ # ruby opt.rb --verbose foo --force file.zzz
21
+ #
22
+ # == STEPS
23
+ # 1. define global_options (optional)
24
+ #
25
+ # global_options do |opts|
26
+ # opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
27
+ # opts.description = "Stupid program that does something"
28
+ # opts.separator ""
29
+ # opts.separator "Global options are:"
30
+ # opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
31
+ # options[:verbose] = v
32
+ # end
33
+ # end
34
+ #
35
+ # 2. define commands using command().
36
+ # command :foo do |opts|
37
+ # opts.banner = "Usage: foo [options]"
38
+ # opts.description = "desc for foo"
39
+ # opts.on("-f", "--[no-]force", "force verbosely") do |v|
40
+ # options[:force] = v
41
+ # end
42
+ # end
43
+ #
44
+ # 3. call opt_parse()
45
+ #
46
+ # 4. As before, handle ARGS and options hash.
47
+ #
48
+ # TODO: add aliases for commands
49
+ ######################################
50
+ require 'optparse'
51
+
52
+ # Allow command to have a description to generate help
53
+ class OptionParser
54
+ attr_accessor :description
55
+ #attr_accessor :action
56
+ end
57
+
58
+ module Subcommands
59
+ ##
60
+ # specify a single command and all its options
61
+ # If multiple names are given, they are treated as aliases.
62
+ # Do repeatedly for each command
63
+ # Yields the optionparser
64
+ def command *names
65
+ #puts "inside command with #{names} "
66
+ name = names.shift
67
+ @commands ||= {}
68
+ @aliases ||= {}
69
+ if names.length > 0
70
+ names.each do |n|
71
+ #puts "aliases #{n} => #{name} "
72
+ @aliases[n.to_s] = name.to_s
73
+ end
74
+ end
75
+ # Thanks to Robert Klemme for the lazy loading idea.
76
+ opt = lambda { OptionParser.new do |opts|
77
+ yield opts
78
+ # append desc to banner in next line
79
+ opts.banner << "\n#{opts.description}\n" if opts.description
80
+ end }
81
+ @commands[name.to_s] = opt
82
+ end
83
+ # specify global options and banner and description
84
+ # Yields the optionparser
85
+ def global_options
86
+ if !defined? @global
87
+ @global = OptionParser.new do |opts|
88
+ yield opts
89
+ end
90
+ else
91
+ yield @global
92
+ end
93
+ end
94
+ # first parse global optinos
95
+ # then parse subcommand options if valid subcommand
96
+ # special case of "help command" so we print help of command - git style (3)
97
+ # in all invalid cases print global help
98
+ def opt_parse
99
+ # if user has not defined global, we need to create it
100
+ if !defined? @global
101
+ global_options do |opts|
102
+ opts.banner = "Usage: #{$0} [options] [subcommand [options]]"
103
+ opts.separator ""
104
+ opts.separator "Global options are:"
105
+ opts.on("-h", "--help", "Print this help") do |v|
106
+ puts @global
107
+ exit
108
+ end
109
+ opts.separator ""
110
+ opts.separator subtext
111
+ end
112
+ else
113
+ # user has defined some, but lets add subcommand information
114
+ cmdtext = "Commands are:"
115
+ @commands.each_pair do |c, opt|
116
+ desc = opt.call.description
117
+ cmdtext << "\n #{c} : #{desc}"
118
+ end
119
+
120
+ # print aliases
121
+ unless @aliases.empty?
122
+ cmdtext << "\n\nAliases: \n"
123
+ @aliases.each_pair { |name, val| cmdtext << " #{name} - #{val}" }
124
+ end
125
+
126
+ cmdtext << "\n\nSee '#{$0} help COMMAND' for more information on a specific command."
127
+
128
+ global_options do |opts|
129
+ # lets add the description user gave into banner
130
+ opts.banner << "\n#{opts.description}\n" if opts.description
131
+ opts.separator ""
132
+ opts.separator cmdtext
133
+ end
134
+ end
135
+ @global.order!
136
+ cmd = ARGV.shift
137
+ if cmd
138
+ #puts "Command: #{cmd} "
139
+ sc = @commands[cmd]
140
+ unless sc
141
+ # see if an alias exists
142
+ #puts "sc nil #{@aliases} "
143
+ alas = @aliases[cmd]
144
+ #puts "sc nil #{alas} "
145
+ sc = @commands[alas] if alas
146
+ #puts "sc nil #{sc} "
147
+ end
148
+ # if valid command parse the args
149
+ if sc
150
+ sc.call.order!
151
+ else
152
+ # else if help <command> then print its help GIT style (3)
153
+ if !ARGV.empty? and cmd == "help"
154
+ cmd = ARGV.shift
155
+ sc = @commands[cmd]
156
+ # if valid command print help, else print global help
157
+ if sc
158
+ #puts " 111 help foo/baz"
159
+ puts sc.call
160
+ else puts @global
161
+ end
162
+ else
163
+ # invalid command
164
+ puts @global
165
+ end
166
+ exit 0
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ if __FILE__ == $PROGRAM_NAME
173
+ include Subcommands
174
+ options = {}
175
+ appname = File.basename($0)
176
+ # global is optional
177
+ global_options do |opts|
178
+ opts.banner = "Usage: #{appname} [options] [subcommand [options]]"
179
+ opts.description = "Stupid program that does something"
180
+ opts.separator ""
181
+ opts.separator "Global options are:"
182
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
183
+ options[:verbose] = v
184
+ end
185
+ end
186
+ # define a command
187
+ command :foo, :goo do |opts|
188
+ opts.banner = "Usage: foo [options]"
189
+ opts.description = "desc for foo"
190
+ opts.on("-f", "--[no-]force", "force verbosely") do |v|
191
+ options[:force] = v
192
+ end
193
+ end
194
+ command :baz do |opts|
195
+ opts.banner = "Usage: baz [options]"
196
+ opts.description = "desc for baz"
197
+ opts.on("-q", "--[no-]quiet", "quietly run ") do |v|
198
+ options[:quiet] = v
199
+ end
200
+ end
201
+
202
+ # do the parsing.
203
+ opt_parse()
204
+
205
+ puts "options ......"
206
+ p options
207
+ puts "ARGV:"
208
+ p ARGV
209
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'subcommand'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestSubcommand < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: subcommand
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Rahul Kumar
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-21 00:00:00 +05:30
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: yard
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ description: Subcommand and alias facility for command line programs with elegant help printing
33
+ email: sentinel.1879@gmail.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.rdoc
41
+ - TODO
42
+ files:
43
+ - .document
44
+ - .gitignore
45
+ - LICENSE
46
+ - README.rdoc
47
+ - Rakefile
48
+ - VERSION
49
+ - lib/subcommand.rb
50
+ - test/helper.rb
51
+ - test/test_subcommand.rb
52
+ - TODO
53
+ has_rdoc: true
54
+ homepage: http://github.com/rkumar/subcommand
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ requirements: []
77
+
78
+ rubyforge_project:
79
+ rubygems_version: 1.3.6
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: A tiny wrapper over OptionParser giving simple, elegant subcommand facility
83
+ test_files:
84
+ - test/helper.rb
85
+ - test/test_subcommand.rb