cmdline 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/CHANGELOG +6 -0
- data/COPYING +728 -0
- data/LICENSE +58 -0
- data/README +242 -0
- data/Rakefile +124 -0
- data/examples/example.rb +9 -0
- data/examples/long_example.rb +34 -0
- data/examples/plain_args_example.rb +10 -0
- data/examples/regexp_example.rb +9 -0
- data/examples/subcommand_example.rb +20 -0
- data/lib/cmdline.rb +251 -0
- metadata +57 -0
data/LICENSE
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
This package is copyrighted free software by Tim Becker <tim@kuriositaet.de>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
(see COPYING.txt file), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) rename any non-standard executables so the names do not conflict
|
21
|
+
with standard executables, which must also be provided.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or executable
|
26
|
+
form, provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the executables and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard executables non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under this terms.
|
43
|
+
|
44
|
+
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
|
45
|
+
files under the ./missing directory. See each file for the copying
|
46
|
+
condition.
|
47
|
+
|
48
|
+
5. The scripts and library files supplied as input to or produced as
|
49
|
+
output from the software do not automatically fall under the
|
50
|
+
copyright of the software, but belong to whomever generated them,
|
51
|
+
and may be sold commercially, and may be aggregated with this
|
52
|
+
software.
|
53
|
+
|
54
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
55
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
56
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
57
|
+
PURPOSE.
|
58
|
+
|
data/README
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
|
2
|
+
= cmdline -- Yet Another Command Line Tool
|
3
|
+
|
4
|
+
+cmdline+ is a small library to facilitate handling of command line
|
5
|
+
arguments. +cmdline+ automatically checks that all required arguments
|
6
|
+
and flags are set, performs validity checks on the arguments
|
7
|
+
and automatically generates a usage message from the command line
|
8
|
+
specification. Arguments are available via named accessors.
|
9
|
+
|
10
|
+
cmdline=CommandLine.new [
|
11
|
+
["-f", "-flag", :starts_with_a_digit, "value", true, nil, "must start with a number", /^\d.*/]
|
12
|
+
]
|
13
|
+
cmdline.parse ARGV
|
14
|
+
puts cmdline.starts_with_a_digit
|
15
|
+
|
16
|
+
In the example above, +cmdline+ ensure the +ARGV+ array contains a -f
|
17
|
+
(or -flag) flag which must have an argument that starts with a digit. If
|
18
|
+
an approriate argument is found, it will be accessible via the
|
19
|
+
automaticaly created +starts_with_a_digit+ accessor. If not, a usage
|
20
|
+
message will be generate, printed and the application will exit.
|
21
|
+
|
22
|
+
|
23
|
+
== Installing
|
24
|
+
|
25
|
+
You can install the +cmdline+ package by executing:
|
26
|
+
|
27
|
+
gem install cmdline -r
|
28
|
+
|
29
|
+
alternatively, you can download +.tar.gz+ or +.zip+ archives from
|
30
|
+
Rubyforge[http://rubyforge.org/frs/?group_id=3612] and install using the
|
31
|
+
+setup.rb+ script.
|
32
|
+
|
33
|
+
== Types of Arguments
|
34
|
+
|
35
|
+
* long and short flags :
|
36
|
+
script.rb -s -long_flag
|
37
|
+
* flags taking arguments:
|
38
|
+
script.rb -o outfilename
|
39
|
+
* subcommands (a la +gem+ or +svn+):
|
40
|
+
script.rb generate -h
|
41
|
+
if you want to use subcommands, they have to appear as the very first
|
42
|
+
argument, i.e. this is not possible
|
43
|
+
script.rb -v subcommand -h # NOT POSSIBLE
|
44
|
+
* plain arguments:
|
45
|
+
script.rb -v file_name
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
== Usage
|
50
|
+
|
51
|
+
You'll need to require +cmdline+ like this:
|
52
|
+
|
53
|
+
require 'cmdline'
|
54
|
+
|
55
|
+
(if you installed the package using gems, you'll either need to use:
|
56
|
+
|
57
|
+
require_gem 'cmdline'
|
58
|
+
|
59
|
+
or start ruby with the -rubygems command line flag.)
|
60
|
+
|
61
|
+
In order to use +cmdline+, you'll need to provide an array containing
|
62
|
+
a definition for each argument and pass the +ARGV+ to the method
|
63
|
+
+parse+. (Actually, you can pass in any array, or none, in which case,
|
64
|
+
ARGV will be used by default) An example (from examples/exmaple.rb):
|
65
|
+
|
66
|
+
require 'cmdline'
|
67
|
+
cmdline=CommandLine.new [
|
68
|
+
["-m", "-message", :message, "message", true, nil, "message for 'usage'"]
|
69
|
+
]
|
70
|
+
cmdline.parse ARGV
|
71
|
+
puts cmdline.message
|
72
|
+
|
73
|
+
Running the script yields:
|
74
|
+
|
75
|
+
$ruby example.rb
|
76
|
+
usage: example.rb options
|
77
|
+
-m/-message <message>* message for 'usage'
|
78
|
+
-h/--help print this message
|
79
|
+
* required flags
|
80
|
+
|
81
|
+
missing mandatory flag -m
|
82
|
+
|
83
|
+
The definition for the --help flag was added by default. Running the
|
84
|
+
script with the required argument yields:
|
85
|
+
|
86
|
+
$ruby example.rb -message 'This is the message to print.'
|
87
|
+
This is the message to print.
|
88
|
+
|
89
|
+
=== Flag Definition
|
90
|
+
|
91
|
+
Each argument that is should be accepted is defined using an array. In the
|
92
|
+
above example, a single argument is defined:
|
93
|
+
|
94
|
+
["-m", "-message", :message, "message", true, nil, "message for 'usage'"]
|
95
|
+
|
96
|
+
The meaning of the fields in the definition array (at least for flags)
|
97
|
+
are as follows:
|
98
|
+
|
99
|
+
1. the 'short' flag name
|
100
|
+
2. the long flag name
|
101
|
+
3. the name of the accessor through which the flag value will be available
|
102
|
+
4. this value defines whether the flag takes arguments (i.e. script.rb -o outfile). Value should be +false+ if the flag takes no argument (i.e. script.rb -verbose) or a string which is used in the generated +usage+ message.
|
103
|
+
5. whether this is a required argument
|
104
|
+
6. default value in case the flag is not set on the command line
|
105
|
+
7. a detailed message for the generated usage string
|
106
|
+
8. an optional eighth argument that may be either a +proc+ or a regular expression to check the the validity of the passed argument or and Array containing all allowed arguments.
|
107
|
+
|
108
|
+
|
109
|
+
=== Subcommand Definition
|
110
|
+
|
111
|
+
Subcommands are defined in a simliar manner. An example of how one would parse
|
112
|
+
+gem+ subcommands (from examples/subcommand_example.rb):
|
113
|
+
|
114
|
+
doc= <<END_DOC
|
115
|
+
build Build a gem from a gemspec
|
116
|
+
cert Adjust RubyGems certificate settings
|
117
|
+
check Check installed gems
|
118
|
+
cleanup Clean up old versions of installed gems in the local
|
119
|
+
repository
|
120
|
+
contents Display the contents of the installed gems
|
121
|
+
...
|
122
|
+
END_DOC
|
123
|
+
|
124
|
+
command_arr=["build", "cert", "check", "cleanup", "contents"] # ...
|
125
|
+
cmdline=CommandLine.new [
|
126
|
+
[:command, nil, :command, "command", false, "build", doc, command_arr]
|
127
|
+
]
|
128
|
+
|
129
|
+
puts cmdline.command
|
130
|
+
|
131
|
+
In this example, the subcommand isn't required, so we'll use the
|
132
|
+
automatically generated -h flag to display the usage message:
|
133
|
+
|
134
|
+
$ruby subcommand_example.rb -h
|
135
|
+
usage: subcommand_example.rb [command] [options]
|
136
|
+
build Build a gem from a gemspec
|
137
|
+
cert Adjust RubyGems certificate settings
|
138
|
+
check Check installed gems
|
139
|
+
cleanup Clean up old versions of installed gems in the local
|
140
|
+
repository
|
141
|
+
contents Display the contents of the installed gems
|
142
|
+
...
|
143
|
+
-h/--help print this message
|
144
|
+
|
145
|
+
|
146
|
+
=== Final Arguments
|
147
|
+
|
148
|
+
In order to access, verify and add usage information for plain
|
149
|
+
arguments after flags (e.g. copy.rb -name tim -v file1 file2 file3) you
|
150
|
+
can add a final definition (from examples/plain_args_example.rb):
|
151
|
+
|
152
|
+
args_doc = "files to process"
|
153
|
+
file_readable=lambda{|f| File.readable? f}
|
154
|
+
cmdline=CommandLine.new [
|
155
|
+
[:args, nil, :args, "args", false, nil, args_doc, file_readable]
|
156
|
+
]
|
157
|
+
cmdline.parse ARGV
|
158
|
+
puts cmdline.args
|
159
|
+
|
160
|
+
In the example above the file arguments are required. So running the
|
161
|
+
example without args yields:
|
162
|
+
|
163
|
+
$ruby plain_args_example.rb
|
164
|
+
usage: plain_args_example.rb [options] args
|
165
|
+
-h/--help print this message
|
166
|
+
|
167
|
+
args: files to process
|
168
|
+
|
169
|
+
missing mandatory args
|
170
|
+
|
171
|
+
Finally, a proc is passed to check that any filename arguments refer to
|
172
|
+
readable files.
|
173
|
+
|
174
|
+
=== Putting it all together
|
175
|
+
|
176
|
+
(from examples/long_example.rb):
|
177
|
+
|
178
|
+
commands_check= ["add", "blame", "cat", "checkout"]
|
179
|
+
file_readable=lambda{|f| File.readable? f}
|
180
|
+
cmdline=CommandLine.new [
|
181
|
+
[:command, nil, :command, "command", false, "add", commands_doc, commands_check],
|
182
|
+
["-o", nil, :outfile, "file", false, STDOUT, "filename to write output to, default STDOUT"],
|
183
|
+
["-i", "--infile", :infile, "file", false, STDIN, "filename to read from, default STDIN", file_readable],
|
184
|
+
["-v", "--verbose", :verbose, false, false, nil, "verbose"],
|
185
|
+
["-n", "--numeric", :number, "num", true, nil, "numeric value", /^\d+$/],
|
186
|
+
[:args, nil, :args, "args", false, nil, args_doc, file_readable]
|
187
|
+
]
|
188
|
+
|
189
|
+
|
190
|
+
This definition requires:
|
191
|
+
|
192
|
+
* an optional subcommand which defaults to "add"
|
193
|
+
* an optional -o flag which defaults to STDOUT
|
194
|
+
* an optional -i/--infile flag which checks that filename args refer to readable files
|
195
|
+
* an optional -v flag that doesn't take an argument
|
196
|
+
* a mandatory -n/--numeric flag which checks the argument is numeric
|
197
|
+
* optional args, which, if passed must be names of readable files
|
198
|
+
|
199
|
+
The generated usage message will look like this:
|
200
|
+
|
201
|
+
$ruby long_example.rb
|
202
|
+
usage: long_example.rb [command] options [args]
|
203
|
+
|
204
|
+
Available commands:
|
205
|
+
add
|
206
|
+
blame
|
207
|
+
cat
|
208
|
+
checkout
|
209
|
+
|
210
|
+
-o <file> filename to write output to, default STDOUT
|
211
|
+
-i/--infile <file> filename to read from, default STDIN
|
212
|
+
-v/--verbose verbose
|
213
|
+
-n/--numeric <num>* numeric value
|
214
|
+
-h/--help print this message
|
215
|
+
* required flags
|
216
|
+
|
217
|
+
args: files to process
|
218
|
+
|
219
|
+
missing mandatory flag -n
|
220
|
+
|
221
|
+
|
222
|
+
== Contact
|
223
|
+
|
224
|
+
In case you discover bugs, offer suggestions for improvements or would
|
225
|
+
like to help out with the project, you can contact me via email
|
226
|
+
(tim@kuriositaet.de).
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
|
241
|
+
|
242
|
+
=
|
data/Rakefile
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require "rake/rdoctask"
|
2
|
+
require "rake/gempackagetask"
|
3
|
+
require "rake/testtask"
|
4
|
+
require "rake/clean"
|
5
|
+
require "rubygems"
|
6
|
+
|
7
|
+
# Some definitions that you'll need to edit in case you reuse this
|
8
|
+
# Rakefile for your own project.
|
9
|
+
|
10
|
+
SHORTNAME ='cmdline' # this should be the rubyforge project name
|
11
|
+
DESC ='Yet Another Command Line Tool'
|
12
|
+
PKG_VERSION ='0.0.0'
|
13
|
+
LONG_DESC = <<END_DESC
|
14
|
+
Library used to handle command line arguments.
|
15
|
+
END_DESC
|
16
|
+
RUBYFORGE_USER ='a2800276'
|
17
|
+
|
18
|
+
# Specifies the default task to execute. This is often the "test" task
|
19
|
+
# and we'll change things around as soon as we have some tests.
|
20
|
+
|
21
|
+
task :default => [:rdoc]
|
22
|
+
|
23
|
+
# The directory to generate +rdoc+ in.
|
24
|
+
RDOC_DIR="doc/html"
|
25
|
+
|
26
|
+
# This global variable contains files that will be erased by the `clean` task.
|
27
|
+
# The `clean` task itself is automatically generated by requiring `rake/clean`.
|
28
|
+
|
29
|
+
CLEAN << RDOC_DIR << "pkg"
|
30
|
+
|
31
|
+
|
32
|
+
# This is the task that generates the +rdoc+ documentation from the
|
33
|
+
# source files. Instantiating Rake::RDocTask automatically generates a
|
34
|
+
# task called `rdoc`.
|
35
|
+
|
36
|
+
Rake::RDocTask.new do |rd|
|
37
|
+
# Options for documenation generation are specified inside of
|
38
|
+
# this block. For example the following line specifies that the
|
39
|
+
# content of the README file should be the main page of the
|
40
|
+
# documenation.
|
41
|
+
rd.main = "README"
|
42
|
+
|
43
|
+
# The following line specifies all the files to extract
|
44
|
+
# documenation from.
|
45
|
+
rd.rdoc_files.include( "README", "AUTHORS", "LICENSE",
|
46
|
+
"CHANGELOG", "bin/**/*", "lib/**/*.rb",
|
47
|
+
"examples/**/*rb","test/**/*.rb", "doc/*.rdoc")
|
48
|
+
# This one specifies the output directory ...
|
49
|
+
rd.rdoc_dir = "doc/html"
|
50
|
+
|
51
|
+
# Or the HTML title of the generated documentation set.
|
52
|
+
rd.title = "#{SHORTNAME}: #{DESC}"
|
53
|
+
|
54
|
+
# These are options specifiying how source code inlined in the
|
55
|
+
# documentation should be formatted.
|
56
|
+
|
57
|
+
rd.options = ["--line-numbers", "--inline-source"]
|
58
|
+
|
59
|
+
# Check:
|
60
|
+
# `rdoc --help` for more rdoc options
|
61
|
+
# the {rdoc documenation home}[http://www.ruby-doc.org/stdlib/libdoc/rdoc/rdoc/index.html]
|
62
|
+
# or the documentation for the +Rake::RDocTask+ task[http://rake.rubyforge.org/classes/Rake/RDocTask.html]
|
63
|
+
end
|
64
|
+
|
65
|
+
# The GemPackageTask facilitates getting all your files collected
|
66
|
+
# together into gem archives. You can also use it to generate tarball
|
67
|
+
# and zip archives.
|
68
|
+
|
69
|
+
# First you'll need to assemble a gemspec
|
70
|
+
|
71
|
+
PKG_FILES = FileList['lib/**/*.rb', 'bin/**/*', 'examples/**/*', '[A-Z]*', 'test/**/*'].to_a
|
72
|
+
|
73
|
+
spec = Gem::Specification.new do |s|
|
74
|
+
s.platform = Gem::Platform::RUBY
|
75
|
+
s.summary = "#{SHORTNAME}: #{DESC}"
|
76
|
+
s.name = SHORTNAME
|
77
|
+
s.version = PKG_VERSION
|
78
|
+
s.files = PKG_FILES
|
79
|
+
s.requirements << "none"
|
80
|
+
s.require_path = 'lib'
|
81
|
+
s.description = LONG_DESC
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adding a new GemPackageTask adds a task named `package`, which generates
|
85
|
+
# packages as gems, tarball and zip archives.
|
86
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
87
|
+
pkg.need_zip = true
|
88
|
+
pkg.need_tar_gz = true
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# This task is used to demonstrate how to upload files to Rubyforge.
|
93
|
+
# Calling `upload_page` creates a current version of the +rdoc+
|
94
|
+
# documentation and uploads it to the Rubyforge homepage of the project,
|
95
|
+
# assuming it's hosted there and naming conventions haven't changed.
|
96
|
+
#
|
97
|
+
# This task uses `sh` to call the `scp` binary, which is plattform
|
98
|
+
# dependant and may not be installed on your computer if you're using
|
99
|
+
# Windows. I'm currently not aware of any pure ruby way to do scp
|
100
|
+
# transfers.
|
101
|
+
|
102
|
+
RubyForgeProject=SHORTNAME
|
103
|
+
|
104
|
+
desc "Upload the web pages to the web."
|
105
|
+
task :upload_pages => ["rdoc"] do
|
106
|
+
if RubyForgeProject then
|
107
|
+
path = "/var/www/gforge-projects/#{RubyForgeProject}"
|
108
|
+
sh "scp -r doc/html/* #{RUBYFORGE_USER}@rubyforge.org:#{path}"
|
109
|
+
sh "scp doc/images/*.png #{RUBYFORGE_USER}@rubyforge.org:#{path}/images"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# This task will run the unit tests provided in files called
|
114
|
+
# `test/test*.rb`. The task itself can be run with a call to `rake test`
|
115
|
+
|
116
|
+
Rake::TestTask.new do |t|
|
117
|
+
t.libs << "test"
|
118
|
+
t.libs << "lib"
|
119
|
+
t.test_files = FileList['test/*.rb']
|
120
|
+
t.verbose = true
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
|
data/examples/example.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'cmdline'
|
2
|
+
|
3
|
+
if $0 == __FILE__
|
4
|
+
|
5
|
+
commands_doc= <<ENDDOC
|
6
|
+
|
7
|
+
Available commands:
|
8
|
+
add
|
9
|
+
blame
|
10
|
+
cat
|
11
|
+
checkout
|
12
|
+
|
13
|
+
ENDDOC
|
14
|
+
|
15
|
+
args_doc = "files to process"
|
16
|
+
commands_check= ["add", "blame", "cat", "checkout"]
|
17
|
+
|
18
|
+
file_readable=lambda{|f| File.readable? f}
|
19
|
+
|
20
|
+
|
21
|
+
cmdline=CommandLine.new [
|
22
|
+
[:command, nil, :command, "command", false, "add", commands_doc, commands_check],
|
23
|
+
["-o", nil, :outfile, "file", false, STDOUT, "filename to write output to, default STDOUT"],
|
24
|
+
["-i", "--infile", :infile, "file", false, STDIN, "filename to read from, default STDIN", file_readable],
|
25
|
+
["-v", "--verbose", :verbose, false, false, nil, "verbose"],
|
26
|
+
["-n", "--numeric", :number, "num", true, nil, "numeric value", /^\d+$/],
|
27
|
+
[:args, nil, :args, "args", false, nil, args_doc, file_readable]
|
28
|
+
]
|
29
|
+
|
30
|
+
cmdline.parse ARGV
|
31
|
+
puts cmdline.outfile
|
32
|
+
puts cmdline.command
|
33
|
+
puts cmdline.args
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'cmdline'
|
2
|
+
|
3
|
+
doc= <<END_DOC
|
4
|
+
build Build a gem from a gemspec
|
5
|
+
cert Adjust RubyGems certificate settings
|
6
|
+
check Check installed gems
|
7
|
+
cleanup Clean up old versions of installed gems in the local
|
8
|
+
repository
|
9
|
+
contents Display the contents of the installed gems
|
10
|
+
...
|
11
|
+
END_DOC
|
12
|
+
|
13
|
+
|
14
|
+
command_arr=["build", "cert", "check", "cleanup", "contents"] # ...
|
15
|
+
cmdline=CommandLine.new [
|
16
|
+
[:command, nil, :command, "command", false, "add", doc, command_arr]
|
17
|
+
]
|
18
|
+
cmdline.parse ARGV
|
19
|
+
puts cmdline.command
|
20
|
+
|