rack-less 1.5.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.bundle/config +2 -0
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +53 -0
- data/Rakefile +5 -43
- data/lib/rack/less.rb +6 -12
- data/lib/rack/less/config.rb +13 -25
- data/lib/rack/less/request.rb +36 -22
- data/lib/rack/less/source.rb +7 -7
- data/lib/rack/less/version.rb +3 -11
- data/rack-less.gemspec +29 -0
- data/test/app_helper.rb +25 -0
- data/test/config_test.rb +215 -0
- data/test/env.rb +9 -0
- data/test/fixtures/mock_options.rb +9 -0
- data/test/fixtures/sinatra/app.rb +9 -0
- data/test/fixtures/sinatra/app/stylesheets/all_compiled.css +7 -0
- data/test/fixtures/sinatra/app/stylesheets/all_one.less +10 -0
- data/test/fixtures/sinatra/app/stylesheets/all_two.less +4 -0
- data/test/fixtures/sinatra/app/stylesheets/css.css +4 -0
- data/test/fixtures/sinatra/app/stylesheets/css_compiled.css +4 -0
- data/test/fixtures/sinatra/app/stylesheets/nested/file.css +10 -0
- data/test/fixtures/sinatra/app/stylesheets/nested/file_compiled.css +2 -0
- data/test/fixtures/sinatra/app/stylesheets/nested/really/really.less +10 -0
- data/test/fixtures/sinatra/app/stylesheets/nested/really/really_compiled.css +2 -0
- data/test/fixtures/sinatra/app/stylesheets/normal.less +10 -0
- data/test/fixtures/sinatra/app/stylesheets/normal_compiled.css +2 -0
- data/test/fixtures/sinatra/app/stylesheets/some-styles.less +8 -0
- data/test/fixtures/sinatra/app/stylesheets/some_styles.less +8 -0
- data/test/fixtures/sinatra/app/stylesheets/styles1.less +8 -0
- data/test/helper.rb +77 -0
- data/test/options_test.rb +60 -0
- data/test/request_test.rb +142 -0
- data/test/response_test.rb +41 -0
- data/test/sinatra_test.rb +54 -0
- data/test/source_test.rb +158 -0
- metadata +93 -57
data/.bundle/config
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rack-less (2.0.0)
|
5
|
+
less (~> 1.2)
|
6
|
+
rack (~> 1.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
json (1.5.1)
|
12
|
+
kelredd-useful (0.4.1)
|
13
|
+
json
|
14
|
+
leftright (0.9.0)
|
15
|
+
less (1.2.21)
|
16
|
+
mutter (>= 0.4.2)
|
17
|
+
treetop (>= 1.4.2)
|
18
|
+
mutter (0.5.3)
|
19
|
+
nokogiri (1.4.4)
|
20
|
+
polyglot (0.3.1)
|
21
|
+
rack (1.2.2)
|
22
|
+
rack-test (0.5.7)
|
23
|
+
rack (>= 1.0)
|
24
|
+
shoulda (2.11.3)
|
25
|
+
sinatra (1.2.1)
|
26
|
+
rack (~> 1.1)
|
27
|
+
tilt (>= 1.2.2, < 2.0)
|
28
|
+
test-belt (0.2.1)
|
29
|
+
kelredd-useful (~> 0.4.0)
|
30
|
+
leftright (~> 0.9.0)
|
31
|
+
shoulda (~> 2.11)
|
32
|
+
tilt (1.2.2)
|
33
|
+
treetop (1.4.9)
|
34
|
+
polyglot (>= 0.3.1)
|
35
|
+
webrat (0.7.3)
|
36
|
+
nokogiri (>= 1.2.0)
|
37
|
+
rack (>= 1.0)
|
38
|
+
rack-test (>= 0.5.3)
|
39
|
+
yui-compressor (0.9.4)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
bundler (~> 1.0)
|
46
|
+
less (~> 1.2)
|
47
|
+
rack (~> 1.0)
|
48
|
+
rack-less!
|
49
|
+
rack-test (>= 0.5.3)
|
50
|
+
sinatra (>= 0.9.4)
|
51
|
+
test-belt (= 0.2.1)
|
52
|
+
webrat (>= 0.6.0)
|
53
|
+
yui-compressor (>= 0.9.1)
|
data/Rakefile
CHANGED
@@ -1,45 +1,7 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'simple_gem/testtasks'
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
4
3
|
|
5
|
-
require '
|
4
|
+
require 'test_belt/rake_tasks'
|
5
|
+
TestBelt::RakeTasks.for :test
|
6
6
|
|
7
|
-
|
8
|
-
s.name = 'rack-less'
|
9
|
-
s.version = RackLess::Version.to_s
|
10
|
-
s.has_rdoc = true
|
11
|
-
s.extra_rdoc_files = %w(README.rdoc)
|
12
|
-
s.rdoc_options = %w(--main README.rdoc)
|
13
|
-
s.summary = "A better way to use LESS CSS in Ruby web apps."
|
14
|
-
s.author = 'Kelly Redding'
|
15
|
-
s.email = 'kelly@kelredd.com'
|
16
|
-
s.homepage = 'http://github.com/kelredd/rack-less'
|
17
|
-
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib}/**/*")
|
18
|
-
# s.executables = ['rack-less']
|
19
|
-
|
20
|
-
s.add_development_dependency("shoulda", [">= 2.10.2"])
|
21
|
-
s.add_development_dependency("leftright", [">= 0.0.6"])
|
22
|
-
s.add_development_dependency("sinatra", [">= 0.9.4"])
|
23
|
-
s.add_development_dependency("rack-test", [">= 0.5.3"])
|
24
|
-
s.add_development_dependency("webrat", [">= 0.6.0"])
|
25
|
-
s.add_development_dependency("yui-compressor", [">=0.9.1"])
|
26
|
-
s.add_development_dependency("kelredd-simple-gem", [">= 0.7.0"])
|
27
|
-
|
28
|
-
s.add_dependency("rack", [">= 0.4"])
|
29
|
-
s.add_dependency("less", [">= 1.2.21"])
|
30
|
-
end
|
31
|
-
|
32
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
33
|
-
pkg.gem_spec = spec
|
34
|
-
end
|
35
|
-
|
36
|
-
SimpleGem::TestTasks.new
|
37
|
-
|
38
|
-
desc 'Generate the gemspec to serve this gem'
|
39
|
-
task :gemspec do
|
40
|
-
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
41
|
-
File.open(file, 'w') {|f| f << spec.to_ruby }
|
42
|
-
puts "Created gemspec: #{file}"
|
43
|
-
end
|
44
|
-
|
45
|
-
task :default => :gem
|
7
|
+
task :default => :build
|
data/lib/rack/less.rb
CHANGED
@@ -24,9 +24,9 @@ require 'rack/less/source'
|
|
24
24
|
module Rack::Less
|
25
25
|
MIME_TYPE = "text/css"
|
26
26
|
@@config = Config.new
|
27
|
-
|
27
|
+
|
28
28
|
class << self
|
29
|
-
|
29
|
+
|
30
30
|
# Configuration accessors for Rack::Less
|
31
31
|
# (see config.rb for details)
|
32
32
|
def configure
|
@@ -38,12 +38,12 @@ module Rack::Less
|
|
38
38
|
def config=(value)
|
39
39
|
@@config = value
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Combinations config convenience method
|
43
43
|
def combinations(key=nil)
|
44
44
|
@@config.combinations(key)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
# Stylesheet helper, config convenience method
|
48
48
|
def stylesheet(key)
|
49
49
|
@@config.stylesheet(key)
|
@@ -54,19 +54,13 @@ module Rack::Less
|
|
54
54
|
@@config.cache_bust
|
55
55
|
end
|
56
56
|
|
57
|
-
# <b>DEPRECATED:</b> Please use <tt>cache_bust</tt> instead.
|
58
|
-
def combination_timestamp
|
59
|
-
warn "[DEPRECATION] `combination_timestamp` is deprecated. Please use `cache_bust` instead."
|
60
|
-
cache_bust
|
61
|
-
end
|
62
|
-
|
63
57
|
end
|
64
58
|
|
65
|
-
# Create a new Rack::Less middleware component
|
59
|
+
# Create a new Rack::Less middleware component
|
66
60
|
# => the +options+ Hash can be used to specify default configuration values
|
67
61
|
# => (see Rack::Less::Options for possible key/values)
|
68
62
|
def self.new(app, options={}, &block)
|
69
63
|
Base.new(app, options, &block)
|
70
64
|
end
|
71
|
-
|
65
|
+
|
72
66
|
end
|
data/lib/rack/less/config.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Rack::Less
|
2
|
-
|
2
|
+
|
3
3
|
# Handles configuration for Rack::Less
|
4
4
|
# Available config settings:
|
5
5
|
# :cache
|
@@ -24,10 +24,10 @@ module Rack::Less
|
|
24
24
|
# :cache_bust
|
25
25
|
# whether to append a timestamp to the sheet requests generated by combinations
|
26
26
|
class Config
|
27
|
-
|
27
|
+
|
28
28
|
ATTRIBUTES = [:cache, :compress, :combinations, :cache_bust]
|
29
29
|
attr_accessor *ATTRIBUTES
|
30
|
-
|
30
|
+
|
31
31
|
DEFAULTS = {
|
32
32
|
:cache => false,
|
33
33
|
:compress => false,
|
@@ -37,30 +37,18 @@ module Rack::Less
|
|
37
37
|
def initialize(settings={})
|
38
38
|
ATTRIBUTES.each do |a|
|
39
39
|
instance_variable_set("@#{a}", settings[a] || DEFAULTS[a])
|
40
|
-
end
|
40
|
+
end
|
41
41
|
@cache_bust = default_cache_bust if @cache_bust.nil?
|
42
42
|
end
|
43
|
-
|
44
|
-
# <b>DEPRECATED:</b> Please use <tt>cache_bust</tt> instead.
|
45
|
-
def combination_timestamp
|
46
|
-
warn "[DEPRECATION] `combination_timestamp` is deprecated. Please use `cache_bust` instead."
|
47
|
-
cache_bust
|
48
|
-
end
|
49
|
-
|
50
|
-
# <b>DEPRECATED:</b> Please use <tt>cache_bust=</tt> instead.
|
51
|
-
def combination_timestamp=(value)
|
52
|
-
warn "[DEPRECATION] `combination_timestamp=` is deprecated. Please use `cache_bust=` instead."
|
53
|
-
cache_bust = value
|
54
|
-
end
|
55
|
-
|
43
|
+
|
56
44
|
def cache?
|
57
45
|
!!@cache
|
58
46
|
end
|
59
|
-
|
47
|
+
|
60
48
|
def compress?
|
61
49
|
!!@compress
|
62
50
|
end
|
63
|
-
|
51
|
+
|
64
52
|
def combinations(key=nil)
|
65
53
|
if key.nil?
|
66
54
|
@combinations
|
@@ -74,7 +62,7 @@ module Rack::Less
|
|
74
62
|
end
|
75
63
|
end
|
76
64
|
end
|
77
|
-
|
65
|
+
|
78
66
|
def stylesheet(key)
|
79
67
|
if @combinations[key]
|
80
68
|
combinations(key.to_s)
|
@@ -84,7 +72,7 @@ module Rack::Less
|
|
84
72
|
end
|
85
73
|
|
86
74
|
private
|
87
|
-
|
75
|
+
|
88
76
|
def stylesheet_filename(key)
|
89
77
|
filename = key.strip
|
90
78
|
filename += ".css" unless filename.include?('.css')
|
@@ -98,7 +86,7 @@ module Rack::Less
|
|
98
86
|
end
|
99
87
|
filename
|
100
88
|
end
|
101
|
-
|
89
|
+
|
102
90
|
def default_cache_bust
|
103
91
|
if defined?(::Sinatra) && defined?(::Sinatra::Application)
|
104
92
|
app_root_cache_bust(::Sinatra::Application)
|
@@ -106,18 +94,18 @@ module Rack::Less
|
|
106
94
|
app_root_cache_bust(::Rails)
|
107
95
|
end || false
|
108
96
|
end
|
109
|
-
|
97
|
+
|
110
98
|
def app_root_cache_bust(app)
|
111
99
|
if app.respond_to?(:root)
|
112
100
|
mtime_cache_bust(app.root.to_s)
|
113
101
|
end
|
114
102
|
end
|
115
|
-
|
103
|
+
|
116
104
|
def mtime_cache_bust(path)
|
117
105
|
if File.exists?(path)
|
118
106
|
File.mtime(path).to_i
|
119
107
|
end
|
120
108
|
end
|
121
|
-
|
109
|
+
|
122
110
|
end
|
123
111
|
end
|
data/lib/rack/less/request.rb
CHANGED
@@ -23,28 +23,42 @@ module Rack::Less
|
|
23
23
|
@env['REQUEST_METHOD']
|
24
24
|
end
|
25
25
|
|
26
|
-
def path_info
|
27
|
-
@env['PATH_INFO']
|
28
|
-
end
|
29
|
-
|
30
26
|
def http_accept
|
31
27
|
@env['HTTP_ACCEPT']
|
32
28
|
end
|
33
29
|
|
34
|
-
def
|
35
|
-
|
30
|
+
def path_info
|
31
|
+
@env['PATH_INFO']
|
32
|
+
end
|
33
|
+
|
34
|
+
def hosted_at_option
|
35
|
+
# sanitized :hosted_at option
|
36
|
+
# remove any trailing '/'
|
37
|
+
# ensure single leading '/'
|
38
|
+
@hosted_at_option ||= options(:hosted_at).sub(/\/+$/, '').sub(/^\/*/, '/')
|
36
39
|
end
|
37
40
|
|
38
|
-
def
|
39
|
-
|
41
|
+
def path_info_resource
|
42
|
+
# sanitized path to the resource being requested
|
43
|
+
# ensure single leading '/'
|
44
|
+
# remove any resource format
|
45
|
+
# ex:
|
46
|
+
# '/something.css' => '/something'
|
47
|
+
# '/nested/something.css' => '/nested/something'
|
48
|
+
# '///something.css' => '/something'
|
49
|
+
# '/nested///something.css' => '/nested/something'
|
50
|
+
@path_info_resource ||= File.join(
|
51
|
+
File.dirname(path_info.gsub(/\/+/, '/')).sub(/^#{hosted_at_option}/, ''),
|
52
|
+
File.basename(path_info.gsub(/\/+/, '/'), path_info_format)
|
53
|
+
).sub(/^\/*/, '/')
|
40
54
|
end
|
41
55
|
|
42
|
-
def
|
43
|
-
File.
|
56
|
+
def path_info_format
|
57
|
+
@path_info_format ||= File.extname(path_info.gsub(/\/+/, '/'))
|
44
58
|
end
|
45
59
|
|
46
60
|
def cache
|
47
|
-
File.join(options(:root), options(:public),
|
61
|
+
File.join(options(:root), options(:public), hosted_at_option)
|
48
62
|
end
|
49
63
|
|
50
64
|
# The Rack::Less::Source that the request is for
|
@@ -55,35 +69,35 @@ module Rack::Less
|
|
55
69
|
:cache => Rack::Less.config.cache? ? cache : nil,
|
56
70
|
:compress => Rack::Less.config.compress?
|
57
71
|
}
|
58
|
-
Source.new(
|
72
|
+
Source.new(path_info_resource, source_opts)
|
59
73
|
end
|
60
74
|
end
|
61
75
|
|
62
76
|
def for_css?
|
63
77
|
(http_accept && http_accept.include?(Rack::Less::MIME_TYPE)) ||
|
64
78
|
(media_type && media_type.include?(Rack::Less::MIME_TYPE )) ||
|
65
|
-
CSS_PATH_FORMATS.include?(
|
79
|
+
CSS_PATH_FORMATS.include?(path_info_format)
|
66
80
|
end
|
67
81
|
|
68
82
|
def hosted_at?
|
69
|
-
path_info =~ /^#{
|
83
|
+
path_info =~ /^#{hosted_at_option}\//
|
70
84
|
end
|
71
85
|
|
72
|
-
def
|
73
|
-
File.exists?(File.join(cache, "#{
|
86
|
+
def cached?
|
87
|
+
File.exists?(File.join(cache, "#{path_info_resource}#{path_info_format}"))
|
74
88
|
end
|
75
89
|
|
76
|
-
# Determine if the request is for existing LESS CSS file
|
90
|
+
# Determine if the request is for a non-cached existing LESS CSS source file
|
77
91
|
# This will be called on every request so speed is an issue
|
78
|
-
# => first check if the request is a GET on a css resource :hosted_at (fast)
|
79
|
-
# => don't process if a file already
|
92
|
+
# => first check if the request is a GET on a css resource in :hosted_at (fast)
|
93
|
+
# => don't process if a file has already been cached
|
80
94
|
# => otherwise, check for less source files that match the request (slow)
|
81
95
|
def for_less?
|
82
|
-
get? &&
|
96
|
+
get? && # GET on css resource in :hosted_at (fast, check first)
|
83
97
|
for_css? &&
|
84
98
|
hosted_at? &&
|
85
|
-
!
|
86
|
-
!source.files.empty?
|
99
|
+
!cached? && # resource not cached (little slower)
|
100
|
+
!source.files.empty? # there is source for the resource (slow, check last)
|
87
101
|
end
|
88
102
|
|
89
103
|
end
|
data/lib/rack/less/source.rb
CHANGED
@@ -21,10 +21,10 @@ module Rack::Less
|
|
21
21
|
|
22
22
|
YUI_OPTS = {}
|
23
23
|
|
24
|
-
attr_reader :
|
24
|
+
attr_reader :css_resource
|
25
25
|
|
26
|
-
def initialize(
|
27
|
-
@
|
26
|
+
def initialize(css_resource, options={})
|
27
|
+
@css_resource = css_resource.gsub(/^\/+/, '')
|
28
28
|
@compress = options[:compress]
|
29
29
|
@cache = options[:cache]
|
30
30
|
@folder = get_required_path(options, :folder)
|
@@ -64,8 +64,8 @@ module Rack::Less
|
|
64
64
|
compiled_css
|
65
65
|
end
|
66
66
|
|
67
|
-
if cache? && !File.exists?(cf = File.join(@cache, "#{@
|
68
|
-
FileUtils.mkdir_p(
|
67
|
+
if cache? && !File.exists?(cf = File.join(@cache, "#{@css_resource}.css"))
|
68
|
+
FileUtils.mkdir_p(File.dirname(cf))
|
69
69
|
File.open(cf, "w") do |file|
|
70
70
|
file.write(compiled_css)
|
71
71
|
end
|
@@ -81,13 +81,13 @@ module Rack::Less
|
|
81
81
|
|
82
82
|
# Preferred, existing source files matching the css name
|
83
83
|
def css_sources
|
84
|
-
@css_sources ||= preferred_sources([
|
84
|
+
@css_sources ||= preferred_sources([*@css_resource])
|
85
85
|
end
|
86
86
|
|
87
87
|
# Preferred, existing source files matching a corresponding
|
88
88
|
# Rack::Less::Config combination directive, if any
|
89
89
|
def combination_sources
|
90
|
-
@combination_sources ||= preferred_sources(Rack::Less.config.combinations[@
|
90
|
+
@combination_sources ||= preferred_sources(Rack::Less.config.combinations[@css_resource] || [])
|
91
91
|
end
|
92
92
|
|
93
93
|
private
|
data/lib/rack/less/version.rb
CHANGED
data/rack-less.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rack/less/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rack-less"
|
7
|
+
s.version = Rack::Less::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Kelly Redding"]
|
10
|
+
s.email = ["kelly@kelredd.com"]
|
11
|
+
s.homepage = "http://github.com/kelredd/rack-less"
|
12
|
+
s.summary = %q{LESS CSS preprocessing for Rack apps.}
|
13
|
+
s.description = %q{Use rack middleware to handle LESS CSS preprocessing. Processing happens on requests to LESS resources. This allows you to develop, check in, and deploy unprocessed LESS stylesheets and leave the processing to the middleware. Allows for optimizing by environment: never-cache, always-reprocess in development; cache, process-once in production (for example).}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_development_dependency("bundler", ["~> 1.0"])
|
21
|
+
s.add_development_dependency("test-belt", ["= 0.2.1"]) # locked to a specific version for test stability
|
22
|
+
s.add_development_dependency("sinatra", [">= 0.9.4"])
|
23
|
+
s.add_development_dependency("rack-test", [">= 0.5.3"])
|
24
|
+
s.add_development_dependency("webrat", [">= 0.6.0"])
|
25
|
+
s.add_development_dependency("yui-compressor", [">=0.9.1"])
|
26
|
+
|
27
|
+
s.add_dependency("rack", ["~> 1.0"])
|
28
|
+
s.add_dependency("less", ["~> 1.2"])
|
29
|
+
end
|