rabal 0.0.1

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.
Files changed (56) hide show
  1. data/COPYING +339 -0
  2. data/LICENSE +54 -0
  3. data/README +172 -0
  4. data/README.PLUGIN +276 -0
  5. data/bin/rabal +12 -0
  6. data/lib/rabal/action_tree.rb +42 -0
  7. data/lib/rabal/application.rb +209 -0
  8. data/lib/rabal/directory_tree.rb +59 -0
  9. data/lib/rabal/error.rb +7 -0
  10. data/lib/rabal/file_tree.rb +89 -0
  11. data/lib/rabal/logger.rb +18 -0
  12. data/lib/rabal/plugin/bin.rb +8 -0
  13. data/lib/rabal/plugin/core.rb +24 -0
  14. data/lib/rabal/plugin/foundation.rb +154 -0
  15. data/lib/rabal/plugin/license.rb +36 -0
  16. data/lib/rabal/plugin/spec.rb +8 -0
  17. data/lib/rabal/plugin/test.rb +8 -0
  18. data/lib/rabal/plugin.rb +5 -0
  19. data/lib/rabal/plugin_tree.rb +61 -0
  20. data/lib/rabal/project_tree.rb +17 -0
  21. data/lib/rabal/tree.rb +231 -0
  22. data/lib/rabal/usage.rb +100 -0
  23. data/lib/rabal/util.rb +62 -0
  24. data/lib/rabal/version.rb +18 -0
  25. data/lib/rabal.rb +49 -0
  26. data/resources/trees/bin/rabal.project +10 -0
  27. data/resources/trees/core/CHANGES +4 -0
  28. data/resources/trees/core/README +15 -0
  29. data/resources/trees/core/Rakefile +0 -0
  30. data/resources/trees/core/lib/rabal.project/version.rb.erb +17 -0
  31. data/resources/trees/core/lib/rabal.project.rb.erb +27 -0
  32. data/resources/trees/license/COPYING.gpl +339 -0
  33. data/resources/trees/license/COPYING.lgpl +504 -0
  34. data/resources/trees/license/COPYING.ruby +339 -0
  35. data/resources/trees/license/LICENSE.bsd +31 -0
  36. data/resources/trees/license/LICENSE.mit +19 -0
  37. data/resources/trees/license/LICENSE.ruby +54 -0
  38. data/resources/trees/spec/rabal.project_spec.rb.erb +16 -0
  39. data/resources/trees/spec/spec_helper.rb.erb +5 -0
  40. data/resources/trees/test/rabal.project_test.rb.erb +10 -0
  41. data/resources/trees/test/test_helper.rb.erb +3 -0
  42. data/spec/action_tree_spec.rb +28 -0
  43. data/spec/bin_plugin_spec.rb +23 -0
  44. data/spec/core_plugin_spec.rb +29 -0
  45. data/spec/directory_tree_spec.rb +28 -0
  46. data/spec/file_tree_spec.rb +48 -0
  47. data/spec/license_plugin_spec.rb +39 -0
  48. data/spec/plugin_tree_spec.rb +53 -0
  49. data/spec/project_tree_spec.rb +39 -0
  50. data/spec/spec_helper.rb +59 -0
  51. data/spec/spec_plugin_spec.rb +23 -0
  52. data/spec/test_plugin_spec.rb +23 -0
  53. data/spec/tree_spec.rb +80 -0
  54. data/spec/utils_spec.rb +45 -0
  55. data/spec/version_spec.rb +26 -0
  56. metadata +134 -0
@@ -0,0 +1,18 @@
1
+ require 'logger'
2
+ module Rabal
3
+ module Log
4
+ LOGGER = Logger.new(STDOUT)
5
+ LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S"
6
+
7
+
8
+ class << self
9
+ %w(debug info warn error fatal).each do |m|
10
+ module_eval <<-code
11
+ def #{ m } *a, &b
12
+ LOGGER.#{ m } *a, &b
13
+ end
14
+ code
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Bin < Rabal::Plugin::Base "/rabal/bin"
5
+ description "Add a commandline application."
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Core < Rabal::Plugin::Base "/rabal/core"
5
+ parameter "author", "Author of the project"
6
+ parameter "email", "Email address of the author"
7
+ use_always
8
+ description <<-DESC
9
+ The core functionality and baseline information needed by every project.
10
+ DESC
11
+
12
+ # core is slightly different from the default and uses a
13
+ # ProjecTree instead of a PluginTree. It does attach a
14
+ # PluginTree below the project tree with the basic file
15
+ # structure
16
+ def initialize(options)
17
+ @parameters = OpenStruct.new(options)
18
+ validate_parameters
19
+ @tree = ProjectTree.new(options[:project] || options["project"],options)
20
+ @tree << PluginTree.new({},resource_by_name(my_main_tree_name))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,154 @@
1
+ require 'rabal'
2
+ require 'rubygems'
3
+ require 'main'
4
+
5
+ module Rabal
6
+ module Plugin
7
+ #
8
+ # Base plugin that all other plugins will inherit from, but not
9
+ # directly. New plugins are declared with:
10
+ #
11
+ # class NewPlugin < Rabal::Plugin::Base "/foo/bar"
12
+ # ...
13
+ # end
14
+ #
15
+ # This process uses GemPlugin under the covers, it has just been
16
+ # wrapped to provide a different +Base+ class for everything to
17
+ # inherit from.
18
+ #
19
+ class Foundation
20
+
21
+ # the PluginTree that the plugin creates.
22
+ attr_reader :tree
23
+
24
+ class << self
25
+
26
+ # Called when another class inherits from Foundation.
27
+ # when that happens that class is registered in the
28
+ # GemPlugin::Manager
29
+ def inherited(by_class)
30
+ register_key = "/" + by_class.to_s.downcase
31
+ by_class.register_path register_as
32
+ GemPlugin::Manager.instance.register(register_as,register_key,by_class)
33
+ register_as = nil
34
+ end
35
+
36
+ # allows Plugin::Base to store the registration
37
+ # information in the class variable.
38
+ attribute :register_as => nil
39
+
40
+ # part of the mini DSL for describing a Plugin
41
+ def parameter(pname,description)
42
+ @parameters ||= {}
43
+ @parameters[pname] = [pname, description]
44
+ end
45
+
46
+ # get the parameters bac
47
+ def parameters
48
+ @parameters ||= {}
49
+ end
50
+
51
+ def use_always?
52
+ @use_always
53
+ end
54
+
55
+ def use_always(d = true)
56
+ @use_always = d
57
+ end
58
+
59
+ attribute :description => "I Need a Description"
60
+ attribute :register_path
61
+
62
+ def use_name
63
+ name.split("::").last.dashify
64
+ end
65
+ end
66
+
67
+ # A Plugin is instantiated and the options passed to it are
68
+ # the results of the command line options for this plugin.
69
+ #
70
+ # The default action for any Plugin is to create a
71
+ # PluginTree from its options utilizing the +register_path+
72
+ # to determine a location within the gem's resources. The
73
+ # resources is used to instantiate a PluginTree and that is
74
+ # set to +tree+ and by default, this tree will be 'mounted'
75
+ # at the root of some other tree.
76
+ def initialize(options = {})
77
+ @parameters = OpenStruct.new(options)
78
+ validate_parameters
79
+ main_tree_name = my_main_tree_name
80
+ @tree = PluginTree.new(options,resource_by_name(main_tree_name),
81
+ File.basename(main_tree_name))
82
+ end
83
+
84
+ ############################################################
85
+ # regular instance methods, provide for convenience to the
86
+ # child plugins
87
+ ############################################################
88
+
89
+ #
90
+ # validate the parameters of the plugin in the simplest way
91
+ # possible. Make sure that each listend parameters is not
92
+ # null. This assumes that @parameters has a method for each
93
+ # parameter naem
94
+ #
95
+ def validate_parameters
96
+ self.class.parameters.each do |param,desc|
97
+ if not @parameters.respond_to?(param) or @parameters.send(param).nil? then
98
+ raise PluginParameterMissingError, "Missing parameter '#{param}' from #{self.class.use_name} plugin. See --use-#{self.class.use_name} --help"
99
+ end
100
+ end
101
+ end
102
+ # What gem a plugin belongs to. This is necessary to access
103
+ # the resources of the gem the plugin may use. Overload
104
+ # this in a child plugin to return what you want. By
105
+ # default it uses the first part of the path the gem is
106
+ # registered under.
107
+ #
108
+ # That is when the plugin is defined
109
+ #
110
+ # class MyPlugin < Rabal::Plugin::Base "/my-plugin/something"
111
+ # ...
112
+ # end
113
+ #
114
+ # 'my-plugin' is defined as being the default gem name.
115
+ def my_gem_name
116
+ self.class.register_path.split("/").find{|p| p.length > 0}
117
+ end
118
+
119
+ # The main resource for this Plugin. This is generally a
120
+ # file or a directory that the plugin will use as a template
121
+ # and create a PluginTree from.
122
+ def my_main_tree_name
123
+ tree_name = self.class.register_path.split("/").find_all {|p| p.length > 0}
124
+ tree_name.shift
125
+ tree_name.unshift "trees"
126
+ tree_name.join("/")
127
+ end
128
+
129
+ # Access a resource utilized by the gem. The name is the
130
+ # path to a file or directory under the 'resources'
131
+ # directory in the gem this plugin is a part of.
132
+ def resource_by_name(resource_name)
133
+ Rabal.application.plugin_resource(my_gem_name,resource_name)
134
+ end
135
+ end
136
+ end
137
+
138
+ #
139
+ # This is the happen'n way to do things. Camping does it,
140
+ # GemPlugin does it. Come on You can do it too.
141
+ #
142
+ # Put +register_path+ into the class variable @@path of
143
+ # Plugin::Foundation and then return the Plugin::Foundation class
144
+ # which will be used as the parent class for the new class.
145
+ #
146
+ # Upon declaration of the new class, Foundation.inherited will be
147
+ # invoked which will register the new class with GemPlugin::Manager
148
+ # an clear out @@path
149
+ #
150
+ def Plugin::Base(register_path)
151
+ Plugin::Foundation.register_as = register_path
152
+ Plugin::Foundation
153
+ end
154
+ end
@@ -0,0 +1,36 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ #
5
+ # The license plugin helps the user pick a license for their
6
+ # project. The current available license to choose from are
7
+ # BSD, GPL, LGPG, MIT and Ruby
8
+ #
9
+ class License < Rabal::Plugin::Base "/rabal/license"
10
+ TYPES = %w[BSD GPL LGPL MIT Ruby]
11
+ parameter "flavor", "Flavor of License for your project: #{TYPES.join(', ')}"
12
+ description "Indicate under what license your project is released."
13
+ use_always
14
+
15
+ def initialize(options)
16
+ @parameters = OpenStruct.new(options)
17
+ if not @parameters.respond_to?(:flavor) then
18
+ raise PluginParameterMissingError, "Missing parameter 'flavor' from license plugin. See --use-license --help"
19
+ end
20
+ suffix = @parameters.flavor
21
+ # look at all files in our resource directory and any
22
+ # that have the same suffix as the 'flavor' load it into
23
+ # the tree.
24
+ if TYPES.include?(suffix) then
25
+ resource_dir = resource_by_name(my_main_tree_name)
26
+ @tree = DirectoryTree.new(".")
27
+ Dir.glob(File.join(resource_dir,"*.#{suffix.downcase}")).each do |file|
28
+ @tree << FileTree.from_file(file)
29
+ end
30
+ else
31
+ raise PluginParameterMissingError, "Invalid value '#{suffix}' for 'flavor' parameter from license plugin. Only #{TYPES.join(",")} are currently supported."
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Spec < Rabal::Plugin::Base "/rabal/spec"
5
+ description "Add an RSpec framework."
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'rabal/plugin/foundation'
2
+ module Rabal
3
+ module Plugin
4
+ class Test < Rabal::Plugin::Base "/rabal/test"
5
+ description "Add a Test::Unit framework."
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'gem_plugin'
3
+
4
+ # load up all the builtin plugins
5
+ Rabal.require_all_libs_relative_to(__FILE__)
@@ -0,0 +1,61 @@
1
+ require 'rabal'
2
+ require 'find'
3
+ require 'rabal/util'
4
+
5
+ module Rabal
6
+ #
7
+ # Represents the root of a plugin directory structure. This plugin
8
+ # could also only represent a single FileTree by having the
9
+ # 'directory' it represents being '.'
10
+ #
11
+ class PluginTree < DirectoryTree
12
+
13
+ include Util
14
+
15
+ # the source directory from which the project is generated
16
+ attr_accessor :src_directory
17
+
18
+ # create a new Plugin Tree based upon a source directory. This
19
+ # 'mounts' the src_directory into the dest_directory in the
20
+ # project. The dest_directory defaults to "." . The +options+
21
+ # are a hash that are propogated to the +parameters+ member
22
+ # variable.
23
+ def initialize(options,src_directory,dest_directory= ".")
24
+ super(dest_directory)
25
+ @src_directory = src_directory
26
+ @parameters = OpenStruct.new(options)
27
+ end
28
+
29
+ #
30
+ # populating the tree needs to take place after the PluginTree
31
+ # has been added to the Tree, but before the processing of the
32
+ # tree takes place
33
+ #
34
+ def post_add
35
+ populate_tree(src_directory)
36
+ end
37
+
38
+ private
39
+
40
+ #
41
+ # Given a source directory populate a PluginTree based upon the
42
+ # contents of the directory. All files will be mapped to
43
+ # FileTree and directories will be mapped to DirectoryTree.
44
+ #
45
+ def populate_tree(src_directory,tree=self)
46
+ Dir.chdir(src_directory) do |pwd|
47
+ Dir.entries(".").each do |entry|
48
+ next if entry[0] == ?.
49
+ next if pwd == entry
50
+
51
+ if File.file?(entry) then
52
+ tree << FileTree.from_file(entry,true,replace_known_words(entry))
53
+ elsif File.directory?(entry) then
54
+ tree << dir = DirectoryTree.new(replace_known_words(entry))
55
+ populate_tree(entry,dir)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,17 @@
1
+ require 'rabal/directory_tree'
2
+ module Rabal
3
+ #
4
+ # The ProjectTree represents the master configuration/specification
5
+ # of a project.
6
+ #
7
+ class ProjectTree < DirectoryTree
8
+
9
+ # FIXME: this should derive a whole bunch of instance variables
10
+ # and delegate items to a Gem specification.
11
+ def initialize(project_name,options)
12
+ super(project_name)
13
+ @parameters = OpenStruct.new(options)
14
+ @parameters.project_name = project_name
15
+ end
16
+ end
17
+ end
data/lib/rabal/tree.rb ADDED
@@ -0,0 +1,231 @@
1
+ require 'rabal'
2
+
3
+ module Rabal
4
+ #
5
+ # A basic Tree structure
6
+ #
7
+ class Tree
8
+
9
+ include Enumerable
10
+
11
+ # The name of this Tree
12
+ attr_accessor :name
13
+
14
+ # The parent of this node. If this is nil then this Tree is a
15
+ # root.
16
+ attr_accessor :parent
17
+
18
+ # The children of this node. If this Array is empty, then this
19
+ # Tree is a leaf.
20
+ attr_accessor :children
21
+
22
+ # An abstract data point that can be utilized by child classes
23
+ # for whatever they like. If this is non-nil and responds to
24
+ # method calls it will be searched as part of the
25
+ # 'method_missing' protocol.
26
+ attr_accessor :parameters
27
+
28
+ #
29
+ # Create a new Tree with the given object.to_s as its +name+.
30
+ #
31
+ def initialize(name)
32
+ @name = name.to_s
33
+ @parent = nil
34
+ @children = {}
35
+ @parameters = nil
36
+ end
37
+
38
+ #
39
+ # Return true if this Tree has no children.
40
+ #
41
+ def is_leaf?
42
+ @children.empty?
43
+ end
44
+
45
+ #
46
+ # Return true if this Tree has no parent.
47
+ #
48
+ def is_root?
49
+ @parent.nil?
50
+ end
51
+
52
+ #
53
+ # Return the root node of the tree
54
+ #
55
+ def root
56
+ return self if is_root?
57
+ return @parent.root
58
+ end
59
+
60
+ #
61
+ # Return the distance from the root
62
+ #
63
+ def depth
64
+ return 0 if is_root?
65
+ return (1 + @parent.depth)
66
+ end
67
+
68
+ #
69
+ # Attach the given tree at the indicated path. The path given
70
+ # is always assumed to be from the root of the Tree being
71
+ # attached to.
72
+ #
73
+ # The path is given as a string separated by '/'. Each portion
74
+ # of the string is matched against the name of the particular
75
+ # tree.
76
+ #
77
+ # Given :
78
+ #
79
+ # a --- b --- c
80
+ # \
81
+ # d - e --- f
82
+ # \
83
+ # g - h
84
+ #
85
+ # * the path +a/b/c+ will match the path to Tree +c+
86
+ # * the path +d/e/g+ will _not_ match anything as the path must start at +a+ here
87
+ # * the path +a/d/e+ will _not_ match anytthin as +e+ is not a child of +d+
88
+ # * the path +a/d/e/g+ will match node +g+
89
+ #
90
+ # Leading and trailing '/' on the path are not necessary and removed.
91
+ #
92
+ def add_at_path(path,subtree)
93
+ parent_tree = tree_at_path(path)
94
+ parent_tree << subtree
95
+ return self
96
+ end
97
+
98
+
99
+ #
100
+ # Return the Tree that resides at the given path
101
+ #
102
+ def tree_at_path(path_str)
103
+ path_str = path_str.chomp("/").reverse.chomp("/").reverse
104
+ path = path_str.split("/")
105
+
106
+ # strip of the redundant first match if it is the same as
107
+ # the current node
108
+ find_subtree(path)
109
+ end
110
+
111
+ #
112
+ # Add the given object to the Tree as a child of this node. If
113
+ # the given object is not a Tree then wrap it with a Tree.
114
+ #
115
+ def <<(subtree)
116
+ # this should not generally be the case, but wrap things
117
+ # up to be nice.
118
+ if not subtree.kind_of?(Tree) then
119
+ subtree = Tree.new(subtree)
120
+ end
121
+
122
+ subtree.parent = self
123
+
124
+ # Don't overwrite any existing children with the same name,
125
+ # just put this one's children in that one, I think this
126
+ # works recursively now.
127
+ if children.has_key?(subtree.name) then
128
+ subtree.children.each do |n,tree|
129
+ children[n] = tree
130
+ end
131
+ else
132
+ children[subtree.name] = subtree
133
+ end
134
+
135
+ subtree.post_add
136
+
137
+ return self
138
+ end
139
+
140
+ alias :add :<<
141
+
142
+ #
143
+ # Allow for Enumerable to be included. This just wraps walk.
144
+ #
145
+ def each
146
+ self.walk(self,lambda { |tree| yield tree })
147
+ end
148
+
149
+ #
150
+ # Count how many items are in the tree
151
+ #
152
+ def size
153
+ inject(0) { |count,n| count + 1 }
154
+ end
155
+
156
+ #
157
+ # Walk the tree in a depth first manner, visiting the Tree
158
+ # first, then its children
159
+ #
160
+ def walk(tree,method)
161
+ method.call(tree)
162
+ tree.children.each_pair do |name,child|
163
+ walk(child,method)
164
+ end
165
+ end
166
+
167
+ #
168
+ # Allow for a method call to cascade up the tree looking for a
169
+ # Tree that responds to the call.
170
+ #
171
+ def method_missing(method_id,*params,&block)
172
+ if not parameters.nil? and parameters.respond_to?(method_id) then
173
+ return parameters.send(method_id, *params, &block)
174
+ elsif not is_root? then
175
+ @parent.send method_id, *params, &block
176
+ else
177
+ raise NoMethodError, "undefined method `#{method_id}' for #{name}:Tree"
178
+ end
179
+ end
180
+
181
+
182
+ #
183
+ # allow for a hook so newly added Tree objects may do custom
184
+ # processing after being added to the tree, but before the tree
185
+ # is walked or processed
186
+ #
187
+ def post_add
188
+ end
189
+ #
190
+ # find the current path of the tree from root to here, return it
191
+ # as a '/' separates string.
192
+ #
193
+ def current_path
194
+ return "*#{name}*" if is_root?
195
+ return ([name,parent.current_path]).flatten.reverse.join("/")
196
+ end
197
+
198
+ #
199
+ # Given the initial path to match as an Array find the Tree that
200
+ # matches that path.
201
+ #
202
+ def find_subtree(path)
203
+
204
+ if path.empty? then
205
+ return self
206
+ else
207
+ possible_child = path.shift
208
+ if children.has_key?(possible_child) then
209
+ children[possible_child].find_subtree(path)
210
+ else
211
+ raise PathNotFoundError, "`#{possible_child}' does not match anything at the current path in the Tree (#{current_path})"
212
+ end
213
+ end
214
+ end
215
+
216
+ private
217
+
218
+ #
219
+ # Log to the Rabal::Log padding the message with 2 spaces *
220
+ # depth.
221
+ #
222
+ %w(debug info warn error fatal).each do |m|
223
+ class_eval <<-code
224
+ def #{ m }(msg)
225
+ msg = (" " * depth) + msg
226
+ Rabal::Log.#{ m }(msg)
227
+ end
228
+ code
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,100 @@
1
+ require 'main'
2
+ module Rabal
3
+
4
+ # Rabal has unique Usage output requirements and as such the default
5
+ # usage provided by the Main gem although nice are not sufficient.
6
+ #
7
+ # Rabal requires the Usage to be generated after the parameters have
8
+ # been parsed as the parameters that are on the commandline
9
+ # determine how the help is printed.
10
+ class Usage
11
+
12
+ attr_reader :app
13
+ attr_reader :old_usage
14
+
15
+ def initialize(app)
16
+ @app = app
17
+ @old_usage = {}
18
+ app.main.usage.each_pair do |key,value|
19
+ @old_usage[key] = value
20
+ end
21
+ end
22
+
23
+ # some of the generated usage is quite useful, others we want
24
+ # to dump, or rename
25
+ def to_s
26
+ u = ::Main::Usage.new
27
+ # just transfer directly over these
28
+ %w[name synopsis description].each do |chunk|
29
+ u[chunk.dup] = old_usage[chunk].to_s
30
+ end
31
+
32
+ arguments = app.main.parameters.select{|p| p.type == :argument}
33
+ global_options = app.main.parameters.select{|p| p.type == :option and app.global_option_names.include?(p.name) }
34
+ load_options = app.main.parameters.select{|p| p.type == :option and app.plugin_load_option_names.include?(p.name) }
35
+ plugin_options = app.main.parameters.select{|p| p.type == :option and app.plugin_option_names.include?(p.name) }
36
+
37
+ # rework the formatting of the parameters limiting them to
38
+ # the globals, force
39
+ u['global options'] = section_options(" ",global_options)
40
+
41
+ # format the available modules
42
+ s = ""
43
+ s << ::Main::Util.columnize("Force any module to be used by giving the --use-[modulename] option. Modules with a '*' next to them are always used.",:indent => 0, :width => 72)
44
+ s << "\n\n"
45
+ s << ""
46
+ module_options = []
47
+ app.plugin_manager.plugins.sort_by{|c,p| c}.each do |cat,plugins|
48
+ plugins.each do |key,plugin|
49
+ pre = " " + (plugin.use_always? ? "*" : " ")
50
+ s << option_format(pre,"#{plugin.use_name} (#{plugin.register_path})",plugin.description,30,32,78)
51
+ s << "\n"
52
+
53
+ # create the module options for this one, if the
54
+ # plugin is use_always.
55
+ if app.main.parameters['use-all'].given? or plugin.use_always? or
56
+ app.main.parameters["use-#{plugin.use_name}"].given? then
57
+ plugin_options = app.main.parameters.select{|p| p.type == :option and p.name =~ %r{^#{plugin.use_name}}}
58
+ module_options << ["Module options - #{plugin.use_name.camelize}", section_options(" ",plugin_options)]
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+ u['Available Modules'] = s
65
+
66
+ module_options.each { |k,v| u[k] = v }
67
+
68
+ u['author'] = old_usage['author']
69
+ u.to_s
70
+ end
71
+
72
+ # take in an option and a description and some formatting
73
+ # criteria and format a single option
74
+ def option_format(pre,option,description,col1,col2,width)
75
+ s = ""
76
+ s << "#{pre}#{option}".ljust(col1)
77
+ if description then
78
+ lines = ::Main::Util.columnize(description,:indent => col2, :width => width).split("\n")
79
+ inter_first = ' ' * (col2 - col1 - 2)
80
+ s << lines.shift.sub(/^\s*/,"#{inter_first}- ")
81
+ if lines.size > 0 then
82
+ s << "\n"
83
+ s << lines.join("\n")
84
+ end
85
+ end
86
+ s
87
+ end
88
+
89
+ def section_options(pre,list)
90
+ if list.size == 0 then
91
+ return "No options available\n"
92
+ end
93
+ list.sort_by{|p| p.name}.collect do |p|
94
+ ps = ""
95
+ ps << option_format(pre,p.short_synopsis,p.description,35,39,78)
96
+ ps
97
+ end.join("\n")
98
+ end
99
+ end
100
+ end