sprout 0.7.220-x86-darwin-10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sprout might be problematic. Click here for more details.

@@ -0,0 +1,278 @@
1
+
2
+ module Sprout
3
+ # The ProjectModel gives you a place to describe your project so that you
4
+ # don't need to repeat yourself throughout a rakefile.
5
+ #
6
+ # The default set of properties are also used from code generators, library tasks and sometimes tools.
7
+ #
8
+ # The ProjectModel can be configured as follows:
9
+ # project_model :model do |p|
10
+ # p.name = 'SomeProject'
11
+ # p.source_path << 'somedir/otherdir'
12
+ # p.library_path << 'somedir'
13
+ # end
14
+ #
15
+ # This class should have some reasonable default values, but can be modified from any rakefile.
16
+ # If you don't find some properties that you'd like on the ProjectModel, you can simply add
17
+ # new properties and use them however you wish.
18
+ #
19
+ # Arbitrary properties can be added as follows:
20
+ # m = project_model :model do |p|
21
+ # p.unknown_property = 'someValue'
22
+ # end
23
+ #
24
+ # puts "Unknown Property: #{m.unknown_property}"
25
+ #
26
+ # The ProjectModel is typically treated as if it is a Singleton, and many helper tasks
27
+ # will automatically go look for their model at:
28
+ #
29
+ # Sprout::ProjectModel.instance
30
+ #
31
+ # Unlike a real Singleton, this static property will actually be populated with the most
32
+ # recently instantiated ProjectModel, and any well-behaved helper task will also
33
+ # allow you to send in a model as a prerequisite.
34
+ #
35
+ # project_model :model_a
36
+ # project_model :model_b
37
+ #
38
+ # desc 'Compile and run a'
39
+ # debug :debug_a => :model_a
40
+ #
41
+ # desc 'Compile and run b'
42
+ # debug :debug_b => :model_b
43
+ #
44
+ class ProjectModel < Hash
45
+
46
+ # Relative path to the folder where compile time assets will be stored
47
+ attr_accessor :asset_dir
48
+ # The folder where binary files will be created. Usually this is where any build artifacts like SWF files get placed.
49
+ attr_accessor :bin_dir
50
+ # The Background Color of the SWF file
51
+ attr_accessor :background_color
52
+ # Contributors to the SWF file
53
+ attr_accessor :contributors
54
+ # If you don't want to use the default compiler for your language
55
+ # set it manually here.
56
+ # Possible values are:
57
+ # * sprout-flex2sdk-tool
58
+ # * sprout-flex3sdk-tool
59
+ # * sprout-flex4sdk-tool (Experimental)
60
+ # * sprout-mtasc-tool
61
+ attr_accessor :compiler_gem_name
62
+ # The version number of the compiler gem to use
63
+ attr_accessor :compiler_gem_version
64
+ # The primary creator of the SWF file
65
+ attr_accessor :creator
66
+ # Directory where documentation should be placed.
67
+ attr_accessor :doc_dir
68
+ # CSS documents that should be individually compiled
69
+ # for runtime stylesheet loading.
70
+ attr_accessor :external_css
71
+ # The default frame rate of the SWF file
72
+ attr_accessor :frame_rate
73
+ # The default height of the SWF file
74
+ # _(This value is overridden when embedded in an HTML page)_
75
+ attr_accessor :height
76
+ # The technology language that is being used, right now this value can be 'as2', 'as3' or 'mxml'.
77
+ # Code generators take advantage of this setting to determine which templates to use
78
+ # and build tasks use this setting to determin the input file suffix (.as or .mxml).
79
+ attr_accessor :language
80
+ # The relative path to your library directory. Defaults to 'lib'
81
+ #
82
+ # Any remote .SWC and source libraries that are referenced in your rakefile will be installed
83
+ # into this directory. Source libraries will be placed in a folder that matches the library name,
84
+ # while SWCs will be simply placed directly into the lib_dir.
85
+ attr_accessor :lib_dir
86
+ # Array of sprout library symbols
87
+ attr_accessor :libraries
88
+ # The Array of SWC paths to add to all compilation tasks
89
+ attr_accessor :library_path
90
+ # The locale for the SWF file
91
+ attr_accessor :locale
92
+ # A collection of Flex Module root source files. If this collection
93
+ # has items added to it, the deploy task will generate a 'link_report' from
94
+ # the main application compilation and then consume it as 'load_externs' for
95
+ # each module compilation.
96
+ attr_accessor :modules
97
+ # Organization responsible for this SWF file
98
+ attr_accessor :organization
99
+ # The production file that this Project will generate
100
+ attr_accessor :output
101
+ # Terminal command to preprocessor application that accepts STDIN and returns on STDOUT
102
+ attr_accessor :preprocessor
103
+ # Folder where preprocessed files will be created. Defaults to '.preprocessed'
104
+ attr_accessor :preprocessed_path
105
+ # The real name of the project, usually capitalized like a class name 'SomeProject'
106
+ attr_accessor :project_name
107
+ # The folder where compile time skins can be loaded from
108
+ attr_accessor :skin_dir
109
+ # The skin file that will be generated
110
+ attr_accessor :skin_output
111
+ # The Array of source paths to add to all compilation tasks
112
+ # _Do not add task-specific paths (like lib/asunit) to this value_
113
+ attr_accessor :source_path
114
+ # The relative path to your main source directory. Defaults to 'src'
115
+ attr_accessor :src_dir
116
+ # Enforce strict type checking
117
+ attr_accessor :strict
118
+ # The relative path to the directory where swc files should be kept.
119
+ # This value defaults to lib_dir
120
+ attr_accessor :swc_dir
121
+ # Relative path to the folder that contains your test cases
122
+ attr_accessor :test_dir
123
+ # The test executable
124
+ attr_accessor :test_output
125
+ # The test runner SWF height
126
+ attr_accessor :test_height
127
+ # The test runner SWF width
128
+ attr_accessor :test_width
129
+ # Tasks that can, will use the Flex Compiler SHell.
130
+ attr_accessor :use_fcsh
131
+ # Flash Player Tasks will launch using the Flex Debugger.
132
+ attr_accessor :use_fdb
133
+ # The default width of the SWF file
134
+ # _(This value is overridden when embedded in an HTML page)_
135
+ attr_accessor :width
136
+
137
+ # Static method that returns the most recently instantiated ProjectModel,
138
+ # or instantiates one if none have been created yet.
139
+ def self.instance
140
+ @@instance ||= ProjectModel.new
141
+ yield @@instance if block_given?
142
+ return @@instance
143
+ end
144
+
145
+ # Decorates the static instance method.
146
+ def self.setup
147
+ @@instance ||= ProjectModel.new
148
+ yield @@instance if block_given?
149
+ return @@instance
150
+ end
151
+
152
+ def self.destroy # :nodoc:
153
+ @@instance = nil
154
+ end
155
+
156
+ def initialize
157
+ super
158
+ @project_name = ''
159
+ @doc_dir = 'doc'
160
+ @src_dir = 'src'
161
+ @lib_dir = 'lib'
162
+ @swc_dir = 'lib'
163
+ @bin_dir = 'bin'
164
+ @test_dir = 'test'
165
+ @asset_dir = 'assets'
166
+ @skin_dir = File.join(@asset_dir, 'skins')
167
+ @frame_rate = 24
168
+ @language = 'as3'
169
+
170
+ @external_css = []
171
+ @libraries = []
172
+ @library_path = []
173
+ @modules = []
174
+ @source_path = []
175
+
176
+ @model_dir = nil
177
+ @view_dir = nil
178
+ @controller_dir = nil
179
+
180
+ @test_height = 550
181
+ @test_width = 900
182
+ @@instance = self
183
+ end
184
+
185
+ # Path to the project directory from which all other paths are created
186
+ def project_path
187
+ return Sprout.project_path
188
+ end
189
+
190
+ def model_dir=(dir)
191
+ @model_dir = dir
192
+ end
193
+
194
+ # Simple MVC helper for project-wide models if your project is called 'SomeProject'
195
+ # this will default to:
196
+ # SomeProject/src/someproject/models
197
+ def model_dir
198
+ if(@model_dir.nil?)
199
+ @model_dir = File.join(src_dir, project_name.downcase, 'models')
200
+ end
201
+ return @model_dir
202
+ end
203
+
204
+ def view_dir=(dir)
205
+ @view_dir = dir
206
+ end
207
+
208
+ # Simple MVC helper for project-wide views if your project is called 'SomeProject'
209
+ # this will default to:
210
+ # SomeProject/src/someproject/views
211
+ def view_dir
212
+ if(@view_dir.nil?)
213
+ @view_dir = File.join(src_dir, project_name.downcase, 'views')
214
+ end
215
+ return @view_dir
216
+ end
217
+
218
+ def controller_dir=(dir)
219
+ @controller_dir = dir
220
+ end
221
+
222
+ # Simple MVC helper for project-wide views if your project is called 'SomeProject'
223
+ # this will default to:
224
+ # SomeProject/src/someproject/controllers
225
+ def controller_dir
226
+ if(@controller_dir.nil?)
227
+ @controller_dir = File.join(src_dir, project_name.downcase, 'controllers')
228
+ end
229
+ return @controller_dir
230
+ end
231
+
232
+ # Alias for project_name
233
+ def name=(name)
234
+ @project_name = name
235
+ end
236
+
237
+ def name
238
+ @project_name
239
+ end
240
+
241
+ def to_s
242
+ return "[Sprout::ProjectModel project_name=#{project_name}]"
243
+ end
244
+
245
+ protected
246
+
247
+ def method_missing(method_name, *args)
248
+ method_name = method_name.to_s
249
+ if method_name =~ /=$/
250
+ super if args.size > 1
251
+ self[method_name[0...-1]] = args[0]
252
+ else
253
+ super unless has_key?(method_name) and args.empty?
254
+ self[method_name]
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ # Helper method to expose the project model as a Rake Task
261
+ def project_model(task_name)
262
+ model = Sprout::ProjectModel.new
263
+ yield model if block_given?
264
+
265
+ t = task task_name
266
+
267
+ def t.project_model=(model)
268
+ @model = model
269
+ end
270
+
271
+ def t.project_model
272
+ return @model
273
+ end
274
+
275
+ t.project_model = model
276
+ return model
277
+ end
278
+
@@ -0,0 +1,71 @@
1
+
2
+ module Sprout
3
+ class RemoteFileLoaderError < StandardError #:nodoc:
4
+ end
5
+
6
+ class RemoteFileLoader #:nodoc:
7
+
8
+ def get_remote_file(uri, force=false, md5=nil)
9
+ response = fetch(uri.to_s)
10
+ if(force || response_is_valid?(response, md5))
11
+ return response
12
+ end
13
+ end
14
+
15
+ def response_is_valid?(response, expected_md5sum=nil)
16
+ if(expected_md5sum)
17
+ md5 = Digest::MD5.new
18
+ md5 << response
19
+
20
+ if(expected_md5sum != md5.hexdigest)
21
+ puts "The MD5 Sum of the downloaded file (#{md5.hexdigest}) does not match what was expected (#{expected_md5sum})."
22
+ puts "Would you like to install anyway? [Yn]"
23
+ response = $stdin.gets.chomp!
24
+ if(response.downcase == 'y')
25
+ return true
26
+ else
27
+ raise RemoteFileLoaderError.new('MD5 Checksum failed')
28
+ end
29
+ end
30
+ end
31
+ return true
32
+ end
33
+
34
+ def fetch(uri)
35
+ uri = URI.parse(uri)
36
+ progress = nil
37
+ response = nil
38
+ name = uri.path.split("/").pop
39
+
40
+ raise RemoteFileLoaderError.new("The RemoteFileTask failed for #{name}. We can only handle HTTP requests at this time, it seems you were trying: '#{uri.scheme}'") if uri.scheme != 'http'
41
+ begin
42
+ open(uri.to_s, :content_length_proc => lambda {|t|
43
+ if t && t > 0
44
+ progress = ProgressBar.new(name, t)
45
+ progress.file_transfer_mode
46
+ progress.set(0)
47
+ else
48
+ progress = ProgressBar.new(name, 0)
49
+ progress.file_transfer_mode
50
+ progress.set(0)
51
+ end
52
+ },
53
+ :progress_proc => lambda {|s|
54
+ progress.set s if progress
55
+ }) do |f|
56
+ response = f.read
57
+ progress.finish
58
+ end
59
+ rescue SocketError => sock_err
60
+ raise RemoteFileLoaderError.new("[ERROR] #{sock_err.to_s}")
61
+ rescue OpenURI::HTTPError => http_err
62
+ raise RemoteFileLoaderError.new("[ERROR] Failed to load file from: '#{uri.to_s}'\n[REMOTE ERROR] #{http_err.io.read.strip}")
63
+ rescue Errno::ECONNREFUSED => econ_err
64
+ raise Errno::ECONNREFUSED.new("[ERROR] Connection refused at: '#{uri.to_s}'")
65
+ end
66
+
67
+ return response
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,151 @@
1
+
2
+ module Sprout
3
+ class RemoteFileTargetError < StandardError #:nodoc:
4
+ end
5
+
6
+ class RemoteFileTarget # :nodoc:
7
+
8
+ attr_writer :archive_path
9
+
10
+ # The string environment variable name to check before downloading anything.
11
+ attr_accessor :environment
12
+
13
+ # The user path where this gem will download and install files
14
+ # This value is set by the Sprout::Builder that creates this RemoteFileTarget
15
+ attr_accessor :install_path
16
+
17
+ # Optional md5 hash, usually set in the sprout.spec for each RemoteFileTarget
18
+ # If this value is set, the downloaded archive will be hashed, the hashes will
19
+ # be compared and if they differ, the installation process will break.
20
+ attr_accessor :md5
21
+
22
+ # Used for dmg archives. Absolute path to the mounted dmg (essentially its name)
23
+ attr_accessor :mount_path
24
+
25
+ # Which platform will this RemoteFileTarget support.
26
+ # Supported options are:
27
+ # * universal
28
+ # * macosx
29
+ # * win32
30
+ # * linux
31
+ attr_accessor :platform
32
+
33
+ # URL where Sprouts can go to download the RemoteFileTarget archive
34
+ attr_accessor :url
35
+
36
+ # If the archive type cannot be assumed from the returned file name,
37
+ # it must be provided as one of the following:
38
+ # :exe
39
+ # :zip
40
+ # :targz
41
+ # :gzip
42
+ # :swc
43
+ # :rb
44
+ # :dmg
45
+ # @see ArchiveUnpacker
46
+ attr_accessor :archive_type
47
+
48
+ # Filename for the downloaded file. Introduced to fix railsy URL issues.
49
+ attr_accessor :filename
50
+
51
+ # Relative path within the archive to the executable or binary of interest
52
+ def archive_path
53
+ @archive_path ||= ''
54
+ end
55
+
56
+ # Resolve this RemoteFileTarget now. This method is called by the Sprout::Builder
57
+ # and will download, install and unpack the described archive, unless it is
58
+ # already installed
59
+ def resolve(update=false)
60
+ # Wanted to raise, but it seems we support RemoteFileTargets that are actually self-installed binaries...
61
+ # like SWFMill on Linux. @see the BuilderTest.test_build_no_install for more info.
62
+ # raise RemoteFileTargetError.new('Cannot retrieve a RemoteFileTarget without a url') if url.nil?
63
+ return if url.nil?
64
+
65
+ if(filename)
66
+ self.downloaded_path = File.join(File.dirname(downloaded_path), filename)
67
+ end
68
+
69
+ if(url && (update || !File.exists?(downloaded_path)))
70
+ content = download(url, update)
71
+ FileUtils.makedirs(File.dirname(downloaded_path))
72
+ FileUtils.touch(downloaded_path)
73
+ File.open(downloaded_path, 'rb+') do |file|
74
+ file.write(content)
75
+ end
76
+ end
77
+
78
+ if(!File.exists?(installed_path) || !File.exists?(File.join(installed_path, archive_path) ))
79
+ archive_root = File.join(install_path, 'archive')
80
+ install(downloaded_path, archive_root, update, archive_type)
81
+ end
82
+ end
83
+
84
+ # Return the basename of the executable that this RemoteFileTarget refers to
85
+ def executable
86
+ return File.basename(archive_path)
87
+ end
88
+
89
+ # The root path to the unpacked archive files. This is the base path that will be added to any
90
+ # +archive_path+ relative paths
91
+ def installed_path
92
+ @installed_path ||= inferred_installed_path
93
+ return @installed_path
94
+ end
95
+
96
+ def downloaded_path=(path)
97
+ @downloaded_path = path
98
+ end
99
+
100
+ # Parent directory where archives are downloaded
101
+ # can be something like: ~/Library/Sprouts/cache/0.7/sprout-somesprout-tool.x.x.x/
102
+ def downloaded_path
103
+ @downloaded_path ||= File.join(install_path, file_name(url))
104
+ return @downloaded_path
105
+ end
106
+
107
+ # Base file name represented by the provided +url+
108
+ # Will strip off any ? arguments and trailing slashes. May not play nice with Rails URLS,
109
+ # We expect archive file name suffixes like, zip, gzip, tar.gz, dmg, etc.
110
+ def file_name(url=nil)
111
+ return @filename if(@filename)
112
+
113
+ url ||= self.url
114
+ url = url.split('?').shift
115
+
116
+ parts = url.split('/')
117
+ if(parts.last == '/')
118
+ parts.pop
119
+ end
120
+
121
+ file = parts.pop
122
+
123
+ if(!archive_type.nil? && file.match(/\.#{archive_type.to_s}$/).nil?)
124
+ file << ".#{archive_type.to_s}"
125
+ end
126
+
127
+ return file
128
+ end
129
+
130
+ private
131
+
132
+ def inferred_installed_path
133
+ if(!environment.nil? && !ENV[environment].nil? && File.exists?(ENV[environment]))
134
+ return ENV[environment]
135
+ end
136
+
137
+ return File.join(install_path, 'archive')
138
+ end
139
+
140
+ def download(url, update=false)
141
+ loader = RemoteFileLoader.new
142
+ loader.get_remote_file(url, update, md5)
143
+ end
144
+
145
+ def install(from, to, force, archive_type=nil)
146
+ unpacker = ArchiveUnpacker.new
147
+ unpacker.unpack_archive(from, to, force, archive_type)
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,88 @@
1
+ =begin
2
+ Copyright (c) 2007 Pattern Park
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ =end
23
+ require 'erb'
24
+
25
+ module Sprout
26
+
27
+ class SimpleResolver #:nodoc:
28
+
29
+ def initialize(template, output, files, base_dir=nil)
30
+ @template = template
31
+ @output = output
32
+ @files = files
33
+ @base_dir = base_dir
34
+ @ignored_files = []
35
+ execute
36
+ finish
37
+ end
38
+
39
+ def execute
40
+ template_file = File.open(@template, 'r')
41
+ content = template_file.read
42
+ result = ERB.new(content, nil, '>').result(binding)
43
+
44
+ output_file = File.open(@output, 'w')
45
+ output_file.write(result)
46
+
47
+ template_file.close
48
+ output_file.close
49
+ end
50
+
51
+ def files
52
+ return @files
53
+ end
54
+
55
+ def finish
56
+ if(@ignored_files.size > 0)
57
+ Logger.puts '>> SimpleResolver ignored the following files because their names were invalid:'
58
+ @ignored_files.each do |file|
59
+ puts file
60
+ end
61
+ end
62
+ end
63
+
64
+ def xml_edit_warning
65
+ return <<EOF
66
+ <!--
67
+ DO NOT EDIT THIS FILE!
68
+ This file was auto-generated from
69
+ an ERB template which can be
70
+ found at:
71
+ #{@template}
72
+ -->
73
+ EOF
74
+ end
75
+
76
+ def edit_warning
77
+ return <<EOF
78
+ /*************************************
79
+ * DO NOT EDIT THIS FILE!
80
+ * This file was auto-generated from
81
+ * an ERB template which can be
82
+ * found at:
83
+ * #{@template}
84
+ *************************************/
85
+ EOF
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,118 @@
1
+ require 'erb'
2
+
3
+ # Rake task that makes it stupid-easy to render ERB templates
4
+ # to disk. Just add parameters to the yielded object, and
5
+ # they will be available to your Template.
6
+ #
7
+ # erb_resolver 'config/SomeFile.xml' do |t|
8
+ # t.param1 = 'value'
9
+ # t.other_param = 'other value'
10
+ # t.another_param = ['a', 'b', 'c']
11
+ # end
12
+ #
13
+ # Your erb template must be found at:
14
+ #
15
+ # [task_name].erb
16
+ #
17
+ # For the above example, this file would be:
18
+ #
19
+ # config/SomeFile.xml.erb
20
+ #
21
+ module Sprout
22
+
23
+ class ERBResolver < Rake::FileTask
24
+
25
+ # Path to the input ERB template. This
26
+ # value will default to the value of
27
+ # "#{ERBResolver.output}.erb"
28
+ attr_accessor :template
29
+
30
+ def initialize(name, app) # :nodoc:
31
+ super
32
+ @context = ERBContext.new
33
+ end
34
+
35
+ def define(args)
36
+ end
37
+
38
+ def prepare
39
+ prepare_prerequisites
40
+ end
41
+
42
+ # Modified from Rake::Task.execute
43
+ def execute(args=nil)
44
+ args ||= EMPTY_TASK_ARGS
45
+ if application.options.dryrun
46
+ puts "** Execute (dry run) #{name}"
47
+ return
48
+ end
49
+ if application.options.trace
50
+ puts "** Execute #{name}"
51
+ end
52
+ application.enhance_with_matching_rule(name) if @actions.empty?
53
+ @actions.each do |action|
54
+ execute_erb_task(action, args)
55
+ end
56
+ end
57
+
58
+ def execute_erb_task(action, args=nil)
59
+ case action.arity
60
+ when 1
61
+ action.call(@context)
62
+ else
63
+ action.call(@context, args)
64
+ end
65
+
66
+ @context.execute(template, output, args)
67
+ end
68
+
69
+ def self.define_task(*args, &block)
70
+ t = super
71
+ if(t.is_a?(ERBResolver))
72
+ t.define(args)
73
+ t.prepare
74
+ end
75
+ return t
76
+ end
77
+
78
+ def template
79
+ @template ||= "#{output}.erb"
80
+ end
81
+
82
+ def output
83
+ self.name
84
+ end
85
+
86
+ protected
87
+
88
+ def prepare_prerequisites
89
+ prerequisites << file(template)
90
+ CLEAN.add(output)
91
+ end
92
+
93
+ end
94
+
95
+ # An empty, dynamic object that will be yielded
96
+ # to the provided block and later supplied to the
97
+ # ERB template.
98
+ #
99
+ # Returning this empty object gives us the ability
100
+ # to use parameter names in our templates even if
101
+ # they are already used by Rake tasks (i.e. name).
102
+ class ERBContext
103
+ include DynamicAccessors
104
+
105
+ def execute(template, output, args=nil)
106
+ content = nil
107
+ File.open(template, 'r') { |f| content = f.read }
108
+ result = ERB.new(content, nil, '>').result(binding)
109
+ File.open(output, 'w') { |f| f.write(result) }
110
+ Log.puts ">> Created ERB output at: #{output} from: #{template}"
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ def erb_resolver(*args, &block)
117
+ Sprout::ERBResolver.define_task(args, &block)
118
+ end