dassets 0.14.5 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -7
- data/.ruby-version +1 -0
- data/Gemfile +3 -1
- data/README.md +15 -17
- data/dassets.gemspec +7 -6
- data/lib/dassets.rb +20 -18
- data/lib/dassets/asset_file.rb +14 -12
- data/lib/dassets/cache.rb +27 -33
- data/lib/dassets/config.rb +55 -51
- data/lib/dassets/engine.rb +11 -23
- data/lib/dassets/file_store.rb +27 -28
- data/lib/dassets/server.rb +27 -28
- data/lib/dassets/server/request.rb +43 -41
- data/lib/dassets/server/response.rb +93 -81
- data/lib/dassets/source.rb +13 -8
- data/lib/dassets/source_file.rb +100 -82
- data/lib/dassets/source_proxy.rb +32 -16
- data/lib/dassets/version.rb +3 -1
- data/test/helper.rb +18 -24
- data/test/support/app.rb +3 -5
- data/test/support/factory.rb +1 -2
- data/test/support/linked_source_files/linked_file.txt +0 -0
- data/test/support/source_files/linked +1 -0
- data/test/support/source_files/linked_file2.txt +1 -0
- data/test/system/rack_tests.rb +55 -59
- data/test/unit/asset_file_tests.rb +63 -59
- data/test/unit/cache_tests.rb +14 -35
- data/test/unit/config_tests.rb +53 -49
- data/test/unit/dassets_tests.rb +25 -40
- data/test/unit/engine_tests.rb +7 -43
- data/test/unit/file_store_tests.rb +33 -25
- data/test/unit/server/request_tests.rb +43 -48
- data/test/unit/server/response_tests.rb +79 -81
- data/test/unit/server_tests.rb +3 -9
- data/test/unit/source_file_tests.rb +73 -72
- data/test/unit/source_proxy_tests.rb +78 -89
- data/test/unit/source_tests.rb +58 -50
- metadata +78 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 51a6c8bbf4e5b1a6cebb52c6da1ce5a6eae5714cf8cd410d2aa06a79737fc9b5
|
4
|
+
data.tar.gz: f97b79e8148698de5d6a1cd97419e34b416a1a03c4d9773e742614403fd9180d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8310a78cfbbcb27795f0319303f1471625edb03e10a747e52c195a85f0b791adc41ed52a45aa4756525d67160bcbc50d788a45076f52f60513bd51ac5b63932
|
7
|
+
data.tar.gz: f01e81b5758d052dcf8b5e602eb1798e206ff1cb5c9ab8d80dfaf90c83841ce278e83e8dd3577f976c37fd05a073b66ff7cd57e27d3c11bfff092a1fdb93a967
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.5
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,27 +10,25 @@ You have some css, js, images, etc files. You want to update, deploy, and serve
|
|
10
10
|
|
11
11
|
```ruby
|
12
12
|
# in config/dassets.rb
|
13
|
-
require
|
13
|
+
require "dassets"
|
14
14
|
|
15
15
|
Dassets.configure do |c|
|
16
|
-
|
17
16
|
# tell Dassets where to look for source files
|
18
|
-
c.source
|
17
|
+
c.source "/path/to/app/assets"
|
19
18
|
|
20
19
|
# (optional) tell Dassets where to store digested asset files
|
21
20
|
# if none given, Dassets will not write any digested output
|
22
21
|
# use this to "cache" digested assets to the public dir so that
|
23
22
|
# your web server can serve them directly
|
24
|
-
c.file_store
|
25
|
-
|
23
|
+
c.file_store "/path/to/public" # default: `Dassets::NullFileStore.new`
|
26
24
|
end
|
27
25
|
```
|
28
26
|
|
29
27
|
### Link To
|
30
28
|
|
31
|
-
```
|
32
|
-
Dassets[
|
33
|
-
Dassets[
|
29
|
+
```ruby
|
30
|
+
Dassets["css/site.css"].url # => "/css/site-123abc.css"
|
31
|
+
Dassets["img/logos/main.jpg"].url # => "/img/logos/main-a1b2c3.jpg"
|
34
32
|
```
|
35
33
|
|
36
34
|
### Serve
|
@@ -39,7 +37,7 @@ Use the Dassets middleware to serve your digested asset files:
|
|
39
37
|
|
40
38
|
```ruby
|
41
39
|
# `app` is a rack application
|
42
|
-
require
|
40
|
+
require "dassets/server"
|
43
41
|
app.use Dassets::Server
|
44
42
|
```
|
45
43
|
|
@@ -75,16 +73,16 @@ Dassets.configure do |c|
|
|
75
73
|
c.source /path/to/assets do |s|
|
76
74
|
s.filter{ |paths| paths.reject{ |p| File.basename(p) =~ /^_/ } }
|
77
75
|
|
78
|
-
s.engine
|
79
|
-
s.engine
|
80
|
-
|
76
|
+
s.engine "erb", Dassets::Erb::Engine
|
77
|
+
s.engine "scss", Dassets::Sass::Engine, {
|
78
|
+
"syntax" => "scss",
|
81
79
|
# any other engine-specific options here
|
82
80
|
}
|
83
81
|
end
|
84
82
|
end
|
85
83
|
```
|
86
84
|
|
87
|
-
This configuration says that Dassets, for assets in `/path/to/assets`, should 1) ignore any files beginning in `_` 2) process any files ending in `.erb` with the Erb engine and 3) process any files ending in `.scss` with the Sass engine (using
|
85
|
+
This configuration says that Dassets, for assets in `/path/to/assets`, should 1) ignore any files beginning in `_` 2) process any files ending in `.erb` with the Erb engine and 3) process any files ending in `.scss` with the Sass engine (using scss syntax).
|
88
86
|
|
89
87
|
The goal here is to allow you to control how certain asset files are handled based on their location root. This is handy for 3rd-paty gems that provide asset source files (such as [Romo](https://github.com/redding/romo)). See https://github.com/redding/romo/blob/master/lib/romo/dassets.rb for an example of how Romo integrates with Dassets.
|
90
88
|
|
@@ -95,9 +93,9 @@ Combinations are a way to alias many asset files as a single asset. Dassets res
|
|
95
93
|
```ruby
|
96
94
|
Dassets.configure do |c|
|
97
95
|
c.combination "css/special.css", [
|
98
|
-
|
99
|
-
|
100
|
-
|
96
|
+
"css/romo/normalize.css",
|
97
|
+
"css/romo/base.css",
|
98
|
+
"css/romo/component1.css",
|
101
99
|
]
|
102
100
|
end
|
103
101
|
```
|
@@ -110,7 +108,7 @@ Combinations are treated just like regular asset files (think of them as a kind
|
|
110
108
|
|
111
109
|
Add this line to your application's Gemfile:
|
112
110
|
|
113
|
-
gem
|
111
|
+
gem "dassets"
|
114
112
|
|
115
113
|
And then execute:
|
116
114
|
|
data/dassets.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require "dassets/version"
|
5
5
|
|
@@ -11,17 +11,18 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.summary = %q{Digested asset files}
|
12
12
|
gem.description = %q{Digest and serve HTML asset files}
|
13
13
|
gem.homepage = "http://github.com/redding/dassets"
|
14
|
-
gem.license =
|
14
|
+
gem.license = "MIT"
|
15
15
|
|
16
16
|
gem.files = `git ls-files`.split($/)
|
17
17
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.
|
22
|
-
gem.add_development_dependency('assert-rack-test', ["~> 1.0.5"])
|
23
|
-
gem.add_development_dependency("sinatra", ["~> 1.4"])
|
21
|
+
gem.required_ruby_version = "~> 2.5"
|
24
22
|
|
25
|
-
gem.
|
23
|
+
gem.add_development_dependency("assert", ["~> 2.19.0"])
|
24
|
+
gem.add_development_dependency("assert-rack-test", ["~> 1.1.0"])
|
25
|
+
gem.add_development_dependency("sinatra", ["~> 2.1"])
|
26
26
|
|
27
|
+
gem.add_dependency("rack", ["~> 2.1"])
|
27
28
|
end
|
data/lib/dassets.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dassets/version"
|
4
|
+
require "dassets/asset_file"
|
5
|
+
require "dassets/config"
|
6
|
+
require "dassets/source_file"
|
5
7
|
|
6
8
|
module Dassets
|
9
|
+
AssetFileError = Class.new(RuntimeError)
|
10
|
+
|
11
|
+
def self.config
|
12
|
+
@config ||= Config.new
|
13
|
+
end
|
7
14
|
|
8
|
-
def self.config; @config ||= Config.new; end
|
9
15
|
def self.configure(&block)
|
10
16
|
block.call(self.config)
|
11
17
|
end
|
12
18
|
|
13
19
|
def self.init
|
14
|
-
@asset_files
|
15
|
-
@source_files
|
20
|
+
@asset_files ||= {}
|
21
|
+
@source_files = SourceFiles.new(self.config.sources)
|
16
22
|
end
|
17
23
|
|
18
24
|
def self.reset
|
@@ -27,11 +33,12 @@ module Dassets
|
|
27
33
|
def self.[](digest_path)
|
28
34
|
self.asset_file(digest_path).tap do |af|
|
29
35
|
if af.fingerprint.nil?
|
30
|
-
msg =
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
msg =
|
37
|
+
+"error digesting `#{digest_path}`.\n\nMake sure Dassets has " \
|
38
|
+
"either a combination or source file for this digest path. If " \
|
39
|
+
"this path is for a combination, make sure Dassets has either " \
|
40
|
+
"a combination or source file for each digest path of the " \
|
41
|
+
"combination.\n\n"
|
35
42
|
|
36
43
|
msg << "\nCombination digest paths:"
|
37
44
|
msg << (Dassets.combinations.keys.empty? ? " (none)\n\n" : "\n\n")
|
@@ -40,7 +47,7 @@ module Dassets
|
|
40
47
|
values = Dassets.combinations[key].sort
|
41
48
|
msg << (
|
42
49
|
["#{bullet}#{values.first}"] +
|
43
|
-
(values[1..-1] || []).map{ |v| "#{
|
50
|
+
(values[1..-1] || []).map{ |v| "#{" "*bullet.size}#{v}" }
|
44
51
|
).join("\n")
|
45
52
|
msg << "\n\n"
|
46
53
|
end
|
@@ -63,7 +70,6 @@ module Dassets
|
|
63
70
|
end
|
64
71
|
|
65
72
|
module SourceFiles
|
66
|
-
|
67
73
|
def self.new(sources)
|
68
74
|
# use a hash to store the source files so in the case two source files
|
69
75
|
# have the same digest path, the last one *should* be correct since it
|
@@ -76,11 +82,7 @@ module Dassets
|
|
76
82
|
hash
|
77
83
|
end
|
78
84
|
end
|
79
|
-
|
80
85
|
end
|
81
|
-
|
82
|
-
AssetFileError = Class.new(RuntimeError)
|
83
|
-
|
84
86
|
end
|
85
87
|
|
86
88
|
Dassets.init
|
data/lib/dassets/asset_file.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dassets/source_proxy"
|
4
|
+
require "rack/utils"
|
5
|
+
require "rack/mime"
|
4
6
|
|
5
7
|
module Dassets; end
|
6
8
|
class Dassets::AssetFile
|
7
|
-
|
8
9
|
attr_reader :digest_path, :dirname, :extname, :basename, :source_proxy
|
9
10
|
|
10
11
|
def initialize(digest_path)
|
@@ -12,10 +13,12 @@ class Dassets::AssetFile
|
|
12
13
|
@dirname = File.dirname(@digest_path)
|
13
14
|
@extname = File.extname(@digest_path)
|
14
15
|
@basename = File.basename(@digest_path, @extname)
|
15
|
-
@source_proxy =
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
@source_proxy =
|
17
|
+
Dassets::SourceProxy.new(
|
18
|
+
@digest_path,
|
19
|
+
content_cache: Dassets.config.content_cache,
|
20
|
+
fingerprint_cache: Dassets.config.fingerprint_cache,
|
21
|
+
)
|
19
22
|
end
|
20
23
|
|
21
24
|
def digest!
|
@@ -25,10 +28,10 @@ class Dassets::AssetFile
|
|
25
28
|
|
26
29
|
def url
|
27
30
|
path_basename = "#{@basename}-#{self.fingerprint}#{@extname}"
|
28
|
-
path =
|
31
|
+
path =
|
32
|
+
File.join(@dirname, path_basename).sub(/^\.\//, "").sub(/^\//, "")
|
29
33
|
"#{dassets_base_url}/#{path}"
|
30
34
|
end
|
31
|
-
|
32
35
|
alias_method :href, :url
|
33
36
|
|
34
37
|
def fingerprint
|
@@ -48,7 +51,7 @@ class Dassets::AssetFile
|
|
48
51
|
|
49
52
|
def size
|
50
53
|
return nil if !self.exists?
|
51
|
-
|
54
|
+
self.content.bytesize
|
52
55
|
end
|
53
56
|
|
54
57
|
def mime_type
|
@@ -75,5 +78,4 @@ class Dassets::AssetFile
|
|
75
78
|
def dassets_base_url
|
76
79
|
Dassets.config.base_url.to_s
|
77
80
|
end
|
78
|
-
|
79
81
|
end
|
data/lib/dassets/cache.rb
CHANGED
@@ -1,45 +1,39 @@
|
|
1
|
-
|
2
|
-
module Dassets::Cache
|
3
|
-
|
4
|
-
class MemCache
|
5
|
-
require 'thread'
|
6
|
-
|
7
|
-
# this is a thread-safe in-memory cache
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@hash = {}
|
11
|
-
@write_mutex = ::Mutex.new
|
12
|
-
end
|
1
|
+
# frozen_string_literal: true
|
13
2
|
|
14
|
-
|
15
|
-
@hash.keys
|
16
|
-
end
|
3
|
+
require "thread"
|
17
4
|
|
18
|
-
|
19
|
-
@hash[key]
|
20
|
-
end
|
21
|
-
|
22
|
-
def []=(key, value)
|
23
|
-
@write_mutex.synchronize{ @hash[key] = value }
|
24
|
-
end
|
5
|
+
module Dassets; end
|
25
6
|
|
7
|
+
# This is a thread-safe in-memory cache.
|
8
|
+
class Dassets::MemCache
|
9
|
+
def initialize
|
10
|
+
@hash = {}
|
11
|
+
@write_mutex = ::Mutex.new
|
26
12
|
end
|
27
13
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# off caching.
|
14
|
+
def keys
|
15
|
+
@hash.keys
|
16
|
+
end
|
32
17
|
|
33
|
-
|
34
|
-
|
35
|
-
|
18
|
+
def [](key)
|
19
|
+
@hash[key]
|
20
|
+
end
|
36
21
|
|
37
|
-
|
38
|
-
|
22
|
+
def []=(key, value)
|
23
|
+
@write_mutex.synchronize{ @hash[key] = value }
|
24
|
+
end
|
25
|
+
end
|
39
26
|
|
40
|
-
|
41
|
-
|
27
|
+
# This is a no-op cache object. This is the default cache in use and "turns
|
28
|
+
# off caching.
|
29
|
+
class Dassets::NoCache
|
30
|
+
def keys
|
31
|
+
[]
|
32
|
+
end
|
42
33
|
|
34
|
+
def [](key)
|
43
35
|
end
|
44
36
|
|
37
|
+
def []=(key, value)
|
38
|
+
end
|
45
39
|
end
|
data/lib/dassets/config.rb
CHANGED
@@ -1,67 +1,71 @@
|
|
1
|
-
|
2
|
-
require 'dassets/cache'
|
3
|
-
require 'dassets/file_store'
|
4
|
-
require 'dassets/source'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
3
|
+
require "pathname"
|
4
|
+
require "dassets/cache"
|
5
|
+
require "dassets/file_store"
|
6
|
+
require "dassets/source"
|
7
7
|
|
8
|
-
|
8
|
+
module Dassets; end
|
9
|
+
class Dassets::Config
|
10
|
+
attr_reader :sources, :combinations
|
9
11
|
|
10
|
-
|
12
|
+
def initialize
|
13
|
+
super
|
14
|
+
self.reset
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@fingerprint_cache = Dassets::Cache::NoCache.new
|
17
|
-
@file_store = FileStore::NullStore.new
|
18
|
-
end
|
19
|
-
|
20
|
-
def reset
|
21
|
-
@sources = []
|
22
|
-
@combinations = Hash.new{ |h, k| [k] } # digest pass-thru if none defined
|
23
|
-
end
|
24
|
-
|
25
|
-
def base_url(value = nil)
|
26
|
-
set_base_url(value) if !value.nil?
|
27
|
-
@base_url
|
28
|
-
end
|
16
|
+
@content_cache = Dassets::NoCache.new
|
17
|
+
@fingerprint_cache = Dassets::NoCache.new
|
18
|
+
@file_store = Dassets::NullFileStore.new
|
19
|
+
end
|
29
20
|
|
30
|
-
|
31
|
-
|
32
|
-
|
21
|
+
def reset
|
22
|
+
@sources = []
|
23
|
+
@combinations = Hash.new { |h, k| [k] } # digest pass-thru if none defined
|
24
|
+
@file_store = Dassets::NullFileStore.new
|
25
|
+
end
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@file_store
|
39
|
-
end
|
27
|
+
def base_url(value = nil)
|
28
|
+
set_base_url(value) if !value.nil?
|
29
|
+
@base_url
|
30
|
+
end
|
40
31
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
32
|
+
def set_base_url(value)
|
33
|
+
@base_url = value
|
34
|
+
end
|
45
35
|
|
46
|
-
|
47
|
-
|
48
|
-
@
|
36
|
+
def file_store(value = nil)
|
37
|
+
if !value.nil?
|
38
|
+
@file_store =
|
39
|
+
if value.kind_of?(Dassets::FileStore)
|
40
|
+
value
|
41
|
+
else
|
42
|
+
Dassets::FileStore.new(value)
|
43
|
+
end
|
49
44
|
end
|
45
|
+
@file_store
|
46
|
+
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
def content_cache(cache = nil)
|
49
|
+
@content_cache = cache if !cache.nil?
|
50
|
+
@content_cache
|
51
|
+
end
|
54
52
|
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
def fingerprint_cache(cache = nil)
|
54
|
+
@fingerprint_cache = cache if !cache.nil?
|
55
|
+
@fingerprint_cache
|
56
|
+
end
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@combinations[key_digest_path.to_s] != [key_digest_path]
|
63
|
-
end
|
58
|
+
def source(path, &block)
|
59
|
+
@sources << Dassets::Source.new(path).tap{ |s| block.call(s) if block }
|
60
|
+
end
|
64
61
|
|
62
|
+
def combination(key_digest_path, value_digest_paths)
|
63
|
+
@combinations[key_digest_path.to_s] = [*value_digest_paths]
|
65
64
|
end
|
66
65
|
|
66
|
+
def combination?(key_digest_path)
|
67
|
+
# a digest path is only considered a combination is it is not the default
|
68
|
+
# pass-thru above
|
69
|
+
@combinations[key_digest_path.to_s] != [key_digest_path]
|
70
|
+
end
|
67
71
|
end
|