/
plugins.rb
139 lines (114 loc) · 3.62 KB
/
plugins.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# frozen_string_literal: true
require 'ostruct'
class Pry
class PluginManager
PRY_PLUGIN_PREFIX = /^pry-/.freeze
# Placeholder when no associated gem found, displays warning
class NoPlugin
def initialize(name)
@name = name
end
def method_missing(*)
warn "Warning: The plugin '#{@name}' was not found! (no gem found)"
super
end
def respond_to_missing?(*)
false
end
end
class Plugin
attr_accessor :name, :gem_name, :enabled, :spec, :active
def initialize(name, gem_name, spec, enabled)
@name = name
@gem_name = gem_name
@enabled = enabled
@spec = spec
end
# Disable a plugin. (prevents plugin from being loaded, cannot
# disable an already activated plugin)
def disable!
self.enabled = false
end
# Enable a plugin. (does not load it immediately but puts on
# 'white list' to be loaded)
def enable!
self.enabled = true
end
# Load the Command line options defined by this plugin (if they exist)
def load_cli_options
cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb")
return unless File.exist?(cli_options_file)
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.4.4")
cli_options_file = File.realpath(cli_options_file)
end
require cli_options_file
end
# Activate the plugin (require the gem - enables/loads the
# plugin immediately at point of call, even if plugin is
# disabled)
# Does not reload plugin if it's already active.
def activate!
# Create the configuration object for the plugin.
Pry.config.send("#{gem_name.tr('-', '_')}=", OpenStruct.new)
begin
require gem_name unless active?
rescue LoadError => e
warn "Found plugin #{gem_name}, but could not require '#{gem_name}'"
warn e
rescue StandardError => e
warn "require '#{gem_name}' # Failed, saying: #{e}"
end
self.active = true
self.enabled = true
end
alias active? active
alias enabled? enabled
def supported?
pry_version = Gem::Version.new(VERSION)
spec.dependencies.each do |dependency|
if dependency.name == "pry"
return dependency.requirement.satisfied_by?(pry_version)
end
end
true
end
end
def initialize
@plugins = []
end
# Find all installed Pry plugins and store them in an internal array.
def locate_plugins
gem_list.each do |gem|
next if gem.name !~ PRY_PLUGIN_PREFIX
plugin_name = gem.name.split('-', 2).last
plugin = Plugin.new(plugin_name, gem.name, gem, false)
@plugins << plugin.tap(&:enable!) if plugin.supported? && !plugin_located?(plugin)
end
@plugins
end
# @return [Hash] A hash with all plugin names (minus the 'pry-') as
# keys and Plugin objects as values.
def plugins
h = Hash.new { |_, key| NoPlugin.new(key) }
@plugins.each do |plugin|
h[plugin.name] = plugin
end
h
end
# Require all enabled plugins, disabled plugins are skipped.
def load_plugins
@plugins.each do |plugin|
plugin.activate! if plugin.enabled?
end
end
private
def plugin_located?(plugin)
@plugins.any? { |existing| existing.gem_name == plugin.gem_name }
end
def gem_list
Gem.refresh
return Gem::Specification if Gem::Specification.respond_to?(:each)
Gem.source_index.find_name('')
end
end
end