cmdparse 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,4 +1,44 @@
1
1
  ------------------------------------------------------------------------
2
+ r291 | thomas | 2005-06-09 12:24:24 +0200 (Thu, 09 Jun 2005) | 1 line
3
+ Changed paths:
4
+ M /trunk/cmdparse/doc/src/index.page
5
+
6
+ * small docu change
7
+ ------------------------------------------------------------------------
8
+ r290 | thomas | 2005-06-09 12:19:20 +0200 (Thu, 09 Jun 2005) | 1 line
9
+ Changed paths:
10
+ M /trunk/cmdparse/doc/src/default.template
11
+
12
+
13
+ ------------------------------------------------------------------------
14
+ r285 | thomas | 2005-05-21 14:05:54 +0200 (Sat, 21 May 2005) | 1 line
15
+ Changed paths:
16
+ M /trunk/cmdparse/doc/src/default.template
17
+
18
+ * added validation images to default.template
19
+ ------------------------------------------------------------------------
20
+ r284 | thomas | 2005-05-21 13:16:15 +0200 (Sat, 21 May 2005) | 3 lines
21
+ Changed paths:
22
+ M /trunk/cmdparse/README
23
+ M /trunk/cmdparse/Rakefile
24
+ M /trunk/cmdparse/TODO
25
+ A /trunk/cmdparse/doc/plugin
26
+ A /trunk/cmdparse/doc/plugin/extract.rb
27
+ A /trunk/cmdparse/doc/src/about.page
28
+ M /trunk/cmdparse/doc/src/default.css
29
+ M /trunk/cmdparse/doc/src/default.template
30
+ A /trunk/cmdparse/doc/src/documentation.page
31
+ M /trunk/cmdparse/doc/src/download.page
32
+ M /trunk/cmdparse/doc/src/features.page
33
+ M /trunk/cmdparse/doc/src/index.page
34
+ M /trunk/cmdparse/doc/src/meta.info
35
+ M /trunk/cmdparse/lib/cmdparse.rb
36
+ M /trunk/cmdparse/test.rb
37
+
38
+ * added optional graceful exception handling to CommandParser
39
+ * added two doc pages: about.page and documentation.page
40
+ * uniformed naming: only <cmdparse> valid anymore
41
+ ------------------------------------------------------------------------
2
42
  r265 | thomas | 2005-04-21 12:57:51 +0200 (Thu, 21 Apr 2005) | 1 line
3
43
  Changed paths:
4
44
  M /trunk/cmdparse/doc/src/index.page
data/README CHANGED
@@ -36,7 +36,7 @@ You can build the documentation by invoking
36
36
  $ rake doc
37
37
 
38
38
  This builds the API and the additional documentation. The additional documentation needs webgen
39
- >=0.3.2 (webgen.rubyforge.org) for building.
39
+ >=0.3.4 (webgen.rubyforge.org) for building.
40
40
 
41
41
 
42
42
  = Example
data/Rakefile CHANGED
@@ -70,9 +70,9 @@ end
70
70
  CLOBBER << "doc/output"
71
71
  desc "Builds the documentation"
72
72
  task :doc => [:rdoc] do
73
- Dir.chdir("doc")
74
- sh "webgen -V 3"
75
- Dir.chdir("..")
73
+ chdir "doc" do
74
+ sh "webgen"
75
+ end
76
76
  end
77
77
 
78
78
  rd = Rake::RDocTask.new do |rdoc|
@@ -94,6 +94,7 @@ PKG_FILES = FileList.new( [
94
94
  'README',
95
95
  'Rakefile',
96
96
  'ChangeLog',
97
+ 'test.rb',
97
98
  'VERSION',
98
99
  'lib/**/*.rb',
99
100
  'doc/**/*'
data/TODO CHANGED
@@ -5,3 +5,4 @@
5
5
  * raise NoCommandGivenError when no command was given
6
6
  * ability to specify default command (used when no command was given)
7
7
  * add order,order!,... methods to mimic optparse
8
+ * optionally capture error messages and provide friendlier output
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.2
1
+ 1.0.3
@@ -0,0 +1,29 @@
1
+ module CmdparsePlugins
2
+
3
+ class ExtractTag < Tags::DefaultTag
4
+
5
+ summary "Extracts lines from a file"
6
+ depends_on 'Tags'
7
+ add_param 'file', nil, 'the file from which to read the lines'
8
+ add_param 'lines', nil, 'the lines which should be read (Range)'
9
+ set_mandatory 'file'
10
+ set_mandatory 'lines'
11
+
12
+ def initialize
13
+ super
14
+ @processOutput = false
15
+ register_tag( 'extract' )
16
+ end
17
+
18
+ def process_tag( tag, node, refNode )
19
+ data = File.readlines( get_param( 'file' ) ).unshift( 'empty null line' )[get_param( 'lines' )]
20
+ out = '<table class="cmdparse-example"><tr>'
21
+ out << '<td><pre>' << get_param( 'lines' ).collect {|n| "#{n}<br />" }.to_s << '</pre></td>'
22
+ out << '<td><pre>' << data.collect {|line| "#{CGI::escapeHTML(line)}<br />" }.to_s << '</pre></td>'
23
+ out << '</tr></table>'
24
+ out
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,20 @@
1
+ ---
2
+ title: About
3
+ inMenu: true
4
+ orderInfo: 2
5
+ ---
6
+ h2. About @cmdparse@
7
+
8
+ Some new programs use a "command style" command line. Examples for such programs are the "svn"
9
+ program from Subversion and the "gem" program from Rubygems. The standard Ruby distribution has no
10
+ library to create programs that use such a command line interface.
11
+
12
+ This library, cmdparse, can be used to create such a command line interface. Internally it uses
13
+ optparse to parse options and it provides a nice API for specifying commands.
14
+
15
+ h2. Author
16
+
17
+ * *Thomas Leitner*
18
+ * Web: "http://cmdparse.rubyforge.org":http://cmdparse.rubyforge.org
19
+ * e-Mail: "t_leitner@gmx.at":mailto:t_leitner@gmx.at
20
+ * GPG Key-Id: 0xD942E7F6
@@ -143,4 +143,9 @@
143
143
  .webgen-gallery table td{
144
144
  text-align: center;
145
145
  border: 1px solid black;
146
- }
146
+ }
147
+
148
+ table.cmdparse-example td {
149
+ border: 1px solid #408040;
150
+ background-color: white;
151
+ }
@@ -2,7 +2,7 @@
2
2
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3
3
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{lang:}">
4
4
  <head>
5
- <title>CommandParser: {title:}</title>
5
+ <title>cmdparse: {title:}</title>
6
6
  <link href="{relocatable: default.css}" rel="stylesheet" />
7
7
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8
8
  </head>
@@ -13,7 +13,7 @@
13
13
  <table>
14
14
  <tr>
15
15
  <td><img src="{relocatable: logo.png}" alt="Logo" title="Logo" /></td>
16
- <td><h1>CommandParser<span style="font-size: 60%"> - advanced command line parser which supports commands</span></h1>
16
+ <td><h1>cmdparse<span style="font-size: 60%"> - advanced command line parser which supports commands</span></h1>
17
17
  </td>
18
18
  </tr>
19
19
  </table>
@@ -34,7 +34,9 @@
34
34
  </div>
35
35
 
36
36
  <div id="footer" class="bar">
37
- generated with <em><b><a href="http://webgen.rubyforge.org"><em><b>webgen</b></em></a></b></em> on <b>{date: }</b>
37
+ <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml11" alt="Valid XHTML 1.1!" height="31" width="88" /></a>
38
+ <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" /></a>
39
+ <a href="http://webgen.rubyforge.org"><img src="http://webgen.rubyforge.org/generated_by_webgen.png" alt="Generated by webgen" height="31" width="88"/></a> on <b>{date: }</b>
38
40
  </div>
39
41
  </div>
40
42
  </body>
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: Documentation
3
+ inMenu: true
4
+ orderInfo: 6
5
+ ---
6
+ h2. Documentation
7
+
8
+ The <a href="{relocatable: /rdoc/index.html}">API reference</a> provides information on how to use
9
+ @cmdparse@. Here is only a short tutorial which shows most of the features.
10
+
11
+ h2. Tutorial
12
+
13
+ <b>The complete code for this example can be found in the file @test.rb@ of the @cmdparse@
14
+ package!</b>
15
+
16
+ h3. Require statements
17
+
18
+ Create a new new file and write the necessary @require@ statements.
19
+
20
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 4..5}}</notextile>
21
+
22
+ h3. The @CommandParser@ class
23
+
24
+ Next we will define our basic @CommandParser@ by defining the name of the program, its version and
25
+ release number and the global options. These global options are always used by @CommandParser@ and
26
+ have to be specified on the command line before the name of a command. The global options and, for
27
+ the matter, the local command specific options are instances of the @OptionParser@ class which is
28
+ available in the Ruby Standard library.
29
+
30
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 29..37}}</notextile>
31
+
32
+ Now we only have to tell the program to use our newly defined class to process the command line
33
+ arguments.
34
+
35
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 41..42}}</notextile>
36
+
37
+ The @#parse!@ method of our @CommandParser@ object parses the given array of options (the second
38
+ argument specifies if a command should be executed immediately or if the options should only be
39
+ parsed). The @#execute@ method then executes the command.
40
+
41
+ The program can be executed now but won't be useful as we have not specified any commands. It will
42
+ always produce error messages.
43
+
44
+ h3. Defining commands
45
+
46
+ So, as we have defined our @CommandParser@ object, we need to add some commands to it. First, we
47
+ will add two predefined commands, namely the @help@ and the @version@ command.
48
+
49
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 39..40}}</notextile>
50
+
51
+ That was easy! Now you can execute the program and specify the commands @help@ or @version@.
52
+ However, we want the program to do something "useful". Therefore we define a new command.
53
+
54
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 8..27}}</notextile>
55
+
56
+ The command specific options are initialized in the @#initialize@ method. These options are used by
57
+ our @CommandParser@ object if, and only if, the command is specified on the command line. The
58
+ @#description@ method describes the command and the @#execute@ is called when the command needs to
59
+ be executed.
60
+
61
+ This command has to be added to our @CommandParser@ object.
62
+
63
+ <notextile>{extract: {file: ../test.rb, lines: !ruby/range 38..38}}</notextile>
64
+
65
+ By providing @true@ as second argument, we specifiy that the @test@ command should be the default
66
+ command which gets invoked when no command is specified on the command line. Only one command can be
67
+ specified as default command!
68
+
69
+ h3. Running the program
70
+
71
+ That's all! You can run the program now and have a look at the output which differs depending on
72
+ which arguments you choose.
73
+
74
+ *Notice:* Options, command name and additional arguments have to be in a certain order on the
75
+ command line:
76
+
77
+ # [optional] Global options
78
+ # Command name
79
+ # [optional] Command specific options
80
+ # [optional] Additional arguments
81
+
82
+ So, a typical invokation looks like this:
83
+
84
+ <pre>
85
+ $ ruby test.rb -r myfunc test -a arg1 arg2 arg3
86
+ </pre>
87
+
88
+ * <tt>-r myfunc</tt> is a global option
89
+ * @test@ is the command name
90
+ * @-a@ is a command specific option (only available for the test command)
91
+ * <tt>arg1 arg2 arg3</tt> are additional arguments
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Download &amp; Installation
3
3
  inMenu: true
4
- menuOrder: 3
4
+ orderInfo: 4
5
5
  ---
6
6
  h2. Download
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Features
3
3
  inMenu: true
4
- menuOrder: 5
4
+ orderInfo: 3
5
5
  ---
6
6
  h2. Feature list
7
7
 
@@ -1,24 +1,31 @@
1
1
  ---
2
2
  title: HomePage
3
3
  inMenu: true
4
- directoryName: CommandParser
4
+ directoryName: cmdparse
5
5
  menuOrder: 1
6
6
  ---
7
7
  h2. Welcome
8
8
 
9
- ... to the homepage of _*CommandParser*_, an advanced command line parser.
9
+ ... to the homepage of _*cmdparse*_, an advanced command line parser.
10
10
 
11
11
  Have a look around the site!
12
12
 
13
13
  h2. News
14
14
 
15
- <b>cmdparse 1.0.2 released!!!</b>
15
+ <b>2005-06-09 cmdparse 1.0.3 released!!!</b>
16
+
17
+ Changes:
18
+
19
+ * added optional graceful exception handling
20
+
21
+
22
+ <b>2005-04-21 cmdparse 1.0.2 released!!!</b>
16
23
 
17
24
  Changes:
18
25
 
19
26
  * splitted parsing of the arguments and executing the command into two methods
20
27
 
21
- <b>cmdparse 1.0.1 released!!!</b>
28
+ <b>2005-04-13 cmdparse 1.0.1 released!!!</b>
22
29
 
23
30
  Changes:
24
31
 
@@ -26,15 +33,6 @@ Changes:
26
33
  * Possibility to define a default command which is used when no command was specified
27
34
  * A @NoCommandGivenError@ is thrown when no command on the CLI and no default command was specified
28
35
 
29
- h2. Description
30
-
31
- Some new programs use a "command style" command line. Examples for such programs are the "svn"
32
- program from Subversion and the "gem" program from Rubygems. The standard Ruby distribution has no
33
- library to create programs that use such a command line interface.
34
-
35
- This library, cmdparse, can be used to create such a command line interface. Internally it uses
36
- optparse to parse options and it provides a nice API for specifying commands.
37
-
38
36
  h2. And so
39
37
 
40
38
  ... have fun!
@@ -1,6 +1,5 @@
1
1
  api.html:
2
- en:
3
2
  dest: rdoc/index.html
4
3
  title: API Reference
5
- menuOrder: 7
4
+ orderInfo: 7
6
5
  inMenu: true
@@ -1,7 +1,7 @@
1
1
  #
2
2
  #--
3
3
  #
4
- # $Id: cmdparse.rb 246 2005-04-13 13:36:19Z thomas $
4
+ # $Id: cmdparse.rb 284 2005-05-21 11:16:15Z thomas $
5
5
  #
6
6
  # cmdparse: an advanced command line parser using optparse which supports commands
7
7
  # Copyright (C) 2004 Thomas Leitner
@@ -27,6 +27,9 @@ require 'optparse'
27
27
  # Some extension to the standard option parser class
28
28
  class OptionParser
29
29
 
30
+ Officious.delete( 'version' )
31
+ Officious.delete( 'help' )
32
+
30
33
  # Returns the <tt>@banner</tt> value. Needed because the method <tt>OptionParser#banner</tt> does
31
34
  # not return the internal value of <tt>@banner</tt> but a modified one.
32
35
  def get_banner
@@ -99,7 +102,7 @@ end
99
102
  class CommandParser
100
103
 
101
104
  # The version of the command parser
102
- VERSION = [1, 0, 2]
105
+ VERSION = [1, 0, 3]
103
106
 
104
107
  # This error is thrown when an invalid command is encountered.
105
108
  class InvalidCommandError < OptionParser::ParseError
@@ -216,7 +219,7 @@ class CommandParser
216
219
  width = commandParser.commands.keys.max {|a,b| a.length <=> b.length }.length
217
220
  commandParser.commands.sort.each do |name, command|
218
221
  print commandParser.options.summary_indent + name.ljust( width + 4 ) + command.description
219
- print " (default)" if name == commandParser.default
222
+ print " (=default command)" if name == commandParser.default
220
223
  print "\n"
221
224
  end
222
225
  puts ""
@@ -268,15 +271,23 @@ class CommandParser
268
271
 
269
272
  end
270
273
 
271
- # Holds the registered commands
274
+ # Holds the registered commands.
272
275
  attr_reader :commands
276
+
277
+ # Returns the name of the default command.
273
278
  attr_reader :default
274
279
 
275
- def initialize
280
+ # Are Exceptions be handled gracefully? I.e. by printing error message and help screen?
281
+ attr_reader :handleExceptions
282
+
283
+ # Create a new CommandParser object. The optional argument +handleExceptions+ specifies if the
284
+ # object should handle exceptions gracefully.
285
+ def initialize( handleExceptions = false )
276
286
  @options = OptionParser.new
277
287
  @commands = {}
278
288
  @default = nil
279
289
  @parsed = {}
290
+ @handleExceptions = handleExceptions
280
291
  end
281
292
 
282
293
  # If called with a block, this method yields the global options of the +CommandParser+. If no
@@ -314,18 +325,30 @@ class CommandParser
314
325
  # is true, the command is executed immediately. If false, the +CommandParser#execute+ has to be
315
326
  # called to execute the command.
316
327
  def parse!( args, execCommand = true )
317
- @options.order!( args )
318
- @parsed[:command] = args.shift
319
- if @parsed[:command].nil?
320
- if @default.nil?
321
- raise NoCommandGivenError
328
+ # parse global options
329
+ begin
330
+ @options.order!( args )
331
+ @parsed[:command] = args.shift
332
+ if @parsed[:command].nil?
333
+ if @default.nil?
334
+ raise NoCommandGivenError
335
+ else
336
+ @parsed[:command] = @default
337
+ end
322
338
  else
323
- @parsed[:command] = @default
339
+ raise InvalidCommandError.new( @parsed[:command] ) unless commands.include?( @parsed[:command] )
324
340
  end
325
- else
326
- raise InvalidCommandError.new( @parsed[:command] ) unless commands.include?( @parsed[:command] )
341
+ rescue OptionParser::ParseError => e
342
+ handle_exception( e, :global )
327
343
  end
328
- commands[@parsed[:command]].options.permute!( args ) unless commands[@parsed[:command]].options.nil?
344
+
345
+ # parse local options
346
+ begin
347
+ commands[@parsed[:command]].options.permute!( args ) unless commands[@parsed[:command]].options.nil?
348
+ rescue OptionParser::ParseError => e
349
+ handle_exception( e, :local )
350
+ end
351
+
329
352
  @parsed[:args] = args
330
353
  execute if execCommand
331
354
  end
@@ -335,5 +358,16 @@ class CommandParser
335
358
  commands[@parsed[:command]].execute( self, @parsed[:args] ) if @parsed[:command]
336
359
  end
337
360
 
361
+ private
362
+
363
+ def handle_exception( exception, context )
364
+ raise unless @handleExceptions
365
+ s = (context == :global ? "global" : "command specific")
366
+ puts "Error parsing #{s} options:\n " + exception.message
367
+ puts
368
+ commands['help'].execute( self, (context == :global ? [] : [@parsed[:command]]) ) if commands['help']
369
+ exit
370
+ end
371
+
338
372
  end
339
373
 
data/test.rb ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # if something is changed here -> change line numbers in doc/src/documentation.page
3
+ $:.unshift "lib"
4
+ require 'cmdparse'
5
+ require 'ostruct'
6
+
7
+
8
+ class TestCommand < CommandParser::Command
9
+ def initialize
10
+ super('test')
11
+ @internal = OpenStruct.new
12
+ @internal.function = nil
13
+ @internal.audible = false
14
+ options.separator "Options:"
15
+ options.on("-t", "--test FUNCTION", "Test only FUNCTION") do |func|
16
+ @internal.function = func
17
+ end
18
+ options.on("-a", "--[no-]audible", "Run audible") { |@internal.audible| }
19
+ end
20
+ def description
21
+ "Executes various tests"
22
+ end
23
+ def execute( commandParser, args )
24
+ puts "Additional arguments: "+ args.inspect
25
+ puts "Internal values: " + @internal.inspect
26
+ end
27
+ end
28
+
29
+ cmd = CommandParser.new(true)
30
+ cmd.options do |opt|
31
+ opt.program_name = "test.rb"
32
+ opt.version = [0, 1, 0]
33
+ opt.release = "1.0"
34
+ opt.separator "Global options:"
35
+ opt.on("-r", "--require TEST", "Require the TEST") {|t| puts "required: #{t}"}
36
+ opt.on("--delay N", Integer, "Delay test for N seconds before executing") {|d| puts "delay: #{d}"}
37
+ end
38
+ cmd.add_command TestCommand.new, true
39
+ cmd.add_command CommandParser::HelpCommand.new
40
+ cmd.add_command CommandParser::VersionCommand.new
41
+ cmd.parse!( ARGV, false )
42
+ cmd.execute
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.6
3
3
  specification_version: 1
4
4
  name: cmdparse
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.2
7
- date: 2005-04-21
6
+ version: 1.0.3
7
+ date: 2005-06-09
8
8
  summary: An advanced command line parser using optparse which supports commands
9
9
  require_paths:
10
10
  - lib
@@ -35,16 +35,21 @@ files:
35
35
  - README
36
36
  - Rakefile
37
37
  - ChangeLog
38
+ - test.rb
38
39
  - VERSION
39
40
  - lib/cmdparse.rb
40
41
  - doc/src
42
+ - doc/plugin
41
43
  - doc/src/default.css
42
44
  - doc/src/features.page
43
45
  - doc/src/index.page
46
+ - doc/src/about.page
44
47
  - doc/src/download.page
45
48
  - doc/src/default.template
46
49
  - doc/src/meta.info
47
50
  - doc/src/logo.png
51
+ - doc/src/documentation.page
52
+ - doc/plugin/extract.rb
48
53
  test_files: []
49
54
  rdoc_options:
50
55
  - "--line-numbers"