hanami-assets 1.3.5 → 2.1.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
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