jekyll_plugin_support 0.8.0 → 0.8.1

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