asset-trip 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +10 -0
- data/asset-trip.gemspec +4 -2
- data/lib/asset_trip.rb +1 -1
- data/lib/asset_trip/asset.rb +15 -9
- data/lib/asset_trip/ssl_stylesheet.rb +2 -2
- data/lib/asset_trip/stylesheet.rb +7 -3
- data/spec/asset_trip/ssl_stylesheet_spec.rb +11 -0
- data/spec/asset_trip/stylesheet_spec.rb +51 -38
- data/spec/integration/bundle_spec.rb +48 -29
- data/spec/support/core_extensions.rb +22 -0
- data/spec/support/helpers.rb +7 -0
- metadata +4 -2
data/History.txt
CHANGED
data/asset-trip.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{asset-trip}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.1"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Bryan Helmkamp"]
|
9
|
-
s.date = %q{2009-11-
|
9
|
+
s.date = %q{2009-11-09}
|
10
10
|
s.description = %q{Asset Trip bundles JavaScript and CSS files at deploy time. The assets are
|
11
11
|
then served from a Git-esque object store in the application's public
|
12
12
|
directory.}
|
@@ -48,6 +48,7 @@ directory.}
|
|
48
48
|
"spec/asset_trip/load_path_spec.rb",
|
49
49
|
"spec/asset_trip/manifest_writer_spec.rb",
|
50
50
|
"spec/asset_trip/middleware_spec.rb",
|
51
|
+
"spec/asset_trip/ssl_stylesheet_spec.rb",
|
51
52
|
"spec/asset_trip/stylesheet_spec.rb",
|
52
53
|
"spec/asset_trip/url_rewriter_spec.rb",
|
53
54
|
"spec/asset_trip_spec.rb",
|
@@ -81,6 +82,7 @@ directory.}
|
|
81
82
|
"spec/asset_trip/load_path_spec.rb",
|
82
83
|
"spec/asset_trip/manifest_writer_spec.rb",
|
83
84
|
"spec/asset_trip/middleware_spec.rb",
|
85
|
+
"spec/asset_trip/ssl_stylesheet_spec.rb",
|
84
86
|
"spec/asset_trip/stylesheet_spec.rb",
|
85
87
|
"spec/asset_trip/url_rewriter_spec.rb",
|
86
88
|
"spec/asset_trip_spec.rb",
|
data/lib/asset_trip.rb
CHANGED
data/lib/asset_trip/asset.rb
CHANGED
@@ -14,33 +14,39 @@ module AssetTrip
|
|
14
14
|
instance_eval(&block) if block_given?
|
15
15
|
end
|
16
16
|
|
17
|
+
def bundle!
|
18
|
+
FileWriter.new(path).write!(contents) if expired?
|
19
|
+
end
|
20
|
+
|
17
21
|
def contents
|
18
22
|
compressor.compress(joined_contents)
|
19
23
|
end
|
24
|
+
memoize :contents
|
20
25
|
|
21
26
|
def paths
|
22
27
|
files.map do |file|
|
23
28
|
@config.resolve_file(asset_type, file)
|
24
29
|
end
|
25
30
|
end
|
31
|
+
memoize :paths
|
26
32
|
|
27
|
-
def
|
33
|
+
def md5sum
|
28
34
|
if expired?
|
29
|
-
|
35
|
+
Digest::MD5.hexdigest(contents)
|
30
36
|
else
|
31
|
-
last_package
|
32
|
-
@md5sum = File.dirname(last_package).last(12).gsub(/\//, '')
|
37
|
+
File.dirname(last_package).to_s.last(12).gsub("/", "")
|
33
38
|
end
|
34
39
|
end
|
35
|
-
|
36
|
-
def md5sum
|
37
|
-
@md5sum ||= Digest::MD5.hexdigest(contents)
|
38
|
-
end
|
40
|
+
memoize :md5sum
|
39
41
|
|
40
42
|
private
|
41
43
|
|
44
|
+
def last_package
|
45
|
+
packaged_files.sort_by { |path| File.mtime(path) }.last
|
46
|
+
end
|
47
|
+
|
42
48
|
def expired?
|
43
|
-
packaged_files.empty? || generated_at <= last_change_at
|
49
|
+
ENV["FORCE"] || packaged_files.empty? || generated_at <= last_change_at
|
44
50
|
end
|
45
51
|
|
46
52
|
def generated_at
|
@@ -25,10 +25,10 @@ module AssetTrip
|
|
25
25
|
public_path = AssetTrip.app_root.join("public")
|
26
26
|
|
27
27
|
if filesystem_path.to_s.starts_with?(public_path)
|
28
|
-
|
29
|
-
UrlRewriter.new(
|
28
|
+
public_path = Pathname.new("/").join(filesystem_path.relative_path_from(public_path))
|
29
|
+
UrlRewriter.new(url_scheme, public_path)
|
30
30
|
else
|
31
|
-
UrlRewriter.new(
|
31
|
+
UrlRewriter.new(url_scheme)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -36,6 +36,10 @@ module AssetTrip
|
|
36
36
|
:stylesheets
|
37
37
|
end
|
38
38
|
|
39
|
+
def url_scheme
|
40
|
+
"http"
|
41
|
+
end
|
42
|
+
|
39
43
|
def extension
|
40
44
|
".css"
|
41
45
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "asset_trip/stylesheet_spec"
|
3
|
+
|
4
|
+
describe AssetTrip::SSLStylesheet do
|
5
|
+
let(:url_scheme) { "https" }
|
6
|
+
it_should_behave_like "an Asset that rewrites URLs"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe AssetTrip::SSLStylesheet do
|
10
|
+
it_should_behave_like "an Asset that compresses"
|
11
|
+
end
|
@@ -1,51 +1,64 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
setup_sandbox_app!
|
3
|
+
describe "an Asset that rewrites URLs", :shared => true do
|
4
|
+
setup_sandbox_app!
|
6
5
|
|
7
|
-
|
8
|
-
AssetTrip::Compressor.stub!(:new => compressor)
|
9
|
-
File.stub!(:read => "contents")
|
10
|
-
end
|
6
|
+
let(:url_rewriter) { stub(:rewrite => "rewritten") }
|
11
7
|
|
12
|
-
|
13
|
-
|
8
|
+
before do
|
9
|
+
AssetTrip::Compressor.stub!(:new => stub(:compress => "compressed"))
|
10
|
+
File.stub!(:read => "contents")
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
it "rewrites the URLs" do
|
14
|
+
AssetTrip::UrlRewriter.stub(:new => url_rewriter)
|
15
|
+
url_rewriter.should_receive(:rewrite).with("contents")
|
16
|
+
described_class.new(stub(:resolve_file => "/fonts.css"), "all", ["fonts"]).contents
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
context "when the stylesheet is in the public directory" do
|
20
|
+
it "does not initialize the UrlRewriter with a path" do
|
21
|
+
AssetTrip::UrlRewriter.should_receive(:new).with(url_scheme).and_return(url_rewriter)
|
22
|
+
described_class.new(stub(:resolve_file => "/fonts.css"), "all", ["fonts"]).contents
|
25
23
|
end
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
context "when the stylesheet is not in the public directory" do
|
27
|
+
it "initializes the UrlRewriter with a path" do
|
28
|
+
AssetTrip::UrlRewriter.should_receive(:new).with(url_scheme, Pathname.new("/fonts.css")).and_return(url_rewriter)
|
29
|
+
public_path = fixture_app.join("public", "fonts.css")
|
30
|
+
described_class.new(stub(:resolve_file => public_path), "all", ["fonts"]).contents
|
32
31
|
end
|
32
|
+
end
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
AssetTrip::UrlRewriter.should_receive(:new).with("http").and_return(url_rewriter)
|
37
|
-
asset = AssetTrip::Stylesheet.new(stub(:resolve_file => "/fonts.css"), "all", ["fonts"])
|
38
|
-
asset.contents
|
39
|
-
end
|
40
|
-
end
|
35
|
+
describe "an Asset that compresses", :shared => true do
|
36
|
+
setup_sandbox_app!
|
41
37
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
38
|
+
let(:compressor) { stub(:compress => "compressed") }
|
39
|
+
|
40
|
+
before do
|
41
|
+
AssetTrip::Compressor.stub!(:new => compressor)
|
42
|
+
File.stub!(:read => "contents")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "compresses the contents" do
|
46
|
+
AssetTrip::Compressor.should_receive(:new).with("css")
|
47
|
+
described_class.new(stub, "all.css").contents.should == "compressed"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "only runs the Compressor once for the package" do
|
51
|
+
compressor.should_receive(:compress).exactly(:once)
|
52
|
+
described_class.new(stub, "all.css").contents.should == "compressed"
|
50
53
|
end
|
51
54
|
end
|
55
|
+
|
56
|
+
describe AssetTrip::Stylesheet do
|
57
|
+
let(:url_scheme) { "http" }
|
58
|
+
it_should_behave_like "an Asset that rewrites URLs"
|
59
|
+
end
|
60
|
+
|
61
|
+
describe AssetTrip::Stylesheet do
|
62
|
+
it_should_behave_like "an Asset that compresses"
|
63
|
+
end
|
64
|
+
|
@@ -152,40 +152,59 @@ describe "rake asset_trip:bundle" do
|
|
152
152
|
end
|
153
153
|
|
154
154
|
it "does not write a new bundle if the package has not expired" do
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
155
|
+
Time.freeze do
|
156
|
+
install_config <<-CONFIG
|
157
|
+
js_asset "signup" do
|
158
|
+
include "main.js"
|
159
|
+
end
|
160
|
+
CONFIG
|
161
|
+
AssetTrip.bundle!
|
162
|
+
|
163
|
+
asset("signup.js").utime(5.minutes.ago, 5.minutes.ago)
|
164
|
+
app_javascript("main.js").utime(10.minutes.ago, 10.minutes.ago)
|
165
|
+
|
166
|
+
AssetTrip.bundle!
|
167
|
+
asset("signup.js").mtime.to_i.should == 5.minutes.ago.to_i
|
168
|
+
end
|
169
169
|
end
|
170
170
|
|
171
|
-
it "
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
171
|
+
it "writes a new bundle when forced even when the package is not expired" do
|
172
|
+
Time.freeze do
|
173
|
+
install_config <<-CONFIG
|
174
|
+
js_asset "signup" do
|
175
|
+
include "main.js"
|
176
|
+
end
|
177
|
+
CONFIG
|
178
|
+
AssetTrip.bundle!
|
178
179
|
|
179
|
-
|
180
|
-
|
181
|
-
oldest_asset_mtime = 15.minutes.ago
|
180
|
+
asset("signup.js").utime(5.minutes.ago, 5.minutes.ago)
|
181
|
+
app_javascript("main.js").utime(10.minutes.ago, 10.minutes.ago)
|
182
182
|
|
183
|
-
|
184
|
-
|
185
|
-
|
183
|
+
with_env("FORCE", "1") do
|
184
|
+
AssetTrip.bundle!
|
185
|
+
end
|
186
|
+
asset("signup.js").mtime.to_i.should > 5.minutes.ago.to_i
|
187
|
+
end
|
188
|
+
end
|
186
189
|
|
187
|
-
|
188
|
-
|
190
|
+
it "should use the most recent package to detect mtimes for expiry" do
|
191
|
+
Time.freeze do
|
192
|
+
install_config <<-CONFIG
|
193
|
+
js_asset "signup" do
|
194
|
+
include "main.js"
|
195
|
+
end
|
196
|
+
CONFIG
|
197
|
+
AssetTrip.bundle!
|
198
|
+
|
199
|
+
asset("signup.js").utime(5.minutes.ago, 5.minutes.ago)
|
200
|
+
app_javascript("main.js").utime(10.minutes.ago, 10.minutes.ago)
|
201
|
+
create_asset("46/123431bdc/signup.js", :mtime => 15.minutes.ago)
|
202
|
+
|
203
|
+
AssetTrip.bundle!
|
204
|
+
assets("signup.js").map { |asset|
|
205
|
+
asset.mtime.to_i
|
206
|
+
}.sort.should == [15.minutes.ago.to_i, 5.minutes.ago.to_i]
|
207
|
+
end
|
189
208
|
end
|
190
209
|
end
|
191
210
|
|
@@ -11,3 +11,25 @@ module AssetTrip
|
|
11
11
|
Pathname.send(:include, PathnameExtensions)
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
class Time
|
16
|
+
class << self
|
17
|
+
alias_method :orig_new, :new
|
18
|
+
|
19
|
+
undef :now
|
20
|
+
def now
|
21
|
+
defined?(@time) ? @time || orig_new : orig_new
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :new, :now
|
25
|
+
|
26
|
+
undef :freeze
|
27
|
+
def freeze
|
28
|
+
@time = now
|
29
|
+
yield
|
30
|
+
ensure
|
31
|
+
@time = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/spec/support/helpers.rb
CHANGED
@@ -2,6 +2,13 @@ module AssetTrip
|
|
2
2
|
module Spec
|
3
3
|
module Helpers
|
4
4
|
|
5
|
+
def with_env(key, value)
|
6
|
+
old, ENV[key] = ENV[key], value
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
old ? ENV[key] = old : ENV.delete(key)
|
10
|
+
end
|
11
|
+
|
5
12
|
def install_config(config_source, filename = "assets.rb")
|
6
13
|
FileUtils.mkdir_p(fixture_app)
|
7
14
|
File.open(fixture_app("config", "asset_trip", filename), 'w') do |f|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asset-trip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Helmkamp
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-09 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- spec/asset_trip/load_path_spec.rb
|
59
59
|
- spec/asset_trip/manifest_writer_spec.rb
|
60
60
|
- spec/asset_trip/middleware_spec.rb
|
61
|
+
- spec/asset_trip/ssl_stylesheet_spec.rb
|
61
62
|
- spec/asset_trip/stylesheet_spec.rb
|
62
63
|
- spec/asset_trip/url_rewriter_spec.rb
|
63
64
|
- spec/asset_trip_spec.rb
|
@@ -114,6 +115,7 @@ test_files:
|
|
114
115
|
- spec/asset_trip/load_path_spec.rb
|
115
116
|
- spec/asset_trip/manifest_writer_spec.rb
|
116
117
|
- spec/asset_trip/middleware_spec.rb
|
118
|
+
- spec/asset_trip/ssl_stylesheet_spec.rb
|
117
119
|
- spec/asset_trip/stylesheet_spec.rb
|
118
120
|
- spec/asset_trip/url_rewriter_spec.rb
|
119
121
|
- spec/asset_trip_spec.rb
|