Class: CLAide::Command::PluginManager

Inherits:
Object
  • Object
show all
Defined in:
lib/claide/command/plugin_manager.rb

Overview

Handles plugin related logic logic for the Command class.

Plugins are loaded the first time a command run and are identified by the prefix specified in the command class. Plugins must adopt the following conventions:

  • Support being loaded by a file located under the lib/#{plugin_prefix}_plugin relative path.
  • Be stored in a folder named after the plugin.

Helper Methods collapse

Class Method Summary collapse

Class Method Details

.installed_specifications_for_prefix(plugin_prefix) ⇒ Array<Specification>



45
46
47
48
# File 'lib/claide/command/plugin_manager.rb', line 45

def self.installed_specifications_for_prefix(plugin_prefix)
  loaded_plugins[plugin_prefix] ||
    plugin_gems_for_prefix(plugin_prefix).map(&:first)
end

.load_plugins(plugin_prefix) ⇒ Array<Gem::Specification>



28
29
30
31
32
33
# File 'lib/claide/command/plugin_manager.rb', line 28

def self.load_plugins(plugin_prefix)
  loaded_plugins[plugin_prefix] ||=
    plugin_gems_for_prefix(plugin_prefix).map do |spec, paths|
      spec if safe_require(paths)
    end.compact
end

.loaded_pluginsHash<String,Gem::Specification>



19
20
21
# File 'lib/claide/command/plugin_manager.rb', line 19

def self.loaded_plugins
  @loaded_plugins ||= {}
end

.plugin_gems_for_prefix(prefix) ⇒ Array<[Gem::Specification, Array<String>]>



72
73
74
75
76
77
78
# File 'lib/claide/command/plugin_manager.rb', line 72

def self.plugin_gems_for_prefix(prefix)
  glob = "#{prefix}_plugin#{Gem.suffix_pattern}"
  Gem::Specification.latest_specs(true).map do |spec|
    matches = spec.matches_for_glob(glob)
    [spec, matches] unless matches.empty?
  end.compact
end

.plugins_involved_in_exception(exception) ⇒ Array<String>



56
57
58
59
60
61
62
63
64
# File 'lib/claide/command/plugin_manager.rb', line 56

def self.plugins_involved_in_exception(exception)
  specifications.select do |gemspec|
    exception.backtrace.any? do |line|
      full_require_paths_for(gemspec).any? do |plugin_path|
        line.include?(plugin_path)
      end
    end
  end.map(&:name)
end

.safe_require(paths) ⇒ Bool

Requires the given paths. If any exception occurs it is caught and an informative message is printed.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/claide/command/plugin_manager.rb', line 89

def self.safe_require(paths)
  paths.each do |path|
    begin
      require(path)
    rescue Exception => exception # rubocop:disable RescueException
      message = "\n---------------------------------------------"
      message << "\nError loading plugin file `#{path}`.\n"
      message << "\n#{exception.class} - #{exception.message}"
      message << "\n#{exception.backtrace.join("\n")}"
      message << "\n---------------------------------------------\n"
      warn message.ansi.yellow
      return false
    end
  end

  true
end

.specificationsArray<Specification>



38
39
40
# File 'lib/claide/command/plugin_manager.rb', line 38

def self.specifications
  loaded_plugins.values.flatten.uniq
end