Permalink
Browse files

Added support for scss (sass v3 css files) and less css files

  • Loading branch information...
1 parent 9d97f22 commit 99ecebdb85346141b9001b15020f77dd4a596aa1 @andriijas andriijas committed with Charles Jolley May 16, 2010
View
@@ -25,6 +25,16 @@ namespace :build do
SC::Builder::Sass.build ENTRY, DST_PATH
end
+ desc "builds a single scss (sass v3 syntax) file"
+ build_task :scss do
+ SC::Builder::Sass.build ENTRY, DST_PATH, :scss
+ end
+
+ desc "builds a single less file"
+ build_task :less do
+ SC::Builder::Less.build ENTRY, DST_PATH
+ end
+
desc "builds a single javascript file"
build_task :javascript do
SC::Builder::JavaScript.build ENTRY, DST_PATH
View
@@ -136,7 +136,7 @@ namespace :manifest do
namespace :prepare_build_tasks do
desc "main entrypoint for preparing all build tasks. This should invoke all needed tasks"
- task :all => %w(css javascript bundle_info bundle_loaded sass combine minify html strings tests packed)
+ task :all => %w(css javascript bundle_info bundle_loaded sass scss less combine minify html strings tests packed)
desc "executes prerequisites needed before one of the subtasks can be invoked. All subtasks that have this as a prereq"
task :setup => %w(manifest:catalog manifest:hide_buildfiles manifest:localize)
@@ -288,7 +288,7 @@ namespace :manifest do
task :bundle_loaded => :tests # IMPORTANT! to avoid JS including unit tests.
desc "generates combined entries for javascript and css"
- task :combine => %w(setup css javascript bundle_info bundle_loaded sass) do
+ task :combine => %w(setup css javascript bundle_info bundle_loaded sass scss less) do
# sort entries...
css_entries = {}
@@ -397,21 +397,23 @@ namespace :manifest do
end
task :minify => :packed # IMPORTANT: don't want minified version
-
- desc "create a builder task for all sass files to create css files"
- task :sass => :setup do
- MANIFEST.entries.each do |entry|
- next unless entry.ext == "sass"
-
- MANIFEST.add_transform entry,
- :filename => ['source', entry.filename].join('/'),
- :build_path => File.join(MANIFEST.build_root, 'source', entry.filename),
- :url => [MANIFEST.url_root, 'source', entry.filename].join("/"),
- :build_task => 'build:sass',
- :entry_type => :css,
- :ext => 'css',
- :resource => 'stylesheet',
- :required => []
+ #Create builder tasks for sass, scss (sass v3) and less in a DRY way
+ [:sass, :scss, :less].each do |csscompiler|
+ desc sprintf("create a builder task for all %s files to create css files", csscompiler.to_s)
+ task csscompiler => :setup do
+ MANIFEST.entries.each do |entry|
+ next unless entry.ext == csscompiler.to_s
+
+ MANIFEST.add_transform entry,
+ :filename => ['source', entry.filename].join('/'),
+ :build_path => File.join(MANIFEST.build_root, 'source', entry.filename),
+ :url => [MANIFEST.url_root, 'source', entry.filename].join("/"),
+ :build_task => 'build:'+csscompiler.to_s,
+ :entry_type => :css,
+ :ext => 'css',
+ :resource => 'stylesheet',
+ :required => []
+ end
end
end
@@ -512,7 +514,7 @@ namespace :manifest do
end
desc "creates transform entries for all css and Js entries to minify them if needed"
- task :minify => %w(setup javascript bundle_info bundle_loaded css combine sass) do
+ task :minify => %w(setup javascript bundle_info bundle_loaded css combine sass scss less) do
minify_css = CONFIG.minify_css
minify_css = CONFIG.minify if minify_css.nil?
@@ -30,7 +30,7 @@ def initialize(entry=nil)
def build(dst_path)
end
- # main entry called by build tasls
+ # main entry called by build tasks
def self.build(entry, dst_path)
new(entry).build(dst_path)
end
@@ -0,0 +1,41 @@
+# ===========================================================================
+# Project: Abbot - SproutCore Build Tools
+# Copyright: ©2009 Apple Inc.
+# portions copyright @2006-2009 Sprout Systems, Inc.
+# and contributors
+# ===========================================================================
+
+require File.expand_path(File.join(File.dirname(__FILE__), 'stylesheet'))
+require 'fileutils'
+
+module SC
+
+ # This build can compile a Less stylesheet.
+ class Builder::Less < Builder::Stylesheet
+
+ def build(dst_path)
+ begin
+ require 'less'
+ rescue
+ raise "Cannot compile #{entry.source_path} because less is not installed. Please try 'sudo gem install less' and try again"
+ end
+
+ begin
+ content = readlines(entry.source_path)*''
+ css = ::Less::Engine.new(content).to_css
+ lines = []
+ css.each_line { |l| lines << rewrite_inline_code(l) }
+ writelines dst_path, lines
+ rescue Exception => e
+
+ # explain sass syntax error a bit more...
+ if e.is_a? Less::SyntaxError
+ e.message << " of #{@entry.source_path}"
+ end
+ raise e # reraise
+ end # rescue
+ end # def
+
+ end
+
+end
@@ -15,8 +15,15 @@ module SC
# add support for sc_static and other directives at some point.
#
class Builder::Sass < Builder::Stylesheet
+ @@sass_syntax = :sass
- def build(dst_path)
+ # main entry called by build tasks
+ def self.build(entry, dst_path, sass_syntax=:sass)
+ @@sass_syntax =sass_syntax
+ new(entry).build(dst_path)
+ end
+
+ def build(dst_path, sass_syntax=:sass)
begin
require 'sass'
rescue
@@ -25,7 +32,7 @@ def build(dst_path)
begin
content = readlines(entry.source_path)*''
- css = ::Sass::Engine.new(content).render
+ css = ::Sass::Engine.new(content, :syntax => @@sass_syntax).render
lines = []
css.each_line { |l| lines << rewrite_inline_code(l) }
writelines dst_path, lines
@@ -18,8 +18,8 @@ def run_task
}
end
- it "should run setup, javascript, css, & sass as prereq" do
- %w(setup javascript css sass).each do |task_name|
+ it "should run setup, javascript, css, sass, scss & less as prereq" do
+ %w(setup javascript css sass scss less).each do |task_name|
should_run("manifest:prepare_build_tasks:#{task_name}") { run_task }
end
end
@@ -46,6 +46,14 @@ def run_task
# Test that sass file is included...
expected = entry_for('source/demo2.css', :entry_type => :css)
entry.source_entries.should include(expected)
+
+ # Test that scss file is included...
+ expected = entry_for('source/demo3.css', :entry_type => :css)
+ entry.source_entries.should include(expected)
+
+ # Test that less file is included...
+ expected = entry_for('source/demo4.css', :entry_type => :css)
+ entry.source_entries.should include(expected)
entry = entry_for 'bar.css'
expected = entry_for('source/sc_resource.css', :entry_type => :css)
@@ -15,7 +15,7 @@ def run_task
end
it "should run setup, javascript, css, and combine as prereq" do
- %w(setup javascript css sass combine).each do |task_name|
+ %w(setup javascript css sass scss less combine).each do |task_name|
should_run("manifest:prepare_build_tasks:#{task_name}") { run_task }
end
end
@@ -0,0 +1,4 @@
+#main p {
+ color: lime;
+ width: 97%;
+ background: static_url("image"); }
@@ -0,0 +1,4 @@
+#main p {
+ color: lime;
+ width: 97%;
+ background: static_url("image"); }
@@ -0,0 +1,51 @@
+require File.join(File.dirname(__FILE__), 'spec_helper')
+
+# If less is not installed, just skip these.
+has_less = true
+begin
+ require 'less'
+
+rescue Exception => e
+ puts "WARNING: Skipping SC::Builder::Less tests because less is not installed. Run 'sudo gem install less' first and try again."
+ has_less = false
+end
+
+if has_less
+ describe SC::Builder::Less do
+
+ include SC::SpecHelpers
+ include SC::BuilderSpecHelper
+
+ before do
+ std_before :less_test
+ @manifest.add_entry 'icons/image.png'
+ end
+
+
+ after do
+ std_after
+ end
+
+ def run_builder(filename)
+ super do |entry, dst_path|
+ SC::Builder::Less.build(entry, dst_path)
+ end
+ end
+
+ it "should build a less file" do
+ lines = run_builder('sample.less')
+ lines = lines.join('').gsub("\n",'') # strip newlines to make compare easy
+
+ # just verify that output looks like the CSS we expect
+ lines.should =~ /\#main\s+p.+\{.+color.+width.+\}/
+ end
+
+ it "converts static_url() and sc_static() => 'url('foo')' " do
+ lines = run_builder('sample.less')
+ css = lines.join("\n")
+
+ css.should_not =~ /(static_url|sc_static)/
+ css.should =~ /url\('.+'\)/ # important MUST have some url...
+ end
+ end
+end
@@ -15,7 +15,8 @@
include SC::SpecHelpers
include SC::BuilderSpecHelper
-
+ @sass_syntax = :sass
+
before do
std_before :sass_test
@manifest.add_entry 'icons/image.png'
@@ -28,24 +29,44 @@
def run_builder(filename)
super do |entry, dst_path|
- SC::Builder::Sass.build(entry, dst_path)
+ SC::Builder::Sass.build(entry, dst_path, @sass_syntax)
end
end
it "should build a sass file" do
+ @sass_syntax = :sass
lines = run_builder('sample.sass')
lines = lines.join('').gsub("\n",'') # strip newlines to make compare easy
# just verify that output looks like the CSS we expect
lines.should =~ /\#main\s+p.+\{.+color.+width.+\}/
end
- it "converts static_url() and sc_static() => 'url('foo')' " do
+ it "should build a sass file" do
+ @sass_syntax = :scss
+ lines = run_builder('sample.scss')
+ lines = lines.join('').gsub("\n",'') # strip newlines to make compare easy
+
+ # just verify that output looks like the CSS we expect
+ lines.should =~ /\#main\s+p.+\{.+color.+width.+\}/
+ end
+
+ it "converts static_url() and sc_static() => 'url('foo')' in sass" do
+ @sass_syntax = :sass
lines = run_builder('sample.sass')
css = lines.join("\n")
css.should_not =~ /(static_url|sc_static)/
css.should =~ /url\('.+'\)/ # important MUST have some url...
end
+
+ it "converts static_url() and sc_static() => 'url('foo')' in scss" do
+ @sass_syntax = :scss
+ lines = run_builder('sample.scss')
+ css = lines.join("\n")
+
+ css.should_not =~ /(static_url|sc_static)/
+ css.should =~ /url\('.+'\)/ # important MUST have some url...
+ end
end
end

0 comments on commit 99ecebd

Please sign in to comment.