barista 0.6.1 → 0.7.0.pre2
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.
- data/DESCRIPTION +7 -0
- data/Gemfile +6 -4
- data/Gemfile.lock +23 -12
- data/Rakefile +3 -11
- data/barista.gemspec +53 -50
- data/lib/barista.rb +129 -106
- data/lib/barista/compiler.rb +131 -33
- data/lib/barista/extensions.rb +92 -0
- data/lib/barista/filter.rb +13 -3
- data/lib/barista/framework.rb +48 -13
- data/lib/barista/haml_filter.rb +42 -0
- data/lib/barista/helpers.rb +61 -0
- data/lib/barista/integration.rb +28 -0
- data/lib/barista/integration/rails2.rb +16 -0
- data/lib/barista/integration/rails3.rb +26 -0
- data/lib/barista/integration/sinatra.rb +23 -0
- data/lib/barista/server.rb +110 -0
- data/lib/barista/version.rb +3 -3
- data/lib/generators/barista/install/templates/initializer.rb +0 -13
- metadata +61 -65
- data/.gitignore +0 -21
- data/app/controllers/barista_controller.rb +0 -25
- data/config/routes.rb +0 -3
- data/lib/barista/compilers.rb +0 -9
- data/lib/barista/compilers/base.rb +0 -39
- data/lib/barista/compilers/native.rb +0 -55
- data/lib/barista/compilers/node.rb +0 -59
- data/lib/coffee-script/coffee-script-0.9.4.js +0 -469
data/lib/barista/compiler.rb
CHANGED
@@ -3,53 +3,151 @@ require 'digest/sha2'
|
|
3
3
|
module Barista
|
4
4
|
class Compiler
|
5
5
|
|
6
|
+
# TODO: Deprecate.
|
6
7
|
class << self
|
7
|
-
attr_accessor :bin_path, :js_path
|
8
|
-
end
|
9
|
-
self.bin_path ||= "coffee"
|
10
|
-
self.js_path ||= File.expand_path('../coffee-script/coffee-script-0.9.4.js', File.dirname(__FILE__))
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
def js_path
|
10
|
+
CoffeeScript::Source.path
|
11
|
+
end
|
12
|
+
|
13
|
+
def js_path=(value)
|
14
|
+
CoffeeScript::Source.path = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def bin_path
|
18
|
+
CoffeeScript::Engines::Node.binary
|
19
|
+
end
|
20
|
+
|
21
|
+
def bin_path=(path)
|
22
|
+
CoffeeScript::Engines::Node.binary = path
|
23
|
+
end
|
24
|
+
|
25
|
+
def available?
|
26
|
+
CoffeeScript.engine.present? && CoffeeScript.engine.supported?
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_availability!(silence = false)
|
30
|
+
available = available?
|
31
|
+
if !available && Barista.exception_on_error? && !silence
|
32
|
+
raise CompilerUnavailableError, "No method of compiling cofffescript is currently available. Please install therubyracer or node."
|
33
|
+
end
|
34
|
+
available
|
35
|
+
end
|
36
|
+
|
37
|
+
def compile(content, options = {})
|
38
|
+
self.new(content, options).to_js
|
39
|
+
end
|
40
|
+
|
41
|
+
def autocompile_file(file, force = false, silence_error = false)
|
42
|
+
# Ensure we have a coffeescript compiler available.
|
43
|
+
if !check_availability!(silence_error)
|
44
|
+
Barista.debug "The coffeescript compiler at '#{Compiler.bin_path}' is currently unavailable."
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
# Expand the path from the framework.
|
48
|
+
origin_path, framework = Framework.full_path_for(file)
|
49
|
+
return if origin_path.nil?
|
50
|
+
destination_path = framework.output_path_for(file)
|
51
|
+
return File.read(destination_path) unless dirty?(origin_path, destination_path) || force
|
52
|
+
Barista.debug "Compiling #{file} from framework '#{framework.name}'"
|
53
|
+
compiler = new(origin_path, :silence_error => silence_error, :output_path => destination_path)
|
54
|
+
content = compiler.to_js
|
55
|
+
compiler.save
|
56
|
+
content
|
57
|
+
end
|
58
|
+
|
59
|
+
def compile_as(file, type)
|
60
|
+
origin_path, framework = Framework.full_path_for(file)
|
61
|
+
return if origin_path.nil?
|
62
|
+
if type == :coffeescript
|
63
|
+
return File.read(origin_path), File.mtime(origin_path)
|
64
|
+
else
|
65
|
+
return autocompile_file(file), Time.now
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def dirty?(from, to)
|
70
|
+
File.exist?(from) && (!File.exist?(to) || File.mtime(to) < File.mtime(from))
|
71
|
+
end
|
72
|
+
|
73
|
+
def setup_default_error_logger
|
74
|
+
Barista.on_compilation_error do |where, message|
|
75
|
+
if Barista.verbose?
|
76
|
+
Barista.debug "There was an error compiling coffeescript from #{where}:"
|
77
|
+
message.each_line { |line| Barista.debug line.rstrip }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
14
82
|
end
|
15
83
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
self.compiler_klass = nil
|
84
|
+
def initialize(context, options = {})
|
85
|
+
@compiled = false
|
86
|
+
@options = options
|
87
|
+
setup_compiler_context context
|
21
88
|
end
|
22
|
-
|
23
|
-
def
|
24
|
-
|
89
|
+
|
90
|
+
def compile!
|
91
|
+
location = @options.fetch(:origin, 'inline')
|
92
|
+
@compiled_content = compile(@context, location)
|
93
|
+
@compiled_content = preamble(location) + @compiled_content if Barista.add_preamble?
|
94
|
+
@compiled = true
|
25
95
|
end
|
26
|
-
|
27
|
-
def
|
28
|
-
|
96
|
+
|
97
|
+
def to_js
|
98
|
+
compile! unless defined?(@compiled) && @compiled
|
99
|
+
@compiled_content
|
29
100
|
end
|
30
101
|
|
31
|
-
def
|
32
|
-
|
102
|
+
def compile(script, where = 'inline')
|
103
|
+
Barista.invoke_hook :before_compilation, where
|
104
|
+
out = CoffeeScript.compile script, :bare => Barista.bare?
|
105
|
+
Barista.invoke_hook :compiled, where
|
106
|
+
out
|
107
|
+
rescue CoffeeScript::Error => e
|
108
|
+
Barista.invoke_hook :compilation_failed, where, e.message
|
109
|
+
if Barista.exception_on_error? && !@options[:silence]
|
110
|
+
raise CompilationError, "CoffeeScript encountered an error compiling #{where}: #{e.message}"
|
111
|
+
end
|
112
|
+
compilation_error_for where, e.message
|
33
113
|
end
|
34
114
|
|
35
|
-
def
|
36
|
-
|
115
|
+
def save(path = @options[:output_path])
|
116
|
+
return false unless path.is_a?(String) && !to_js.nil?
|
117
|
+
FileUtils.mkdir_p File.dirname(path)
|
118
|
+
File.open(path, "w+") { |f| f.write @compiled_content }
|
119
|
+
true
|
120
|
+
rescue Errno::EACCES
|
121
|
+
false
|
37
122
|
end
|
38
123
|
|
39
|
-
|
40
|
-
available?.tap do |available|
|
41
|
-
if !available && Barista.exception_on_error? && !silence
|
42
|
-
raise CompilerUnavailableError, "A coffee script compiler is currently unavailable. Please install therubyracer or coffee-script via node"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
124
|
+
protected
|
46
125
|
|
47
|
-
def
|
48
|
-
|
126
|
+
def preamble(location)
|
127
|
+
"/* DO NOT MODIFY. This file was compiled #{Time.now.httpdate} from\n * #{location.strip}\n */\n\n"
|
49
128
|
end
|
50
|
-
|
51
|
-
def
|
52
|
-
|
129
|
+
|
130
|
+
def compilation_error_for(location, message)
|
131
|
+
details = "Compilation of '#{location}' failed:\n#{message}"
|
132
|
+
Barista.verbose? ? "alert(#{details.to_json});" : nil
|
53
133
|
end
|
134
|
+
|
135
|
+
def setup_compiler_context(context)
|
136
|
+
if context.respond_to?(:read)
|
137
|
+
@context = context.read
|
138
|
+
@type = :string
|
139
|
+
default_path = context.respond_to?(:path) ? context.path : 'inline'
|
140
|
+
@options[:origin] ||= default_path
|
141
|
+
elsif !context.include?("\n") && File.exist?(context)
|
142
|
+
@context = File.read(context)
|
143
|
+
@type = :file
|
144
|
+
@options[:origin] ||= context
|
145
|
+
else
|
146
|
+
@context = context.to_s
|
147
|
+
@type = :string
|
148
|
+
@options[:origin] ||= 'inline'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
54
152
|
end
|
55
153
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Barista
|
2
|
+
module Extensions
|
3
|
+
|
4
|
+
def self.included(parent)
|
5
|
+
parent.class_eval do
|
6
|
+
extend ClassMethods
|
7
|
+
include InstanceMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
def has_boolean_options(*names)
|
14
|
+
source = []
|
15
|
+
names.each do |name|
|
16
|
+
source << <<-EOM
|
17
|
+
|
18
|
+
def #{name}!
|
19
|
+
@#{name} = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def #{name}?
|
23
|
+
defined?(@#{name}) ? @#{name} : default_for_#{name}
|
24
|
+
end
|
25
|
+
|
26
|
+
def #{name}=(value)
|
27
|
+
@#{name} = !!value
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_for_#{name}
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
EOM
|
35
|
+
end
|
36
|
+
class_eval source.join("\n"), __FILE__, __LINE__
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_hook_method(options)
|
40
|
+
source = []
|
41
|
+
options.each_pair do |name, event|
|
42
|
+
source << <<-EOM
|
43
|
+
def #{name}(&blk)
|
44
|
+
on_hook #{event.to_sym.inspect}, &blk
|
45
|
+
end
|
46
|
+
EOM
|
47
|
+
end
|
48
|
+
class_eval source.join("\n"), __FILE__, __LINE__
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_delegate_methods(delegate, *args)
|
52
|
+
source = []
|
53
|
+
args.each do |method|
|
54
|
+
source << <<-EOM
|
55
|
+
|
56
|
+
def #{method}(*args, &blk)
|
57
|
+
#{delegate}.send(:#{method}, *args, &blk)
|
58
|
+
end
|
59
|
+
|
60
|
+
EOM
|
61
|
+
end
|
62
|
+
class_eval source.join("\n"), __FILE__, __LINE__
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_deprecated_methods(*args)
|
66
|
+
source = []
|
67
|
+
args.each do |method|
|
68
|
+
source << <<-EOM
|
69
|
+
|
70
|
+
def #{method}(*args, &blk)
|
71
|
+
Barista.deprecate!(self, :#{method})
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
EOM
|
76
|
+
end
|
77
|
+
class_eval source.join("\n"), __FILE__, __LINE__
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
module InstanceMethods
|
83
|
+
|
84
|
+
def deprecate!(object, method, other = nil)
|
85
|
+
klass_prefix = (object.is_a?(Class) || object.is_a?(Module)) ? "#{object.name}." : "#{object.class.name}#"
|
86
|
+
warn "#{klass_prefix}#{method} is deprecated and will be removed in 1.0. #{other}".strip
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
data/lib/barista/filter.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
module Barista
|
2
2
|
class Filter
|
3
3
|
|
4
|
-
def
|
5
|
-
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
dup._call(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
def _call(env)
|
13
|
+
Barista.debug 'Compiling all scripts for barista'
|
6
14
|
Barista.compile_all!
|
15
|
+
# Now, actually call the app.
|
16
|
+
@app.call env
|
7
17
|
end
|
8
18
|
|
9
19
|
end
|
10
|
-
end
|
20
|
+
end
|
data/lib/barista/framework.rb
CHANGED
@@ -10,9 +10,9 @@ module Barista
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.all(include_default = false)
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
(@all ||= []).dup.tap do |all|
|
14
|
+
all.unshift default_framework if include_default
|
15
|
+
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.exposed_coffeescripts
|
@@ -20,6 +20,10 @@ module Barista
|
|
20
20
|
collection + fw.exposed_coffeescripts
|
21
21
|
end.uniq.sort_by { |f| f.length }
|
22
22
|
end
|
23
|
+
|
24
|
+
def self.coffeescript_glob_paths
|
25
|
+
all(true).map { |fw| fw.coffeescript_glob_path }
|
26
|
+
end
|
23
27
|
|
24
28
|
def self.full_path_for(script)
|
25
29
|
script = script.to_s.gsub(/\.js$/, '.coffee').gsub(/^\/+/, '')
|
@@ -31,7 +35,7 @@ module Barista
|
|
31
35
|
end
|
32
36
|
|
33
37
|
def self.register(name, root)
|
34
|
-
(@all ||= []) << self.new(name, root)
|
38
|
+
(@all ||= []) << self.new(:name => name, :root => root)
|
35
39
|
end
|
36
40
|
|
37
41
|
def self.[](name)
|
@@ -41,19 +45,34 @@ module Barista
|
|
41
45
|
|
42
46
|
attr_reader :name, :framework_root, :output_prefix
|
43
47
|
|
44
|
-
def initialize(
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
def initialize(options, root = nil, output_prefix = nil)
|
49
|
+
unless options.is_a?(Hash)
|
50
|
+
Barista.deprecate! self, "initialize(name, root = nil, output_prefix = nil)", "Please use the option syntax instead."
|
51
|
+
options = {
|
52
|
+
:name => options,
|
53
|
+
:root => root,
|
54
|
+
:output_prefix => output_prefix
|
55
|
+
}
|
56
|
+
end
|
57
|
+
# actually setup the framework.
|
58
|
+
check_options! options, :name, :root
|
59
|
+
@name = options[:name].to_s
|
60
|
+
@output_prefix = options[:output_prefix]
|
61
|
+
@framework_root = File.expand_path(options[:root].to_s)
|
62
|
+
@output_root = options[:output_root] && Pathname(options[:output_root])
|
48
63
|
end
|
49
64
|
|
50
65
|
def coffeescripts
|
51
|
-
Dir[
|
66
|
+
Dir[coffeescript_glob_path]
|
67
|
+
end
|
68
|
+
|
69
|
+
def coffeescript_glob_path
|
70
|
+
@coffeescript_glob_path ||= File.join(@framework_root, "**", "*.coffee")
|
52
71
|
end
|
53
72
|
|
54
73
|
def short_name(script)
|
55
74
|
short_name = remove_prefix script, @framework_root
|
56
|
-
File.join
|
75
|
+
File.join(*[@output_prefix, short_name].compact)
|
57
76
|
end
|
58
77
|
|
59
78
|
def exposed_coffeescripts
|
@@ -61,8 +80,8 @@ module Barista
|
|
61
80
|
end
|
62
81
|
|
63
82
|
def output_prefix=(value)
|
64
|
-
value = value.to_s.gsub
|
65
|
-
@output_prefix = value.
|
83
|
+
value = value.to_s.gsub(/(^\/|\/$)/, '').strip
|
84
|
+
@output_prefix = value.empty? ? nil : value
|
66
85
|
end
|
67
86
|
|
68
87
|
def full_path_for(name)
|
@@ -70,10 +89,26 @@ module Barista
|
|
70
89
|
File.exist?(full_path) ? full_path : nil
|
71
90
|
end
|
72
91
|
|
92
|
+
def output_root
|
93
|
+
@output_root || Barista.output_root
|
94
|
+
end
|
95
|
+
|
96
|
+
def output_path_for(file, format = 'js')
|
97
|
+
# Strip the leading slashes
|
98
|
+
file = file.to_s.gsub(/^\/+/, '')
|
99
|
+
output_root.join(file).to_s.gsub(/\.[^\.]+$/, ".#{format}")
|
100
|
+
end
|
101
|
+
|
73
102
|
protected
|
74
103
|
|
75
104
|
def remove_prefix(path, prefix)
|
76
|
-
path.to_s.gsub
|
105
|
+
path.to_s.gsub(/^#{Regexp.escape(prefix.to_s)}\/?/, '')
|
106
|
+
end
|
107
|
+
|
108
|
+
def check_options!(options, *keys)
|
109
|
+
keys.each do |option|
|
110
|
+
raise ArgumentError, "#{option.inspect} is a required options." if options[option].nil?
|
111
|
+
end
|
77
112
|
end
|
78
113
|
|
79
114
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Barista
|
2
|
+
module HamlFilter
|
3
|
+
module CoffeeScript
|
4
|
+
|
5
|
+
def render_with_options(text, options)
|
6
|
+
type = render_type
|
7
|
+
case type
|
8
|
+
when :coffeescript
|
9
|
+
content_type = 'text/coffeescript'
|
10
|
+
cdata_wrapper = '#%s'
|
11
|
+
inner = text
|
12
|
+
when :javascript
|
13
|
+
content_type = 'text/javascript'
|
14
|
+
cdata_wrapper = '//%s'
|
15
|
+
inner = Barista::Compiler.compile(text)
|
16
|
+
end
|
17
|
+
output = []
|
18
|
+
output << "<script type=#{options[:attr_wrapper]}#{content_type(type)}#{options[:attr_wrapper]}>"
|
19
|
+
output << " #{cdata_wrapper % '<![CDATA['}"
|
20
|
+
output << " #{inner}".rstrip.gsub("\n", "\n ")
|
21
|
+
output << " #{cdata_wrapper % ']]>'}"
|
22
|
+
output << "</script>"
|
23
|
+
output.join("\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_type
|
27
|
+
Barista.embedded_interpreter? ? :coffeescript : :javascript
|
28
|
+
end
|
29
|
+
|
30
|
+
def content_type(render_type)
|
31
|
+
Barista::Server::CONTENT_TYPE_MAPPING[render_type]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.setup
|
37
|
+
if defined?(Haml)
|
38
|
+
CoffeeScript.module_eval { include Haml::Filters::Base }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|