hanami-assets 1.3.5 → 2.1.0.beta2

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