From 9a7a6684c2ec116d28afff69df3bc24aaa6c5260 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Mon, 7 Jul 2008 11:45:39 -0700 Subject: [PATCH 01/11] get an error message, even if you can't read the file --- lib/sass/plugin.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb index 11176f2d..90fcba67 100644 --- a/lib/sass/plugin.rb +++ b/lib/sass/plugin.rb @@ -98,10 +98,14 @@ module Sass e_string << "\n\n" min = [e.sass_line - 5, 0].max - File.read(e.sass_filename).rstrip.split("\n")[ - min .. e.sass_line + 5 - ].each_with_index do |line, i| - e_string << "#{min + i + 1}: #{line}\n" + begin + File.read(e.sass_filename).rstrip.split("\n")[ + min .. e.sass_line + 5 + ].each_with_index do |line, i| + e_string << "#{min + i + 1}: #{line}\n" + end + rescue + e_string << "Couldn't read sass file: #{e.sass_filename}" end end end From 69c5a66169a0610f11bde1b941324277f6c3a354 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Thu, 19 Jun 2008 16:10:50 -0700 Subject: [PATCH 02/11] Allow Sass::Plugin.options[:template_location] to accept either a String path from where Sass templates are read or a Hash of template location paths to css output paths. Sass::Plugin.options[:css_location] is ignored when :template_location is a Hash. :template_location will also accept a list of pairs as is commonly returned from Array#zip or Hash#to_a, etc. --- lib/sass.rb | 10 +- lib/sass/plugin.rb | 112 ++++++++++++-------- test/sass/more_results/more1.css | 9 ++ test/sass/more_results/more_import.css | 29 +++++ test/sass/more_templates/_more_partial.sass | 2 + test/sass/more_templates/more1.sass | 23 ++++ test/sass/more_templates/more_import.sass | 11 ++ test/sass/plugin_test.rb | 30 ++++-- 8 files changed, 171 insertions(+), 55 deletions(-) create mode 100644 test/sass/more_results/more1.css create mode 100644 test/sass/more_results/more_import.css create mode 100644 test/sass/more_templates/_more_partial.sass create mode 100644 test/sass/more_templates/more1.sass create mode 100644 test/sass/more_templates/more_import.sass diff --git a/lib/sass.rb b/lib/sass.rb index 890c67a1..d87a1b90 100644 --- a/lib/sass.rb +++ b/lib/sass.rb @@ -846,12 +846,18 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir) # Defaults to false in production mode, true otherwise. # Only has meaning within Ruby on Rails or Merb. # -# [:template_location] The directory where Sass templates should be read from. +# [:template_location] A path to the root sass template directory for you application. +# If a hash, :css_location is ignored and this option designates +# both a mapping between input and output directories. +# May also be given a list of 2-element lists, instead of a hash. # Defaults to RAILS_ROOT + "/public/stylesheets/sass" # or MERB_ROOT + "/public/stylesheets/sass". # Only has meaning within Ruby on Rails or Merb. +# This will be derived from the :css_location path list if not provided +# by appending a folder of "sass" to each corresponding css location. # -# [:css_location] The directory where CSS output should be written to. +# [:css_location] The path where CSS output should be written to. +# This option is ignored when :template_location is a Hash. # Defaults to RAILS_ROOT + "/public/stylesheets" # or MERB_ROOT + "/public/stylesheets". # Only has meaning within Ruby on Rails or Merb. diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb index 90fcba67..b6dc1a3a 100644 --- a/lib/sass/plugin.rb +++ b/lib/sass/plugin.rb @@ -8,7 +8,6 @@ module Sass module Plugin class << self @@options = { - :template_location => './public/stylesheets/sass', :css_location => './public/stylesheets', :always_update => false, :always_check => true, @@ -35,44 +34,20 @@ module Sass @@options.merge!(value) end - # Checks each stylesheet in options[:css_location] - # to see if it needs updating, - # and updates it using the corresponding template - # from options[:templates] - # if it does. + # Checks each css stylesheet to see if it needs updating, + # and updates it using the corresponding sass template if it does. def update_stylesheets return if options[:never_update] @@checked_for_updates = true - Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file| + template_locations.zip(css_locations).each do |template_location, css_location| - # Get the relative path to the file with no extension - name = file.sub(options[:template_location] + "/", "")[0...-5] + Dir.glob(File.join(template_location, "**", "*.sass")).each do |file| + # Get the relative path to the file with no extension + name = file.sub(template_location + "/", "")[0...-5] - if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name)) - css = css_filename(name) - File.delete(css) if File.exists?(css) - - filename = template_filename(name) - l_options = @@options.dup - l_options[:css_filename] = css - l_options[:filename] = filename - l_options[:load_paths] = load_paths - engine = Engine.new(File.read(filename), l_options) - result = begin - engine.render - rescue Exception => e - exception_string(e) - end - - # Create any directories that might be necessary - dirs = [l_options[:css_location]] - name.split("/")[0...-1].each { |dir| dirs << "#{dirs[-1]}/#{dir}" } - dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) } - - # Finally, write the file - File.open(css, 'w') do |file| - file.print(result) + if !forbid_update?(name) && (options[:always_update] || stylesheet_needs_update?(name, template_location, css_location)) + update_stylesheet(name, template_location, css_location) end end end @@ -80,8 +55,57 @@ module Sass private + def update_stylesheet(name, template_location, css_location) + css = css_filename(name, css_location) + File.delete(css) if File.exists?(css) + + filename = template_filename(name, template_location) + l_options = @@options.dup + l_options[:css_filename] = css + l_options[:filename] = filename + l_options[:load_paths] = load_paths + engine = Engine.new(File.read(filename), l_options) + result = begin + engine.render + rescue Exception => e + exception_string(e) + end + + # Create any directories that might be necessary + mkpath(css_location, name) + + # Finally, write the file + File.open(css, 'w') do |file| + file.print(result) + end + end + + # Create any successive directories required to be able to write a file to: File.join(base,name) + def mkpath(base, name) + dirs = [base] + name.split('/')[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) } + dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) } + end + def load_paths - (options[:load_paths] || []) + [options[:template_location]] + (options[:load_paths] || []) + template_locations + end + + def template_locations + location = (options[:template_location] || File.join(options[:css_location],'sass')) + if location.is_a?(String) + [location] + else + location.to_a.map { |l| l.first } + end + end + + def css_locations + if options[:template_location] && !options[:template_location].is_a?(String) + options[:template_location].to_a.map { |l| l.last } + else + [options[:css_location]] + end end def exception_string(e) @@ -127,25 +151,27 @@ END end end - def template_filename(name) - "#{options[:template_location]}/#{name}.sass" + def template_filename(name, path) + "#{path}/#{name}.sass" end - def css_filename(name) - "#{options[:css_location]}/#{name}.css" + def css_filename(name, path) + "#{path}/#{name}.css" end def forbid_update?(name) name.sub(/^.*\//, '')[0] == ?_ end - def stylesheet_needs_update?(name) - if !File.exists?(css_filename(name)) + def stylesheet_needs_update?(name, template_path, css_path) + css_file = css_filename(name, css_path) + template_file = template_filename(name, template_path) + if !File.exists?(css_file) return true else - css_mtime = File.mtime(css_filename(name)) - File.mtime(template_filename(name)) > css_mtime || - dependencies(template_filename(name)).any?(&dependency_updated?(css_mtime)) + css_mtime = File.mtime(css_file) + File.mtime(template_file) > css_mtime || + dependencies(template_file).any?(&dependency_updated?(css_mtime)) end end diff --git a/test/sass/more_results/more1.css b/test/sass/more_results/more1.css new file mode 100644 index 00000000..b0d1182f --- /dev/null +++ b/test/sass/more_results/more1.css @@ -0,0 +1,9 @@ +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } diff --git a/test/sass/more_results/more_import.css b/test/sass/more_results/more_import.css new file mode 100644 index 00000000..97c4797e --- /dev/null +++ b/test/sass/more_results/more_import.css @@ -0,0 +1,29 @@ +imported { otherconst: hello; myconst: goodbye; pre-mixin: here; } + +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } + +midrule { inthe: middle; } + +body { font: Arial; background: blue; } + +#page { width: 700px; height: 100; } +#page #header { height: 300px; } +#page #header h1 { font-size: 50px; color: blue; } + +#content.user.show #container.top #column.left { width: 100px; } +#content.user.show #container.top #column.right { width: 600px; } +#content.user.show #container.bottom { background: brown; } + +@import url(basic.css); +@import url(../results/complex.css); +#foo { background-color: #baf; } + +nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; } diff --git a/test/sass/more_templates/_more_partial.sass b/test/sass/more_templates/_more_partial.sass new file mode 100644 index 00000000..bef627d2 --- /dev/null +++ b/test/sass/more_templates/_more_partial.sass @@ -0,0 +1,2 @@ +#foo + :background-color #baf diff --git a/test/sass/more_templates/more1.sass b/test/sass/more_templates/more1.sass new file mode 100644 index 00000000..71117bf5 --- /dev/null +++ b/test/sass/more_templates/more1.sass @@ -0,0 +1,23 @@ + + +body + :font Arial + :background blue + +#page + :width 700px + :height 100 + #header + :height 300px + h1 + :font-size 50px + :color blue + +#content.user.show + #container.top + #column.left + :width 100px + #column.right + :width 600px + #container.bottom + :background brown \ No newline at end of file diff --git a/test/sass/more_templates/more_import.sass b/test/sass/more_templates/more_import.sass new file mode 100644 index 00000000..fa329b32 --- /dev/null +++ b/test/sass/more_templates/more_import.sass @@ -0,0 +1,11 @@ +!preconst = hello + +=premixin + pre-mixin: here + +@import importee, basic, basic.css, ../results/complex.css, more_partial + +nonimported + :myconst = !preconst + :otherconst = !postconst + +postmixin diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index f1a379e0..b56c5859 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -15,12 +15,14 @@ class SassPluginTest < Test::Unit::TestCase def setup FileUtils.mkdir File.dirname(__FILE__) + '/tmp' + FileUtils.mkdir File.dirname(__FILE__) + '/more_tmp' set_plugin_opts Sass::Plugin.update_stylesheets end def teardown FileUtils.rm_r File.dirname(__FILE__) + '/tmp' + FileUtils.rm_r File.dirname(__FILE__) + '/more_tmp' end def test_templates_should_render_correctly @@ -69,6 +71,14 @@ class SassPluginTest < Test::Unit::TestCase Sass::Plugin.options[:full_exception] = true end + + def test_two_template_directories + templates = ['templates', 'more_templates'].map{ |t| File.dirname(__FILE__) + "/#{t}" } + csses = ['tmp', 'more_tmp'].map{ |c| File.dirname(__FILE__) + "/#{c}" } + set_plugin_opts :template_location => templates.zip(csses) + Sass::Plugin.update_stylesheets + ['more1', 'more_import'].each { |name| assert_renders_correctly(name, 'more_') } + end def test_rails_update File.delete(tempfile_loc('basic')) @@ -105,33 +115,33 @@ class SassPluginTest < Test::Unit::TestCase private - def assert_renders_correctly(name) - File.read(result_loc(name)).split("\n").zip(File.read(tempfile_loc(name)).split("\n")).each_with_index do |pair, line| + def assert_renders_correctly(name, prefix = nil) + File.read(result_loc(name,prefix)).split("\n").zip(File.read(tempfile_loc(name,prefix)).split("\n")).each_with_index do |pair, line| message = "template: #{name}\nline: #{line + 1}" assert_equal(pair.first, pair.last, message) end end - def template_loc(name) - File.dirname(__FILE__) + "/templates/#{name}.sass" + def template_loc(name, prefix = nil) + File.dirname(__FILE__) + "/#{prefix}templates/#{name}.sass" end - def tempfile_loc(name) - File.dirname(__FILE__) + "/tmp/#{name}.css" + def tempfile_loc(name, prefix = nil) + File.dirname(__FILE__) + "/#{prefix}tmp/#{name}.css" end - def result_loc(name) - File.dirname(__FILE__) + "/results/#{name}.css" + def result_loc(name, prefix = nil) + File.dirname(__FILE__) + "/#{prefix}results/#{name}.css" end - def set_plugin_opts + def set_plugin_opts(overides = {}) Sass::Plugin.options = { :template_location => File.dirname(__FILE__) + '/templates', :css_location => File.dirname(__FILE__) + '/tmp', :style => :compact, :load_paths => [File.dirname(__FILE__) + '/results'], :always_update => true, - } + }.merge(overides) end end From 432871bb84c897a4ded02e7dfa9a899c327014d9 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Mon, 14 Jul 2008 11:32:08 -0700 Subject: [PATCH 03/11] DRY up the path locations to the various template, temp, and output locations. pass a hash instead of a pairwise array as this is the preferred mechanism. --- test/sass/plugin_test.rb | 75 +++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index b56c5859..26dc6413 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -14,15 +14,15 @@ class SassPluginTest < Test::Unit::TestCase } def setup - FileUtils.mkdir File.dirname(__FILE__) + '/tmp' - FileUtils.mkdir File.dirname(__FILE__) + '/more_tmp' + FileUtils.mkdir tempfile_loc + FileUtils.mkdir tempfile_loc(nil,"more_") set_plugin_opts Sass::Plugin.update_stylesheets end def teardown - FileUtils.rm_r File.dirname(__FILE__) + '/tmp' - FileUtils.rm_r File.dirname(__FILE__) + '/more_tmp' + FileUtils.rm_r tempfile_loc + FileUtils.rm_r tempfile_loc(nil,"more_") end def test_templates_should_render_correctly @@ -31,32 +31,32 @@ class SassPluginTest < Test::Unit::TestCase def test_no_update File.delete(tempfile_loc('basic')) - assert Sass::Plugin.stylesheet_needs_update?('basic') + assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) Sass::Plugin.update_stylesheets - assert !Sass::Plugin.stylesheet_needs_update?('basic') + assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) end def test_update_needed_when_modified sleep(1) FileUtils.touch(template_loc('basic')) - assert Sass::Plugin.stylesheet_needs_update?('basic') + assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) Sass::Plugin.update_stylesheets - assert !Sass::Plugin.stylesheet_needs_update?('basic') + assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) end def test_update_needed_when_dependency_modified sleep(1) FileUtils.touch(template_loc('basic')) - assert Sass::Plugin.stylesheet_needs_update?('import') + assert Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc) Sass::Plugin.update_stylesheets - assert !Sass::Plugin.stylesheet_needs_update?('import') + assert !Sass::Plugin.stylesheet_needs_update?('import', template_loc, tempfile_loc) end def test_full_exception_handling File.delete(tempfile_loc('bork')) Sass::Plugin.update_stylesheets File.open(tempfile_loc('bork')) do |file| - assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\".\non line 2 of #{File.dirname(__FILE__) + '/templates/bork.sass'}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n")) + assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\".\non line 2 of #{template_loc('bork')}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n")) end File.delete(tempfile_loc('bork')) end @@ -73,20 +73,21 @@ class SassPluginTest < Test::Unit::TestCase end def test_two_template_directories - templates = ['templates', 'more_templates'].map{ |t| File.dirname(__FILE__) + "/#{t}" } - csses = ['tmp', 'more_tmp'].map{ |c| File.dirname(__FILE__) + "/#{c}" } - set_plugin_opts :template_location => templates.zip(csses) + set_plugin_opts :template_location => { + template_loc => tempfile_loc, + template_loc(nil,'more_') => tempfile_loc(nil,'more_') + } Sass::Plugin.update_stylesheets ['more1', 'more_import'].each { |name| assert_renders_correctly(name, 'more_') } end def test_rails_update File.delete(tempfile_loc('basic')) - assert Sass::Plugin.stylesheet_needs_update?('basic') + assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) ActionController::Base.new.process - assert !Sass::Plugin.stylesheet_needs_update?('basic') + assert !Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc) end def test_merb_update @@ -116,32 +117,50 @@ class SassPluginTest < Test::Unit::TestCase private def assert_renders_correctly(name, prefix = nil) - File.read(result_loc(name,prefix)).split("\n").zip(File.read(tempfile_loc(name,prefix)).split("\n")).each_with_index do |pair, line| + expected_lines = File.read(result_loc(name, prefix)).split("\n") + actual_lines = File.read(tempfile_loc(name, prefix)).split("\n") + expected_lines.zip(actual_lines).each_with_index do |pair, line| message = "template: #{name}\nline: #{line + 1}" assert_equal(pair.first, pair.last, message) end end - def template_loc(name, prefix = nil) - File.dirname(__FILE__) + "/#{prefix}templates/#{name}.sass" + def template_loc(name = nil, prefix = nil) + if name + absolutize "#{prefix}templates/#{name}.sass" + else + absolutize "#{prefix}templates" + end end - def tempfile_loc(name, prefix = nil) - File.dirname(__FILE__) + "/#{prefix}tmp/#{name}.css" + def tempfile_loc(name = nil, prefix = nil) + if name + absolutize "#{prefix}tmp/#{name}.css" + else + absolutize "#{prefix}tmp" + end end - def result_loc(name, prefix = nil) - File.dirname(__FILE__) + "/#{prefix}results/#{name}.css" + def result_loc(name = nil, prefix = nil) + if name + absolutize "#{prefix}results/#{name}.css" + else + absolutize "#{prefix}results" + end end - def set_plugin_opts(overides = {}) + def absolutize(file) + "#{File.dirname(__FILE__)}/#{file}" + end + + def set_plugin_opts(overrides = {}) Sass::Plugin.options = { - :template_location => File.dirname(__FILE__) + '/templates', - :css_location => File.dirname(__FILE__) + '/tmp', + :template_location => template_loc, + :css_location => tempfile_loc, :style => :compact, - :load_paths => [File.dirname(__FILE__) + '/results'], + :load_paths => [result_loc], :always_update => true, - }.merge(overides) + }.merge(overrides) end end From fb49552da5047e6189db971583acea2a9422acb6 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Mon, 21 Jul 2008 21:01:48 -0700 Subject: [PATCH 04/11] Use File::SEPARATOR instead of assuming it is '/'. --- lib/sass/plugin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb index b6dc1a3a..b6564a7d 100644 --- a/lib/sass/plugin.rb +++ b/lib/sass/plugin.rb @@ -83,7 +83,7 @@ module Sass # Create any successive directories required to be able to write a file to: File.join(base,name) def mkpath(base, name) dirs = [base] - name.split('/')[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) } + name.split(File::SEPARATOR)[0...-1].each { |dir| dirs << File.join(dirs[-1],dir) } dirs.each { |dir| Dir.mkdir(dir) unless File.exist?(dir) } end From 92aff4d76fd0761d5f7ecd9c7e971e81f40c5a71 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sun, 27 Jul 2008 12:46:57 -0700 Subject: [PATCH 05/11] fixed a bug in assert_renders_correctly where trailing lines in the CSS file would not trigger a test failure --- test/sass/plugin_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index 26dc6413..c5c580d1 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -123,6 +123,9 @@ class SassPluginTest < Test::Unit::TestCase message = "template: #{name}\nline: #{line + 1}" assert_equal(pair.first, pair.last, message) end + if expected_lines.size < actual_lines.size + assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}") + end end def template_loc(name = nil, prefix = nil) From a98b4def37d925bc7b93f9b8e70e0cdcb16595a8 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 2 Aug 2008 09:15:44 -0700 Subject: [PATCH 06/11] The relative pathname calculation can fail, if it does, use the absolute filename instead. --- lib/sass/tree/rule_node.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/sass/tree/rule_node.rb b/lib/sass/tree/rule_node.rb index 1711958b..ad900d60 100644 --- a/lib/sass/tree/rule_node.rb +++ b/lib/sass/tree/rule_node.rb @@ -68,8 +68,16 @@ module Sass::Tree if @options[:line_comments] && @style != :compressed to_return << "#{old_spaces}/* line #{line}" - if filename && @options[:css_filename] - relative_filename = Pathname.new(filename).relative_path_from(Pathname.new(File.dirname(@options[:css_filename]))).to_s + if filename + relative_filename = if @options[:css_filename] + begin + Pathname.new(filename).relative_path_from( + Pathname.new(File.dirname(@options[:css_filename]))).to_s + rescue ArgumentError + nil + end + end + relative_filename ||= filename to_return << ", #{relative_filename}" end From 49a063fa88d3550ed4cdcec128d0f8a8021a760a Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 2 Aug 2008 09:55:52 -0700 Subject: [PATCH 07/11] find partial files, even if they're in a subdirectory --- lib/sass/engine.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index 26bda485..929518e5 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -461,7 +461,9 @@ END def self.find_full_path(filename, load_paths) load_paths.each do |path| - ["_#{filename}", filename].each do |name| + segments = filename.split(File::SEPARATOR) + segments.push "_#{segments.pop}" + [segments.join(File::SEPARATOR), filename].each do |name| full_path = File.join(path, name) if File.readable?(full_path) return full_path From c171d11c1478048e591dfba82be251b8d4225a9e Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 2 Aug 2008 10:07:53 -0700 Subject: [PATCH 08/11] when importing, first look relative to the current template file --- lib/sass/engine.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb index 929518e5..19da5cdc 100644 --- a/lib/sass/engine.rb +++ b/lib/sass/engine.rb @@ -396,6 +396,12 @@ END raise SyntaxError.new("Unbalanced brackets.", @line) end + def import_paths + paths = @options[:load_paths] || [] + paths.unshift(File.dirname(@options[:filename])) if @options[:filename] + paths + end + def import(files) nodes = [] @@ -403,7 +409,7 @@ END engine = nil begin - filename = self.class.find_file_to_import(filename, @options[:load_paths]) + filename = self.class.find_file_to_import(filename, import_paths) rescue Exception => e raise SyntaxError.new(e.message, @line) end From e3409eba5b35684a928ff950d4b172aca667f5cc Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 9 Aug 2008 09:39:49 -0700 Subject: [PATCH 09/11] allow line comments option to be set via sass command line --- lib/haml/exec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/haml/exec.rb b/lib/haml/exec.rb index 42df9cc7..f6e86a6b 100644 --- a/lib/haml/exec.rb +++ b/lib/haml/exec.rb @@ -180,6 +180,10 @@ END 'Output style. Can be nested (default), compact, compressed, or expanded.') do |name| @options[:for_engine][:style] = name.to_sym end + opts.on('-l', '--line-comments', + 'Line Comments. Emit comments in the generated CSS indicating the corresponding sass line.') do + @options[:for_engine][:line_comments] = true + end end def process_result From d96e0a37967dba455923beab90fa3696d60c0ce4 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 9 Aug 2008 09:43:15 -0700 Subject: [PATCH 10/11] allow assert_renders_correctly to accept different filenames for comparison --- test/sass/plugin_test.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index c5c580d1..198fe490 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -78,7 +78,7 @@ class SassPluginTest < Test::Unit::TestCase template_loc(nil,'more_') => tempfile_loc(nil,'more_') } Sass::Plugin.update_stylesheets - ['more1', 'more_import'].each { |name| assert_renders_correctly(name, 'more_') } + ['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') } end def test_rails_update @@ -116,15 +116,19 @@ class SassPluginTest < Test::Unit::TestCase private - def assert_renders_correctly(name, prefix = nil) - expected_lines = File.read(result_loc(name, prefix)).split("\n") - actual_lines = File.read(tempfile_loc(name, prefix)).split("\n") + def assert_renders_correctly(*arguments) + options = arguments.last.is_a?(Hash) ? arguments.pop : {} + prefix = options[:prefix] + result_name = arguments.shift + tempfile_name = arguments.shift || result_name + expected_lines = File.read(result_loc(result_name, prefix)).split("\n") + actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n") expected_lines.zip(actual_lines).each_with_index do |pair, line| - message = "template: #{name}\nline: #{line + 1}" + message = "template: #{result_name}\nline: #{line + 1}" assert_equal(pair.first, pair.last, message) end if expected_lines.size < actual_lines.size - assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}") + assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{tempfile_name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}") end end From 94ecc74eca94197891d1fe97e73a208ed0ecaafb Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Sat, 9 Aug 2008 09:44:40 -0700 Subject: [PATCH 11/11] new test to ensure that line comments work correctly when passing template location as a hash --- .../more_results/more1_with_line_comments.css | 26 +++++++++++++++++++ test/sass/plugin_test.rb | 11 ++++++++ 2 files changed, 37 insertions(+) create mode 100644 test/sass/more_results/more1_with_line_comments.css diff --git a/test/sass/more_results/more1_with_line_comments.css b/test/sass/more_results/more1_with_line_comments.css new file mode 100644 index 00000000..f31dbca2 --- /dev/null +++ b/test/sass/more_results/more1_with_line_comments.css @@ -0,0 +1,26 @@ +/* line 3, ../more_templates/more1.sass */ +body { + font: Arial; + background: blue; } + +/* line 7, ../more_templates/more1.sass */ +#page { + width: 700px; + height: 100; } + /* line 10, ../more_templates/more1.sass */ + #page #header { + height: 300px; } + /* line 12, ../more_templates/more1.sass */ + #page #header h1 { + font-size: 50px; + color: blue; } + +/* line 18, ../more_templates/more1.sass */ +#content.user.show #container.top #column.left { + width: 100px; } +/* line 20, ../more_templates/more1.sass */ +#content.user.show #container.top #column.right { + width: 600px; } +/* line 22, ../more_templates/more1.sass */ +#content.user.show #container.bottom { + background: brown; } diff --git a/test/sass/plugin_test.rb b/test/sass/plugin_test.rb index 198fe490..ef025669 100644 --- a/test/sass/plugin_test.rb +++ b/test/sass/plugin_test.rb @@ -81,6 +81,17 @@ class SassPluginTest < Test::Unit::TestCase ['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') } end + def test_two_template_directories_with_line_annotations + set_plugin_opts :line_comments => true, + :style => :nested, + :template_location => { + template_loc => tempfile_loc, + template_loc(nil,'more_') => tempfile_loc(nil,'more_') + } + Sass::Plugin.update_stylesheets + assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_') + end + def test_rails_update File.delete(tempfile_loc('basic')) assert Sass::Plugin.stylesheet_needs_update?('basic', template_loc, tempfile_loc)