bpm 1.0.0.beta.6 → 1.0.0.beta.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +26 -0
- data/TODO.md +0 -3
- data/lib/bpm/cli/base.rb +3 -3
- data/lib/bpm/default.json +5 -1
- data/lib/bpm/errors.rb +8 -0
- data/lib/bpm/generator.rb +8 -0
- data/lib/bpm/init_generator.rb +1 -1
- data/lib/bpm/package.rb +113 -11
- data/lib/bpm/pipeline/format_processor.rb +28 -0
- data/lib/bpm/pipeline/generated_asset.rb +2 -2
- data/lib/bpm/pipeline/package_pipeline.rb +79 -0
- data/lib/bpm/pipeline/plugin_asset.rb +7 -8
- data/lib/bpm/pipeline/plugin_processor.rb +52 -0
- data/lib/bpm/pipeline.rb +89 -26
- data/lib/bpm/project.rb +55 -29
- data/lib/bpm/version.rb +1 -1
- data/lib/bpm.rb +3 -1
- data/spec/cli/list_spec.rb +1 -0
- data/spec/cli/pack_spec.rb +125 -103
- data/spec/fixtures/projects/coffee/coffee.json +17 -0
- data/spec/fixtures/projects/coffee/index.html.handlebars +1 -0
- data/spec/fixtures/projects/coffee/lib/main.coffee +1 -0
- data/spec/fixtures/projects/coffee/packages/coffee-script/compiler.js +4 -0
- data/spec/fixtures/projects/coffee/packages/coffee-script/lib/main.js +1 -0
- data/spec/fixtures/projects/coffee/packages/coffee-script/package.json +15 -0
- data/spec/fixtures/projects/coffee/packages/handlebars/format.js +6 -0
- data/spec/fixtures/projects/coffee/packages/handlebars/lib/main.js +2 -0
- data/spec/fixtures/projects/coffee/packages/handlebars/package.json +16 -0
- data/spec/fixtures/projects/coffee/packages/spade/lib/main.js +1 -0
- data/spec/fixtures/projects/coffee/packages/spade/package.json +14 -0
- data/spec/fixtures/projects/coffee/packages/spade/transport.js +3 -0
- data/spec/fixtures/projects/coffee/templates/section.handlebars +1 -0
- data/spec/fixtures/projects/minitrans/packages/transport/package.json +5 -1
- data/spec/fixtures/projects/transporter/packages/transport/package.json +5 -1
- data/spec/package_pipeline_spec.rb +30 -0
- data/spec/package_spec.rb +328 -316
- data/spec/plugins/format_spec.rb +38 -0
- data/spec/plugins/transport_spec.rb +1 -1
- data/spec/support/matchers.rb +1 -2
- metadata +57 -24
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,30 @@
|
|
1
1
|
|
2
|
+
* First cut at support for formats.
|
3
|
+
* Also introduces new requirement for defining transport and format plugins
|
4
|
+
in the package.json. Now you must use the "bpm:provides" keyword:
|
5
|
+
|
6
|
+
New format for defining a format or transport plugin:
|
7
|
+
|
8
|
+
"bpm:provides": {
|
9
|
+
"transport": {
|
10
|
+
"main": "path/to/transport/plugin"
|
11
|
+
},
|
12
|
+
|
13
|
+
"format:EXT": {
|
14
|
+
"default:mime": "application/javascript",
|
15
|
+
"main": "path/to/format/plugin"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
# 1.0.0.beta.7
|
20
|
+
|
21
|
+
* fixed bug where local packages that are indirect dependencies of other
|
22
|
+
remote packages could cause bpm to error out unable to find dependencies.
|
23
|
+
|
24
|
+
* improved logging slightly
|
25
|
+
|
26
|
+
# 1.0.0.beta.6 (yanked)
|
27
|
+
|
2
28
|
* bpm now passes a context object with build settings and a minify option
|
3
29
|
to plugins - this will allow spade to support string loading.
|
4
30
|
|
data/TODO.md
CHANGED
data/lib/bpm/cli/base.rb
CHANGED
@@ -277,7 +277,7 @@ module BPM
|
|
277
277
|
package = local.pack(File.join(package_path, "package.json"), options[:email])
|
278
278
|
|
279
279
|
if package.errors.empty?
|
280
|
-
|
280
|
+
say "Successfully built package: #{package.file_name}"
|
281
281
|
else
|
282
282
|
failure_message = "BPM encountered the following problems building your package:"
|
283
283
|
package.errors.each do |error|
|
@@ -298,7 +298,7 @@ module BPM
|
|
298
298
|
begin
|
299
299
|
package = local.unpack(path, options[:target])
|
300
300
|
unpack_path = File.expand_path(File.join(Dir.pwd, options[:target], package.full_name))
|
301
|
-
|
301
|
+
say "Unpacked package into: #{unpack_path}"
|
302
302
|
rescue Errno::EACCES, LibGems::FilePermissionError => ex
|
303
303
|
abort "There was a problem unpacking #{path}:\n#{ex.message}"
|
304
304
|
end
|
@@ -391,7 +391,7 @@ module BPM
|
|
391
391
|
abort %{No packages found matching "#{names.join('", "')}".}
|
392
392
|
else
|
393
393
|
packages.each do |name, versions|
|
394
|
-
|
394
|
+
say "#{name} (#{versions.sort.reverse.join(", ")})"
|
395
395
|
end
|
396
396
|
end
|
397
397
|
end
|
data/lib/bpm/default.json
CHANGED
data/lib/bpm/errors.rb
CHANGED
@@ -48,4 +48,12 @@ module BPM
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
class TooManyTransportsError < BPM::Error
|
52
|
+
def format_message(pkg)
|
53
|
+
err = <<EOF
|
54
|
+
#{pkg.name} depends on #{pkg.provided_transports.size} packages that define transport plugins. Select a plugin by adding a `bpm:use:transport` property to the package.json
|
55
|
+
EOF
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
51
59
|
end
|
data/lib/bpm/generator.rb
CHANGED
data/lib/bpm/init_generator.rb
CHANGED
data/lib/bpm/package.rb
CHANGED
@@ -26,10 +26,11 @@ module BPM
|
|
26
26
|
"bpm:formats" => :hash,
|
27
27
|
"bpm:transport" => :string,
|
28
28
|
"bpm:use:transport" => :string,
|
29
|
-
"bpm:minifier" => :string
|
29
|
+
"bpm:minifier" => :string,
|
30
|
+
"bpm:provides" => :hash
|
30
31
|
}
|
31
32
|
|
32
|
-
PLUGIN_FIELDS = %w[bpm:
|
33
|
+
PLUGIN_FIELDS = %w[bpm:minifier]
|
33
34
|
|
34
35
|
# Fields that can be loaded straight into the gemspec
|
35
36
|
SPEC_FIELDS = %w[name email]
|
@@ -75,9 +76,9 @@ module BPM
|
|
75
76
|
spec.licenses = licenses.map{|l| l["type"]}
|
76
77
|
spec.executables = bin_files.map{|p| File.basename(p) } if bin_path
|
77
78
|
|
78
|
-
spec.homepage = homepage || url
|
79
|
-
spec.description = description || summary
|
80
|
-
spec.summary = summary || description
|
79
|
+
spec.homepage = self.homepage || self.url
|
80
|
+
spec.description = self.description || self.summary
|
81
|
+
spec.summary = self.summary || self.description
|
81
82
|
|
82
83
|
metadata = Hash[METADATA_FIELDS.map{|f| [f, send(c2u(f)) ] }]
|
83
84
|
spec.requirements = [metadata.to_json]
|
@@ -124,6 +125,14 @@ module BPM
|
|
124
125
|
as_json.to_json
|
125
126
|
end
|
126
127
|
|
128
|
+
def shell
|
129
|
+
@shell ||= Thor::Base.shell.new
|
130
|
+
end
|
131
|
+
|
132
|
+
def say(*args)
|
133
|
+
shell.say *args
|
134
|
+
end
|
135
|
+
|
127
136
|
def full_name
|
128
137
|
"#{name}-#{version}"
|
129
138
|
end
|
@@ -133,7 +142,10 @@ module BPM
|
|
133
142
|
end
|
134
143
|
|
135
144
|
def directory_files
|
136
|
-
dir_names =
|
145
|
+
dir_names = [bin_path, lib_path, tests_path]
|
146
|
+
dir_names += directories.reject { |k,_| dir_names.include?(k) }.values
|
147
|
+
dir_names.reject! { |t| t == tests_path }
|
148
|
+
|
137
149
|
build_names = bpm_build.values.map do |hash|
|
138
150
|
hash['directories'] || hash['assets']
|
139
151
|
end
|
@@ -144,6 +156,12 @@ module BPM
|
|
144
156
|
val
|
145
157
|
end
|
146
158
|
|
159
|
+
bpm_provides.each do |_,values|
|
160
|
+
val = values['main']
|
161
|
+
val = val && val =~ /^#{name}\// ? val[name.size+1..-1]+'.js' : nil
|
162
|
+
build_names << val if val
|
163
|
+
end
|
164
|
+
|
147
165
|
(dir_names+build_names).flatten.compact.uniq.map do |dir|
|
148
166
|
glob_files(dir)
|
149
167
|
end.flatten
|
@@ -207,6 +225,12 @@ module BPM
|
|
207
225
|
ret.merge! minifier
|
208
226
|
end
|
209
227
|
end
|
228
|
+
|
229
|
+
bpm_provides.each do |_,opts|
|
230
|
+
next unless opts.is_a?(Hash) && opts['dependencies']
|
231
|
+
ret.merge! opts['dependencies']
|
232
|
+
end
|
233
|
+
|
210
234
|
ret
|
211
235
|
end
|
212
236
|
|
@@ -233,12 +257,12 @@ module BPM
|
|
233
257
|
end
|
234
258
|
|
235
259
|
def has_json?
|
236
|
-
File.exist?(json_path)
|
260
|
+
!!json_path && File.exist?(json_path)
|
237
261
|
end
|
238
262
|
|
239
263
|
def validate_name_and_path
|
240
264
|
filename = File.basename(root_path)
|
241
|
-
unless filename==name || filename=="#{name}-#{version}"
|
265
|
+
unless name.nil? || name.empty? || filename==name || filename=="#{name}-#{version}"
|
242
266
|
raise BPM::InvalidPackageNameError.new self
|
243
267
|
end
|
244
268
|
end
|
@@ -276,6 +300,10 @@ module BPM
|
|
276
300
|
self.author = spec.authors.first
|
277
301
|
self.version = spec.version.to_s
|
278
302
|
|
303
|
+
self.description = spec.description
|
304
|
+
self.summary = spec.summary
|
305
|
+
self.homepage = spec.homepage
|
306
|
+
|
279
307
|
metadata = spec.requirements.first
|
280
308
|
if metadata
|
281
309
|
metadata = JSON.parse(metadata)
|
@@ -311,6 +339,69 @@ module BPM
|
|
311
339
|
ret
|
312
340
|
end
|
313
341
|
|
342
|
+
def merged_dependencies(*kinds)
|
343
|
+
kinds.inject({}) do |ret, kind|
|
344
|
+
deps = case kind
|
345
|
+
when :runtime
|
346
|
+
dependencies
|
347
|
+
when :development
|
348
|
+
dependencies_development
|
349
|
+
when :build
|
350
|
+
dependencies_build
|
351
|
+
end
|
352
|
+
ret.merge! deps
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def used_dependencies(project)
|
357
|
+
if project.has_local_package?(self.name)
|
358
|
+
merged_dependencies(:runtime, :development)
|
359
|
+
else
|
360
|
+
merged_dependencies(:runtime)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def provided_formats
|
365
|
+
ret = {}
|
366
|
+
bpm_provides.each do | key, opts |
|
367
|
+
ret[key[7..-1]] = opts if key =~ /^format:/
|
368
|
+
end
|
369
|
+
ret
|
370
|
+
end
|
371
|
+
|
372
|
+
def used_formats(project)
|
373
|
+
pkgs=project.map_to_packages used_dependencies(project)
|
374
|
+
pkgs.inject({}) { |ret, pkg| ret.merge!(pkg.provided_formats) }
|
375
|
+
end
|
376
|
+
|
377
|
+
def provided_preprocessors
|
378
|
+
bpm_provides['preprocessors'] || []
|
379
|
+
end
|
380
|
+
|
381
|
+
def used_preprocessors(project)
|
382
|
+
pkgs=project.map_to_packages used_dependencies(project)
|
383
|
+
pkgs.map { |pkg| pkg.provided_postprocessors }.flatten
|
384
|
+
end
|
385
|
+
|
386
|
+
def provided_postprocessors
|
387
|
+
bpm_provides['postprocessors'] || []
|
388
|
+
end
|
389
|
+
|
390
|
+
def used_postprocessors(project)
|
391
|
+
pkgs=project.map_to_packages used_dependencies(project)
|
392
|
+
pkgs.map { |pkg| pkg.provided_postprocessors }.flatten
|
393
|
+
end
|
394
|
+
|
395
|
+
def provided_transport
|
396
|
+
bpm_provides['transport']
|
397
|
+
end
|
398
|
+
|
399
|
+
def used_transports(project)
|
400
|
+
pkgs=project.map_to_packages used_dependencies(project)
|
401
|
+
pkgs.map { |pkg| pkg.provided_transport }.compact.flatten
|
402
|
+
end
|
403
|
+
|
404
|
+
|
314
405
|
# TODO: Make better errors
|
315
406
|
# TODO: This might not work well with conflicting versions
|
316
407
|
def local_deps(search_path=nil)
|
@@ -395,15 +486,26 @@ module BPM
|
|
395
486
|
end
|
396
487
|
|
397
488
|
def validate_summary
|
398
|
-
summary || description
|
489
|
+
if (summary.nil? || summary.empty?) && (description.nil? || description.empty?)
|
490
|
+
add_error "Package requires a 'summary' field"
|
491
|
+
add_error "Package requires a 'description' field"
|
492
|
+
false
|
493
|
+
else
|
494
|
+
true
|
495
|
+
end
|
399
496
|
end
|
400
497
|
|
401
498
|
def validate_homepage
|
402
|
-
homepage || url
|
499
|
+
if (homepage.nil? || homepage.empty?) && (url.nil? || url.empty?)
|
500
|
+
add_error "Package requires a 'homepage' field"
|
501
|
+
false
|
502
|
+
else
|
503
|
+
true
|
504
|
+
end
|
403
505
|
end
|
404
506
|
|
405
507
|
def add_error(message)
|
406
|
-
self.errors << message
|
508
|
+
self.errors << message unless self.errors.include?(message)
|
407
509
|
end
|
408
510
|
|
409
511
|
def glob_files(path)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
|
3
|
+
module BPM
|
4
|
+
|
5
|
+
# A Template that will use a format plugin to compile the content
|
6
|
+
# Register a subclass of the template with the with_plugin
|
7
|
+
class FormatProcessor < BPM::PluginProcessor
|
8
|
+
|
9
|
+
def self.with_plugin(ext, plugin_opts)
|
10
|
+
ret = super plugin_opts, 'compileFormat'
|
11
|
+
ret.instance_eval do
|
12
|
+
@extension = ext
|
13
|
+
end
|
14
|
+
ret
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.extension
|
18
|
+
@extension
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.default_mime_type
|
22
|
+
@plugin_opts["mime:default"]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -74,9 +74,9 @@ module BPM
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def build_source
|
77
|
-
|
77
|
+
BPM::GeneratedAsset.push_generating_asset self
|
78
78
|
ret = minify super
|
79
|
-
|
79
|
+
BPM::GeneratedAsset.pop_generating_asset
|
80
80
|
ret
|
81
81
|
end
|
82
82
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
|
3
|
+
module BPM
|
4
|
+
|
5
|
+
# A sub-environment created for each package in the project. Requests for
|
6
|
+
# individual assets will usually end up going through one of these
|
7
|
+
# instances. This allows each package to have its own set of processors
|
8
|
+
# for each file.
|
9
|
+
class PackagePipeline < Sprockets::Environment
|
10
|
+
|
11
|
+
attr_reader :pipeline, :package
|
12
|
+
|
13
|
+
def shell
|
14
|
+
@shell ||= Thor::Base.shell.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(pipeline, package)
|
18
|
+
@pipeline = pipeline
|
19
|
+
@package = package
|
20
|
+
|
21
|
+
super package.root_path
|
22
|
+
|
23
|
+
%w(text/css application/javascript).each do |kind|
|
24
|
+
unregister_processor kind, Sprockets::DirectiveProcessor
|
25
|
+
register_processor kind, BPM::DirectiveProcessor
|
26
|
+
end
|
27
|
+
|
28
|
+
# This gunks things up. I'm not a fan - PDW
|
29
|
+
unregister_postprocessor 'application/javascript', Sprockets::SafetyColons
|
30
|
+
|
31
|
+
package.used_formats(project).each do |ext, opts|
|
32
|
+
register_engine ".#{ext}", BPM::FormatProcessor.with_plugin(ext,opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
package.used_preprocessors(project).each do |opts|
|
36
|
+
register_preprocessor opts['mime'],
|
37
|
+
BPM::PluginProcessor.with_plugin(opts, 'preprocess')
|
38
|
+
end
|
39
|
+
|
40
|
+
package.used_postprocessors(project).each do |opts|
|
41
|
+
register_postprocessor opts['mime'],
|
42
|
+
BPM::PluginProcessor.with_plugin(opts, 'postprocess')
|
43
|
+
end
|
44
|
+
|
45
|
+
opts = package.used_transports(project)
|
46
|
+
raise TooManyTransportsError(package) if opts.size>1
|
47
|
+
if opts.size>0
|
48
|
+
register_postprocessor 'application/javascript',
|
49
|
+
BPM::PluginProcessor.with_plugin(opts.first, 'compileTransport')
|
50
|
+
end
|
51
|
+
|
52
|
+
append_path package.root_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def package_name
|
56
|
+
package.name
|
57
|
+
end
|
58
|
+
|
59
|
+
def project
|
60
|
+
pipeline.project
|
61
|
+
end
|
62
|
+
|
63
|
+
def mode
|
64
|
+
pipeline.mode
|
65
|
+
end
|
66
|
+
|
67
|
+
def plugin_context_for(logical_path)
|
68
|
+
pipeline.plugin_context_for logical_path
|
69
|
+
end
|
70
|
+
|
71
|
+
def resolve(*args)
|
72
|
+
super *args
|
73
|
+
rescue Sprockets::FileNotFound => e
|
74
|
+
raise Sprockets::FileNotFound, "#{e.message} in package '#{package_name}'"
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -5,7 +5,7 @@ module BPM
|
|
5
5
|
# Defines an asset that represents a build plugin (such as a transport or
|
6
6
|
# a minifier.) The generated asset will include dependencies of the plugin
|
7
7
|
# module as well as the module itself.
|
8
|
-
class PluginAsset <
|
8
|
+
class PluginAsset < BPM::GeneratedAsset
|
9
9
|
|
10
10
|
def initialize(environment, module_name)
|
11
11
|
pathname = Pathname.new(File.join(environment.project.root_path, '.bpm', 'plugins', module_name+'.js'))
|
@@ -18,15 +18,14 @@ module BPM
|
|
18
18
|
super(environment, module_name, pathname, {})
|
19
19
|
end
|
20
20
|
|
21
|
-
protected
|
22
|
-
|
23
|
-
def dependency_context_and_body
|
24
|
-
@dependency_context_and_body ||= build_dependency_context_and_body
|
25
|
-
end
|
26
|
-
|
27
21
|
private
|
28
22
|
|
29
|
-
#
|
23
|
+
# do not minify plugin assets
|
24
|
+
def minify(hash)
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
|
28
|
+
# Note: logical path must be the module
|
30
29
|
def plugin_module
|
31
30
|
project = environment.project
|
32
31
|
parts = logical_path.split('/')
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'sprockets'
|
2
|
+
|
3
|
+
module BPM
|
4
|
+
|
5
|
+
# A processor that will invoke a JavaScript-based plugin provided by a
|
6
|
+
# package in the system. The passed method name will be invoked on the
|
7
|
+
# plugin.
|
8
|
+
class PluginProcessor < Tilt::Template
|
9
|
+
|
10
|
+
def self.with_plugin(plugin_opts, method_name)
|
11
|
+
ret = Class.new(self)
|
12
|
+
ret.instance_eval do
|
13
|
+
@method_name = method_name
|
14
|
+
@plugin_opts = plugin_opts
|
15
|
+
end
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.method_name
|
20
|
+
@method_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.plugin_name
|
24
|
+
@plugin_opts["main"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def prepare
|
28
|
+
end
|
29
|
+
|
30
|
+
def evaluate(context, locals, &block)
|
31
|
+
ctx = context.environment.plugin_context_for self.class.plugin_name
|
32
|
+
project = context.environment.project
|
33
|
+
pkg, module_id = project.package_and_module_from_path file
|
34
|
+
|
35
|
+
filepath = file.to_s
|
36
|
+
out = ''
|
37
|
+
|
38
|
+
V8::C::Locker() do
|
39
|
+
ctx["DATA"] = data
|
40
|
+
ctx["CTX"] = BPM::PluginContext.new(pkg, module_id)
|
41
|
+
out = ctx.eval("BPM_PLUGIN.#{self.class.method_name}(DATA, CTX, '#{filepath}');")
|
42
|
+
end
|
43
|
+
|
44
|
+
out
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
data/lib/bpm/pipeline.rb
CHANGED
@@ -5,8 +5,15 @@ module BPM
|
|
5
5
|
|
6
6
|
class Console
|
7
7
|
def log(str)
|
8
|
-
|
8
|
+
shell.say str
|
9
9
|
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def shell
|
14
|
+
@shell ||= Thor::Base.shell.new
|
15
|
+
end
|
16
|
+
|
10
17
|
end
|
11
18
|
|
12
19
|
# A BPM package-aware asset pipeline. Asset lookup respects package.json
|
@@ -17,6 +24,7 @@ module BPM
|
|
17
24
|
|
18
25
|
attr_reader :project
|
19
26
|
attr_reader :mode
|
27
|
+
attr_reader :package_pipelines
|
20
28
|
|
21
29
|
# Pass in the project you want the pipeline to manage.
|
22
30
|
def initialize(project, mode = :debug, include_preview = false)
|
@@ -24,34 +32,84 @@ module BPM
|
|
24
32
|
@project = project
|
25
33
|
@mode = mode
|
26
34
|
@plugin_contexts = {}
|
35
|
+
|
36
|
+
# Create a pipeline for each package. Will be used for searching.
|
37
|
+
@package_pipelines = project.local_deps.map do |pkg|
|
38
|
+
BPM::PackagePipeline.new self, pkg
|
39
|
+
end
|
40
|
+
@package_pipelines << BPM::PackagePipeline.new(self, project)
|
27
41
|
|
28
42
|
project_path = project.root_path
|
29
43
|
|
30
44
|
super project_path
|
31
45
|
|
32
|
-
#
|
46
|
+
# Unregister built-in processors. We want most things served by the
|
47
|
+
# pipeline directly to just pass through. (package pipelines do the
|
48
|
+
# processing)
|
33
49
|
%w(text/css application/javascript).each do |kind|
|
34
50
|
unregister_processor kind, Sprockets::DirectiveProcessor
|
35
|
-
register_processor kind, BPM::DirectiveProcessor
|
36
51
|
end
|
37
|
-
|
38
|
-
register_postprocessor 'application/javascript', BPM::TransportProcessor
|
39
|
-
#register_postprocessor 'application/javascript', BPM::SourceURLProcessor
|
40
|
-
|
41
|
-
# This gunks things up. I'm not a fan - PDW
|
42
52
|
unregister_postprocessor 'application/javascript', Sprockets::SafetyColons
|
43
53
|
|
44
54
|
# configure search paths
|
45
|
-
append_path File.join project_path, '.bpm', 'packages'
|
46
|
-
append_path File.dirname project_path
|
47
55
|
append_path project.assets_root
|
48
56
|
append_path project.preview_root if include_preview
|
49
57
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
58
|
+
|
59
|
+
# determines the proper pipeline for the path
|
60
|
+
def pipeline_for(path)
|
61
|
+
return nil if magic_paths.include?(path)
|
62
|
+
package_pipelines.find do |cur_pipeline|
|
63
|
+
path.to_s[cur_pipeline.package.root_path.to_s]
|
64
|
+
end
|
53
65
|
end
|
54
66
|
|
67
|
+
def attributes_for(path)
|
68
|
+
if path.to_s[File.join(project.root_path, '.bpm')] || !Pathname.new(path).absolute?
|
69
|
+
return super(path)
|
70
|
+
end
|
71
|
+
|
72
|
+
pipeline = pipeline_for path
|
73
|
+
pipeline ? pipeline.attributes_for(path) : super(path)
|
74
|
+
end
|
75
|
+
|
76
|
+
def resolve(logical_path, options={}, &block)
|
77
|
+
|
78
|
+
magic_path = magic_paths.find do |path|
|
79
|
+
path =~ /#{Regexp.escape logical_path.to_s}(\..+)?$/
|
80
|
+
end
|
81
|
+
|
82
|
+
package_name = logical_path.to_s.sub(/#{Regexp.escape File::SEPARATOR}.+/,'')
|
83
|
+
pipeline = package_pipelines.find do |cur_pipeline|
|
84
|
+
cur_pipeline.package_name == package_name
|
85
|
+
end
|
86
|
+
|
87
|
+
if pipeline && magic_path.nil?
|
88
|
+
logical_path = logical_path.to_s[package_name.size+1..-1]
|
89
|
+
pipeline.resolve Pathname.new(logical_path), options, &block
|
90
|
+
else
|
91
|
+
super logical_path, options, &block
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# Detect whenever we are asked to build some of the magic files and swap
|
97
|
+
# in a custom asset type that can generate the contents.
|
98
|
+
def build_asset(logical_path, pathname, options)
|
99
|
+
if magic_paths.include? pathname.to_s
|
100
|
+
BPM::GeneratedAsset.new(self, logical_path, pathname, options)
|
101
|
+
elsif pipeline = pipeline_for(pathname)
|
102
|
+
pipeline.build_asset logical_path, pathname, options
|
103
|
+
else
|
104
|
+
super logical_path, pathname, options
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Paths to files that should be built.
|
109
|
+
def magic_paths
|
110
|
+
@magic_paths ||= build_magic_paths
|
111
|
+
end
|
112
|
+
|
55
113
|
# Returns an array of all the buildable assets in the current directory.
|
56
114
|
# These are the assets that will be built when you compile the project.
|
57
115
|
def buildable_assets
|
@@ -85,29 +143,34 @@ module BPM
|
|
85
143
|
|
86
144
|
ret.sort.map { |x| find_asset x }.compact
|
87
145
|
end
|
146
|
+
|
147
|
+
def plugin_context_for(logical_path)
|
148
|
+
@plugin_contexts[logical_path] ||= build_plugin_context(logical_path)
|
149
|
+
end
|
88
150
|
|
89
|
-
|
90
|
-
|
91
|
-
def
|
151
|
+
protected
|
152
|
+
|
153
|
+
def build_magic_paths
|
92
154
|
magic_paths = project.buildable_asset_filenames(mode).map do |filename|
|
93
155
|
project.assets_root filename
|
94
156
|
end
|
95
|
-
|
157
|
+
|
96
158
|
magic_paths += project.buildable_asset_filenames(mode).map do |filename|
|
97
159
|
project.preview_root filename
|
98
160
|
end
|
99
|
-
|
100
|
-
if magic_paths.include? pathname.to_s
|
101
|
-
BPM::GeneratedAsset.new(self, logical_path, pathname, options)
|
102
|
-
else
|
103
|
-
super logical_path, pathname, options
|
104
|
-
end
|
105
161
|
end
|
106
|
-
|
162
|
+
|
163
|
+
# Pass along to package pipelines
|
164
|
+
def expire_index!
|
165
|
+
super
|
166
|
+
@magic_paths = nil
|
167
|
+
package_pipelines.each { |pipeline| pipeline.expire_index! }
|
168
|
+
end
|
169
|
+
|
107
170
|
private
|
108
171
|
|
109
|
-
def build_plugin_context(
|
110
|
-
asset = BPM::PluginAsset.new(self,
|
172
|
+
def build_plugin_context(logical_path)
|
173
|
+
asset = BPM::PluginAsset.new(self, logical_path)
|
111
174
|
plugin_text = asset.to_s
|
112
175
|
|
113
176
|
ctx = nil
|