dassets 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -7
  2. data/.ruby-version +1 -0
  3. data/Gemfile +3 -1
  4. data/README.md +15 -17
  5. data/dassets.gemspec +7 -6
  6. data/lib/dassets.rb +54 -11
  7. data/lib/dassets/asset_file.rb +14 -12
  8. data/lib/dassets/cache.rb +27 -33
  9. data/lib/dassets/config.rb +55 -47
  10. data/lib/dassets/engine.rb +11 -23
  11. data/lib/dassets/file_store.rb +27 -27
  12. data/lib/dassets/server.rb +27 -28
  13. data/lib/dassets/server/request.rb +43 -41
  14. data/lib/dassets/server/response.rb +93 -81
  15. data/lib/dassets/source.rb +13 -8
  16. data/lib/dassets/source_file.rb +100 -82
  17. data/lib/dassets/source_proxy.rb +32 -16
  18. data/lib/dassets/version.rb +3 -1
  19. data/test/helper.rb +18 -24
  20. data/test/support/app.rb +3 -5
  21. data/test/support/factory.rb +1 -2
  22. data/test/support/{public/nested/file3-d41d8cd98f00b204e9800998ecf8427e.txt → linked_source_files/linked_file.txt} +0 -0
  23. data/test/support/source_files/linked +1 -0
  24. data/test/support/source_files/linked_file2.txt +1 -0
  25. data/test/system/rack_tests.rb +55 -59
  26. data/test/unit/asset_file_tests.rb +64 -60
  27. data/test/unit/cache_tests.rb +14 -35
  28. data/test/unit/config_tests.rb +65 -45
  29. data/test/unit/dassets_tests.rb +41 -23
  30. data/test/unit/engine_tests.rb +7 -43
  31. data/test/unit/file_store_tests.rb +42 -31
  32. data/test/unit/server/request_tests.rb +48 -53
  33. data/test/unit/server/response_tests.rb +79 -81
  34. data/test/unit/server_tests.rb +3 -9
  35. data/test/unit/source_file_tests.rb +73 -72
  36. data/test/unit/source_proxy_tests.rb +78 -89
  37. data/test/unit/source_tests.rb +58 -50
  38. metadata +78 -70
  39. data/test/support/public/file2-9bbe1047cffbb590f59e0e5aeff46ae4.txt +0 -1
  40. data/test/support/public/grumpy_cat-b0d1f399a916f7a25c4c0f693c619013.jpg +0 -0
  41. data/test/support/public/nested/a-thing.txt-7413d18f2eba9c695a880aff67fde135.no-use +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 89a17e9e4689219cffdda2b968a4c481f9813591
4
- data.tar.gz: 2a74fdbbc78e44ec82d23f1aabbc284d70f03397
5
- SHA512:
6
- metadata.gz: d19a0f7587afb5d0d19a9878a0667973474ef55a3d684d363a66cb750394249a97cf957cac9e99df6662fd72d32be6e9eb46794c7d121c7d7b45558f85dd0dd7
7
- data.tar.gz: bf6bfb399f0ab12d21f50d58db6b6e39b22da71768660236ae21f287ebf3470477598dc95a397a39395c960980fd428bf6cf1968145975a65ab7db67da28041b
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 51a6c8bbf4e5b1a6cebb52c6da1ce5a6eae5714cf8cd410d2aa06a79737fc9b5
4
+ data.tar.gz: f97b79e8148698de5d6a1cd97419e34b416a1a03c4d9773e742614403fd9180d
5
+ SHA512:
6
+ metadata.gz: a8310a78cfbbcb27795f0319303f1471625edb03e10a747e52c195a85f0b791adc41ed52a45aa4756525d67160bcbc50d788a45076f52f60513bd51ac5b63932
7
+ data.tar.gz: f01e81b5758d052dcf8b5e602eb1798e206ff1cb5c9ab8d80dfaf90c83841ce278e83e8dd3577f976c37fd05a073b66ff7cd57e27d3c11bfff092a1fdb93a967
@@ -0,0 +1 @@
1
+ 2.5.5
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
+ ruby "~> 2.5"
4
+
3
5
  gemspec
4
6
 
5
- gem 'pry', "~> 0.9.0"
7
+ gem "pry", "~> 0.12.2"
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 'dassets'
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 '/path/to/app/assets'
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 '/path/to/public' # default: `FileStore::NullStore.new`
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
- ```rb
32
- Dassets['css/site.css'].url # => "/css/site-123abc.css"
33
- Dassets['img/logos/main.jpg'].url # => "/img/logos/main-a1b2c3.jpg"
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 'dassets/server'
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 'erb', Dassets::Erb::Engine
79
- s.engine 'scss', Dassets::Sass::Engine, {
80
- :syntax => 'scss'
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 'scss' syntax).
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
- 'css/romo/normalize.css',
99
- 'css/romo/base.css',
100
- 'css/romo/component1.css'
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 'dassets'
111
+ gem "dassets"
114
112
 
115
113
  And then execute:
116
114
 
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
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 = 'MIT'
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.add_development_dependency("assert", ["~> 2.16.3"])
22
- gem.add_development_dependency('assert-rack-test', ["~> 1.0.4"])
23
- gem.add_development_dependency("sinatra", ["~> 1.4"])
21
+ gem.required_ruby_version = "~> 2.5"
24
22
 
25
- gem.add_dependency("rack", ["~> 1.0"])
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
@@ -1,30 +1,75 @@
1
- require 'dassets/version'
2
- require 'dassets/asset_file'
3
- require 'dassets/config'
4
- require 'dassets/source_file'
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 = SourceFiles.new(self.config.sources)
20
+ @asset_files ||= {}
21
+ @source_files = SourceFiles.new(self.config.sources)
16
22
  end
17
23
 
18
- def self.[](digest_path)
24
+ def self.reset
25
+ @asset_files = {}
26
+ self.config.reset
27
+ end
28
+
29
+ def self.asset_file(digest_path)
19
30
  @asset_files[digest_path] ||= AssetFile.new(digest_path)
20
31
  end
21
32
 
33
+ def self.[](digest_path)
34
+ self.asset_file(digest_path).tap do |af|
35
+ if af.fingerprint.nil?
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"
42
+
43
+ msg << "\nCombination digest paths:"
44
+ msg << (Dassets.combinations.keys.empty? ? " (none)\n\n" : "\n\n")
45
+ Dassets.combinations.keys.sort.each do |key|
46
+ bullet = "#{key} => "
47
+ values = Dassets.combinations[key].sort
48
+ msg << (
49
+ ["#{bullet}#{values.first}"] +
50
+ (values[1..-1] || []).map{ |v| "#{" "*bullet.size}#{v}" }
51
+ ).join("\n")
52
+ msg << "\n\n"
53
+ end
54
+
55
+ msg << "\nSource file digest paths:"
56
+ msg << (Dassets.source_files.keys.empty? ? " (none)\n\n" : "\n\n")
57
+ msg << Dassets.source_files.keys.sort.join("\n")
58
+
59
+ raise AssetFileError, msg
60
+ end
61
+ end
62
+ end
63
+
22
64
  def self.source_files
23
65
  @source_files
24
66
  end
25
67
 
26
- module SourceFiles
68
+ def self.combinations
69
+ self.config.combinations
70
+ end
27
71
 
72
+ module SourceFiles
28
73
  def self.new(sources)
29
74
  # use a hash to store the source files so in the case two source files
30
75
  # have the same digest path, the last one *should* be correct since it
@@ -37,9 +82,7 @@ module Dassets
37
82
  hash
38
83
  end
39
84
  end
40
-
41
85
  end
42
-
43
86
  end
44
87
 
45
88
  Dassets.init
@@ -1,10 +1,11 @@
1
- require 'rack/utils'
2
- require 'rack/mime'
3
- require 'dassets/source_proxy'
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 = Dassets::SourceProxy.new(@digest_path, {
16
- :content_cache => Dassets.config.content_cache,
17
- :fingerprint_cache => Dassets.config.fingerprint_cache
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 = File.join(@dirname, path_basename).sub(/^\.\//, '').sub(/^\//, '')
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
- Rack::Utils.bytesize(self.content)
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
@@ -1,45 +1,39 @@
1
- module Dassets; end
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
- def keys
15
- @hash.keys
16
- end
3
+ require "thread"
17
4
 
18
- def [](key)
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
- class NoCache
29
-
30
- # This is a no-op cache object. This is the default cache in use and "turns
31
- # off caching.
14
+ def keys
15
+ @hash.keys
16
+ end
32
17
 
33
- def keys
34
- []
35
- end
18
+ def [](key)
19
+ @hash[key]
20
+ end
36
21
 
37
- def [](key)
38
- end
22
+ def []=(key, value)
23
+ @write_mutex.synchronize{ @hash[key] = value }
24
+ end
25
+ end
39
26
 
40
- def []=(key, value)
41
- end
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
@@ -1,63 +1,71 @@
1
- require 'pathname'
2
- require 'dassets/cache'
3
- require 'dassets/file_store'
4
- require 'dassets/source'
1
+ # frozen_string_literal: true
5
2
 
6
- module Dassets
3
+ require "pathname"
4
+ require "dassets/cache"
5
+ require "dassets/file_store"
6
+ require "dassets/source"
7
7
 
8
- class Config
8
+ module Dassets; end
9
+ class Dassets::Config
10
+ attr_reader :sources, :combinations
9
11
 
10
- attr_reader :sources, :combinations
12
+ def initialize
13
+ super
14
+ self.reset
11
15
 
12
- def initialize
13
- super
14
- @sources = []
15
- @combinations = Hash.new{ |h, k| [k] } # digest pass-thru if none defined
16
- @content_cache = Dassets::Cache::NoCache.new
17
- @fingerprint_cache = Dassets::Cache::NoCache.new
18
- @file_store = FileStore::NullStore.new
19
- end
20
-
21
- def base_url(value = nil)
22
- set_base_url(value) if !value.nil?
23
- @base_url
24
- end
16
+ @content_cache = Dassets::NoCache.new
17
+ @fingerprint_cache = Dassets::NoCache.new
18
+ @file_store = Dassets::NullFileStore.new
19
+ end
25
20
 
26
- def set_base_url(value)
27
- @base_url = value
28
- end
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
29
26
 
30
- def file_store(value = nil)
31
- if !value.nil?
32
- @file_store = (value.kind_of?(FileStore) ? value : FileStore.new(value))
33
- end
34
- @file_store
35
- end
27
+ def base_url(value = nil)
28
+ set_base_url(value) if !value.nil?
29
+ @base_url
30
+ end
36
31
 
37
- def content_cache(cache = nil)
38
- @content_cache = cache if !cache.nil?
39
- @content_cache
40
- end
32
+ def set_base_url(value)
33
+ @base_url = value
34
+ end
41
35
 
42
- def fingerprint_cache(cache = nil)
43
- @fingerprint_cache = cache if !cache.nil?
44
- @fingerprint_cache
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
45
44
  end
45
+ @file_store
46
+ end
46
47
 
47
- def source(path, &block)
48
- @sources << Source.new(path).tap{ |s| block.call(s) if block }
49
- end
48
+ def content_cache(cache = nil)
49
+ @content_cache = cache if !cache.nil?
50
+ @content_cache
51
+ end
50
52
 
51
- def combination(key_digest_path, value_digest_paths)
52
- @combinations[key_digest_path.to_s] = [*value_digest_paths]
53
- end
53
+ def fingerprint_cache(cache = nil)
54
+ @fingerprint_cache = cache if !cache.nil?
55
+ @fingerprint_cache
56
+ end
54
57
 
55
- def combination?(key_digest_path)
56
- # a digest path is only considered a combination is it is not the default
57
- # pass-thru above
58
- @combinations[key_digest_path.to_s] != [key_digest_path]
59
- end
58
+ def source(path, &block)
59
+ @sources << Dassets::Source.new(path).tap{ |s| block.call(s) if block }
60
+ end
60
61
 
62
+ def combination(key_digest_path, value_digest_paths)
63
+ @combinations[key_digest_path.to_s] = [*value_digest_paths]
61
64
  end
62
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
63
71
  end