tap 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/History +35 -1
  2. data/MIT-LICENSE +1 -1
  3. data/README +16 -15
  4. data/bin/tap +1 -1
  5. data/cmd/console.rb +4 -3
  6. data/cmd/manifest.rb +2 -2
  7. data/cmd/run.rb +12 -15
  8. data/doc/Class Reference +120 -117
  9. data/doc/Command Reference +27 -27
  10. data/doc/Syntax Reference +55 -111
  11. data/doc/Tutorial +69 -26
  12. data/lib/tap.rb +3 -8
  13. data/lib/tap/app.rb +122 -146
  14. data/lib/tap/constants.rb +2 -2
  15. data/lib/tap/env.rb +178 -252
  16. data/lib/tap/exe.rb +67 -30
  17. data/lib/tap/file_task.rb +224 -411
  18. data/lib/tap/generator/arguments.rb +13 -0
  19. data/lib/tap/generator/base.rb +112 -30
  20. data/lib/tap/generator/destroy.rb +36 -13
  21. data/lib/tap/generator/generate.rb +69 -48
  22. data/lib/tap/generator/generators/command/templates/command.erb +3 -3
  23. data/lib/tap/generator/generators/config/config_generator.rb +82 -10
  24. data/lib/tap/generator/generators/generator/generator_generator.rb +16 -6
  25. data/lib/tap/generator/generators/generator/templates/task.erb +2 -2
  26. data/lib/tap/generator/generators/generator/templates/test.erb +26 -0
  27. data/lib/tap/generator/generators/root/root_generator.rb +24 -13
  28. data/lib/tap/generator/generators/root/templates/Rakefile +4 -4
  29. data/lib/tap/generator/generators/root/templates/{tapfile → Rapfile} +6 -6
  30. data/lib/tap/generator/generators/root/templates/gemspec +0 -1
  31. data/lib/tap/generator/generators/task/task_generator.rb +3 -3
  32. data/lib/tap/generator/generators/task/templates/test.erb +1 -1
  33. data/lib/tap/generator/manifest.rb +7 -1
  34. data/lib/tap/generator/preview.rb +76 -0
  35. data/lib/tap/root.rb +222 -156
  36. data/lib/tap/spec.rb +41 -0
  37. data/lib/tap/support/aggregator.rb +25 -28
  38. data/lib/tap/support/audit.rb +278 -357
  39. data/lib/tap/support/constant.rb +2 -1
  40. data/lib/tap/support/constant_manifest.rb +28 -25
  41. data/lib/tap/support/dependency.rb +1 -1
  42. data/lib/tap/support/executable.rb +52 -183
  43. data/lib/tap/support/executable_queue.rb +50 -20
  44. data/lib/tap/support/gems.rb +1 -1
  45. data/lib/tap/support/intern.rb +0 -6
  46. data/lib/tap/support/join.rb +49 -83
  47. data/lib/tap/support/joins.rb +0 -3
  48. data/lib/tap/support/joins/switch.rb +13 -11
  49. data/lib/tap/support/joins/sync_merge.rb +25 -50
  50. data/lib/tap/support/manifest.rb +1 -0
  51. data/lib/tap/support/node.rb +140 -20
  52. data/lib/tap/support/parser.rb +56 -42
  53. data/lib/tap/support/schema.rb +183 -157
  54. data/lib/tap/support/templater.rb +9 -1
  55. data/lib/tap/support/versions.rb +39 -0
  56. data/lib/tap/task.rb +150 -177
  57. data/lib/tap/tasks/dump.rb +4 -4
  58. data/lib/tap/tasks/load.rb +29 -29
  59. data/lib/tap/test.rb +66 -53
  60. data/lib/tap/test/env_vars.rb +3 -3
  61. data/lib/tap/test/extensions.rb +11 -17
  62. data/lib/tap/test/file_test.rb +74 -132
  63. data/lib/tap/test/file_test_class.rb +4 -1
  64. data/lib/tap/test/regexp_escape.rb +2 -2
  65. data/lib/tap/test/script_test.rb +2 -2
  66. data/lib/tap/test/subset_test.rb +6 -6
  67. data/lib/tap/test/tap_test.rb +28 -154
  68. metadata +30 -51
  69. data/bin/rap +0 -118
  70. data/cgi/run.rb +0 -97
  71. data/lib/tap/declarations.rb +0 -229
  72. data/lib/tap/generator/generators/config/templates/doc.erb +0 -12
  73. data/lib/tap/generator/generators/config/templates/nodoc.erb +0 -8
  74. data/lib/tap/generator/generators/file_task/file_task_generator.rb +0 -27
  75. data/lib/tap/generator/generators/file_task/templates/file.txt +0 -11
  76. data/lib/tap/generator/generators/file_task/templates/result.yml +0 -6
  77. data/lib/tap/generator/generators/file_task/templates/task.erb +0 -33
  78. data/lib/tap/generator/generators/file_task/templates/test.erb +0 -29
  79. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +0 -5
  80. data/lib/tap/patches/optparse/summarize.rb +0 -62
  81. data/lib/tap/support/assignments.rb +0 -173
  82. data/lib/tap/support/class_configuration.rb +0 -182
  83. data/lib/tap/support/combinator.rb +0 -125
  84. data/lib/tap/support/configurable.rb +0 -113
  85. data/lib/tap/support/configurable_class.rb +0 -271
  86. data/lib/tap/support/configuration.rb +0 -170
  87. data/lib/tap/support/gems/rake.rb +0 -111
  88. data/lib/tap/support/instance_configuration.rb +0 -173
  89. data/lib/tap/support/joins/fork.rb +0 -19
  90. data/lib/tap/support/joins/merge.rb +0 -22
  91. data/lib/tap/support/joins/sequence.rb +0 -21
  92. data/lib/tap/support/lazy_attributes.rb +0 -45
  93. data/lib/tap/support/lazydoc.rb +0 -386
  94. data/lib/tap/support/lazydoc/comment.rb +0 -503
  95. data/lib/tap/support/lazydoc/config.rb +0 -17
  96. data/lib/tap/support/lazydoc/definition.rb +0 -36
  97. data/lib/tap/support/lazydoc/document.rb +0 -152
  98. data/lib/tap/support/lazydoc/method.rb +0 -24
  99. data/lib/tap/support/tdoc.rb +0 -409
  100. data/lib/tap/support/tdoc/tdoc_html_generator.rb +0 -38
  101. data/lib/tap/support/tdoc/tdoc_html_template.rb +0 -42
  102. data/lib/tap/support/validation.rb +0 -479
  103. data/lib/tap/tasks/rake.rb +0 -57
@@ -0,0 +1,13 @@
1
+ module Tap
2
+ module Generator
3
+
4
+ # A special type of Lazydoc::Arguments that shifts off the standard 'm'
5
+ # argument on generator manifest methods, to properly reflect how may
6
+ # arguments the generator should receive.
7
+ class Arguments < Lazydoc::Arguments
8
+ def arguments(shift_manifest_arg=true)
9
+ shift_manifest_arg ? @arguments[1..-1] : @arguments
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,33 +1,98 @@
1
+ require 'tap'
1
2
  require 'tap/generator/manifest'
3
+ require 'tap/generator/arguments'
2
4
 
3
5
  module Tap
4
- module Generator
6
+ module Generator
7
+
8
+ # :startdoc:::-
9
+ # Base provides the basic structure of a generator and custom generators
10
+ # inherit from it. Base is patterned after the {Ruby on Rails}[http://rubyonrails.org/]
11
+ # generators, but obviously takes on all the advantages of Tasks.
12
+ #
13
+ # === Usage
14
+ #
15
+ # Tap generators define a manifest method that defines what files and
16
+ # directories are created by the generator. Then, at execution time,
17
+ # a mixin with the appropriate funtion (ie Generate or Destory) is
18
+ # overlaid to figure out how to roll those actions forward or backwards.
19
+ #
20
+ # Unlike typical tasks, generators must be named like '<Name>Generator' and
21
+ # are identified using the ::generator flag rather than ::manifest. These
22
+ # requirements make generators available to the generate/destroy commands
23
+ # and not run.
24
+ #
25
+ # Typically, generators live in a directory structure like this:
26
+ #
27
+ # sample
28
+ # |- sample_generator.rb
29
+ # `- templates
30
+ # `- template_file.erb
31
+ #
32
+ # And take the form:
33
+ #
34
+ # [sample/sample_generator.rb]
35
+ # require 'tap/generator/base'
36
+ #
37
+ # # SampleGenerator::generator generates a directory, and two files
38
+ # #
39
+ # # An extended description of the
40
+ # # generator goes here...
41
+ # #
42
+ # class SampleGenerator < Tap::Generator::Base
43
+ #
44
+ # config :key, 'value' # a sample config
45
+ #
46
+ # def manifest(m, *args)
47
+ # # make a directory
48
+ # m.directory('path/to/dir')
49
+ #
50
+ # # make a file
51
+ # m.file('path/to/file.txt') do |file|
52
+ # file << "some content"
53
+ # end
54
+ #
55
+ # # template a file using config
56
+ # m.template('path/to/result.txt', 'template_file.erb', config.to_hash)
57
+ # end
58
+ # end
59
+ #
60
+ # As with any task, generators can have configurations and take arguments
61
+ # specified by manifest (minus the 'm' argument which is standard).
62
+ # Creating directories and files is straightforward, as above. Template
63
+ # generates a target file using the source file in the templates' directory;
64
+ # any attributes specified by the last argument will be available in the erb
65
+ # template.
66
+ # :startdoc:::+
5
67
  class Base < Tap::Task
6
- class << self
7
- def lazydoc(resolve=true)
8
- lazydoc = super(false)
9
- lazydoc[self.to_s]['args'] ||= lazydoc.register_method(:manifest, Task::Args)
10
- super
11
- end
12
- end
13
-
14
- Constant = Tap::Support::Constant
15
-
16
- lazy_attr :manifest, :generator
68
+ lazy_attr :manifest, 'generator'
69
+ lazy_attr :args, :manifest
70
+ lazy_register :manifest, Arguments
17
71
 
18
72
  config :pretend, false, &c.flag # Run but rollback any changes.
19
73
  config :force, false, &c.flag # Overwrite files that already exist.
20
74
  config :skip, false, &c.flag # Skip files that already exist.
21
75
 
22
- attr_accessor :file_task, :template_dir, :target_dir
76
+ # The generator-specific templates directory. By default:
77
+ # 'path/to/name/templates' for 'path/to/name/name_generator.rb'
78
+ attr_accessor :template_dir
23
79
 
24
- def initialize(config={}, name=nil, app=App.instance)
25
- super(config, name, app)
26
-
27
- @file_task = Tap::FileTask.new
80
+ # The IO used to pull prompt inputs (default: $stdin)
81
+ attr_accessor :prompt_in
82
+
83
+ # The IO used to prompt users for input (default: $stdout)
84
+ attr_accessor :prompt_out
85
+
86
+ def initialize(*args)
87
+ super
88
+ @prompt_in = $stdin
89
+ @prompt_out = $stdout
28
90
  @template_dir = File.dirname(self.class.source_file) + '/templates'
29
91
  end
30
92
 
93
+ # Builds the manifest, then executes the actions of the manifest.
94
+ # Process returns the results of iterate, which normally will be
95
+ # an array of files and directories created (or destroyed) by self.
31
96
  def process(*argv)
32
97
  actions = []
33
98
  manifest(Manifest.new(actions), *argv)
@@ -35,38 +100,47 @@ module Tap
35
100
  iterate(actions) do |action, args, block|
36
101
  send(action, *args, &block)
37
102
  end
38
-
39
- @target_dir = nil
40
- file_task.added_files
41
- end
42
-
43
- def log_relative(action, path)
44
- log(action, app.relative_filepath(Dir.pwd, path))
45
103
  end
46
104
 
105
+ # Overridden in subclasses to add actions to the input Manifest.
106
+ # Any arguments passed to process will be passed to manifest
107
+ # unchanged.
47
108
  def manifest(m, *argv)
48
109
  raise NotImplementedError
49
110
  end
50
111
 
51
- def iterate(action)
52
- raise NotImplementedError
112
+ # Peforms each of the input actions in order, and collects the
113
+ # results. The process method returns these results.
114
+ def iterate(actions)
115
+ actions.collect {|action| yield(action) }
53
116
  end
54
-
117
+
118
+ # Peforms a directory action (ex generate or destroy). Must be
119
+ # overridden by one of the action mixins (ex Generate or Destroy).
55
120
  def directory(target, options={})
56
121
  raise NotImplementedError
57
122
  end
58
123
 
59
- def file(target, options={})
124
+ # Peforms a file action (ex generate or destroy). Calls to file specify
125
+ # input for a target by providing a block; the block recieves an IO and
126
+ # pushes content to it. Must be overridden by one of the action mixins
127
+ # (ex Generate or Destroy).
128
+ def file(target, options={}) # :yields: io
60
129
  raise NotImplementedError
61
130
  end
62
131
 
132
+ # Makes (or destroys) the root and each of the targets, relative
133
+ # to root. Options are passed onto directory.
63
134
  def directories(root, targets, options={})
64
- directory(root)
135
+ directory(root, options)
65
136
  targets.each do |target|
66
137
  directory(File.join(root, target), options)
67
138
  end
68
139
  end
69
140
 
141
+ # Makes (or destroys) the target by templating the source using
142
+ # the specified attributes. Source is expanded relative to
143
+ # template_dir. Options are passed onto file.
70
144
  def template(target, source, attributes={}, options={})
71
145
  template_path = File.expand_path(source, template_dir)
72
146
  templater = Support::Templater.new(File.read(template_path), attributes)
@@ -76,13 +150,21 @@ module Tap
76
150
  end
77
151
  end
78
152
 
153
+ # Yields each source file under template_dir to the block, with
154
+ # a target path of the source relative to template_dir.
79
155
  def template_files
80
156
  Dir.glob(template_dir + "/**/*").sort.each do |source|
157
+ next unless File.file?(source)
158
+
81
159
  target = Tap::Root.relative_filepath(template_dir, source)
82
160
  yield(source, target)
83
161
  end
84
162
  end
85
-
163
+
164
+ # Logs the action with the relative filepath from Dir.pwd to path.
165
+ def log_relative(action, path)
166
+ log(action, Root.relative_filepath(Dir.pwd, path))
167
+ end
86
168
  end
87
169
  end
88
170
  end
@@ -1,35 +1,58 @@
1
1
  module Tap
2
2
  module Generator
3
+
4
+ # A mixin defining how to run manifest actions in reverse.
3
5
  module Destroy
6
+
7
+ # Iterates over the actions in reverse, and collects the results.
4
8
  def iterate(actions)
5
- actions.reverse_each {|action| yield(action) }
9
+ results = []
10
+ actions.reverse_each {|action| results << yield(action) }
11
+ results
6
12
  end
7
13
 
14
+ # Removes the target directory if it exists. Missing, non-directory and
15
+ # non-empty targets are simply logged and not removed. When pretend is
16
+ # true, removal is logged but does not actually happen.
17
+ #
18
+ # No options currently affect the behavior of this method.
8
19
  def directory(target, options={})
9
- target = File.expand_path(target, target_dir)
20
+ target = File.expand_path(target)
10
21
 
11
22
  case
12
23
  when !File.exists?(target)
13
24
  log_relative :missing, target
14
- when !file_task.dir_empty?(target)
25
+ when !File.directory?(target)
26
+ log_relative 'not a directory', target
27
+ when !Root.empty?(target)
15
28
  log_relative 'not empty', target
16
29
  else
17
30
  log_relative :rm, target
18
- file_task.added_files << File.expand_path(target)
19
- file_task.rmdir(target) unless pretend
31
+ FileUtils.rmdir(target) unless pretend
20
32
  end
33
+
34
+ target
21
35
  end
22
36
 
37
+ # Removes the target file if it exists. Missing and non-file and targets
38
+ # are simply logged and not removed. When pretend is true, removal is
39
+ # logged but does not actually happen.
40
+ #
41
+ # No options currently affect the behavior of this method.
23
42
  def file(target, options={})
24
- target = File.expand_path(target, target_dir)
25
-
26
- if File.exists?(target)
27
- log_relative :rm, target
28
- file_task.added_files << File.expand_path(target)
29
- file_task.rm(target) unless pretend
30
- else
31
- log_relative :missing, target
43
+ target = File.expand_path(target)
44
+
45
+ case
46
+ when File.file?(target)
47
+ log_relative :rm, target
48
+ FileUtils.rm(target) unless pretend
49
+ when File.directory?(target)
50
+ log_relative 'not a file', target
51
+ else
52
+ log_relative :missing, target
32
53
  end
54
+
55
+ target
33
56
  end
34
57
 
35
58
  end
@@ -1,70 +1,91 @@
1
+ autoload(:Tempfile, 'tempfile')
2
+
1
3
  module Tap
2
- module Generator
4
+ module Generator
5
+
6
+ # A mixin defining how to run manifest actions.
3
7
  module Generate
4
- def iterate(actions)
5
- actions.each {|action| yield(action) }
6
- end
7
-
8
+
9
+ # Creates the target directory if it doesn't exist. When pretend is
10
+ # true, creation is logged but does not actually happen.
11
+ #
12
+ # No options currently affect the behavior of this method.
8
13
  def directory(target, options={})
9
- target = File.expand_path(target, target_dir)
14
+ target = File.expand_path(target)
10
15
 
11
- if File.exists?(target)
16
+ case
17
+ when File.exists?(target)
12
18
  log_relative :exists, target
13
19
  else
14
20
  log_relative :create, target
15
- file_task.mkdir(target) unless pretend
21
+ FileUtils.mkdir_p(target) unless pretend
16
22
  end
23
+
24
+ target
17
25
  end
18
-
19
- def file(target, options={})
20
- source_file = Tempfile.new('generate')
21
- yield(source_file) if block_given?
22
- source_file.close
23
-
24
- source = source_file.path
25
- target = File.expand_path(target, target_dir)
26
-
27
- copy_file = case
28
- when !File.exists?(target)
29
- log_relative :create, target
30
- true
31
- when FileUtils.cmp(source, target)
32
- log_relative :exists, target
33
- false
34
- when force_file_collision?(target)
35
- log_relative :force, target
36
- true
37
- else
38
- log_relative :skip, target
39
- false
40
- end
41
-
42
- if copy_file && !pretend
43
- file_task.prepare(target)
44
- FileUtils.mv(source, target)
26
+
27
+ # Creates the target file; content may be added to the file by providing
28
+ # block. If the target file already exists, the new and existing content
29
+ # is compared and the user will be prompted for how to handle collisions.
30
+ # All activity is logged. When pretend is true, creation is logged but
31
+ # does not actually happen.
32
+ #
33
+ # No options currently affect the behavior of this method.
34
+ def file(target, options={})
35
+ source_file = Tempfile.new('generate')
36
+ yield(source_file) if block_given?
37
+ source_file.close
38
+
39
+ source = source_file.path
40
+ target = File.expand_path(target)
41
+
42
+ copy_file = true
43
+ msg = case
44
+ when !File.exists?(target)
45
+ :create
46
+ when FileUtils.cmp(source, target)
47
+ :exists
48
+ when force_file_collision?(target)
49
+ :force
50
+ else
51
+ copy_file = false
52
+ :skip
53
+ end
54
+
55
+ log_relative msg, target
56
+ if copy_file && !pretend
57
+ dir = File.dirname(target)
58
+ FileUtils.mkdir_p(dir) unless File.exists?(dir)
59
+ FileUtils.mv(source, target, :force => true)
45
60
  end
46
- end
47
-
48
- protected
61
+
62
+ target
63
+ end
64
+
65
+ protected
49
66
 
50
67
  # Ask the user interactively whether to force collision.
51
68
  def force_file_collision?(target)
52
69
  return false if skip
53
70
  return true if force
54
71
 
55
- $stdout.print "overwrite #{target}? [Ynaiq] "
56
- $stdout.flush
57
- case $stdin.gets
58
- when /a/i
72
+ prompt_out.print "overwrite #{target}? [Ynaiq] "
73
+ prompt_out.flush
74
+ case prompt_in.gets.strip
75
+ when /^y(es)?$/i
76
+ true
77
+ when /^n(o)?$/i
78
+ false
79
+ when /^a(ll)?$/i
59
80
  self.force = true
60
- when /i/i
81
+ true
82
+ when /^i(gnore)?$/i
61
83
  self.skip = true
62
- when /q/i
63
- $stdout.puts "aborting #{name}"
84
+ false
85
+ when /^q(uit)?$/i
86
+ prompt_out.puts "aborting"
64
87
  raise SystemExit
65
- when /n/i then false
66
- when /y/i then true
67
- else force_file_collision?(destination)
88
+ else force_file_collision?(target)
68
89
  end
69
90
  end
70
91
  end
@@ -11,12 +11,12 @@ app = Tap::App.instance
11
11
  # handle options
12
12
  #
13
13
 
14
- OptionParser.new do |opts|
14
+ ConfigParser.new do |opts|
15
15
  opts.separator ""
16
16
  opts.separator "options:"
17
17
 
18
18
  opts.on("-h", "--help", "Show this message") do
19
- opts.banner = Tap::Support::Lazydoc.usage(__FILE__)
19
+ puts Lazydoc.usage(__FILE__)
20
20
  puts opts
21
21
  exit
22
22
  end
@@ -29,4 +29,4 @@ end.parse!(ARGV)
29
29
  #
30
30
 
31
31
  puts "Received: #{ARGV.join(', ')}"
32
- puts app.info
32
+ puts app.info
@@ -6,21 +6,93 @@ module Tap::Generator::Generators
6
6
  # and documentation is determined from the task source file.
7
7
  class ConfigGenerator < Tap::Generator::Base
8
8
 
9
- config :doc, true, &c.switch # include documentation in the config
9
+ # Dumps a nested configuration.
10
+ DUMP_DELEGATES = lambda do |leader, delegate, block|
11
+ nested_delegates = delegate.default(false).delegates
12
+ indented_dump = Configurable::Utils.dump(nested_delegates, &block).gsub(/^/, " ")
13
+ "#{leader}: \n#{indented_dump}"
14
+ end
15
+
16
+ # Dumps configurations as YAML with documentation,
17
+ # used when the doc config is true.
18
+ DOC_FORMAT = lambda do |key, delegate|
19
+ # get the description
20
+ desc = delegate.attributes[:desc]
21
+ doc = desc.to_s
22
+ doc = desc.comment if doc.empty?
10
23
 
11
- def env
12
- Tap::Env.instance
24
+ # wrap as lines
25
+ lines = Lazydoc::Utils.wrap(doc, 50).collect {|line| "# #{line}"}
26
+ lines << "" unless lines.empty?
27
+
28
+ if delegate.is_nest?
29
+ leader = "#{lines.join("\n")}#{key}"
30
+ DUMP_DELEGATES[leader, delegate, DOC_FORMAT]
31
+ else
32
+ default = delegate.default
33
+
34
+ # setup formatting
35
+ leader = default == nil ? '# ' : ''
36
+ config = {key => default}.to_yaml[5..-1]
37
+ "#{lines.join("\n")}#{leader}#{config.strip}\n\n"
38
+ end
13
39
  end
14
-
15
- def manifest(m, name, config_name=name)
16
- const = env.tasks.search(name) or raise "unknown task: #{name}"
17
- task_class = const.constantize or raise "unknown task: #{name}"
40
+
41
+ # Dumps configurations as YAML without documentation,
42
+ # used when the doc config is false.
43
+ NODOC_FORMAT = lambda do |key, delegate|
44
+ if delegate.is_nest?
45
+ DUMP_DELEGATES[key, delegate, NODOC_FORMAT]
46
+ else
47
+ default = delegate.default
18
48
 
19
- m.directory app['config']
20
- m.file app.filepath('config', config_name + '.yml') do |file|
21
- task_class.configurations.inspect((doc ? :doc : :nodoc), file)
49
+ # setup formatting
50
+ leader = default == nil ? '# ' : ''
51
+ config = {key => default}.to_yaml[5..-1]
52
+ "#{leader}#{config.strip}\n"
22
53
  end
23
54
  end
24
55
 
56
+ config :doc, true, &c.switch # include documentation in the config
57
+ config :nest, false, &c.switch # generate nested config files
58
+ config :blanks, true, &c.switch # allow generation of empty config files
59
+
60
+ # Lookup the named task class. Lookup happens through the active Env
61
+ # instance, specifically using:
62
+ #
63
+ # Env.instance.tasks.search(name)
64
+ #
65
+ # Raises an error if the name cannot be resolved to a task.
66
+ def lookup(name)
67
+ const = Tap::Env.instance.tasks.search(name) or raise "unknown task: #{name}"
68
+ const.constantize
69
+ end
70
+
71
+ def manifest(m, name, config_name=nil)
72
+ # setup
73
+ tasc = lookup(name)
74
+ config_name ||= tasc.default_name
75
+ config_file = app.filepath('config', config_name)
76
+ config_file += ".yml" if File.extname(config_file).empty?
77
+
78
+ # generate the dumps
79
+ dumps = Configurable::Utils.dump_file(tasc.configurations, config_file, nest, true, &format_block)
80
+
81
+ # now put the dumps to the manifest
82
+ m.directory(app['config'])
83
+
84
+ dumps.each do |path, content|
85
+ next if content.empty? && !blanks
86
+ m.file(path) do |file|
87
+ file << content
88
+ end
89
+ end
90
+ end
91
+
92
+ # A hook to set a formatting block. By default format_blocks
93
+ # returns DOC_FORMAT or NODOC_FORMAT as per the doc config.
94
+ def format_block
95
+ doc ? DOC_FORMAT : NODOC_FORMAT
96
+ end
25
97
  end
26
98
  end