dassets 0.14.4 → 0.15.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -7
  2. data/Gemfile +5 -1
  3. data/README.md +15 -17
  4. data/dassets.gemspec +14 -9
  5. data/lib/dassets.rb +28 -22
  6. data/lib/dassets/asset_file.rb +27 -24
  7. data/lib/dassets/cache.rb +27 -33
  8. data/lib/dassets/config.rb +55 -50
  9. data/lib/dassets/engine.rb +11 -23
  10. data/lib/dassets/file_store.rb +27 -28
  11. data/lib/dassets/server.rb +27 -27
  12. data/lib/dassets/server/request.rb +44 -41
  13. data/lib/dassets/server/response.rb +101 -80
  14. data/lib/dassets/source.rb +24 -9
  15. data/lib/dassets/source_file.rb +110 -81
  16. data/lib/dassets/source_proxy.rb +36 -20
  17. data/lib/dassets/version.rb +3 -1
  18. data/test/helper.rb +31 -25
  19. data/test/support/app.rb +5 -5
  20. data/test/support/empty/{.gitkeep → .keep} +0 -0
  21. data/test/support/factory.rb +3 -2
  22. data/test/support/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 +65 -61
  26. data/test/unit/asset_file_tests.rb +68 -60
  27. data/test/unit/cache_tests.rb +15 -34
  28. data/test/unit/config_tests.rb +58 -51
  29. data/test/unit/dassets_tests.rb +27 -26
  30. data/test/unit/engine_tests.rb +9 -43
  31. data/test/unit/file_store_tests.rb +34 -24
  32. data/test/unit/server/request_tests.rb +49 -52
  33. data/test/unit/server/response_tests.rb +84 -81
  34. data/test/unit/server_tests.rb +5 -9
  35. data/test/unit/source_file_tests.rb +86 -74
  36. data/test/unit/source_proxy_tests.rb +84 -90
  37. data/test/unit/source_tests.rb +89 -50
  38. data/tmp/.gitkeep +0 -0
  39. metadata +92 -64
  40. data/.gitignore +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- data.tar.gz: 434e3a03c8c5bd4b34ae7bb48feb16cd98a6e2e0
4
- metadata.gz: d6cc4fb4b577a182a90b73e1bfa682d231f11d9f
5
- SHA512:
6
- data.tar.gz: ddd7939d9f0273ba6c74a86db795afee1910c0a4d6ae289bdaf7cc77500a65566b963fc0a12b217aa1a1c2756db7e668d2423782f13f7cc4d5598cdb507fed4f
7
- metadata.gz: 8862732285c774b66b688524136f96964d92ad667aeabc263c08e7e142c2c1c8f8c20e02e31f5f0bd2ba01dce7067d394c728f1ce9acdcad22ad2a0b9c401bb1
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 21dcd9eff1212560f079e694d95f4599ff274f5036369c34866fff6f1e42b764
4
+ data.tar.gz: 0f60e29c3ffc03bc71a69cdb93ecaa6d1879550cad3e71b81ea3097bce2ad07a
5
+ SHA512:
6
+ metadata.gz: 8df9db28b66bffb42346f11b43b378159e7764a741666edf1feba7de1171bad97636e1fb894de20db8a962e547bd4a954d7128084de53c2fdf030627b9569f2e
7
+ data.tar.gz: 84afdbc1ae0b5d3e8a5255e58cc163c262ad60f00a42796ffcf6d7c586f7aacd8b5b10c91bb44c0b97fcdddaa433430a03fb4efe8a0b588fc9ab9edd1ae6e934
data/Gemfile CHANGED
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
5
+ ruby "~> 2.5"
6
+
3
7
  gemspec
4
8
 
5
- gem 'pry', "~> 0.9.0"
9
+ gem "pry"
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
 
data/dassets.gemspec CHANGED
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path("../lib", __FILE__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
6
  require "dassets/version"
5
7
 
@@ -8,20 +10,23 @@ Gem::Specification.new do |gem|
8
10
  gem.version = Dassets::VERSION
9
11
  gem.authors = ["Kelly Redding", "Collin Redding"]
10
12
  gem.email = ["kelly@kellyredding.com", "collin.redding@me.com"]
11
- gem.summary = %q{Digested asset files}
12
- gem.description = %q{Digest and serve HTML asset files}
13
+ gem.summary = "Digested asset files"
14
+ gem.description = "Digest and serve HTML asset files"
13
15
  gem.homepage = "http://github.com/redding/dassets"
14
- gem.license = 'MIT'
16
+ gem.license = "MIT"
17
+
18
+ gem.files = `git ls-files | grep "^[^.]"`.split($INPUT_RECORD_SEPARATOR)
15
19
 
16
- gem.files = `git ls-files`.split($/)
17
20
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
21
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
22
  gem.require_paths = ["lib"]
20
23
 
21
- gem.add_development_dependency("assert", ["~> 2.16.3"])
22
- gem.add_development_dependency('assert-rack-test', ["~> 1.0.5"])
23
- gem.add_development_dependency("sinatra", ["~> 1.4"])
24
+ gem.required_ruby_version = "~> 2.5"
24
25
 
25
- gem.add_dependency("rack", ["~> 1.0"])
26
+ gem.add_development_dependency("much-style-guide", ["~> 0.6.0"])
27
+ gem.add_development_dependency("assert", ["~> 2.19.3"])
28
+ gem.add_development_dependency("assert-rack-test", ["~> 1.1.1"])
29
+ gem.add_development_dependency("sinatra", ["~> 2.1"])
26
30
 
31
+ gem.add_dependency("rack", ["~> 2.1"])
27
32
  end
data/lib/dassets.rb CHANGED
@@ -1,33 +1,44 @@
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
- block.call(self.config)
16
+ block.call(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(config.sources)
16
22
  end
17
23
 
18
24
  def self.reset
19
25
  @asset_files = {}
20
- self.config.reset
26
+ config.reset
27
+ end
28
+
29
+ def self.asset_file(digest_path)
30
+ @asset_files[digest_path] ||= AssetFile.new(digest_path)
21
31
  end
22
32
 
23
33
  def self.[](digest_path)
24
- @asset_files[digest_path] ||= AssetFile.new(digest_path).tap do |af|
34
+ asset_file(digest_path).tap do |af|
25
35
  if af.fingerprint.nil?
26
- msg = "error digesting `#{digest_path}`.\n\nMake sure Dassets has " \
27
- "either a combination or source file for this digest path. If " \
28
- "this path is for a combination, make sure Dassets has either " \
29
- "a combination or source file for each digest path of the " \
30
- "combination.\n\n"
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"
31
42
 
32
43
  msg << "\nCombination digest paths:"
33
44
  msg << (Dassets.combinations.keys.empty? ? " (none)\n\n" : "\n\n")
@@ -36,7 +47,7 @@ module Dassets
36
47
  values = Dassets.combinations[key].sort
37
48
  msg << (
38
49
  ["#{bullet}#{values.first}"] +
39
- values[1..-1].map{ |v| "#{' '*bullet.size}#{v}" }
50
+ (values[1..-1] || []).map{ |v| "#{" " * bullet.size}#{v}" }
40
51
  ).join("\n")
41
52
  msg << "\n\n"
42
53
  end
@@ -55,11 +66,10 @@ module Dassets
55
66
  end
56
67
 
57
68
  def self.combinations
58
- self.config.combinations
69
+ config.combinations
59
70
  end
60
71
 
61
72
  module SourceFiles
62
-
63
73
  def self.new(sources)
64
74
  # use a hash to store the source files so in the case two source files
65
75
  # have the same digest path, the last one *should* be correct since it
@@ -72,11 +82,7 @@ module Dassets
72
82
  hash
73
83
  end
74
84
  end
75
-
76
85
  end
77
-
78
- AssetFileError = Class.new(RuntimeError)
79
-
80
86
  end
81
87
 
82
88
  Dassets.init
@@ -1,10 +1,12 @@
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
- class Dassets::AssetFile
7
8
 
9
+ class Dassets::AssetFile
8
10
  attr_reader :digest_path, :dirname, :extname, :basename, :source_proxy
9
11
 
10
12
  def initialize(digest_path)
@@ -12,47 +14,49 @@ class Dassets::AssetFile
12
14
  @dirname = File.dirname(@digest_path)
13
15
  @extname = File.extname(@digest_path)
14
16
  @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
- })
17
+ @source_proxy =
18
+ Dassets::SourceProxy.new(
19
+ @digest_path,
20
+ content_cache: Dassets.config.content_cache,
21
+ fingerprint_cache: Dassets.config.fingerprint_cache,
22
+ )
19
23
  end
20
24
 
21
25
  def digest!
22
- return if !self.exists?
23
- Dassets.config.file_store.save(self.url){ self.content }
26
+ return unless exists?
27
+ Dassets.config.file_store.save(url){ content }
24
28
  end
25
29
 
26
30
  def url
27
- path_basename = "#{@basename}-#{self.fingerprint}#{@extname}"
28
- path = File.join(@dirname, path_basename).sub(/^\.\//, '').sub(/^\//, '')
31
+ path_basename = "#{@basename}-#{fingerprint}#{@extname}"
32
+ path =
33
+ File.join(@dirname, path_basename).sub(%r{^\./}, "").sub(%r{^/}, "")
29
34
  "#{dassets_base_url}/#{path}"
30
35
  end
31
-
32
36
  alias_method :href, :url
33
37
 
34
38
  def fingerprint
35
- return nil if !self.exists?
39
+ return nil unless exists?
36
40
  @source_proxy.fingerprint
37
41
  end
38
42
 
39
43
  def content
40
- return nil if !self.exists?
44
+ return nil unless exists?
41
45
  @source_proxy.content
42
46
  end
43
47
 
44
48
  def mtime
45
- return nil if !self.exists?
49
+ return nil unless exists?
46
50
  @source_proxy.mtime.httpdate
47
51
  end
48
52
 
49
53
  def size
50
- return nil if !self.exists?
51
- Rack::Utils.bytesize(self.content)
54
+ return nil unless exists?
55
+ content.bytesize
52
56
  end
53
57
 
54
58
  def mime_type
55
- return nil if !self.exists?
59
+ return nil unless exists?
56
60
  Rack::Mime.mime_type(@extname)
57
61
  end
58
62
 
@@ -64,10 +68,10 @@ class Dassets::AssetFile
64
68
  @source_proxy.exists?
65
69
  end
66
70
 
67
- def ==(other_asset_file)
68
- other_asset_file.kind_of?(Dassets::AssetFile) &&
69
- self.digest_path == other_asset_file.digest_path &&
70
- self.fingerprint == other_asset_file.fingerprint
71
+ def ==(other)
72
+ other.is_a?(Dassets::AssetFile) &&
73
+ digest_path == other.digest_path &&
74
+ fingerprint == other.fingerprint
71
75
  end
72
76
 
73
77
  private
@@ -75,5 +79,4 @@ class Dassets::AssetFile
75
79
  def dassets_base_url
76
80
  Dassets.config.base_url.to_s
77
81
  end
78
-
79
82
  end
data/lib/dassets/cache.rb CHANGED
@@ -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,67 +1,72 @@
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
9
 
10
- attr_reader :sources, :combinations
10
+ class Dassets::Config
11
+ attr_reader :sources, :combinations
11
12
 
12
- def initialize
13
- super
14
- self.reset
15
- @content_cache = Dassets::Cache::NoCache.new
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
13
+ def initialize
14
+ super
15
+ reset
24
16
 
25
- def base_url(value = nil)
26
- set_base_url(value) if !value.nil?
27
- @base_url
28
- end
17
+ @content_cache = Dassets::NoCache.new
18
+ @fingerprint_cache = Dassets::NoCache.new
19
+ @file_store = Dassets::NullFileStore.new
20
+ end
29
21
 
30
- def set_base_url(value)
31
- @base_url = value
32
- end
22
+ def reset
23
+ @sources = []
24
+ @combinations = Hash.new{ |_h, k| [k] } # digest pass-thru if none defined
25
+ @file_store = Dassets::NullFileStore.new
26
+ end
33
27
 
34
- def file_store(value = nil)
35
- if !value.nil?
36
- @file_store = (value.kind_of?(FileStore) ? value : FileStore.new(value))
37
- end
38
- @file_store
39
- end
28
+ def base_url(value = nil)
29
+ set_base_url(value) unless value.nil?
30
+ @base_url
31
+ end
40
32
 
41
- def content_cache(cache = nil)
42
- @content_cache = cache if !cache.nil?
43
- @content_cache
44
- end
33
+ def set_base_url(value)
34
+ @base_url = value
35
+ end
45
36
 
46
- def fingerprint_cache(cache = nil)
47
- @fingerprint_cache = cache if !cache.nil?
48
- @fingerprint_cache
37
+ def file_store(value = nil)
38
+ unless value.nil?
39
+ @file_store =
40
+ if value.is_a?(Dassets::FileStore)
41
+ value
42
+ else
43
+ Dassets::FileStore.new(value)
44
+ end
49
45
  end
46
+ @file_store
47
+ end
50
48
 
51
- def source(path, &block)
52
- @sources << Source.new(path).tap{ |s| block.call(s) if block }
53
- end
49
+ def content_cache(cache = nil)
50
+ @content_cache = cache unless cache.nil?
51
+ @content_cache
52
+ end
54
53
 
55
- def combination(key_digest_path, value_digest_paths)
56
- @combinations[key_digest_path.to_s] = [*value_digest_paths]
57
- end
54
+ def fingerprint_cache(cache = nil)
55
+ @fingerprint_cache = cache unless cache.nil?
56
+ @fingerprint_cache
57
+ end
58
58
 
59
- def combination?(key_digest_path)
60
- # a digest path is only considered a combination is it is not the default
61
- # pass-thru above
62
- @combinations[key_digest_path.to_s] != [key_digest_path]
63
- end
59
+ def source(path, &block)
60
+ @sources << Dassets::Source.new(path).tap{ |s| block.call(s) if block }
61
+ end
64
62
 
63
+ def combination(key_digest_path, value_digest_paths)
64
+ @combinations[key_digest_path.to_s] = [*value_digest_paths]
65
65
  end
66
66
 
67
+ def combination?(key_digest_path)
68
+ # a digest path is only considered a combination is it is not the default
69
+ # pass-thru above
70
+ @combinations[key_digest_path.to_s] != [key_digest_path]
71
+ end
67
72
  end