Skip to content

Commit 4819cac

Browse files
committed
Adds new Plugin loader to load native plugin files
1 parent 08ae9a4 commit 4819cac

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

lib/git_commander/loader_result.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
module GitCommander
44
# @abstract A simple object to wrap errors loading any given loader
55
class LoaderResult
6-
attr_accessor :commands, :errors
6+
attr_accessor :commands, :plugins, :errors
77

88
def initialize
99
@errors = []
1010
@commands = []
11+
@plugins = []
1112
end
1213

1314
def success?

lib/git_commander/plugin/loader.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/inline"
4+
require_relative "../loader"
5+
6+
module GitCommander
7+
class Plugin
8+
# @abstract Handles loading native plugins by name.
9+
class Loader < ::GitCommander::Loader
10+
class NotFoundError < StandardError; end
11+
class LoadError < StandardError; end
12+
13+
NATIVE_PLUGIN_DIR = File.expand_path(File.join(__dir__, "..", "plugins"))
14+
15+
attr_reader :content
16+
17+
def load(name)
18+
@content = File.read("#{NATIVE_PLUGIN_DIR}/#{name}.rb")
19+
result.plugins << GitCommander::Plugin.new(name.to_sym, source_instance: instance_eval(@content))
20+
result
21+
rescue Errno::ENOENT => e
22+
handle_error LoadError, e
23+
rescue StandardError => e
24+
handle_error NotFoundError, e
25+
end
26+
27+
private
28+
29+
def handle_error(error_klass, original_error)
30+
error = error_klass.new(original_error.message)
31+
error.set_backtrace original_error.backtrace
32+
@result.errors << error
33+
@result
34+
end
35+
end
36+
end
37+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
RSpec.describe GitCommander::Plugin::Loader do
6+
let(:registry) { GitCommander::Registry.new }
7+
let(:loader) { described_class.new(registry) }
8+
9+
describe ".load(name, path:, url:)" do
10+
it "returns a Result" do
11+
expect(loader.load(:git)).to be_a GitCommander::LoaderResult
12+
end
13+
14+
it "loads the plugins result with matching native plugin" do
15+
result = loader.load(:git)
16+
17+
expect(result).to be_success
18+
19+
plugin = result.plugins.first
20+
expect(plugin.name).to eq :git
21+
expect(plugin.executor).to respond_to(:branches)
22+
end
23+
24+
it "reports NotFound if the native plugin doesn't exist" do
25+
result = loader.load(:bubbles)
26+
27+
expect(result).to_not be_success
28+
29+
resulting_error = result.errors.first
30+
expect(resulting_error).to be_kind_of described_class::LoadError
31+
expect(resulting_error.message).to include "No such file or directory"
32+
expect(resulting_error.backtrace).to_not be_empty
33+
end
34+
35+
it "reports LoadError if there's a problem reading the native plugin" do
36+
allow(File).to receive(:read).and_raise Errno::EACCES
37+
result = loader.load(:bubbles)
38+
39+
expect(result).to_not be_success
40+
41+
resulting_error = result.errors.first
42+
expect(resulting_error).to be_kind_of described_class::NotFoundError
43+
expect(resulting_error.message).to include "Permission denied"
44+
expect(resulting_error.backtrace).to_not be_empty
45+
end
46+
end
47+
end

0 commit comments

Comments
 (0)