hanami-assets 1.3.4 → 2.1.0.beta2

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 +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +92 -315
  5. data/bin/hanami-assets +7 -6
  6. data/hanami-assets.gemspec +23 -28
  7. data/lib/hanami/assets/asset.rb +83 -0
  8. data/lib/hanami/assets/base_url.rb +64 -0
  9. data/lib/hanami/assets/config.rb +106 -0
  10. data/lib/hanami/assets/errors.rb +46 -0
  11. data/lib/hanami/assets/version.rb +4 -2
  12. data/lib/hanami/assets.rb +63 -143
  13. data/lib/hanami-assets.rb +3 -0
  14. metadata +36 -104
  15. data/lib/hanami/assets/bundler/asset.rb +0 -98
  16. data/lib/hanami/assets/bundler/compressor.rb +0 -61
  17. data/lib/hanami/assets/bundler/manifest_entry.rb +0 -62
  18. data/lib/hanami/assets/bundler.rb +0 -152
  19. data/lib/hanami/assets/cache.rb +0 -100
  20. data/lib/hanami/assets/compiler.rb +0 -285
  21. data/lib/hanami/assets/compilers/less.rb +0 -29
  22. data/lib/hanami/assets/compilers/sass.rb +0 -59
  23. data/lib/hanami/assets/compressors/abstract.rb +0 -119
  24. data/lib/hanami/assets/compressors/builtin_javascript.rb +0 -36
  25. data/lib/hanami/assets/compressors/builtin_stylesheet.rb +0 -57
  26. data/lib/hanami/assets/compressors/closure_javascript.rb +0 -25
  27. data/lib/hanami/assets/compressors/javascript.rb +0 -77
  28. data/lib/hanami/assets/compressors/jsmin.rb +0 -284
  29. data/lib/hanami/assets/compressors/null_compressor.rb +0 -19
  30. data/lib/hanami/assets/compressors/sass_stylesheet.rb +0 -36
  31. data/lib/hanami/assets/compressors/stylesheet.rb +0 -77
  32. data/lib/hanami/assets/compressors/uglifier_javascript.rb +0 -25
  33. data/lib/hanami/assets/compressors/yui_javascript.rb +0 -25
  34. data/lib/hanami/assets/compressors/yui_stylesheet.rb +0 -25
  35. data/lib/hanami/assets/config/global_sources.rb +0 -50
  36. data/lib/hanami/assets/config/manifest.rb +0 -140
  37. data/lib/hanami/assets/config/sources.rb +0 -78
  38. data/lib/hanami/assets/configuration.rb +0 -652
  39. data/lib/hanami/assets/helpers.rb +0 -935
  40. data/lib/hanami/assets/precompiler.rb +0 -95
metadata CHANGED
@@ -1,63 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 2.1.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-11 00:00:00.000000000 Z
11
+ date: 2023-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: hanami-utils
14
+ name: zeitwerk
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '2.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: hanami-helpers
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.3'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.3'
41
- - !ruby/object:Gem::Dependency
42
- name: tilt
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '2.0'
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 2.0.2
51
- type: :runtime
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - "~>"
56
- - !ruby/object:Gem::Version
57
- version: '2.0'
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: 2.0.2
26
+ version: '2.6'
61
27
  - !ruby/object:Gem::Dependency
62
28
  name: bundler
63
29
  requirement: !ruby/object:Gem::Requirement
@@ -84,58 +50,58 @@ dependencies:
84
50
  requirements:
85
51
  - - "~>"
86
52
  - !ruby/object:Gem::Version
87
- version: '12.0'
53
+ version: '13'
88
54
  type: :development
89
55
  prerelease: false
90
56
  version_requirements: !ruby/object:Gem::Requirement
91
57
  requirements:
92
58
  - - "~>"
93
59
  - !ruby/object:Gem::Version
94
- version: '12.0'
60
+ version: '13'
95
61
  - !ruby/object:Gem::Dependency
96
62
  name: rspec
97
63
  requirement: !ruby/object:Gem::Requirement
98
64
  requirements:
99
65
  - - "~>"
100
66
  - !ruby/object:Gem::Version
101
- version: '3.7'
67
+ version: '3.9'
102
68
  type: :development
103
69
  prerelease: false
104
70
  version_requirements: !ruby/object:Gem::Requirement
105
71
  requirements:
106
72
  - - "~>"
107
73
  - !ruby/object:Gem::Version
108
- version: '3.7'
74
+ version: '3.9'
109
75
  - !ruby/object:Gem::Dependency
110
- name: yui-compressor
76
+ name: rubocop
111
77
  requirement: !ruby/object:Gem::Requirement
112
78
  requirements:
113
79
  - - "~>"
114
80
  - !ruby/object:Gem::Version
115
- version: '0.12'
81
+ version: '1.0'
116
82
  type: :development
117
83
  prerelease: false
118
84
  version_requirements: !ruby/object:Gem::Requirement
119
85
  requirements:
120
86
  - - "~>"
121
87
  - !ruby/object:Gem::Version
122
- version: '0.12'
88
+ version: '1.0'
123
89
  - !ruby/object:Gem::Dependency
124
- name: uglifier
90
+ name: rack
125
91
  requirement: !ruby/object:Gem::Requirement
126
92
  requirements:
127
93
  - - "~>"
128
94
  - !ruby/object:Gem::Version
129
- version: '2.7'
95
+ version: '2.2'
130
96
  type: :development
131
97
  prerelease: false
132
98
  version_requirements: !ruby/object:Gem::Requirement
133
99
  requirements:
134
100
  - - "~>"
135
101
  - !ruby/object:Gem::Version
136
- version: '2.7'
102
+ version: '2.2'
137
103
  - !ruby/object:Gem::Dependency
138
- name: closure-compiler
104
+ name: rack-test
139
105
  requirement: !ruby/object:Gem::Requirement
140
106
  requirements:
141
107
  - - "~>"
@@ -149,47 +115,33 @@ dependencies:
149
115
  - !ruby/object:Gem::Version
150
116
  version: '1.1'
151
117
  - !ruby/object:Gem::Dependency
152
- name: sassc
153
- requirement: !ruby/object:Gem::Requirement
154
- requirements:
155
- - - "~>"
156
- - !ruby/object:Gem::Version
157
- version: '2.0'
158
- type: :development
159
- prerelease: false
160
- version_requirements: !ruby/object:Gem::Requirement
161
- requirements:
162
- - - "~>"
163
- - !ruby/object:Gem::Version
164
- version: '2.0'
165
- - !ruby/object:Gem::Dependency
166
- name: coffee-script
118
+ name: dry-configurable
167
119
  requirement: !ruby/object:Gem::Requirement
168
120
  requirements:
169
121
  - - "~>"
170
122
  - !ruby/object:Gem::Version
171
- version: '2.3'
123
+ version: '1.1'
172
124
  type: :development
173
125
  prerelease: false
174
126
  version_requirements: !ruby/object:Gem::Requirement
175
127
  requirements:
176
128
  - - "~>"
177
129
  - !ruby/object:Gem::Version
178
- version: '2.3'
130
+ version: '1.1'
179
131
  - !ruby/object:Gem::Dependency
180
- name: babel-transpiler
132
+ name: dry-inflector
181
133
  requirement: !ruby/object:Gem::Requirement
182
134
  requirements:
183
135
  - - "~>"
184
136
  - !ruby/object:Gem::Version
185
- version: '0.7'
137
+ version: '1.0'
186
138
  type: :development
187
139
  prerelease: false
188
140
  version_requirements: !ruby/object:Gem::Requirement
189
141
  requirements:
190
142
  - - "~>"
191
143
  - !ruby/object:Gem::Version
192
- version: '0.7'
144
+ version: '1.0'
193
145
  description: Assets management for Ruby web applications
194
146
  email:
195
147
  - me@lucaguidi.com
@@ -203,39 +155,19 @@ files:
203
155
  - README.md
204
156
  - bin/hanami-assets
205
157
  - hanami-assets.gemspec
158
+ - lib/hanami-assets.rb
206
159
  - lib/hanami/assets.rb
207
- - lib/hanami/assets/bundler.rb
208
- - lib/hanami/assets/bundler/asset.rb
209
- - lib/hanami/assets/bundler/compressor.rb
210
- - lib/hanami/assets/bundler/manifest_entry.rb
211
- - lib/hanami/assets/cache.rb
212
- - lib/hanami/assets/compiler.rb
213
- - lib/hanami/assets/compilers/less.rb
214
- - lib/hanami/assets/compilers/sass.rb
215
- - lib/hanami/assets/compressors/abstract.rb
216
- - lib/hanami/assets/compressors/builtin_javascript.rb
217
- - lib/hanami/assets/compressors/builtin_stylesheet.rb
218
- - lib/hanami/assets/compressors/closure_javascript.rb
219
- - lib/hanami/assets/compressors/javascript.rb
220
- - lib/hanami/assets/compressors/jsmin.rb
221
- - lib/hanami/assets/compressors/null_compressor.rb
222
- - lib/hanami/assets/compressors/sass_stylesheet.rb
223
- - lib/hanami/assets/compressors/stylesheet.rb
224
- - lib/hanami/assets/compressors/uglifier_javascript.rb
225
- - lib/hanami/assets/compressors/yui_javascript.rb
226
- - lib/hanami/assets/compressors/yui_stylesheet.rb
227
- - lib/hanami/assets/config/global_sources.rb
228
- - lib/hanami/assets/config/manifest.rb
229
- - lib/hanami/assets/config/sources.rb
230
- - lib/hanami/assets/configuration.rb
231
- - lib/hanami/assets/helpers.rb
232
- - lib/hanami/assets/precompiler.rb
160
+ - lib/hanami/assets/asset.rb
161
+ - lib/hanami/assets/base_url.rb
162
+ - lib/hanami/assets/config.rb
163
+ - lib/hanami/assets/errors.rb
233
164
  - lib/hanami/assets/version.rb
234
165
  homepage: http://hanamirb.org
235
166
  licenses:
236
167
  - MIT
237
- metadata: {}
238
- post_install_message:
168
+ metadata:
169
+ rubygems_mfa_required: 'true'
170
+ post_install_message:
239
171
  rdoc_options: []
240
172
  require_paths:
241
173
  - lib
@@ -243,15 +175,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
243
175
  requirements:
244
176
  - - ">="
245
177
  - !ruby/object:Gem::Version
246
- version: 2.3.0
178
+ version: '3.0'
247
179
  required_rubygems_version: !ruby/object:Gem::Requirement
248
180
  requirements:
249
- - - ">="
181
+ - - ">"
250
182
  - !ruby/object:Gem::Version
251
- version: '0'
183
+ version: 1.3.1
252
184
  requirements: []
253
- rubygems_version: 3.0.6
254
- signing_key:
185
+ rubygems_version: 3.4.13
186
+ signing_key:
255
187
  specification_version: 4
256
188
  summary: Assets management
257
189
  test_files: []
@@ -1,98 +0,0 @@
1
- require 'openssl'
2
-
3
- module Hanami
4
- module Assets
5
- # Bundle assets from a single application.
6
- #
7
- # @since 0.1.0
8
- # @api private
9
- class Bundler
10
- # @since 0.3.0
11
- # @api private
12
- class Asset
13
- # @since 0.3.0
14
- # @api private
15
- attr_reader :path
16
-
17
- # @since 0.3.0
18
- # @api private
19
- attr_reader :configuration
20
-
21
- # @since 0.3.0
22
- # @api private
23
- WILDCARD_EXT = '.*'.freeze
24
-
25
- # Return a new instance
26
- #
27
- # @since 0.3.0
28
- # @api private
29
- def initialize(path, configuration)
30
- @path = path
31
- @configuration = configuration
32
- end
33
-
34
- # @since 0.3.0
35
- # @api private
36
- def expanded_path
37
- ::File.expand_path(@path)
38
- end
39
-
40
- # @since 0.3.0
41
- # @api private
42
- def fingerprinted_target
43
- ::File.join(directory, "#{filename}-#{fingerprint}#{extension}")
44
- end
45
-
46
- # @since 0.3.0
47
- # @api private
48
- def expanded_fingerprinted_target
49
- ::File.expand_path(fingerprinted_target)
50
- end
51
-
52
- # @since 0.3.0
53
- # @api private
54
- def base64_digest(algorithm)
55
- raw_digest(algorithm).base64digest
56
- end
57
-
58
- private
59
-
60
- # @since 0.3.0
61
- # @api private
62
- def directory
63
- ::File.dirname(@path)
64
- end
65
-
66
- # @since 0.3.0
67
- # @api private
68
- def filename
69
- ::File.basename(@path, WILDCARD_EXT)
70
- end
71
-
72
- # @since 0.3.0
73
- # @api private
74
- def extension
75
- ::File.extname(@path)
76
- end
77
-
78
- # @since 0.3.0
79
- # @api private
80
- def fingerprint
81
- raw_digest(:md5).hexdigest
82
- end
83
-
84
- # @since 0.3.0
85
- # @api private
86
- def raw_digest(algorithm)
87
- OpenSSL::Digest.new(algorithm.to_s, contents)
88
- end
89
-
90
- # @since 0.3.0
91
- # @api private
92
- def contents
93
- ::File.read(@path)
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,61 +0,0 @@
1
- module Hanami
2
- module Assets
3
- class Bundler
4
- # Compresses a JS or CSS file
5
- #
6
- # @since 0.3.0
7
- # @api private
8
- class Compressor
9
- # @since 0.3.0
10
- # @api private
11
- JAVASCRIPT_EXT = '.js'.freeze
12
-
13
- # @since 0.3.0
14
- # @api private
15
- STYLESHEET_EXT = '.css'.freeze
16
-
17
- # Return a new instance
18
- #
19
- # @since 0.3.0
20
- # @api private
21
- def initialize(path, configuration)
22
- @path = path
23
- @configuration = configuration
24
- end
25
-
26
- # @return [String, nil] the compressed contents of the file OR nil if it's not compressable
27
- #
28
- # @since 0.3.0
29
- # @api private
30
- def compress
31
- case File.extname(@path)
32
- when JAVASCRIPT_EXT then _compress(compressor(:js))
33
- when STYLESHEET_EXT then _compress(compressor(:css))
34
- end
35
- end
36
-
37
- private
38
-
39
- # @since 0.3.0
40
- # @api private
41
- def compressor(type)
42
- @configuration.__send__(:"#{ type }_compressor")
43
- end
44
-
45
- # @since 0.3.0
46
- # @api private
47
- def _compress(compressor)
48
- compressor.compress(@path)
49
- rescue => exception # rubocop:disable Style/RescueStandardError
50
- warn(
51
- [
52
- "Skipping compression of: `#{@path}'",
53
- "Reason: #{exception}\n",
54
- "\t#{exception.backtrace.join("\n\t")}\n\n"
55
- ].join("\n")
56
- )
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,62 +0,0 @@
1
- module Hanami
2
- module Assets
3
- class Bundler
4
- # Constructs a hash for a single asset's manifest file entry
5
- #
6
- # @since 0.3.0
7
- # @api private
8
- class ManifestEntry
9
- # @since 0.3.0
10
- # @api private
11
- SUBRESOURCE_INTEGRITY_SEPARATOR = '-'.freeze
12
-
13
- # Return a new instance
14
- #
15
- # @since 0.3.0
16
- # @api private
17
- def initialize(asset)
18
- @asset = asset
19
- end
20
-
21
- # A single entry for this asset, to go into manifest file
22
- # @since 0.3.0
23
- # @api private
24
- def entry
25
- { name => values }
26
- end
27
-
28
- private
29
-
30
- # @since 0.3.0
31
- # @api private
32
- def name
33
- _convert_to_url(@asset.expanded_path)
34
- end
35
-
36
- # @since 0.3.0
37
- # @api private
38
- def values
39
- Hash[
40
- target: _convert_to_url(@asset.expanded_fingerprinted_target),
41
- sri: subresource_integrity_values
42
- ]
43
- end
44
-
45
- # @since 0.3.0
46
- # @api private
47
- def subresource_integrity_values
48
- @asset.configuration.subresource_integrity_algorithms.map do |algorithm|
49
- [algorithm, @asset.base64_digest(algorithm)].join(SUBRESOURCE_INTEGRITY_SEPARATOR)
50
- end
51
- end
52
-
53
- # @since 0.3.0
54
- # @api private
55
- def _convert_to_url(path)
56
- path.sub(@asset.configuration.public_directory.to_s, URL_REPLACEMENT)
57
- .gsub(File::SEPARATOR, URL_SEPARATOR)
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,152 +0,0 @@
1
- require 'fileutils'
2
- require 'json'
3
-
4
- require 'hanami/assets/bundler/compressor'
5
- require 'hanami/assets/bundler/asset'
6
- require 'hanami/assets/bundler/manifest_entry'
7
-
8
- module Hanami
9
- module Assets
10
- # Bundle assets from a single application.
11
- #
12
- # @since 0.1.0
13
- # @api private
14
- class Bundler
15
- # @since 0.1.0
16
- # @api private
17
- DEFAULT_PERMISSIONS = 0o644
18
-
19
- # @since 0.1.0
20
- # @api private
21
- URL_SEPARATOR = '/'.freeze
22
-
23
- # @since 0.1.0
24
- # @api private
25
- URL_REPLACEMENT = ''.freeze
26
-
27
- # Return a new instance
28
- #
29
- # @param configuration [Hanami::Assets::Configuration] a single application configuration
30
- #
31
- # @param duplicates [Array<Hanami::Assets>] the duplicated frameworks
32
- # (one for each application)
33
- #
34
- # @return [Hanami::Assets::Bundler] a new instance
35
- #
36
- # @since 0.1.0
37
- # @api private
38
- def initialize(configuration, duplicates)
39
- @manifest = Hash[]
40
- @configuration = configuration
41
- @duplicates = duplicates
42
- end
43
-
44
- # Start the process.
45
- #
46
- # For each asset contained in the sources and third party gems, it will:
47
- #
48
- # * Compress
49
- # * Create a fingerprinted version of the file
50
- # * Generate a subresource integrity digest
51
- #
52
- # At the end it will generate a manifest
53
- #
54
- # @see Hanami::Assets::Configuration#fingerprint
55
- # @see Hanami::Assets::Configuration#manifest
56
- # @see Hanami::Assets::Configuration#manifest_path
57
- def run
58
- assets.each do |path|
59
- unless File.directory?(path)
60
- configuration = _configuration_for(path)
61
- process(Asset.new(path, configuration))
62
- end
63
- end
64
-
65
- write_manifest_file
66
- end
67
-
68
- private
69
-
70
- # @since 0.3.0
71
- # @api private
72
- def process(asset)
73
- compress_in_place!(asset)
74
- copy_to_fingerprinted_location!(asset)
75
- @manifest.merge!(ManifestEntry.new(asset).entry)
76
- end
77
-
78
- # @since 0.3.0
79
- # @api private
80
- def copy_to_fingerprinted_location!(asset)
81
- FileUtils.cp(asset.path, asset.fingerprinted_target)
82
- _set_permissions(asset.fingerprinted_target)
83
- end
84
-
85
- # @since 0.3.0
86
- # @api private
87
- def compress_in_place!(asset)
88
- compressed = Compressor.new(asset.path, asset.configuration).compress
89
- _write(asset.path, compressed) unless compressed.nil?
90
- end
91
-
92
- # @since 0.3.0
93
- # @api private
94
- def write_manifest_file
95
- _write(@configuration.manifest_path, JSON.dump(@manifest))
96
- end
97
-
98
- # @since 0.1.0
99
- # @api private
100
- def assets
101
- Dir.glob("#{@configuration.destination_directory}#{::File::SEPARATOR}**#{::File::SEPARATOR}*")
102
- end
103
-
104
- # @since 0.1.0
105
- # @api private
106
- def _convert_to_url(path)
107
- path.sub(public_directory.to_s, URL_REPLACEMENT)
108
- .gsub(File::SEPARATOR, URL_SEPARATOR)
109
- end
110
-
111
- # @since 0.1.0
112
- # @api private
113
- def _write(path, content)
114
- Pathname.new(path).dirname.mkpath
115
- ::File.write(path, content)
116
-
117
- _set_permissions(path)
118
- end
119
-
120
- # @since 0.1.0
121
- # @api private
122
- def _set_permissions(path)
123
- ::File.chmod(DEFAULT_PERMISSIONS, path)
124
- end
125
-
126
- # @since 0.3.0
127
- # @api private
128
- def _configuration_for(asset)
129
- url = _convert_to_url(asset)
130
-
131
- configurations.find { |config| url.start_with?(config.prefix) } ||
132
- @configuration
133
- end
134
-
135
- # @since 0.1.0
136
- # @api private
137
- def public_directory
138
- @configuration.public_directory
139
- end
140
-
141
- # @since 0.4.0
142
- # @api private
143
- def configurations
144
- if @duplicates.empty?
145
- [@configuration]
146
- else
147
- @duplicates.map { |dup| dup.respond_to?(:configuration) ? dup.configuration : dup }
148
- end
149
- end
150
- end
151
- end
152
- end