command-set 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/GUIDED_TOUR ADDED
@@ -0,0 +1,24 @@
1
+ The quickest way to get a handle on what CommandSet can do for you is to
2
+ look at the various pieces and get a handle on how they work together.
3
+
4
+ The rough sketch is that you enumerate a series of commands, which you then
5
+ feed to an interpreter. The interpreter will set you up with a template for
6
+ your porgram's subject, which you fill in with some defaults. Then, give
7
+ the filled in subject back to the interpreter and let it run.
8
+
9
+ Here's the appropriate places to get started:
10
+
11
+ 0. DSL (Read thoroughly - especially the sub modules)
12
+ 0. BaseInterpreter#subject_template
13
+ 0. BaseInterpreter#subject=
14
+ 0. TextInterpreter#go
15
+
16
+ A couple of handy tricks can be found at
17
+
18
+ 0. BaseInterpreter#process_input
19
+ 0. StandardCommands
20
+ 0. QuickInterpreter
21
+
22
+ More advanced stuff that worth learning once your app is off the ground:
23
+
24
+ 0. Results
data/doc/Specifications CHANGED
@@ -214,6 +214,6 @@ Command::Results::Presenter driving a Formatter
214
214
  Command::Results::Presenter driving a strict Formatter
215
215
  - should send notifications in correct order
216
216
 
217
- Finished in 0.174402 seconds
217
+ Finished in 0.24242 seconds
218
218
 
219
219
  137 examples, 0 failures
@@ -176,12 +176,13 @@ module Command
176
176
 
177
177
  def initialize(name, options={})
178
178
  super(name)
179
+ options ||= {}
179
180
  if Hash === options
180
181
  @options = Defaults.merge(options)
181
182
  @acceptor = @options[:acceptor]
182
183
  elsif Proc === options
183
184
  @options = Defaults.dup
184
- @acceptor = options
185
+ @acceptor = proc &options
185
186
  else
186
187
  raise "File argument needs hash or proc!"
187
188
  end
@@ -323,6 +324,19 @@ module Command
323
324
  end
324
325
  end
325
326
 
327
+ class RestOfLineArgument < StringArgument
328
+ register "rest"
329
+
330
+ def consume(subject, arguments)
331
+ term = arguments.join(" ")
332
+ arguments.clear
333
+ unless validate(term, subject)
334
+ raise ArgumentInvalidException, {@name => term}
335
+ end
336
+ return {@name => parse(subject, term)}
337
+ end
338
+ end
339
+
326
340
  class ProcArgument < Argument
327
341
  register "proc", Proc
328
342
 
@@ -42,7 +42,7 @@ Command::wrap_stdout
42
42
 
43
43
  #:startdoc:
44
44
 
45
- #Command::CommandSet is a tight little library that let's you clearly and
45
+ #Command::CommandSet is a tight little library that lets you clearly and
46
46
  #easily describe a set of commands for an interactive application. The
47
47
  #command set can then be handed to one of a number of interpreters that will
48
48
  #facilitate interaction with the user.
@@ -153,6 +153,23 @@ module Command
153
153
  set.define_commands(&block)
154
154
  return set
155
155
  end
156
+
157
+ #In driver code, it's often quickest to yank in commands from a file.
158
+ #To do that, create a code file with a module in it. The module needs
159
+ #a method of the form
160
+ #
161
+ # def self.define_commands()
162
+ #
163
+ #define_commands should return a CommandSet. Then, pass the require
164
+ #path and module name to require_commands, and it'll take care of
165
+ #creating the command set. You can even call
166
+ #DSL::CommandSetDefinition#define_commands on the set that's returned
167
+ #in order to add one-off commands or fold in other command sets.
168
+ def require_commands(file, mod, cmd_path=[])
169
+ set = self.new
170
+ set.require_commands(file, mod, cmd_path)
171
+ return set
172
+ end
156
173
  end
157
174
 
158
175
  include DSL::CommandSetDefinition
@@ -37,7 +37,31 @@ Action:: utility functions within the command action block
37
37
  @command_list[name] = command.dup
38
38
  @command_list[name].parent=self
39
39
  end
40
- #paths_update(command, name)
40
+ end
41
+ end
42
+
43
+ #If you've got a file dedicated to a set of commands, (and you really
44
+ #should) you can use require_commands to require it, call
45
+ #+define_commands+ on a specific Module, pick out a specific
46
+ #subcommand (by passing a path), and then including specific commands
47
+ #from it.
48
+ def require_commands(file, module_name, path = [], *commands)
49
+ require file
50
+ module_path = module_name.to_s.split("::")
51
+ mod = Object
52
+ module_path.each do |part|
53
+ mod = mod.const_get(part)
54
+ end
55
+
56
+ set = mod.define_commands
57
+ set = set.find_command(*path)
58
+
59
+ if CommandSet === set
60
+ include_commands(set, *commands)
61
+ elsif Class === set and Command > set
62
+ command(set)
63
+ else
64
+ raise RuntimeError,"#{set.inspect} isn't a CommandSet or a Command"
41
65
  end
42
66
  end
43
67
 
@@ -353,6 +377,40 @@ Action:: utility functions within the command action block
353
377
  end
354
378
  end
355
379
 
380
+ #The DSL for formatting. A lot of code will do just fine with the
381
+ #Kernel#puts #that Results intercepts. More involved output control
382
+ #starts by including CommandSet::DSL::Formatting, and using
383
+ #Formatting#list and Formatting#item to structure output for the
384
+ #formatters.
385
+ module Formatting
386
+ #To create lists and sublist of data, you can use #list to wrap code
387
+ #in a #begin_list / #end_list pair.
388
+ def list(name, options={}) #:yield:
389
+ begin_list(name, options)
390
+ yield if block_given?
391
+ end_list
392
+ end
393
+
394
+ #Tells the main collector to begin a list. Subsequent output will be
395
+ #gathered into that list. For more, check out Results::Collector
396
+ def begin_list(name, options={})
397
+ @main_collector.begin_list(name, options)
398
+ end
399
+
400
+ #Tells the main collector to end the current list. For more, check out
401
+ #Results::Collector
402
+ def end_list
403
+ @main_collector.end_list
404
+ end
405
+
406
+ #Clean way to create an item of output. Allows for various options to
407
+ #be added. The normal output method (#puts, #p, #write...) are all
408
+ #diverted within a command, and effectively create no-option items.
409
+ def item(name, options={})
410
+ @main_collector.item(name, options)
411
+ end
412
+ end
413
+
356
414
  #The methods available within the DSL::CommandDefinition#action method
357
415
  #
358
416
  #The trickiest thing to realize about writing Commands is that a
@@ -365,6 +423,7 @@ Action:: utility functions within the command action block
365
423
  #which will be local to the invocation of the command. This is
366
424
  #especially useful for undo and redo.
367
425
  module Action
426
+ include Formatting
368
427
 
369
428
  #:section: Basics
370
429
 
@@ -383,35 +442,6 @@ Action:: utility functions within the command action block
383
442
  @subject
384
443
  end
385
444
 
386
- #:section: Formatting
387
-
388
- #To create lists and sublist of data, you can use #list to wrap code
389
- #in a #begin_list / #end_list pair.
390
- def list(name, options={}) #:yield:
391
- begin_list(name, options)
392
- yield if block_given?
393
- end_list
394
- end
395
-
396
- #Tells the main collector to begin a list. Subsequent output will be
397
- #gathered into that list. For more, check out Results::Collector
398
- def begin_list(name, options={})
399
- @main_collector.begin_list(name, options)
400
- end
401
-
402
- #Tells the main collector to end the current list. For more, check out
403
- #Results::Collector
404
- def end_list
405
- @main_collector.end_list
406
- end
407
-
408
- #Clean way to create an item of output. Allows for various options to
409
- #be added. The normal output method (#puts, #p, #write...) are all
410
- #diverted within a command, and effectively create no-option items.
411
- def item(name, options={})
412
- @main_collector.item(name, options)
413
- end
414
-
415
445
  #:section: Pause and Resume
416
446
 
417
447
  #Stop here. Return control to the user. If several commands are
@@ -8,16 +8,49 @@ require 'command-set/interpreter'
8
8
  #platforms, I'm thinking. A more flexible way of doing this would rock,
9
9
  #regardless of length.
10
10
  module Readline
11
- extend DL::Importable
12
- dlload "/lib/libreadline.so"
13
- RLLB = symbol("rl_line_buffer")
14
- def self.line_buffer
15
- p = RLLB.ptr
16
- if p.nil?
17
- return p
18
- else
19
- return p.to_s
11
+ begin
12
+ extend DL::Importable
13
+ found_libreadline = false
14
+ ls_so_dirs = [
15
+ %w{lib},
16
+ %w{usr lib},
17
+ %w{usr local lib}
18
+ ].each{|path| path.unshift("")}
19
+
20
+ begin
21
+ File::open("/etc/ld.so.conf", "r") do |ld_so_conf|
22
+ ld_so_conf.each do |line|
23
+ unless /^#/ =~ line or /^%s*$/ =~ line
24
+ ls_so_dirs << line.chomp.split(File::Separator)
25
+ end
26
+ end
27
+ end
28
+ rescue Exception
20
29
  end
30
+
31
+ ls_so_dirs.each do |libreadline_location|
32
+ begin
33
+ dlload File::join(*(libreadline_location + ["libreadline.so"]))
34
+ RLLB = symbol("rl_line_buffer")
35
+ found_libreadline = true
36
+ break
37
+ rescue RuntimeError
38
+ end
39
+ end
40
+
41
+ raise RuntimeError,"couldn't find libreadline.so" unless found_libreadline
42
+
43
+ def self.line_buffer
44
+ p = RLLB.ptr
45
+ if p.nil?
46
+ return p
47
+ else
48
+ return p.to_s
49
+ end
50
+ end
51
+ rescue RuntimeError => rte
52
+ warn "Couldn't find libreadline - tab-completion will be unpredictable at best."
53
+ warn "The problem was: " + rte.message
21
54
  end
22
55
  end
23
56
 
@@ -147,7 +180,7 @@ module Command
147
180
  end
148
181
 
149
182
  def get_formatter
150
- return Results::TextFormatter.new(::Command::raw_stdout)
183
+ return Results::StrategyFormatter.new(::Command::raw_stdout)
151
184
  end
152
185
 
153
186
  def get_prompt
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: command-set
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.8.0
7
- date: 2007-11-27 00:00:00 -08:00
6
+ version: 0.8.1
7
+ date: 2007-12-13 00:00:00 -08:00
8
8
  summary: Framework for interactive programs focused around a DSL for commands
9
9
  require_paths:
10
10
  - lib
@@ -47,6 +47,7 @@ files:
47
47
  - doc/README
48
48
  - doc/Specifications
49
49
  - doc/argumentDSL
50
+ - GUIDED_TOUR
50
51
  test_files: []
51
52
 
52
53
  rdoc_options:
@@ -55,11 +56,9 @@ rdoc_options:
55
56
  - --main
56
57
  - Command
57
58
  - --title
58
- - command-set-0.8.0 RDoc
59
+ - command-set-0.8.1 RDoc
59
60
  extra_rdoc_files:
60
- - doc/README
61
- - doc/Specifications
62
- - doc/argumentDSL
61
+ - GUIDED_TOUR
63
62
  executables: []
64
63
 
65
64
  extensions: []