diff --git a/Gemfile b/Gemfile index c3f0226..a6d08a7 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source 'https://rubygems.org' # Specify your gem's dependencies in tracer_client.gemspec gemspec -gem 'combustion', '~> 1.1.2' +gem 'combustion', '~> 1.3' gem 'pry', '~> 0.12' gem 'rake', '~> 13.0' gem 'rspec', '~> 3.9' diff --git a/Gemfile.lock b/Gemfile.lock index 1d3775d..85393de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ GIT remote: https://github.com/corp-gp/rubocop-gp.git - revision: 4d390b6cdd2b27f151fe0535bd266525fbf8f25d + revision: 94d07b3b370a199f7d26094d3606d79a0cf92f57 specs: - rubocop-gp (0.0.2) + rubocop-gp (0.0.3) rubocop rubocop-performance rubocop-rails @@ -11,91 +11,98 @@ GIT PATH remote: . specs: - email_stylist (0.1.0) + email_stylist (0.2.0) inky-rb premailer GEM remote: https://rubygems.org/ specs: - actionpack (6.1.3.1) - actionview (= 6.1.3.1) - activesupport (= 6.1.3.1) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.6) + actionview (= 7.0.6) + activesupport (= 7.0.6) + rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actionview (6.1.3.1) - activesupport (= 6.1.3.1) + actionview (7.0.6) + activesupport (= 7.0.6) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activesupport (6.1.3.1) + activesupport (7.0.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.7.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) builder (3.2.4) coderay (1.1.3) - combustion (1.1.2) + combustion (1.3.7) activesupport (>= 3.0.0) railties (>= 3.0.0) thor (>= 0.14.6) - concurrent-ruby (1.1.8) + concurrent-ruby (1.2.2) crass (1.0.6) - css_parser (1.9.0) + css_parser (1.14.0) addressable - diff-lcs (1.4.4) - erubi (1.10.0) + diff-lcs (1.5.0) + erubi (1.12.0) foundation_emails (2.2.1.0) htmlentities (4.3.4) - i18n (1.8.9) + i18n (1.14.1) concurrent-ruby (~> 1.0) - inky-rb (1.3.8.0) + inky-rb (1.4.2.0) foundation_emails (~> 2) nokogiri - loofah (2.9.0) + json (2.6.3) + language_server-protocol (3.17.0.3) + loofah (2.21.3) crass (~> 1.0.2) - nokogiri (>= 1.5.9) + nokogiri (>= 1.12.0) method_source (1.0.0) - minitest (5.14.4) - nokogiri (1.11.2-x86_64-linux) + minitest (5.18.1) + nokogiri (1.15.3-arm64-darwin) racc (~> 1.4) - parallel (1.20.1) - parser (3.0.0.0) + nokogiri (1.15.3-x86_64-linux) + racc (~> 1.4) + parallel (1.23.0) + parser (3.2.2.3) ast (~> 2.4.1) - premailer (1.14.2) + racc + premailer (1.21.0) addressable - css_parser (>= 1.6.0) + css_parser (>= 1.12.0) htmlentities (>= 4.0.0) - pry (0.14.0) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (4.0.6) - racc (1.5.2) - rack (2.2.3) - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + public_suffix (5.0.3) + racc (1.7.1) + rack (2.2.7) + rack-test (2.1.0) + rack (>= 1.3) + rails-dom-testing (2.1.1) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) - loofah (~> 2.3) - railties (6.1.3.1) - actionpack (= 6.1.3.1) - activesupport (= 6.1.3.1) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + railties (7.0.6) + actionpack (= 7.0.6) + activesupport (= 7.0.6) method_source - rake (>= 0.8.7) + rake (>= 12.2) thor (~> 1.0) - rainbow (3.0.0) - rake (13.0.3) - regexp_parser (2.1.1) - rexml (3.2.4) + zeitwerk (~> 2.5) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.8.1) + rexml (3.2.5) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) @@ -117,40 +124,48 @@ GEM rspec-mocks (~> 3.9.0) rspec-support (~> 3.9.0) rspec-support (3.9.4) - rubocop (1.12.0) + rubocop (1.54.2) + json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.0.0.0) + parser (>= 3.2.2.3) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.2.0, < 2.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.4.1) - parser (>= 2.7.1.5) - rubocop-performance (1.10.2) - rubocop (>= 0.90.0, < 2.0) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.18.0) + rubocop (~> 1.41) + rubocop-factory_bot (2.23.1) + rubocop (~> 1.33) + rubocop-performance (1.18.0) + rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.9.1) + rubocop-rails (2.20.2) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.90.0, < 2.0) - rubocop-rspec (2.2.0) - rubocop (~> 1.0) - rubocop-ast (>= 1.1.0) - ruby-progressbar (1.11.0) - thor (1.1.0) - tilt (2.0.10) - tzinfo (2.0.4) + rubocop (>= 1.33.0, < 2.0) + rubocop-rspec (2.22.0) + rubocop (~> 1.33) + rubocop-capybara (~> 2.17) + rubocop-factory_bot (~> 2.22) + ruby-progressbar (1.13.0) + thor (1.2.2) + tilt (2.2.0) + tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.0.0) - zeitwerk (2.4.2) + unicode-display_width (2.4.2) + zeitwerk (2.6.8) PLATFORMS + arm64-darwin-21 x86_64-linux DEPENDENCIES - combustion (~> 1.1.2) + combustion (~> 1.3) email_stylist! pry (~> 0.12) rake (~> 13.0) diff --git a/email_stylist.gemspec b/email_stylist.gemspec index 85c568c..a3bffe7 100644 --- a/email_stylist.gemspec +++ b/email_stylist.gemspec @@ -21,6 +21,8 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] + spec.metadata['rubygems_mfa_required'] = 'true' + spec.add_dependency 'inky-rb' spec.add_dependency 'premailer' end diff --git a/lib/email_stylist/styled_erb_template.rb b/lib/email_stylist/styled_erb_template.rb index 23c609b..0e3d100 100644 --- a/lib/email_stylist/styled_erb_template.rb +++ b/lib/email_stylist/styled_erb_template.rb @@ -7,65 +7,65 @@ module EmailStylist class StyledErbTemplate - class << self - - def render( # rubocop:disable Metrics/ParameterLists - template_path:, - layout_path: nil, - compiled_path: nil, - pack: nil, - disable_caching: false, - view_context: nil - ) - template_id = "#{layout_path}#{template_path}" - - @cache ||= {} - @cache[template_id] = nil if disable_caching - - erb_template = @cache[template_id] ||= - begin - html = compile(template_path, layout_path).gsub(/<%.*?%>/m) { |s| "base64___#{Base64.strict_encode64(s)}___base64" } - - html = Inky::Core.new.release_the_kraken(html) - - pm = Premailer.new( - html, - css_string: (webpacker_css_string(pack) if pack), - with_html_string: true, - include_link_tags: true, - adapter: :nokogiri, - generate_text_part: false, - css_to_attributes: false, - remove_scripts: false, - ) - - html = pm.to_inline_css.force_encoding('ASCII-8BIT').gsub(/base64___(.+?)___base64/) { Base64.strict_decode64(Regexp.last_match(1)) } - - if compiled_path - write_compiled_erb(html, compiled_path) - Tilt::ERBTemplate.new(compiled_path) - else - Tilt::ERBTemplate.new { html } - end + def self.render( # rubocop:disable Metrics/ParameterLists + template_path:, + layout_path: nil, + compiled_path: nil, + pack: nil, + disable_caching: false, + view_context: nil + ) + template_id = "#{layout_path}#{template_path}" + + @cache ||= {} + @cache[template_id] = nil if disable_caching + + erb_template = @cache[template_id] ||= + begin + html = compile(template_path, layout_path).gsub(/<%.*?%>/m) { |s| "base64___#{Base64.strict_encode64(s)}___base64" } + + html = Inky::Core.new.release_the_kraken(html) + + pm = Premailer.new( + html, + css_string: (css_string(pack) if pack), + with_html_string: true, + include_link_tags: true, + adapter: :nokogiri, + generate_text_part: false, + css_to_attributes: false, + remove_scripts: false, + ) + + html = pm.to_inline_css.force_encoding('ASCII-8BIT').gsub(/base64___(.+?)___base64/) { Base64.strict_decode64(Regexp.last_match(1)) } + + if compiled_path + write_compiled_erb(html, compiled_path) + Tilt::ERBTemplate.new(compiled_path) + else + Tilt::ERBTemplate.new { html } end + end - erb_template.render(view_context) - end + erb_template.render(view_context) + end + + class << self private def write_compiled_erb(html, compiled_path) dir_name = File.dirname(compiled_path) - FileUtils.mkdir_p(dir_name) unless File.exist?(dir_name) + FileUtils.mkdir_p(dir_name) - File.open(compiled_path, 'wb') { |file| file.write(html) } + File.binwrite(compiled_path, html) end private def compile(template, layout) - html = File.open(layout || template, 'rb', &:read) + html = File.binread(layout || template) if layout html = html.each_line.map { |s| if s.include?('INCLUDE_BODY') - File.open(template, 'rb', &:read) + File.binread(template) else s end @@ -78,24 +78,27 @@ def render( # rubocop:disable Metrics/ParameterLists private def compile_components(html) html.each_line.map { |s| if (m = s.match(/INCLUDE_COMPONENT.*path="(.*)"/)) && m[1] - compile_components(File.open(m[1], 'rb', &:read)) + compile_components(File.binread(m[1])) else s end }.join end - private def webpacker_css_string(pack) - uri = Webpacker.manifest.lookup!(pack) + private def css_string(pack) + pack += '.css' unless pack.end_with?('.css') - raise "Unable to lookup webpacker pack #{pack}" unless uri + uri = + if ViteRuby.instance.dev_server_running? + ViteRuby.instance.builder.build + manifest = ViteRuby.instance.manifest + entry = manifest.send(:resolve_virtual_entry, pack) + manifest.send(:manifest)[entry].fetch('file') + else + ViteRuby.instance.manifest.path_for(pack) + end - if Webpacker.dev_server.running? - url = URI.join("#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}", uri) - Net::HTTP.get(url) - else - Rails.public_path.join(uri.delete_prefix('/')).read - end + Rails.public_path.join(uri.delete_prefix('/')).read end end diff --git a/lib/email_stylist/version.rb b/lib/email_stylist/version.rb index 032e38d..db97514 100644 --- a/lib/email_stylist/version.rb +++ b/lib/email_stylist/version.rb @@ -2,6 +2,6 @@ module EmailStylist - VERSION = '0.1.1' + VERSION = '0.2.0' end diff --git a/spec/email_stylist/styled_erb_template_spec.rb b/spec/email_stylist/styled_erb_template_spec.rb index 482b5a0..c24cf34 100644 --- a/spec/email_stylist/styled_erb_template_spec.rb +++ b/spec/email_stylist/styled_erb_template_spec.rb @@ -15,12 +15,12 @@
-
+
template: erb_here
component_content
-
+
@@ -35,12 +35,12 @@ expect(html).to eq(<<~HTML) -
+
template: erb_here
component_content
-
+
HTML end