Class: Compass::Compiler
- Inherits:
-
Object
show all
- Includes:
- Actions
- Defined in:
- lib/compass/compiler.rb
Instance Attribute Summary collapse
Attributes included from Actions
#logger
Instance Method Summary
collapse
-
#clean! ⇒ Object
-
#compile(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
-
#compile_if_required(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
-
#corresponding_css_file(sass_file) ⇒ Object
-
#corresponding_sourcemap_file(sass_file) ⇒ Object
-
#css_files ⇒ Object
-
#determine_cache_location ⇒ Object
-
#engine(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
A sass engine for compiling a single file.
-
#error_contents(e, sass_filename) ⇒ Object
Haml refactored this logic in 2.3, this is backwards compatibility for either one.
-
#handle_exception(sass_filename, css_filename, e) ⇒ Object
Place the syntax error into the target css file, formatted to display in the browser (in development mode) if there’s an error.
-
#initialize(working_path, from, to, options) ⇒ Compiler
constructor
A new instance of Compiler.
-
#needs_update?(css_filename, sass_filename) ⇒ Boolean
-
#new_config? ⇒ Boolean
Determines if the configuration file is newer than any css file.
-
#out_of_date? ⇒ Boolean
Returns the sass file that needs to be compiled, if any.
-
#relative_path(from_path, to_path) ⇒ Object
-
#relative_stylesheet_name(sass_file) ⇒ Object
-
#reset! ⇒ Object
-
#reset_staleness_checker! ⇒ Object
-
#run ⇒ Object
-
#sass_files(options = {}) ⇒ Object
-
#should_compile?(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Boolean
-
#show_full_exception? ⇒ Boolean
We don’t want to show the full exception in production environments.
-
#sourcemap_files ⇒ Object
-
#stylesheet_name(sass_file) ⇒ Object
-
#target_directories ⇒ Object
-
#timed(timed_thing = lambda {|res| res}) ⇒ Object
Methods included from Actions
#basename, #copy, #directory, #log_action, #process_erb, #relativize, #remove, #separate, #strip_trailing_separator, #write_file
Constructor Details
#initialize(working_path, from, to, options) ⇒ Compiler
Returns a new instance of Compiler.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/compass/compiler.rb', line 10
def initialize(working_path, from, to, options)
Compass::Deprecation.deprecated!(:compass_compiler_constructor,
"Compass::Compiler is deprecated. Use Compass::SassCompiler instead.")
self.working_path = working_path.to_s
self.from, self.to = File.expand_path(from), to
self.logger = options.delete(:logger)
sass_opts = options.delete(:sass) || {}
self.options = options
self.sass_options = options.dup
self.sass_options.delete(:quiet)
self.sass_options.update(sass_opts)
self.sass_options[:cache_location] ||= determine_cache_location
self.sass_options[:filesystem_importer] ||= Sass::Importers::Filesystem
self.sass_options[:importer] = self.importer = self.sass_options[:filesystem_importer].new(from)
self.sass_options[:compass] ||= {}
self.sass_options[:compass][:logger] = self.logger
self.sass_options[:compass][:environment] = Compass.configuration.environment
self.sass_options[:compass][:compiler_in_use] = true
reset_staleness_checker!
end
|
Instance Attribute Details
#from ⇒ Object
Returns the value of attribute from.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def from
@from
end
|
#importer ⇒ Object
Returns the value of attribute importer.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def importer
@importer
end
|
#options ⇒ Object
Returns the value of attribute options.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def options
@options
end
|
#sass_options ⇒ Object
Returns the value of attribute sass_options.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def sass_options
@sass_options
end
|
#staleness_checker ⇒ Object
Returns the value of attribute staleness_checker.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def staleness_checker
@staleness_checker
end
|
#to ⇒ Object
Returns the value of attribute to.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def to
@to
end
|
#working_path ⇒ Object
Returns the value of attribute working_path.
8
9
10
|
# File 'lib/compass/compiler.rb', line 8
def working_path
@working_path
end
|
Instance Method Details
#clean! ⇒ Object
108
109
110
111
112
113
114
|
# File 'lib/compass/compiler.rb', line 108
def clean!
remove options[:cache_location]
css_files.zip(sourcemap_files).each do |css_file, sourcemap_file|
remove css_file
remove sourcemap_file
end
end
|
#compile(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
# File 'lib/compass/compiler.rb', line 166
def compile(sass_filename, css_filename, sourcemap_filename = nil)
css_content, sourcemap = logger.red do
timed(lambda {|r| r[0]}) do
engine = engine(sass_filename, css_filename, sourcemap_filename)
if sourcemap_filename && options[:sourcemap]
engine.render_with_sourcemap(relative_path(css_filename, sourcemap_filename))
else
[engine.render, nil]
end
end
end
duration = options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : ""
write_file(css_filename, css_content, options.merge(:force => true, :extra => duration), sass_options[:unix_newlines])
Compass.configuration.run_stylesheet_saved(css_filename)
if sourcemap && sourcemap_filename
sourcemap_content = sourcemap.to_json(:css_path => css_filename,
:sourcemap_path => sourcemap_filename)
write_file(sourcemap_filename, sourcemap_content, options.merge(:force => true), sass_options[:unix_newlines])
Compass.configuration.run_sourcemap_saved(sourcemap_filename)
elsif sourcemap_filename && File.exist?(sourcemap_filename)
remove sourcemap_filename
Compass.configuration.run_sourcemap_removed(sourcemap_filename)
end
end
|
#compile_if_required(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
144
145
146
147
148
149
150
151
|
# File 'lib/compass/compiler.rb', line 144
def compile_if_required(sass_filename, css_filename, sourcemap_filename = nil)
if should_compile?(sass_filename, css_filename, sourcemap_filename)
compile sass_filename, css_filename, sourcemap_filename
else
logger.record :unchanged, basename(sass_filename) unless options[:quiet]
remove(sourcemap_filename) if sourcemap_filename && !options[:sourcemap]
end
end
|
#corresponding_css_file(sass_file) ⇒ Object
66
67
68
|
# File 'lib/compass/compiler.rb', line 66
def corresponding_css_file(sass_file)
"#{to}/#{stylesheet_name(sass_file)}.css"
end
|
#corresponding_sourcemap_file(sass_file) ⇒ Object
70
71
72
|
# File 'lib/compass/compiler.rb', line 70
def corresponding_sourcemap_file(sass_file)
"#{to}/#{stylesheet_name(sass_file)}.css.map"
end
|
#css_files ⇒ Object
58
59
60
|
# File 'lib/compass/compiler.rb', line 58
def css_files
@css_files ||= sass_files.map{|sass_file| corresponding_css_file(sass_file)}
end
|
#determine_cache_location ⇒ Object
37
38
39
|
# File 'lib/compass/compiler.rb', line 37
def determine_cache_location
Compass.configuration.cache_path || Sass::Plugin.options[:cache_location] || File.join(working_path, ".sass-cache")
end
|
#engine(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Object
A sass engine for compiling a single file.
204
205
206
207
208
209
210
211
|
# File 'lib/compass/compiler.rb', line 204
def engine(sass_filename, css_filename, sourcemap_filename = nil)
syntax = (sass_filename =~ /\.(s[ac]ss)$/) && $1.to_sym || :sass
opts = sass_options.merge(:filename => sass_filename,
:css_filename => css_filename,
:syntax => syntax,
:sourcemap_filename => sourcemap_filename)
Sass::Engine.new(open(sass_filename).read, opts)
end
|
#error_contents(e, sass_filename) ⇒ Object
Haml refactored this logic in 2.3, this is backwards compatibility for either one
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
# File 'lib/compass/compiler.rb', line 227
def error_contents(e, sass_filename)
if show_full_exception?
e.sass_template = sass_filename
Sass::SyntaxError.exception_to_css(e)
else
= Sass::SyntaxError.send(:header_string, e, 1)
<<END
/*
#{.gsub("*/", "*\\/")}
Backtrace:\n#{e.backtrace.join("\n").gsub("*/", "*\\/")}
*/
END
end
end
|
#handle_exception(sass_filename, css_filename, e) ⇒ Object
Place the syntax error into the target css file, formatted to display in the browser (in development mode) if there’s an error.
216
217
218
219
220
221
222
223
224
|
# File 'lib/compass/compiler.rb', line 216
def handle_exception(sass_filename, css_filename, e)
exception_file = basename(e.sass_filename || sass_filename)
file = basename(sass_filename)
exception_file = nil if exception_file == file
formatted_error = "(Line #{e.sass_line}#{ " of #{exception_file}" if exception_file}: #{e.message})"
logger.record :error, file, formatted_error
Compass.configuration.run_stylesheet_error(sass_filename, formatted_error)
write_file css_filename, error_contents(e, sass_filename), options.merge(:force => true), sass_options[:unix_newlines]
end
|
#needs_update?(css_filename, sass_filename) ⇒ Boolean
86
87
88
|
# File 'lib/compass/compiler.rb', line 86
def needs_update?(css_filename, sass_filename)
staleness_checker.stylesheet_needs_update?(css_filename, File.expand_path(sass_filename), importer)
end
|
#new_config? ⇒ Boolean
Determines if the configuration file is newer than any css file
91
92
93
94
95
96
97
98
99
|
# File 'lib/compass/compiler.rb', line 91
def new_config?
config_file = Compass.detect_configuration_file
return false unless config_file
config_mtime = File.mtime(config_file)
css_files.each do |css_filename|
return config_file if File.exists?(css_filename) && config_mtime > File.mtime(css_filename)
end
nil
end
|
#out_of_date? ⇒ Boolean
Returns the sass file that needs to be compiled, if any.
79
80
81
82
83
84
|
# File 'lib/compass/compiler.rb', line 79
def out_of_date?
sass_files.zip(css_files).each do |sass_filename, css_filename|
return sass_filename if needs_update?(css_filename, sass_filename)
end
false
end
|
#relative_path(from_path, to_path) ⇒ Object
191
192
193
|
# File 'lib/compass/compiler.rb', line 191
def relative_path(from_path, to_path)
Pathname.new(to_path).relative_path_from(Pathname.new(from_path).dirname).to_s
end
|
#relative_stylesheet_name(sass_file) ⇒ Object
46
47
48
|
# File 'lib/compass/compiler.rb', line 46
def relative_stylesheet_name(sass_file)
sass_file[(from.length + 1)..-1]
end
|
#reset! ⇒ Object
101
102
103
104
105
106
|
# File 'lib/compass/compiler.rb', line 101
def reset!
reset_staleness_checker!
@sass_files = nil
@css_files = nil
@sourcemap_files = nil
end
|
#reset_staleness_checker! ⇒ Object
31
32
33
34
35
|
# File 'lib/compass/compiler.rb', line 31
def reset_staleness_checker!
self.staleness_checker = nil
self.staleness_checker = Sass::Plugin::StalenessChecker.new(sass_options)
end
|
#run ⇒ Object
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/compass/compiler.rb', line 116
def run
failure_count = 0
if new_config?
remove options[:cache_location] if options[:cache_location]
options[:force] = true
end
target_directories.each {|dir| directory dir}
result = timed do
sass_files.zip(css_files, sourcemap_files).each do |sass_filename, css_filename, sourcemap_filename|
begin
compile_if_required sass_filename, css_filename, sourcemap_filename
rescue Sass::SyntaxError => e
failure_count += 1
handle_exception(sass_filename, css_filename, e)
end
end
end
if options[:time]
puts "Compilation took #{(result.__duration * 1000).round / 1000.0}s"
end
return failure_count
end
|
#sass_files(options = {}) ⇒ Object
41
42
43
44
|
# File 'lib/compass/compiler.rb', line 41
def sass_files(options = {})
exclude_partials = options.fetch(:exclude_partials, true)
@sass_files = self.options[:sass_files] || Dir.glob(separate("#{from}/**/#{'[^_]' if exclude_partials}*.s[ac]ss"))
end
|
#should_compile?(sass_filename, css_filename, sourcemap_filename = nil) ⇒ Boolean
195
196
197
198
199
200
201
|
# File 'lib/compass/compiler.rb', line 195
def should_compile?(sass_filename, css_filename, sourcemap_filename = nil)
return true if css_filename && !File.exist?(css_filename)
return true if sourcemap_filename && options[:sourcemap] && !File.exist?(sourcemap_filename)
options[:force] ||
needs_update?(css_filename, sass_filename) ||
(options[:sourcemap] && needs_update?(sourcemap_filename, sass_filename))
end
|
#show_full_exception? ⇒ Boolean
We don’t want to show the full exception in production environments.
244
245
246
|
# File 'lib/compass/compiler.rb', line 244
def show_full_exception?
Compass.configuration.environment == :development
end
|
#sourcemap_files ⇒ Object
62
63
64
|
# File 'lib/compass/compiler.rb', line 62
def sourcemap_files
@sourcemap_files ||= sass_files.map{|sass_file| corresponding_sourcemap_file(sass_file)}
end
|
#stylesheet_name(sass_file) ⇒ Object
50
51
52
53
54
55
56
|
# File 'lib/compass/compiler.rb', line 50
def stylesheet_name(sass_file)
if sass_file.index(from) == 0
sass_file[(from.length + 1)..-6].sub(/\.css$/,'')
else
raise Compass::Error, "You must compile individual stylesheets from the project directory."
end
end
|
#target_directories ⇒ Object
74
75
76
|
# File 'lib/compass/compiler.rb', line 74
def target_directories
css_files.map{|css_file| File.dirname(css_file)}.uniq.sort.sort_by{|d| d.length }
end
|
#timed(timed_thing = lambda {|res| res}) ⇒ Object
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/compass/compiler.rb', line 153
def timed(timed_thing = lambda {|res| res})
start_time = Time.now
res = yield
end_time = Time.now
has_duration = timed_thing.call(res)
has_duration.instance_variable_set("@__duration", end_time - start_time)
def has_duration.__duration
@__duration
end
res
end
|