jekyll_plugin_support 0.8.0 → 0.8.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 522c54334332d7fda1dc57bfa90647d419f458ff6153a7afe8bc8a60b0be7bca
4
- data.tar.gz: 6ce396d28eefd925fa8a7a367fbca3991b2ca3625b85c0720bc9eb295a107b03
3
+ metadata.gz: 4efc790e49d3b2d98eb4e96bee8c75a18df25fcf7c08d66a44ef96d7c6db19c6
4
+ data.tar.gz: 6629e04d2170911427e4914c0d356e3f9c95149b7a673b2638242ba43cbe11fa
5
5
  SHA512:
6
- metadata.gz: 65ca01eb7f2a017675220b352ee4f041a87df21cf435ca280acb19e512c547f68004be72e9f8dcd51aaad099a1beaefc3544261a63eae0f44fc9b8a5e636f58a
7
- data.tar.gz: 1049865b366c17bdc3b4d6b2e88e9826e3dfa849ff6b35f03b65b5c6d9b4367ccfe0477a4497ffab2cfea3e3210512ae2d8bf163f71450a05e5c5963d5960883
6
+ metadata.gz: 5afd0123f178c5fe89ddbfbf55e48a63630a3ebdffe07b28b60e6ba5d0df0ee1c7f6c5b4dc25ca0c77c5e0fe4329a46cf9902585cadbcc9ea90fed032dc4b459
7
+ data.tar.gz: fd6cb95f84f50655b12e81a069a6cdf85ec265f244159b200909ec9d7c8559871c4a781ddf162b10dd9a53eefb07614ed7cec172877130a52e2859a306df0512
data/.rubocop.yml CHANGED
@@ -30,7 +30,7 @@ Layout/LineLength:
30
30
  Max: 150
31
31
 
32
32
  Metrics/AbcSize:
33
- Max: 45
33
+ Max: 55
34
34
 
35
35
  Metrics/BlockLength:
36
36
  Exclude:
@@ -64,6 +64,9 @@ RSpec/IndexedLet:
64
64
  RSpec/MultipleExpectations:
65
65
  Max: 15
66
66
 
67
+ Style/ClassVars:
68
+ Enabled: false
69
+
67
70
  Style/Documentation:
68
71
  Enabled: false
69
72
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.8.1 / 2023-12-10
4
+
5
+ * Added the `JekyllPluginHelper.remove_html_tags` method.
6
+
7
+
3
8
  ## 0.8.0 / 2023-11-14
4
9
 
5
10
  * Restructured for better support of Liquid variables.
@@ -0,0 +1,55 @@
1
+ require 'facets/string/camelcase'
2
+ require 'facets/string/snakecase'
3
+
4
+ module Jekyll
5
+ # Use like this:
6
+ # CustomError.new(:MyError, 'blah', 'asdf')
7
+ class CustomError < StandardError
8
+ def self.factory(name)
9
+ return if Object.const_defined? name
10
+
11
+ puts "Defining #{name}".yellow
12
+ eval "#{name} = Class.new Jekyll::CustomError" # rubocop:disable Style/EvalWithLocation, Security/Eval
13
+ end
14
+
15
+ def error_name
16
+ self.class.name.split('::').last
17
+ end
18
+
19
+ def calling_file
20
+ file_fq, _line_number, _extra = backtrace[0].split(':')
21
+ file_fq
22
+ end
23
+
24
+ # @return HTML <div> tag with class set to the snake_case version of the error class name.
25
+ def html_message
26
+ shorten_backtrace
27
+ line_number = self.class.class_variable_get :@@line_number
28
+ path = self.class.class_variable_get :@@path
29
+ <<~END_MSG
30
+ <div class='#{error_name.snakecase}'>
31
+ #{self.class} raised in #{calling_file} while processing line #{line_number} (after front matter) of #{path}
32
+ #{message}
33
+ </div>
34
+ END_MSG
35
+ end
36
+
37
+ def logger_message
38
+ shorten_backtrace
39
+ kaller = caller(1..1).first
40
+ line_number = self.class.class_variable_get :@@line_number
41
+ path = self.class.class_variable_get :@@path
42
+ <<~END_MSG
43
+ #{error_name} raised in #{kaller} while processing line #{line_number} (after front matter) of #{path}
44
+ #{message}
45
+ END_MSG
46
+ end
47
+
48
+ def shorten_backtrace(backtrace_element_count = 3)
49
+ b = backtrace[0..backtrace_element_count - 1].map do |x|
50
+ x.gsub(Dir.pwd + '/', './')
51
+ end
52
+ set_backtrace b
53
+ end
54
+ end
55
+ end
@@ -19,20 +19,23 @@ module JekyllSupportErrorHandling
19
19
  rescue StandardError => e
20
20
  file, line_number, caller = e.backtrace[caller_index].split(':')
21
21
  caller = caller.tr('`', "'")
22
- warn "#{error.msg} #{caller} on line #{line_number} (after front matter) of #{file}".red
22
+ warn "#{error.message} #{caller} on line #{line_number} (after front matter) of #{file}".red
23
23
  # Process.kill('HUP', Process.pid) # generates huge stack trace
24
24
  exec "echo ''"
25
25
  end
26
26
 
27
+ # TODO: Delete this
27
28
  def format_error_message(message)
28
29
  page = " of #{@page['path']}" if @page
29
30
  remove_ansi_color "on line #{line_number} (after front matter)#{page}.\n#{message}"
30
31
  end
31
32
 
33
+ # TODO: Delete this
32
34
  def remove_ansi_color(string)
33
35
  string.gsub(/\e\[([;\d]+)?m/, '')
34
36
  end
35
37
 
38
+ # TODO: Delete this
36
39
  def maybe_reraise_error(error, throw_error: true)
37
40
  fmsg = format_error_message "#{error.class}: #{error.message.strip}"
38
41
  @logger.error { fmsg }
@@ -25,7 +25,7 @@ class JekyllPluginHelper
25
25
  @markup = markup
26
26
  rescue StandardError => e
27
27
  e.shorten_backtrace
28
- @logger.error { e.msg }
28
+ @logger.error { e.message }
29
29
  end
30
30
 
31
31
  # @return undefined if parameter was specified, removes it from the available tokens and returns value
@@ -1,3 +1,7 @@
1
+ require 'facets/string/camelcase'
2
+ require 'facets/string/snakecase'
3
+ require 'yaml'
4
+
1
5
  # Class methods for JekyllPluginHelper
2
6
  class JekyllPluginHelper
3
7
  # Expand an environment variable reference
@@ -11,19 +15,55 @@ class JekyllPluginHelper
11
15
  end
12
16
  end
13
17
 
14
- def self.register(klass, name)
15
- abort("Error: The #{name} plugin does not define VERSION") \
18
+ def self.generate_message(klass, tag_name, version)
19
+ error_ruby_class_name = "#{klass.name.camelcase(:upper)}Error"
20
+ config_die_key = "die_on_#{error_ruby_class_name.snakecase}"
21
+ error_css_class_name = error_ruby_class_name.split('::').last.snakecase
22
+ # config_file_fq = File.realpath 'demo/_config.yml'
23
+ config = YAML.load_file('demo/_config.yml')
24
+ tag_config = config[tag_name]
25
+ tag_config_msg = if tag_config.nil?
26
+ <<~END_MSG
27
+ _config.yml does not contain configuration information for this plugin.
28
+ You could add a section containing default values like this:
29
+
30
+ #{tag_name}:
31
+ #{config_die_key}: false
32
+ END_MSG
33
+ else
34
+ <<~END_MSG
35
+ _config.yml contains the following configuration for this plugin is:
36
+ #{tag_config}
37
+ END_MSG
38
+ end
39
+
40
+ <<~END_MSG
41
+ Loaded plugin #{tag_name} v#{version}. It has:
42
+ Error class: #{error_ruby_class_name}
43
+ CSS class for error messages: #{error_css_class_name}
44
+
45
+ #{tag_config_msg}
46
+ END_MSG
47
+ end
48
+
49
+ def self.register(klass, tag_name)
50
+ abort("Error: The #{tag_name} plugin does not define VERSION") \
16
51
  unless klass.const_defined?(:VERSION)
17
52
 
18
53
  version = klass.const_get(:VERSION)
19
54
 
20
- abort("Error: The #{name} plugin is not an instance of JekyllSupport::JekyllBlock or JekyllSupport::JekyllTag") \
55
+ abort("Error: The #{tag_name} plugin is not an instance of JekyllSupport::JekyllBlock or JekyllSupport::JekyllTag") \
21
56
  unless klass.instance_of?(Class) &&
22
57
  (klass.ancestors.include?(JekyllSupport::JekyllBlock) ||
23
58
  klass.ancestors.include?(JekyllSupport::JekyllTag))
24
59
 
25
- Liquid::Template.register_tag(name, klass)
26
- PluginMetaLogger.instance.info { "Loaded #{name} v#{version} plugin." }
60
+ Liquid::Template.register_tag(tag_name, klass)
61
+ msg = generate_message(klass, tag_name, version)
62
+ PluginMetaLogger.instance.info msg
63
+ end
64
+
65
+ def self.remove_html_tags(string)
66
+ string.gsub(/<[^>]*>/, '').strip
27
67
  end
28
68
 
29
69
  # strip leading and trailing quotes if present
@@ -1,3 +1,3 @@
1
1
  module JekyllPluginSupportVersion
2
- VERSION = '0.8.0'.freeze
2
+ VERSION = '0.8.1'.freeze
3
3
  end
@@ -15,3 +15,4 @@ require_relative 'jekyll_plugin_support_block'
15
15
  require_relative 'jekyll_plugin_support_block_noarg'
16
16
  require_relative 'jekyll_plugin_support_tag'
17
17
  require_relative 'jekyll_plugin_support_tag_noarg'
18
+ require_relative 'jekyll_custom_error'
@@ -8,6 +8,14 @@ module JekyllSupport
8
8
  include JekyllSupportErrorHandling
9
9
  extend JekyllSupportErrorHandling
10
10
 
11
+ def set_error_context
12
+ error_class = Object.const_get error_class_name
13
+ error_class.class_variable_set(:@@argument_string, @argument_string)
14
+ error_class.class_variable_set(:@@line_number, @line_number)
15
+ error_class.class_variable_set(:@@path, @page['path'])
16
+ error_class.class_variable_set(:@@tag_name, @tag_name)
17
+ end
18
+
11
19
  # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
12
20
  # @param tag_name [String] the name of the tag, which we usually know.
13
21
  # @param argument_string [String] the arguments passed to the tag, as a single string.
@@ -24,6 +32,9 @@ module JekyllSupport
24
32
  @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
25
33
  @logger.debug { "#{self.class}: respond_to?(:no_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
26
34
  @helper = JekyllPluginHelper.new tag_name, markup, @logger, respond_to?(:no_arg_parsing)
35
+
36
+ @error_name = "#{tag_name.camelcase(:upper)}Error"
37
+ Jekyll::CustomError.factory @error_name
27
38
  end
28
39
 
29
40
  # Method prescribed by the Jekyll plugin lifecycle.
@@ -41,6 +52,8 @@ module JekyllSupport
41
52
  @config = @site.config
42
53
  @tag_config = @config[@tag_name]
43
54
 
55
+ set_error_context @error_name
56
+
44
57
  @layout = @envs[:layout]
45
58
  @paginator = @envs[:paginator]
46
59
  @theme = @envs[:theme]
@@ -58,11 +71,15 @@ module JekyllSupport
58
71
  render_impl text
59
72
  rescue StandardError => e
60
73
  e.shorten_backtrace
61
- msg = format_error_message e.full_message
62
- @logger.error msg
74
+ @logger.error { "#{e.class} on line #{@line_number} of #{e.backtrace[0].split(':').first} by #{tag_name} - #{e.message}" }
75
+ binding.pry if @pry_on_standard_error # rubocop:disable Lint/Debugger
63
76
  raise e if @die_on_standard_error
64
77
 
65
- "<div class='standard_error'>#{e.class}: #{msg}</div>"
78
+ <<~END_MSG
79
+ <div class='standard_error'>
80
+ #{e.class} on line #{@line_number} of #{e.backtrace[0].split(':').first} by #{tag_name}: #{e.message}
81
+ </div>
82
+ END_MSG
66
83
  end
67
84
 
68
85
  # Jekyll plugins should override this method, not render,
@@ -1,3 +1,5 @@
1
+ require_relative 'jekyll_custom_error'
2
+
1
3
  # Monkey patch StandardError so a new method called shorten_backtrace is added.
2
4
  class StandardError
3
5
  def shorten_backtrace(backtrace_element_count = 3)
@@ -20,7 +22,7 @@ module JekyllSupport
20
22
 
21
23
  # @return a new StandardError subclass containing the shorten_backtrace method
22
24
  def define_error
23
- Class.new StandardError
25
+ Class.new Jekyll::CustomError
24
26
  end
25
27
  module_function :define_error
26
28
 
@@ -78,7 +80,7 @@ module JekyllSupport
78
80
  def self.warn_short_trace(logger, error)
79
81
  remaining = error.backtrace.length - DISPLAYED_CALLS
80
82
  logger.warn do
81
- error.msg + "\n" +
83
+ error.message + "\n" +
82
84
  error.backtrace.take(DISPLAYED_CALLS).join("\n") +
83
85
  "\n...Remaining #{remaining} call sites elided.\n"
84
86
  end
@@ -27,6 +27,17 @@ module JekyllSupport
27
27
  @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
28
28
  @logger.debug { "#{self.class}: respond_to?(:no_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
29
29
  @helper = JekyllPluginHelper.new(tag_name, @argument_string, @logger, respond_to?(:no_arg_parsing))
30
+
31
+ @error_name = "#{tag_name.camelcase(:upper)}Error"
32
+ Jekyll::CustomError.factory @error_name
33
+ end
34
+
35
+ def set_error_context
36
+ error_class = Object.const_get @error_name
37
+ error_class.class_variable_set(:@@argument_string, @argument_string)
38
+ error_class.class_variable_set(:@@line_number, @line_number)
39
+ error_class.class_variable_set(:@@path, @page['path'])
40
+ error_class.class_variable_set(:@@tag_name, @tag_name)
30
41
  end
31
42
 
32
43
  # Method prescribed by the Jekyll plugin lifecycle.
@@ -45,6 +56,8 @@ module JekyllSupport
45
56
  @jps = @config['jekyll_plugin_support']
46
57
  @pry_on_standard_error = @jps['pry_on_standard_error'] || false if @jps
47
58
 
59
+ set_error_context @error_name
60
+
48
61
  # @envs.keys are :content, :highlighter_prefix, :highlighter_suffix, :jekyll, :layout, :page, :paginator, :site, :theme
49
62
  @layout = @envs[:layout]
50
63
  @paginator = @envs[:paginator]
@@ -57,12 +70,15 @@ module JekyllSupport
57
70
  render_impl
58
71
  rescue StandardError => e
59
72
  e.shorten_backtrace
60
- msg = format_error_message e.full_message
61
- @logger.error msg
73
+ @logger.error { "#{e.class} on line #{@line_number} of #{e.backtrace[0].split(':').first} while processing #{tag_name} - #{e.message}" }
62
74
  binding.pry if @pry_on_standard_error # rubocop:disable Lint/Debugger
63
75
  raise e if @die_on_standard_error
64
76
 
65
- "<div class='standard_error'>#{e.class}: #{msg}</div>"
77
+ <<~END_MSG
78
+ <div class='standard_error'>
79
+ #{e.class} on line #{@line_number} of #{e.backtrace[0].split(':').first} while processing #{tag_name}: #{e.message}
80
+ </div>
81
+ END_MSG
66
82
  end
67
83
 
68
84
  # Jekyll plugins must override this method, not render, so their plugin can be tested more easily
@@ -0,0 +1,39 @@
1
+ require_relative '../lib/jekyll_custom_error'
2
+ require_relative '../lib/jekyll_plugin_support_class'
3
+
4
+ class Dummy
5
+ def just_for_testing; end
6
+ end
7
+
8
+ class CustomErrorSpec
9
+ tag_name = 'test_tag'
10
+ argument_string = 'This is the argument string'
11
+ AnError = JekyllSupport.define_error
12
+ AnError.class_variable_set(:@@tag_name, tag_name)
13
+ AnError.class_variable_set(:@@argument_string, argument_string)
14
+
15
+ puts "AnError is a #{AnError.class}; StandardError is a #{StandardError.class}"
16
+ begin
17
+ raise AnError, 'Oops'
18
+ rescue AnError => e
19
+ puts "Caught AnError: #{e.message}"
20
+ rescue Jekyll::CustomError => e
21
+ puts "Caught CustomError: #{e.message}"
22
+ end
23
+
24
+ RSpec.describe JekyllPluginHelper do
25
+ it 'generates messages' do
26
+ msg = described_class.generate_message(Dummy, tag_name, '0.1.0')
27
+ puts msg
28
+ expect(msg).to include(match(/Error class. DummyError/))
29
+ expect(msg).to include(match(/CSS class for error messages. dummy_error/))
30
+ expect(msg).to include(match(/die_on_dummy_error. false/))
31
+ end
32
+ end
33
+
34
+ RSpec.describe Jekyll::CustomError do
35
+ it 'can create custom errors' do
36
+ expect { raise AnError, 'Oops' }.to raise_error(AnError)
37
+ end
38
+ end
39
+ end
@@ -1,7 +1,6 @@
1
1
  example_id | status | run_time |
2
2
  ------------------------------------------------ | ------ | --------------- |
3
- ./spec/jekyll_plugin_helper_options_spec.rb[1:1] | failed | 0.00009 seconds |
4
- ./spec/jekyll_plugin_helper_options_spec.rb[1:2] | failed | 0.00004 seconds |
5
- ./spec/jekyll_plugin_helper_options_spec.rb[1:3] | failed | 0.00002 seconds |
6
- ./spec/jekyll_plugin_helper_options_spec.rb[1:4] | failed | 0.00002 seconds |
7
- ./spec/liquid_variable_parsing_spec.rb[1:1] | failed | 0.00003 seconds |
3
+ ./spec/jekyll_plugin_helper_options_spec.rb[1:1] | passed | 0.00559 seconds |
4
+ ./spec/jekyll_plugin_helper_options_spec.rb[1:2] | passed | 0.00583 seconds |
5
+ ./spec/jekyll_plugin_helper_options_spec.rb[1:3] | passed | 0.00543 seconds |
6
+ ./spec/jekyll_plugin_helper_options_spec.rb[1:4] | passed | 0.00157 seconds |
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll_plugin_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Slinn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-22 00:00:00.000000000 Z
11
+ date: 2024-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facets
@@ -94,6 +94,7 @@ files:
94
94
  - README.md
95
95
  - Rakefile
96
96
  - jekyll_plugin_support.gemspec
97
+ - lib/jekyll_custom_error.rb
97
98
  - lib/jekyll_plugin_error_handling.rb
98
99
  - lib/jekyll_plugin_helper.rb
99
100
  - lib/jekyll_plugin_helper_attribution.rb
@@ -106,6 +107,7 @@ files:
106
107
  - lib/jekyll_plugin_support_spec_support.rb
107
108
  - lib/jekyll_plugin_support_tag.rb
108
109
  - lib/jekyll_plugin_support_tag_noarg.rb
110
+ - spec/custom_error_spec.rb
109
111
  - spec/jekyll_plugin_helper_options_spec.rb
110
112
  - spec/liquid_variable_parsing_spec.rb
111
113
  - spec/spec_helper.rb
@@ -137,11 +139,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
139
  - !ruby/object:Gem::Version
138
140
  version: '0'
139
141
  requirements: []
140
- rubygems_version: 3.3.7
142
+ rubygems_version: 3.4.22
141
143
  signing_key:
142
144
  specification_version: 4
143
145
  summary: Provides a framework for writing and testing Jekyll plugins
144
146
  test_files:
147
+ - spec/custom_error_spec.rb
145
148
  - spec/jekyll_plugin_helper_options_spec.rb
146
149
  - spec/liquid_variable_parsing_spec.rb
147
150
  - spec/spec_helper.rb