Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

upgrading less/more plugin

  • Loading branch information...
commit 4cda3f4ea48b830d7ad265caf15dadf93a004aa4 1 parent 3c32f39
@rick authored
View
1  vendor/plugins/more/.gitignore
@@ -0,0 +1 @@
+*.gem
View
20 vendor/plugins/more/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Logan Raarup, August Lilleaas
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
130 vendor/plugins/more/README.markdown
@@ -0,0 +1,130 @@
+More
+====
+
+*LESS on Rails.*
+
+More is a plugin for Ruby on Rails applications. It automatically parses your applications `.less` files through LESS and outputs CSS files.
+
+In details, More does the following:
+
+* Recursively looks for LESS (`.less`) files in `app/stylesheets`
+* Ignores partials (prefixed with underscore: `_partial.less`) - these can be included with `@import` in your LESS files
+* Saves the resulting CSS files to `public/stylesheets` using the same directory structure as `app/stylesheets`
+
+LESS
+----
+
+LESS extends CSS with: variables, mixins, operations and nested rules. For more information, see [http://lesscss.org](http://lesscss.org).
+
+Upgrading from less-for-rails
+=======================================
+
+The old `less-for-rails` plugin looked for `.less` files in `public/stylesheets`. This plugin looks in `app/stylesheets`.
+
+To migrate, you can either set `Less::More.source_path = Rails.root + "/public/stylesheets"`, or move your `.less` files to `app/stylesheets`.
+
+
+Installation
+============
+
+More depends on the LESS gem. Please install LESS first:
+
+ $ gem install less
+
+Rails Plugin
+------------
+
+Use this to install as a plugin in a Ruby on Rails app:
+
+ $ script/plugin install git://github.com/cloudhead/more.git
+
+Rails Plugin (using git submodules)
+-----------------------------------
+
+Use this if you prefer to use git submodules for plugins:
+
+ $ git submodule add git://github.com/cloudhead/more.git vendor/plugins/more
+ $ script/runner vendor/plugins/more/install.rb
+
+
+Usage
+=====
+
+Upon installation, a new directory will be created in `app/stylesheets`. Any LESS file placed in this directory, including subdirectories, will
+automatically be parsed through LESS and saved as a corresponding CSS file in `public/stylesheets`. Example:
+
+ app/stylesheets/clients/screen.less => public/stylesheets/clients/screen.css
+
+If you prefix a file with an underscore, it is considered to be a partial, and will not be parsed unless included in another file. Example:
+
+ <file: app/stylesheets/clients/partials/_form.less>
+ @text_dark: #222;
+
+ <file: app/stylesheets/clients/screen.less>
+ @import "partials/_form";
+
+ input { color: @text_dark; }
+
+The example above will result in a single CSS file in `public/stylesheets/clients/screen.css`.
+
+Any `.css` file placed in `app/stylesheets` will be copied into `public/stylesheets` without being parsed through LESS.
+
+
+Configuration
+=============
+
+Source path: the location of your LESS files (default: app/stylesheets)
+
+ Less::More.source_path = "public/stylesheets/less"
+
+Destination Path: where the css goes (public/destination_path) (default: stylesheets)
+
+ Less::More.destination_path = "css"
+
+More can compress your files by removing extra line breaks (default: true)
+
+ Less::More.compression = false
+
+More inserts headers in the generated CSS files, letting people know that the file is in fact generated and shouldn't be edited directly. (default: true)
+
+ Less::More.header = false
+
+To configure More for a specific environment, add configuration options into the environment file, such as `config/environments/development.rb`.
+
+If you wish to apply the configuration to all environments, place them in `config/environment.rb`.
+
+
+Tasks
+=====
+
+More provides a set of Rake tasks to help manage your CSS files.
+
+To parse all LESS files and save the resulting CSS files to the destination path, run:
+
+ $ rake more:generate
+
+To delete all generated CSS files, run:
+
+ $ rake more:clean
+
+This task will not delete any CSS files from the destination path, that does not have a corresponding LESS file in the source path.
+
+
+Git / SVN
+=========
+
+Check in all the generated css(destination path), they are only generated in development
+
+Documentation
+=============
+
+To view the full RDoc documentation, go to [http://rdoc.info/projects/cloudhead/more](http://rdoc.info/projects/cloudhead/more)
+
+
+Contributors
+============
+* August Lilleaas ([http://github.com/augustl](http://github.com/augustl))
+* Logan Raarup ([http://github.com/logandk](http://github.com/logandk))
+* Michael Grosser ([http://github.com/grosser](http://github.com/grosser))
+
+LESS is maintained by Alexis Sellier [http://github.com/cloudhead](http://github.com/cloudhead)
View
23 vendor/plugins/more/Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the more plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the more plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'More'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.markdown')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
View
1  vendor/plugins/more/init.rb
@@ -0,0 +1 @@
+require File.join(File.dirname(__FILE__), 'rails', 'init')
View
4 vendor/plugins/more/install.rb
@@ -0,0 +1,4 @@
+require "fileutils"
+include FileUtils::Verbose
+
+mkdir_p File.join(Rails.root, "app", "stylesheets")
View
7 vendor/plugins/more/lib/less/controller_extension.rb
@@ -0,0 +1,7 @@
+class ActionController::Base
+ before_filter :generate_css_from_less
+
+ def generate_css_from_less
+ Less::More.generate_all
+ end
+end
View
142 vendor/plugins/more/lib/less/more.rb
@@ -0,0 +1,142 @@
+# Less::More provides methods for parsing LESS files in a rails application to CSS target files.
+#
+# When Less::More.parse is called, all files in Less::More.source_path will be parsed using LESS
+# and saved as CSS files in Less::More.destination_path. If Less::More.compression is set to true,
+# extra line breaks will be removed to compress the CSS files.
+#
+# By default, Less::More.parse will be called for each request in `development` environment and on
+# application initialization in `production` environment.
+
+begin
+ require 'less'
+rescue LoadError => e
+ e.message << " (You may need to install the less gem)"
+ raise e
+end
+
+class Less::More
+ HEADER = %{/*\n\n\n\n\n\tThis file was auto generated by Less (http://lesscss.org). To change the contents of this file, edit %s instead.\n\n\n\n\n*/}
+
+ class << self
+ # Less::More.compression = true/false --- compress generated css ? (default: false)
+ # Less::More.header = true/false --- insert editing warning into css ? (default: true)
+ # Less::More.destination_path = 'css' --- put css into public/??? (default: stylesheets)
+ # Less::More.source_path = 'public/stylesheets/less' --- where do less files live? (default: app/stylesheets)
+ attr_writer :compression, :header, :destination_path, :source_path
+
+ def header
+ @header.nil? ? true : @header
+ end
+
+ def destination_path
+ @destination_path || 'stylesheets'
+ end
+
+ def source_path
+ @source_path || 'app/stylesheets'
+ end
+
+ def compression
+ @compression
+ end
+
+ # Generates the .css from a .less or .lss file in Less::More.source_path matching
+ # the given parameters.
+ #
+ # Less::More.generate("screen.less")
+ # Less::More.generate("subdirectories/here/homepage.less")
+ def generate(source)
+ generated = to_dot_css(path_to_destination(source))
+ path_to_source = File.join(Rails.root, source_path, source)
+
+ # check if the destination file exists, and compare the modified times to see if it needs to be written
+ if mtime(generated) >= mtime_including_imports(path_to_source)
+ # up to date, nothing to do!
+ else
+ # css file does not exist or is out of date
+ css = if File.extname(path_to_source) == ".css"
+ # vanilla css nothing to do!
+ File.read(path_to_source)
+ else
+ # less or lss file, compile it
+ css = compile(path_to_source)
+ css.delete!("\n") if compression # TODO: use real compression !
+ css = (HEADER % [File.join(source_path, source)]) << css if header
+ css
+ end
+
+ # write the css
+ FileUtils.mkdir_p File.dirname(generated)
+ File.open(generated, "w"){|f| f.write css }
+ end
+ end
+
+ # Generates all the .css files
+ def generate_all
+ all_less_files.each do |path|
+ generate(relative_to_source_path(path))
+ end
+ end
+
+ # Removes all generated css files.
+ def remove_all_generated
+ all_less_files.each do |path|
+ css_path = to_dot_css(relative_to_source_path(path))
+ css_file = path_to_destination(css_path)
+ File.delete(css_file) if File.file?(css_file)
+ end
+ end
+
+ # Array of paths of less source files.
+ def all_less_files
+ all = Dir[File.join(Rails.root, source_path, "**", "*.{css,less,lss}")]
+ all.reject{|path| File.basename(path) =~ /^_/ }
+ end
+
+ private
+
+ def mtime(file)
+ return 0 unless File.file?(file)
+ File.mtime(file).to_i
+ end
+
+ # consider imports for mtime
+ # just 1 level deep so we do not get any looping/nesting errors
+ def mtime_including_imports(file)
+ mtimes = [mtime(file)]
+ File.readlines(file).each do |line|
+ if line =~ /^\s*@import ['"]([^'"]+)/
+ imported = File.join(File.dirname(file), $1)
+ mtimes << if imported =~ /\.le?ss$/ # complete path given ?
+ mtime(imported)
+ else # we need to add .less or .lss
+ [mtime("#{imported}.less"), mtime("#{imported}.lss")].max
+ end
+ end
+ end
+ mtimes.max
+ end
+
+ def compile(file)
+ begin
+ engine = File.open(file){|f| Less::Engine.new(f) }
+ engine.to_css
+ rescue Exception => e
+ e.message << "\nFrom #{file}"
+ raise e
+ end
+ end
+
+ def to_dot_css(path)
+ path.to_s.sub(/(le?|c)ss$/, "css")
+ end
+
+ def path_to_destination(path)
+ File.join(Rails.root, "public", destination_path, path)
+ end
+
+ def relative_to_source_path(path)
+ path.to_s.sub(File.join(Rails.root, source_path), '')[1..-1]
+ end
+ end
+end
View
16 vendor/plugins/more/lib/tasks/more_tasks.rake
@@ -0,0 +1,16 @@
+namespace :more do
+ desc "Generate CSS files from LESS files"
+ task :generate => :environment do
+ puts "Generating css from less files in #{Less::More.source_path}."
+ Less::More.generate_all
+ puts "Done."
+
+ end
+
+ desc "Remove generated CSS files"
+ task :clean => :environment do
+ puts "Deleting all generated css files in #{Less::More.destination_path}"
+ Less::More.remove_all_generated
+ puts "Done."
+ end
+end
View
17 vendor/plugins/more/more.gemspec
@@ -0,0 +1,17 @@
+
+require 'rake'
+
+SPEC = Gem::Specification.new do |s|
+ s.name = "more"
+ s.summary = "LESS on Rails"
+ s.homepage = "http://github.com/cloudhead/more"
+ s.description = <<-EOS
+ More is a plugin for Ruby on Rails applications. It automatically
+ parses your applications .less files through LESS and outputs CSS files.
+ EOS
+ s.authors = ["August Lilleaas", "Logan Raarup"]
+ s.version = "0.1.0"
+ s.files = FileList["README.markdown", "MIT-LICENSE", "Rakefile", "init.rb", "lib/*.rb", "rails/init.rb", "tasks/*", "test/*"]
+ s.has_rdoc = true
+ s.add_dependency "less"
+end
View
1  vendor/plugins/more/rails/init.rb
@@ -0,0 +1 @@
+require File.join(File.dirname(__FILE__), '..', 'lib', 'less', 'controller_extension') if RAILS_ENV == 'development'
View
26 vendor/plugins/more/test/controller_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+class ExampleController < ActionController::Base
+ def test
+ render :text => 'OK'
+ end
+end
+
+class ControllerTest < ActionController::TestCase
+ def setup
+ @controller = ExampleController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ setup_for_generate_test
+ end
+
+ def teardown
+ teardown_for_generate_test
+ end
+
+ should "generate less files" do
+ write_less 'xxx.less', 'a{color:red}'
+ get :test
+ assert_equal 'a { color: red; }', read_css('xxx.css').strip
+ end
+end
View
213 vendor/plugins/more/test/more_test.rb
@@ -0,0 +1,213 @@
+require 'test_helper'
+
+class MoreTest < ActiveSupport::TestCase
+ setup do
+ [:compression, :header, :destination_path, :source_path].each do |variable|
+ Less::More.send("#{variable}=", nil)
+ end
+ end
+
+ context :header do
+ should "be true by default" do
+ assert_equal Less::More.header, true
+ end
+
+ should "be overwriteable" do
+ Less::More.header = false
+ assert_equal false, Less::More.header
+ end
+ end
+
+ context :source_path do
+ should "be app/stylesheets by default" do
+ assert_equal 'app/stylesheets', Less::More.source_path
+ end
+
+ should "be overwritteable" do
+ Less::More.source_path = 'xxx'
+ assert_equal 'xxx', Less::More.source_path
+ end
+ end
+
+ context :destination_path do
+ should "be public/stylesheets by default" do
+ assert_equal 'stylesheets', Less::More.destination_path
+ end
+
+ should "be overwritteable" do
+ Less::More.destination_path = 'xxx'
+ assert_equal 'xxx', Less::More.destination_path
+ end
+ end
+
+ context :compression do
+ should "be off by default" do
+ assert_equal nil, Less::More.compression
+ end
+
+ should "be overwritteable" do
+ Less::More.compression = true
+ assert_equal true, Less::More.compression
+ end
+ end
+
+ context :generate do
+ setup do
+ setup_for_generate_test
+ end
+
+ teardown do
+ teardown_for_generate_test
+ end
+
+ should 'generate css from .less files' do
+ write_less 'test.less', "a{color:red}"
+ Less::More.generate_all
+ assert_include 'a { color: red; }', read_css('test.css')
+ end
+
+ should 'generate css from .lss files' do
+ write_less 'test.lss', "a{color:red}"
+ Less::More.generate_all
+ assert_include 'a { color: red; }', read_css('test.css')
+ end
+
+ should 'generate for files in subfolders' do
+ write_less 'xxx/test.less', "a{color:red}"
+ Less::More.generate_all
+ assert_include 'a { color: red; }', read_css('xxx/test.css')
+ end
+
+ should "include imported partials" do
+ write_less 'test.less', "@import '_partial';\nb{color:blue}"
+ write_less '_partial.less', 'a{color:red}'
+ Less::More.generate_all
+ assert_include 'a { color: red; }', read_css('test.css')
+ end
+
+ should "not generate css from partials" do
+ write_less '_partial.less', 'a{color:red}'
+ Less::More.generate_all
+ assert_equal '', `ls #{css_path}`.strip
+ end
+
+ should "not parse css" do
+ write_less 'test.css', 'a{color:red}'
+ Less::More.generate_all
+ assert_equal 'a{color:red}', read_css('test.css')
+ end
+
+ should "add disclaimer-header when active" do
+ write_less 'test.less', 'a{color:red}'
+ Less::More.header = true
+ Less::More.generate_all
+ assert_match /^\/\*/, read_css('test.css')
+ end
+
+ should "not include header when not set" do
+ write_less 'test.less', 'a{color:red}'
+ Less::More.header = false
+ Less::More.generate_all
+ assert_not_include '/*', read_css('test.css')
+ end
+
+ should "fail with current file when encountering an error" do
+ write_less 'test.less', 'import xxxx;;;;;'
+ content = begin
+ Less::More.generate_all
+ '!no exception!'
+ rescue Exception => e
+ e.message
+ end
+ assert_include '/test.less', content
+ end
+
+ context 'mtime' do
+ should "generate for outdated less files" do
+ write_less 'test.less', "a{color:red}"
+ Less::More.generate_all
+
+ write_css 'test.css', 'im updated!'
+ sleep 1 # or mtime will be still the same ...
+ write_less 'test.less', "a{color:blue}"
+ Less::More.generate_all
+
+ assert_equal 'a { color: blue; }', read_css('test.css').strip
+ end
+
+ should "not generate for up-to-date less files" do
+ write_less 'test.less', "a{color:red}"
+ Less::More.generate_all
+
+ write_css 'test.css', 'im updated!'
+ Less::More.generate_all
+
+ assert_equal 'im updated!', read_css('test.css')
+ end
+
+ should "not generate for files with up-to-date partials" do
+ write_less 'test.less', "@import 'xxx/_test.less';"
+ write_less 'xxx/_test.less', "a{color:red}"
+ Less::More.generate_all
+
+ write_css 'test.css', 'im updated!'
+ Less::More.generate_all
+
+ assert_equal 'im updated!', read_css('test.css')
+ end
+
+ should "generate for files with outdated partials" do
+ write_less 'test.less', "@import 'xxx/_test.less';"
+ write_less 'xxx/_test.less', "a{color:red}"
+ Less::More.generate_all
+
+ write_css 'test.css', 'im updated!'
+ sleep 1 # or mtime will be still the same ...
+ write_less 'xxx/_test.less', "a{color:blue}"
+ Less::More.generate_all
+
+ assert_equal 'a { color: blue; }', read_css('test.css').strip
+ end
+
+ should "generate for files with outdated partials that are not named .less" do
+ write_less 'test.less', "@import 'xxx/_test';"
+ write_less 'xxx/_test.less', "a{color:red}"
+ Less::More.generate_all
+
+ write_css 'test.css', 'im updated!'
+ sleep 1 # or mtime will be still the same ...
+ write_less 'xxx/_test.less', "a{color:blue}"
+ Less::More.generate_all
+
+ assert_equal 'a { color: blue; }', read_css('test.css').strip
+ end
+ end
+ end
+
+ context :remove_all_generated do
+ setup do
+ setup_for_generate_test
+ end
+
+ teardown do
+ teardown_for_generate_test
+ end
+
+ should "remove all generated css" do
+ write_less 'xxx.less', 'a{color:red}'
+ write_less 'yyy.css', 'a{color:red}'
+ write_less 'xxx/yyy.css', 'a{color:red}'
+ Less::More.generate_all
+ Less::More.remove_all_generated
+ # should be '' ideally, but an empty folder is no thread :)
+ assert_equal 'xxx', `ls #{css_path}`.strip
+ end
+
+ should "not remove other files" do
+ write_css 'xxx.css', 'a{color:red}'
+ Less::More.generate_all
+ Less::More.remove_all_generated
+ assert_equal 'xxx.css', `ls #{css_path}`.strip
+ end
+ end
+end
View
79 vendor/plugins/more/test/test_helper.rb
@@ -0,0 +1,79 @@
+# fake Rails with loaded plugin
+require 'rubygems'
+require 'active_support'
+require 'action_pack'
+require 'action_controller'
+
+module Rails
+ def self.root
+ File.expand_path(File.dirname(__FILE__))
+ end
+
+ def self.backtrace_cleaner
+ ActiveSupport::BacktraceCleaner.new
+ end
+end
+
+RAILS_ENV = 'development'
+
+# load plugin
+$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
+require 'less/more'
+load 'init.rb'
+
+# load testing libs
+require 'test/unit'
+require 'active_support/test_case'
+begin; require 'redgreen'; rescue LoadError; end
+require 'shoulda'
+
+# setup controller testing
+require 'action_controller/test_process'
+ActionController::Base.logger = nil
+ActionController::Routing::Routes.reload rescue nil
+
+# test helpers
+def css_path
+ "#{Rails.root}/public/css"
+end
+
+def less_path
+ "#{Rails.root}/less_files"
+end
+
+def write_less file, content
+ write_content File.join(less_path, file), content
+end
+
+def write_css file, content
+ write_content File.join(css_path, file), content
+end
+
+def write_content file, content
+ `mkdir -p #{File.dirname(file)}`
+ File.open(file,'w'){|f| f.print content }
+end
+
+def read_css(file)
+ File.read(File.join(css_path, file)) rescue nil
+end
+
+def assert_include(item, obj)
+ assert_block("#{obj.inspect}\ndoes not include\n#{item.inspect}."){ obj.include? item }
+end
+
+def assert_not_include(item, obj)
+ assert_block("#{obj.inspect}\ndoes include\n#{item.inspect}."){ !obj.include? item }
+end
+
+def setup_for_generate_test
+ Less::More.source_path = 'less_files'
+ Less::More.destination_path = 'css'
+ Less::More.header = false
+ `mkdir -p #{css_path}`
+end
+
+def teardown_for_generate_test
+ `rm -rf #{css_path}`
+ `rm -rf #{less_path}`
+end
Please sign in to comment.
Something went wrong with that request. Please try again.