Skip to content

Commit

Permalink
Added support for scss (sass v3 css files) and less css files
Browse files Browse the repository at this point in the history
  • Loading branch information
andriijas authored and Charles Jolley committed May 18, 2010
1 parent 9d97f22 commit 99ecebd
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 27 deletions.
10 changes: 10 additions & 0 deletions buildtasks/build.rake
Expand Up @@ -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
Expand Down
38 changes: 20 additions & 18 deletions buildtasks/manifest.rake
Expand Up @@ -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)
Expand Down Expand Up @@ -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 = {}
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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?
Expand Down
2 changes: 1 addition & 1 deletion lib/sproutcore/builders/base.rb
Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions lib/sproutcore/builders/less.rb
@@ -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
11 changes: 9 additions & 2 deletions lib/sproutcore/builders/sass.rb
Expand Up @@ -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
Expand All @@ -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
Expand Down
12 changes: 10 additions & 2 deletions spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb
Expand Up @@ -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
Expand All @@ -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)
Expand Down
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/builder_tests/apps/less_test/sample.less
@@ -0,0 +1,4 @@
#main p {
color: lime;
width: 97%;
background: static_url("image"); }
4 changes: 4 additions & 0 deletions spec/fixtures/builder_tests/apps/sass_test/sample.scss
@@ -0,0 +1,4 @@
#main p {
color: lime;
width: 97%;
background: static_url("image"); }
Empty file.
51 changes: 51 additions & 0 deletions spec/lib/builders/less_spec.rb
@@ -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
27 changes: 24 additions & 3 deletions spec/lib/builders/sass_spec.rb
Expand Up @@ -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'
Expand All @@ -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.