jekyll_plugin_support 0.7.2 → 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.
@@ -0,0 +1,94 @@
1
+ require_relative 'jekyll_plugin_error_handling'
2
+
3
+ module JekyllSupport
4
+ # Base class for Jekyll block tags
5
+ class JekyllBlock < Liquid::Block
6
+ attr_reader :argument_string, :helper, :line_number, :logger, :page, :site, :text
7
+
8
+ include JekyllSupportErrorHandling
9
+ extend JekyllSupportErrorHandling
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
+
19
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
20
+ # @param tag_name [String] the name of the tag, which we usually know.
21
+ # @param argument_string [String] the arguments passed to the tag, as a single string.
22
+ # @param parse_context [Liquid::ParseContext] hash that stores Liquid options.
23
+ # By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
24
+ # a boolean parameter that determines if error messages should display the line number the error occurred.
25
+ # This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
26
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
27
+ # @return [void]
28
+ def initialize(tag_name, markup, parse_context)
29
+ super
30
+ @tag_name = tag_name
31
+ @argument_string = markup.to_s # Vars in plugin parameters cannot be replaced yet
32
+ @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
33
+ @logger.debug { "#{self.class}: respond_to?(:no_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
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
38
+ end
39
+
40
+ # Method prescribed by the Jekyll plugin lifecycle.
41
+ # Defines @config, @envs, @mode, @page and @site
42
+ # @return [String]
43
+ def render(liquid_context)
44
+ @helper.liquid_context = JekyllSupport.inject_vars @logger, liquid_context
45
+ text = super # Liquid variable values in content are looked up and substituted
46
+
47
+ @envs = liquid_context.environments.first
48
+ @page = liquid_context.registers[:page] # hash
49
+ @scopes = liquid_context.scopes
50
+ @site = liquid_context.registers[:site]
51
+
52
+ @config = @site.config
53
+ @tag_config = @config[@tag_name]
54
+
55
+ set_error_context @error_name
56
+
57
+ @layout = @envs[:layout]
58
+ @paginator = @envs[:paginator]
59
+ @theme = @envs[:theme]
60
+
61
+ @mode = @config['env']&.key?('JEKYLL_ENV') ? @config['env']['JEKYLL_ENV'] : 'development'
62
+
63
+ @helper.reinitialize(@markup.strip)
64
+
65
+ @attribution = @helper.parameter_specified?('attribution') || false unless @no_arg_parsing
66
+ @logger.debug { "@keys_values='#{@keys_values}'" }
67
+
68
+ markup = JekyllSupport.lookup_liquid_variables liquid_context, @argument_string
69
+ @helper.reinitialize markup
70
+
71
+ render_impl text
72
+ rescue StandardError => e
73
+ e.shorten_backtrace
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
76
+ raise e if @die_on_standard_error
77
+
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
83
+ end
84
+
85
+ # Jekyll plugins should override this method, not render,
86
+ # so they can be tested more easily.
87
+ # The following variables are predefined:
88
+ # @argument_string, @config, @envs, @helper, @layout, @logger, @mode, @page, @paginator, @site, @tag_name and @theme
89
+ # @return [String] The result to be rendered to the invoking page
90
+ def render_impl(text)
91
+ text
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'jekyll_plugin_error_handling'
2
+
3
+ module JekyllSupport
4
+ class JekyllBlockNoArgParsing < JekyllBlock
5
+ attr_reader :argument_string, :helper, :line_number, :logger, :page, :site
6
+
7
+ include JekyllSupportErrorHandling
8
+ extend JekyllSupportErrorHandling
9
+
10
+ def initialize(tag_name, argument_string, parse_context)
11
+ class << self
12
+ include NoArgParsing
13
+ end
14
+
15
+ super
16
+ @logger.debug { "#{self.class}: respond_to?(:o_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
17
+ rescue StandardError => e
18
+ e.shorten_backtrace
19
+ @logger.error { e.full_message }
20
+ JekyllSupport.error_short_trace(@logger, e)
21
+ end
22
+
23
+ # Jekyll plugins must override this method, not render, so their plugin can be tested more easily
24
+ # The following variables are predefined:
25
+ # @argument_string, @config, @envs, @helper, @layout, @logger, @mode, @page, @paginator, @site, @tag_name and @theme
26
+ def render_impl
27
+ abort "#{self.class}.render_impl for tag #{@tag_name} must be overridden, but it was not."
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,88 @@
1
+ require_relative 'jekyll_custom_error'
2
+
3
+ # Monkey patch StandardError so a new method called shorten_backtrace is added.
4
+ class StandardError
5
+ def shorten_backtrace(backtrace_element_count = 3)
6
+ # self.backtrace = backtrace[0..backtrace_element_count].map do |x|
7
+ # raise JekyllPluginSupportError, "backtrace contains a #{x.class} with value '#{x}'." unless x.instance_of? String
8
+
9
+ # x.gsub(Dir.pwd + '/', './')
10
+ # end
11
+ end
12
+ end
13
+
14
+ module JekyllSupport
15
+ DISPLAYED_CALLS = 8
16
+
17
+ def self.error_short_trace(logger, error)
18
+ error.set_backtrace error.backtrace[0..DISPLAYED_CALLS]
19
+ logger.error { error }
20
+ error
21
+ end
22
+
23
+ # @return a new StandardError subclass containing the shorten_backtrace method
24
+ def define_error
25
+ Class.new Jekyll::CustomError
26
+ end
27
+ module_function :define_error
28
+
29
+ JekyllPluginSupportError = define_error
30
+
31
+ def self.dump_vars(_logger, liquid_context)
32
+ page = liquid_context.registers[:page]
33
+ vars = liquid_context.scopes.map do |scope|
34
+ scope.map { |name, value| " #{name} = #{value}" }.join("\n")
35
+ end.join("\n")
36
+ puts <<~END_MSG
37
+ #{page['name']} variables after injecting any defined in _config.yml:
38
+ #{vars}
39
+ END_MSG
40
+ end
41
+
42
+ # Add variable definitions from _config.yml to liquid_context
43
+ # Modifies liquid_context in the caller (call by reference)
44
+ # @return modified liquid_context
45
+ # See README.md#configuration-variable-definitions
46
+ # See demo/variables.html
47
+ def self.inject_vars(_logger, liquid_context)
48
+ site = liquid_context.registers[:site]
49
+
50
+ plugin_variables = site.config['liquid_vars']
51
+ return liquid_context unless plugin_variables
52
+
53
+ scope = liquid_context.scopes.last
54
+
55
+ env = site.config['env']
56
+ mode = env&.key?('JEKYLL_ENV') ? env['JEKYLL_ENV'] : 'development'
57
+
58
+ # Set default values
59
+ plugin_variables&.each do |name, value|
60
+ scope[name] = value if value.instance_of? String
61
+ end
62
+
63
+ # Override with environment-specific values
64
+ plugin_variables[mode]&.each do |name, value|
65
+ scope[name] = value if value.instance_of? String
66
+ end
67
+
68
+ liquid_context
69
+ end
70
+
71
+ def self.lookup_liquid_variables(liquid_context, markup)
72
+ liquid_context.scopes.each do |scope|
73
+ scope.each do |name, value|
74
+ markup = markup.gsub("{{#{name}}}", value.to_s)
75
+ end
76
+ end
77
+ markup
78
+ end
79
+
80
+ def self.warn_short_trace(logger, error)
81
+ remaining = error.backtrace.length - DISPLAYED_CALLS
82
+ logger.warn do
83
+ error.message + "\n" +
84
+ error.backtrace.take(DISPLAYED_CALLS).join("\n") +
85
+ "\n...Remaining #{remaining} call sites elided.\n"
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,91 @@
1
+ require 'pry'
2
+ require_relative 'jekyll_plugin_error_handling'
3
+
4
+ module JekyllSupport
5
+ # Base class for Jekyll tags
6
+ class JekyllTag < Liquid::Tag
7
+ attr_reader :argument_string, :helper, :line_number, :logger, :page, :site
8
+
9
+ include JekyllSupportErrorHandling
10
+ extend JekyllSupportErrorHandling
11
+
12
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
13
+ # @param tag_name [String] the name of the tag, which we usually know.
14
+ # @param argument_string [String] the arguments passed to the tag, as a single string.
15
+ # @param parse_context [Liquid::ParseContext] hash that stores Liquid options.
16
+ # By default it has two keys: :locale and :line_numbers, the first is a Liquid::I18n object, and the second,
17
+ # a boolean parameter that determines if error messages should display the line number the error occurred.
18
+ # This argument is used mostly to display localized error messages on Liquid built-in Tags and Filters.
19
+ # See https://github.com/Shopify/liquid/wiki/Liquid-for-Programmers#create-your-own-tags
20
+ # @return [void]
21
+ def initialize(tag_name, markup, parse_context)
22
+ super
23
+ @tag_name = tag_name
24
+ raise JekyllPluginSupportError, "markup is a #{markup.class} with value '#{markup}'." unless markup.instance_of? String
25
+
26
+ @argument_string = markup
27
+ @logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
28
+ @logger.debug { "#{self.class}: respond_to?(:no_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
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)
41
+ end
42
+
43
+ # Method prescribed by the Jekyll plugin lifecycle.
44
+ def render(liquid_context)
45
+ return if @helper.excerpt_caller
46
+
47
+ @helper.liquid_context = JekyllSupport.inject_vars @logger, liquid_context
48
+
49
+ @envs = liquid_context.environments.first
50
+ @page = liquid_context.registers[:page]
51
+ @scopes = liquid_context.scopes
52
+ @site = liquid_context.registers[:site]
53
+
54
+ @config = @site.config
55
+ @tag_config = @config[@tag_name]
56
+ @jps = @config['jekyll_plugin_support']
57
+ @pry_on_standard_error = @jps['pry_on_standard_error'] || false if @jps
58
+
59
+ set_error_context @error_name
60
+
61
+ # @envs.keys are :content, :highlighter_prefix, :highlighter_suffix, :jekyll, :layout, :page, :paginator, :site, :theme
62
+ @layout = @envs[:layout]
63
+ @paginator = @envs[:paginator]
64
+ @theme = @envs[:theme]
65
+
66
+ @mode = @config['env']&.key?('JEKYLL_ENV') ? @config['env']['JEKYLL_ENV'] : 'development'
67
+
68
+ @helper.reinitialize JekyllSupport.lookup_liquid_variables liquid_context, @argument_string
69
+
70
+ render_impl
71
+ rescue StandardError => e
72
+ e.shorten_backtrace
73
+ @logger.error { "#{e.class} on line #{@line_number} of #{e.backtrace[0].split(':').first} while processing #{tag_name} - #{e.message}" }
74
+ binding.pry if @pry_on_standard_error # rubocop:disable Lint/Debugger
75
+ raise e if @die_on_standard_error
76
+
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
82
+ end
83
+
84
+ # Jekyll plugins must override this method, not render, so their plugin can be tested more easily
85
+ # The following variables are predefined:
86
+ # @argument_string, @config, @envs, @helper, @layout, @logger, @mode, @page, @paginator, @site, @tag_name and @theme
87
+ def render_impl
88
+ abort "#{self.class}.render_impl for tag #{@tag_name} must be overridden, but it was not."
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'jekyll_plugin_error_handling'
2
+
3
+ module JekyllSupport
4
+ class JekyllTagNoArgParsing < JekyllTag
5
+ attr_reader :argument_string, :helper, :line_number, :logger, :page, :site
6
+
7
+ include JekyllSupportErrorHandling
8
+ extend JekyllSupportErrorHandling
9
+
10
+ def initialize(tag_name, argument_string, parse_context)
11
+ class << self
12
+ include NoArgParsing
13
+ end
14
+
15
+ super
16
+ @logger.debug { "#{self.class}: respond_to?(:no_arg_parsing) #{respond_to?(:no_arg_parsing) ? 'yes' : 'no'}." }
17
+ end
18
+
19
+ # Jekyll plugins must override this method, not render, so their plugin can be tested more easily
20
+ # The following variables are predefined:
21
+ # @argument_string, @config, @envs, @helper, @layout, @logger, @mode, @page, @paginator, @site, @tag_name and @theme
22
+ def render_impl
23
+ abort "#{self.class}.render_impl for tag #{@tag_name} must be overridden, but it was not."
24
+ end
25
+ end
26
+ end
@@ -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
@@ -0,0 +1,34 @@
1
+ require 'jekyll_plugin_logger'
2
+ require 'rspec/match_ignoring_whitespace'
3
+ require_relative '../lib/jekyll_plugin_support'
4
+ require_relative '../lib/jekyll_plugin_support_spec_support'
5
+
6
+ class LiquidVariableParsing
7
+ # @return copy of str with references to defined variables replaced by the values of the variables
8
+ def variable_replace(str, scopes)
9
+ result = str.clone
10
+ match_data_list = str.to_enum(:scan, /{{[a-z_][a-zA-Z_0-9]*}}/).map { Regexp.last_match }.reverse
11
+ match_data_list.each do |md|
12
+ from = md.begin(0)
13
+ to = md.end(0) - 1
14
+ ref = str[from..to]
15
+ name = ref[2..-3]
16
+ scopes.each do |scope|
17
+ value = scope.key?(name) ? scope[name] : ref
18
+ # puts "str=#{str}; from=#{from}; to=#{to}; name=#{name} value=#{value}"
19
+ result[from..to] = value
20
+ end
21
+ end
22
+ result
23
+ end
24
+
25
+ RSpec.describe JekyllPluginHelper do
26
+ it 'substitutes variable references for values without recursion' do
27
+ scopes = [{ 'a' => '{{', 'b' => 'asdf', 'c' => '}}' }]
28
+ str = '{{a}}{{b}}{{c}} This should be unchanged: {{d}}'
29
+ new_str = variable_replace(str, scopes)
30
+ expect(str).to start_with('{{a}}')
31
+ expect(new_str).to be('{{asdf}} This should be unchanged: {{d}}')
32
+ end
33
+ end
34
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,9 +2,8 @@ require 'jekyll'
2
2
  require_relative '../lib/jekyll_plugin_support'
3
3
 
4
4
  RSpec.configure do |config|
5
- config.filter_run :focus
5
+ config.filter_run_when_matching focus: true
6
6
  # config.order = 'random'
7
- config.run_all_when_everything_filtered = true
8
7
 
9
8
  # See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
10
9
  config.example_status_persistence_file_path = 'spec/status_persistence.txt'
@@ -0,0 +1,6 @@
1
+ example_id | status | run_time |
2
+ ------------------------------------------------ | ------ | --------------- |
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.7.2
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-08-14 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
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description:
70
84
  email:
71
85
  - mslinn@mslinn.com
@@ -80,13 +94,22 @@ files:
80
94
  - README.md
81
95
  - Rakefile
82
96
  - jekyll_plugin_support.gemspec
83
- - lib/call_chain.rb
84
- - lib/gem_support.rb
97
+ - lib/jekyll_custom_error.rb
98
+ - lib/jekyll_plugin_error_handling.rb
85
99
  - lib/jekyll_plugin_helper.rb
100
+ - lib/jekyll_plugin_helper_attribution.rb
101
+ - lib/jekyll_plugin_helper_class.rb
86
102
  - lib/jekyll_plugin_support.rb
87
103
  - lib/jekyll_plugin_support/version.rb
104
+ - lib/jekyll_plugin_support_block.rb
105
+ - lib/jekyll_plugin_support_block_noarg.rb
106
+ - lib/jekyll_plugin_support_class.rb
88
107
  - lib/jekyll_plugin_support_spec_support.rb
108
+ - lib/jekyll_plugin_support_tag.rb
109
+ - lib/jekyll_plugin_support_tag_noarg.rb
110
+ - spec/custom_error_spec.rb
89
111
  - spec/jekyll_plugin_helper_options_spec.rb
112
+ - spec/liquid_variable_parsing_spec.rb
90
113
  - spec/spec_helper.rb
91
114
  - spec/status_persistence.txt
92
115
  homepage: https://www.mslinn.com/jekyll_plugins/jekyll_plugin_support.html
@@ -116,12 +139,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
116
139
  - !ruby/object:Gem::Version
117
140
  version: '0'
118
141
  requirements: []
119
- rubygems_version: 3.3.3
142
+ rubygems_version: 3.4.22
120
143
  signing_key:
121
144
  specification_version: 4
122
- summary: Provides support for writing Jekyll plugins.
145
+ summary: Provides a framework for writing and testing Jekyll plugins
123
146
  test_files:
147
+ - spec/custom_error_spec.rb
124
148
  - spec/jekyll_plugin_helper_options_spec.rb
149
+ - spec/liquid_variable_parsing_spec.rb
125
150
  - spec/spec_helper.rb
126
151
  - spec/status_persistence.txt
127
152
  ...
data/lib/call_chain.rb DELETED
@@ -1,54 +0,0 @@
1
- # TODO: File not used, delete
2
-
3
- # See https://stackoverflow.com/a/23363883/553865
4
- module CallChain
5
- ACaller = Struct.new(:filepath, :line, :method_name)
6
-
7
- def self.caller_method(depth = 1)
8
- parse_caller(caller(depth + 1).first).method_name
9
- end
10
-
11
- def self.parse_caller(at)
12
- return unless /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
13
-
14
- last_match = Regexp.last_match.to_a
15
- ACaller.new(
16
- last_match[1],
17
- last_match[2].to_i,
18
- last_match[3]
19
- )
20
- end
21
-
22
- def self.excerpt_caller
23
- call_sequence = caller
24
- call_sequence.each do |caller_|
25
- parsed_caller = parse_caller caller_
26
- filepath = parsed_caller.filepath
27
- excerpt = filepath.match? %r{jekyll[.0-9-]*/lib/jekyll/excerpt.rb\z}
28
- puts "excerpt matched #{filepath}" if excerpt
29
- return true if excerpt
30
- end
31
- false
32
- end
33
-
34
- # Return ACaller prior to jekyll_plugin_support
35
- def self.jpsh_subclass_caller
36
- state = :nothing_found
37
- call_sequence = caller
38
- call_sequence.each do |caller_|
39
- parsed_caller = parse_caller caller_
40
- filepath = parsed_caller.filepath
41
- dirname = File.dirname filepath
42
- jpsh = dirname.match? %r{jekyll_plugin_support[.0-9-]*/lib\z}
43
- liquid = dirname.match? %r{liquid[.0-9-]*/lib/\z}
44
- case state
45
- when :nothing_found
46
- state = :jpsh_found if jpsh
47
- when :jpsh_found
48
- # puts "Called from #{parsed_caller.filepath}, on line #{parsed_caller.line}, by method '#{parsed_caller.method_name}'" unless jpsh
49
- return parsed_caller unless jpsh || liquid
50
- end
51
- end
52
- nil
53
- end
54
- end
data/lib/gem_support.rb DELETED
@@ -1,19 +0,0 @@
1
- # See https://stackoverflow.com/a/75890279/553865
2
- module GemSupport
3
- # @param file must be a fully qualified file name that points to a file within a gem.
4
- # @return Gem::Specification of gem that file points into, or nil if not called from a gem
5
- def self.current_spec(file)
6
- abort 'GemSupport::current_spec: file is nil' if file.nil?
7
- return nil unless File.exist?(file)
8
-
9
- searcher = if Gem::Specification.respond_to?(:find)
10
- Gem::Specification
11
- elsif Gem.respond_to?(:searcher)
12
- Gem.searcher.init_gemspecs
13
- end
14
-
15
- searcher&.find do |spec|
16
- file.start_with? spec.full_gem_path
17
- end
18
- end
19
- end