Skip to content
This repository has been archived by the owner on Jun 13, 2022. It is now read-only.

Commit

Permalink
bpm now passes a context object with build settings and a minify opti…
Browse files Browse the repository at this point in the history
…on to plugins - this will allow spade to support string loading.
  • Loading branch information
Charles Jolley committed Jul 21, 2011
1 parent 6abc8db commit 36617b0
Show file tree
Hide file tree
Showing 21 changed files with 236 additions and 53 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,4 +1,9 @@

* bpm now passes a context object with build settings and a minify option
to plugins - this will allow spade to support string loading.

# 1.0.0.beta.5

* bpm list now shows local dependencies by default. Use bpm list --remote
to get remote.
* better compatibility with npm - "summary" field is optional and "url" is
Expand Down
1 change: 0 additions & 1 deletion TODO.md
Expand Up @@ -5,7 +5,6 @@
* Multiple format support. Format processors supplied by dependencies
should
be used to resolve formats.
* minify then transport -> this will allow for string loading.
* HTML manifest support [in general we need a way for packages to generate
new assets]
* cache-friendly URLs
Expand Down
1 change: 1 addition & 0 deletions lib/bpm.rb
Expand Up @@ -19,6 +19,7 @@ module BPM
autoload :TransportProcessor, 'bpm/pipeline/transport_processor'
autoload :SourceURLProcessor, 'bpm/pipeline/source_url_processor'
autoload :PluginAsset, 'bpm/pipeline/plugin_asset'
autoload :PluginContext, 'bpm/pipeline/plugin_context'
end

# The BPM constants need to be defined first
Expand Down
1 change: 1 addition & 0 deletions lib/bpm/pipeline.rb
Expand Up @@ -20,6 +20,7 @@ class Pipeline < Sprockets::Environment

# Pass in the project you want the pipeline to manage.
def initialize(project, mode = :debug, include_preview = false)

@project = project
@mode = mode
@plugin_contexts = {}
Expand Down
105 changes: 64 additions & 41 deletions lib/bpm/pipeline/generated_asset.rb
Expand Up @@ -8,6 +8,62 @@ class GeneratedAsset < Sprockets::BundledAsset
'text/css' => ['css', 'pipeline_css'],
'application/javascript' => ['lib', 'pipeline_libs']
}

def self.generating_asset
@generating_asset && @generating_asset.last
end

def self.push_generating_asset(asset)
@generating_asset ||= []
@generating_asset.push asset
end

def self.pop_generating_asset
@generating_asset && @generating_asset.pop
end

def build_settings
ret = environment.project.build_settings[asset_name]
(ret && ret['bpm:settings']) || {}
end

def minify_body(data)

project = environment.project
minifier_name = project.minifier_name asset_name
minifier_name = minifier_name.keys.first if minifier_name

if minifier_name && content_type == 'application/javascript'
pkg = project.package_from_name minifier_name
if pkg.nil?
raise MinifierNotFoundError.new(minifier_name)
end

minifier_plugin_name = pkg.bpm_minifier
if minifier_plugin_name.nil?
raise MinifierNotFoundError.new(minifier_name)
end

plugin_ctx = environment.plugin_context_for minifier_plugin_name

# slice out the header at the top - we don't want the minifier to
# touch it.
header = data.match /^(\/\* ====.+====\*\/)$/m
if header
header = header[0] + "\n"
data = data[header.size..-1]
end

V8::C::Locker() do
plugin_ctx["CTX"] = BPM::PluginContext.new(pkg)
plugin_ctx["DATA"] = data
data = plugin_ctx.eval("BPM_PLUGIN.minify(DATA, CTX)")
end

data = header+data if header
end
data
end

protected

Expand All @@ -18,53 +74,20 @@ def dependency_context_and_body
private

def build_source
minify super
self.class.push_generating_asset self
ret = minify super
self.class.pop_generating_asset
ret
end

def minify(hash)
return hash if environment.mode == :debug

hash = environment.cache_hash("#{pathname}:minify", id) do
project = environment.project
minifier_name = project.minifier_name asset_name
minifier_name = minifier_name.keys.first if minifier_name

if minifier_name && content_type == 'application/javascript'
pkg = project.package_from_name minifier_name
if pkg.nil?
raise MinifierNotFoundError.new(minifier_name)
end

minifier_plugin_name = pkg.bpm_minifier
if minifier_plugin_name.nil?
raise MinifierNotFoundError.new(minifier_name)
end

plugin_ctx = environment.plugin_context_for minifier_plugin_name

# slice out the header at the top - we don't want the minifier to
# touch it.
data = hash['source']
header = data.match /^(\/\* ====.+====\*\/)$/m
if header
header = header[0] + "\n"
data = data[header.size..-1]
end

V8::C::Locker() do
plugin_ctx["PACKAGE_INFO"] = pkg.as_json
plugin_ctx["DATA"] = data
data = plugin_ctx.eval("BPM_PLUGIN.minify(DATA, PACKAGE_INFO)")
end

data = header+data if header

{ 'length' => Rack::Utils.bytesize(data),
'digest' => environment.digest.update(data).hexdigest,
'source' => data }
else
hash
end
data = minify_body hash['source']
{ 'length' => Rack::Utils.bytesize(data),
'digest' => environment.digest.update(data).hexdigest,
'source' => data }
end

hash['length'] = Integer(hash['length']) if hash['length'].is_a?(String)
Expand Down
24 changes: 24 additions & 0 deletions lib/bpm/pipeline/plugin_context.rb
@@ -0,0 +1,24 @@
module BPM

class PluginContext

attr_reader :moduleId
attr_reader :package

def initialize(pkg, module_id=nil)
@generating_asset = BPM::GeneratedAsset.generating_asset
@package = pkg.as_json
@moduleId = module_id
end

def minify(body)
@generating_asset ? @generating_asset.minify_body(body) : body
end

def settings
@generating_asset ? @generating_asset.build_settings : {}
end

end

end
6 changes: 3 additions & 3 deletions lib/bpm/pipeline/transport_processor.rb
Expand Up @@ -26,9 +26,9 @@ def evaluate(context, locals)
out = ''

V8::C::Locker() do
plugin_ctx["PACKAGE_INFO"] = pkg.as_json
plugin_ctx["DATA"] = data
out = plugin_ctx.eval("BPM_PLUGIN.compileTransport(DATA, PACKAGE_INFO, '#{module_id}', '#{filepath}');")
plugin_ctx["DATA"] = data
plugin_ctx["CTX"] = BPM::PluginContext.new(pkg, module_id)
out = plugin_ctx.eval("BPM_PLUGIN.compileTransport(DATA, CTX, '#{filepath}');")
end

out + "\n\n"
Expand Down
3 changes: 3 additions & 0 deletions lib/bpm/project.rb
Expand Up @@ -745,6 +745,9 @@ def merge_build_opts(ret, dep_name, target_name, opts, mode)
end
end

bpm_settings = ret[target_name]['bpm:settings'] ||= {}
ret[target_name]['bpm:settings'] = soft_merge(bpm_settings, opts)

end

def project_settings_excludes(dep_name, target_name)
Expand Down
6 changes: 4 additions & 2 deletions spec/fixtures/projects/minitest/minitest.json
Expand Up @@ -14,12 +14,14 @@
"bpm:build": {

"bpm_libs.js": {
"minifier": { "uglyduck": ">= 0" }
"minifier": { "uglyduck": ">= 0" },
"uglyduck:where": "boston"
},

"minitest/bpm_libs.js": {
"directories": ["lib"],
"minifier": { "uglyduck": ">= 0" }
"minifier": { "uglyduck": ">= 0" },
"uglyduck:where": "sanfran"
}
}

Expand Down
@@ -1,6 +1,7 @@
/*globals BPM_PLUGIN UGLYDUCK */

BPM_PLUGIN.minify = function(body, pkg, moduleId, pathname) {
BPM_PLUGIN.minify = function(body, context, pathname) {
var whatIsUglyDuck = 'undefined' === typeof UGLYDUCK ? '(main not loaded)' : UGLYDUCK;
return "//MINIFIED START\nUGLY DUCK "+UGLYDUCK+"\n"+body+"\n//MINIFIED END\n";
var whereIsUglyDuck = context.settings['uglyduck:where'] || '(build settings not found)'
return "//MINIFIED START\nUGLY DUCK "+whatIsUglyDuck+whereIsUglyDuck+"\n"+body+"\n//MINIFIED END\n";
};
3 changes: 3 additions & 0 deletions spec/fixtures/projects/minitrans/lib/main.js
@@ -0,0 +1,3 @@
//TRANSPORT
transporter();
//TRANSPORT
25 changes: 25 additions & 0 deletions spec/fixtures/projects/minitrans/minitrans.json
@@ -0,0 +1,25 @@
{
"name": "minitrans",
"version": "2.0.0",
"bpm": "0.1.0",

"description": "DESCRIPTION HERE",
"author": "YOUR NAME HERE",
"homepage": "URL",

"directories": {
"lib": "lib"
},

"dependencies": {
"transport": "0.5.0"
},

"bpm:build": {
"bpm_libs.js": {
"directories": ["lib"],
"minifier": "uglyduck"
}
}

}
@@ -0,0 +1 @@
// TRANSPORT DEMO
21 changes: 21 additions & 0 deletions spec/fixtures/projects/minitrans/packages/transport/package.json
@@ -0,0 +1,21 @@
{
"name": "transport",
"version": "0.5.0",
"bpm": "0.1.0",

"description": "DESCRIPTION HERE",
"author": "YOUR NAME HERE",
"homepage": "URL",

"directories": {
"lib": "./lib",
"test": "./tests"
},

"dependencies": {

},

"bpm:transport": "transport/transports/wrapper"

}
@@ -0,0 +1,6 @@

BPM_PLUGIN.compileTransport = function(body, context, filename) {
body = JSON.stringify("(function() { "+context.minify(body)+" })()\n");
return "define_transport("+body+"), '"+context['package'].name+"', '"+context.moduleId+"', '"+filename+"');";
};

@@ -0,0 +1,3 @@
//UGLY DUCK
UGLYDUCK = "IS UGLY";

@@ -0,0 +1,6 @@
/*globals BPM_PLUGIN UGLYDUCK */

BPM_PLUGIN.minify = function(body, pkg, moduleId, pathname) {
var whatIsUglyDuck = 'undefined' === typeof UGLYDUCK ? '(main not loaded)' : UGLYDUCK;
return "//MINIFIED START\nUGLY DUCK "+UGLYDUCK+"\n"+body+"\n//MINIFIED END\n";
};
21 changes: 21 additions & 0 deletions spec/fixtures/projects/minitrans/packages/uglyduck/package.json
@@ -0,0 +1,21 @@
{
"name": "uglyduck",
"version": "1.0.0",
"bpm": "0.1.0",

"description": "DESCRIPTION HERE",
"author": "YOUR NAME HERE",
"homepage": "URL",

"directories": {
"lib": "lib",
"minifier": "minifier",
"test": "tests"
},

"dependencies": {
},

"bpm:minifier": "uglyduck/minifier/main"

}
@@ -1,5 +1,5 @@

BPM_PLUGIN.compileTransport = function(body, pkg, moduleId, filename) {
return "define_transport(function() {\n"+body+"\n}), '"+pkg.name+"', '"+moduleId+"', '"+filename+"');";
BPM_PLUGIN.compileTransport = function(body, context, filename) {
return "define_transport(function() {\n"+body+"\n}), '"+context['package'].name+"', '"+context.moduleId+"', '"+filename+"');";
};

4 changes: 2 additions & 2 deletions spec/plugins/minifier_spec.rb
Expand Up @@ -29,7 +29,7 @@
This file is generated automatically by the bpm (http://www.bpmjs.org)
=========================================================================*/
//MINIFIED START
UGLY DUCK IS UGLY
UGLY DUCK IS UGLYboston
//MINIFIED END
Expand All @@ -48,7 +48,7 @@
This file is generated automatically by the bpm (http://www.bpmjs.org)
=========================================================================*/
//MINIFIED START
UGLY DUCK IS UGLY
UGLY DUCK IS UGLYsanfran
#{File.read(file_path)}
//MINIFIED END
Expand Down
38 changes: 38 additions & 0 deletions spec/plugins/transport_spec.rb
Expand Up @@ -31,5 +31,43 @@
asset = subject.find_asset 'transport/lib/main.js'
asset.to_s.should == "// TRANSPORT DEMO\n"
end

end

describe BPM::Pipeline, 'transport processor w/ minifier' do

before do
goto_home
set_host
reset_libgems bpm_dir.to_s
start_fake(FakeGemServer.new)

FileUtils.cp_r project_fixture('minitrans'), '.'
cd home('minitrans')

bpm 'rebuild'
wait
end

subject do
project = BPM::Project.new home('minitrans')
BPM::Pipeline.new project
end

it "should invoke minifier in project" do
asset = subject.find_asset 'bpm_libs.js'
exp_path = home('transporter', 'lib', 'main.js')
expected = <<EOF
(function() { //MINIFIED START
UGLY DUCK IS UGLY
//TRANSPORT
transporter();
//TRANSPORT
//MINIFIED END
})()
EOF
asset.to_s.should include(expected.to_json)
end

end

0 comments on commit 36617b0

Please sign in to comment.