Module: Chronicle::ETL::Registry::Plugins
- Defined in:
- lib/chronicle/etl/registry/plugins.rb
Overview
Better validation for whether a gem is actually a plugin
Add ways to load a plugin that don't require a gem on rubygems.org
Responsible for managing plugins available to chronicle-etl
Constant Summary collapse
- KNOWN_PLUGINS =
%w[ apple-podcasts email foursquare github imessage pinboard safari shell spotify zulip ].freeze
Class Method Summary collapse
-
.activate(name) ⇒ Object
Activate a plugin with given name by
require
ing it. -
.all ⇒ Object
Union of installed gems (latest version) + available gems.
-
.available ⇒ Object
List of all plugins available to chronicle-etl.
-
.available_as_gem ⇒ Object
List of plugins available through rubygems TODO: make this concurrent.
-
.exists?(name) ⇒ Boolean
Does a plugin with a given name exist?.
-
.gem_info(name) ⇒ Object
Load info about a gem plugin from rubygems API.
-
.install(name) ⇒ Object
Install a plugin to local gems.
-
.installed ⇒ Object
Plugins either installed as gems or manually loaded/registered.
-
.installed?(name) ⇒ Boolean
Check whether a given plugin is installed.
-
.installed_as_gem ⇒ Object
List of plugins installed as gems.
-
.installed_gemspecs ⇒ Object
All versions of all plugins currently installed.
-
.installed_gemspecs_latest ⇒ Object
Latest version of each installed plugin.
-
.installed_standalone ⇒ Object
List of plugins installed as standalone.
-
.register_standalone(name:) ⇒ Object
Start of a system for having non-gem plugins.
-
.uninstall(name) ⇒ Object
Uninstall a plugin.
Class Method Details
.activate(name) ⇒ Object
Activate a plugin with given name by require
ing it
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 125 def self.activate(name) # By default, activates the latest available version of a gem # so don't have to run Kernel#gem separately plugin_require_name = name.to_s.gsub('-', '_') require "chronicle/#{plugin_require_name}" rescue Gem::ConflictError => e # TODO: figure out if there's more we can do here raise Chronicle::ETL::PluginConflictError.new(name), "Plugin '#{plugin_require_name}' couldn't be loaded. #{e.}" rescue StandardError, LoadError # StandardError to catch random non-loading problems that might occur # when requiring the plugin (eg class macro invoked the wrong way) # TODO: decide if this should be separated raise Chronicle::ETL::PluginLoadError.new(name), "Plugin '#{plugin_require_name}' couldn't be loaded" end |
.all ⇒ Object
Union of installed gems (latest version) + available gems
97 98 99 100 101 102 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 97 def self.all (installed + available) .group_by(&:name) .transform_values { |plugin| plugin.find(&:installed) || plugin.first } .values end |
.available ⇒ Object
List of all plugins available to chronicle-etl
72 73 74 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 72 def self.available available_as_gem end |
.available_as_gem ⇒ Object
List of plugins available through rubygems TODO: make this concurrent
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 78 def self.available_as_gem KNOWN_PLUGINS.map do |name| info = gem_info(name) Chronicle::ETL::Registry::PluginRegistration.new do |p| p.name = name p.gem = info['name'] p.version = info['version'] p.description = info['info'] end end end |
.exists?(name) ⇒ Boolean
Does a plugin with a given name exist?
105 106 107 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 105 def self.exists?(name) KNOWN_PLUGINS.include?(name) end |
.gem_info(name) ⇒ Object
Load info about a gem plugin from rubygems API
91 92 93 94 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 91 def self.gem_info(name) gem_name = "chronicle-#{name}" Gems.info(gem_name) end |
.install(name) ⇒ Object
Install a plugin to local gems
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 143 def self.install(name) return if installed?(name) raise(Chronicle::ETL::PluginNotAvailableError.new(name), "Plugin #{name} doesn't exist") unless exists?(name) gem_name = "chronicle-#{name}" Gem::DefaultUserInteraction.ui = Gem::SilentUI.new Gem.install(gem_name) activate(name) rescue Gem::UnsatisfiableDependencyError # TODO: we need to catch a lot more than this here raise Chronicle::ETL::PluginNotAvailableError.new(name), "Plugin #{name} could not be installed." end |
.installed ⇒ Object
Plugins either installed as gems or manually loaded/registered
44 45 46 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 44 def self.installed installed_standalone + installed_as_gem end |
.installed?(name) ⇒ Boolean
Check whether a given plugin is installed
49 50 51 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 49 def self.installed?(name) installed.map(&:name).include?(name.to_sym) end |
.installed_as_gem ⇒ Object
List of plugins installed as gems
59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 59 def self.installed_as_gem installed_gemspecs_latest.map do |gem| Chronicle::ETL::Registry::PluginRegistration.new do |p| p.name = gem.name.sub('chronicle-', '').to_sym p.gem = gem.name p.description = gem.description p.version = gem.version.to_s p.installed = true end end end |
.installed_gemspecs ⇒ Object
All versions of all plugins currently installed
110 111 112 113 114 115 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 110 def self.installed_gemspecs # TODO: add check for chronicle-etl dependency Gem::Specification.filter do |s| s.name.match(/^chronicle-/) && s.name != 'chronicle-etl' && s.name != 'chronicle-core' end end |
.installed_gemspecs_latest ⇒ Object
Latest version of each installed plugin
118 119 120 121 122 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 118 def self.installed_gemspecs_latest installed_gemspecs.group_by(&:name) .transform_values { |versions| versions.sort_by(&:version).reverse.first } .values end |
.installed_standalone ⇒ Object
List of plugins installed as standalone
54 55 56 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 54 def self.installed_standalone @installed_standalone ||= [] end |
.register_standalone(name:) ⇒ Object
Start of a system for having non-gem plugins. Right now, we just make registry aware of existence of name of non-gem plugin
34 35 36 37 38 39 40 41 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 34 def self.register_standalone(name:) plugin = Chronicle::ETL::Registry::PluginRegistration.new do |p| p.name = name.to_sym p.installed = true end installed_standalone << plugin end |
.uninstall(name) ⇒ Object
Uninstall a plugin
159 160 161 162 163 164 165 166 167 |
# File 'lib/chronicle/etl/registry/plugins.rb', line 159 def self.uninstall(name) gem_name = "chronicle-#{name}" Gem::DefaultUserInteraction.ui = Gem::SilentUI.new uninstaller = Gem::Uninstaller.new(gem_name) uninstaller.uninstall rescue Gem::InstallError # TODO: strengthen this exception handling raise(Chronicle::ETL::PluginError.new(name), "Plugin #{name} wasn't uninstalled") end |