Skip to content

Commit

Permalink
Fix support for Pry 0.13 (#958)
Browse files Browse the repository at this point in the history
Signed-off-by: Rémy Coutable <remy@rymai.me>
  • Loading branch information
rymai committed Mar 25, 2020
1 parent 288a543 commit 32e2d7f
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 71 deletions.
61 changes: 43 additions & 18 deletions lib/guard/jobs/pry_wrapper.rb
Expand Up @@ -101,6 +101,14 @@ def handle_interrupt

attr_reader :thread

def _pry_config
Pry.config
end

def _pry_commands
Pry.commands
end

def _switch_to_pry
th = nil
@mutex.synchronize do
Expand Down Expand Up @@ -131,11 +139,10 @@ def _kill_pry
end

def _setup(options)
Pry.config.should_load_rc = false
Pry.config.should_load_local_rc = false
history_file_path = options[:history_file] || HISTORY_FILE
Pry.config.history.file = File.expand_path(history_file_path)
_pry_config.should_load_rc = false
_pry_config.should_load_local_rc = false

_configure_history_file(options[:history_file] || HISTORY_FILE)
_add_hooks(options)

Commands::All.import
Expand All @@ -150,6 +157,17 @@ def _setup(options)
_configure_prompt
end

def _configure_history_file(history_file)
history_file_path = File.expand_path(history_file)

# Pry >= 0.13
if _pry_config.respond_to?(:history_file=)
_pry_config.history_file = history_file_path
else
_pry_config.history.file = history_file_path
end
end

# Add Pry hooks:
#
# * Load `~/.guardrc` within each new Pry session.
Expand All @@ -165,23 +183,23 @@ def _add_hooks(options)
# Add a `when_started` hook that loads a global .guardrc if it exists.
#
def _add_load_guard_rc_hook(guard_rc)
Pry.config.hooks.add_hook :when_started, :load_guard_rc do
_pry_config.hooks.add_hook :when_started, :load_guard_rc do
guard_rc.expand_path.tap { |p| load p if p.exist? }
end
end

# Add a `when_started` hook that loads a project .guardrc if it exists.
#
def _add_load_project_guard_rc_hook(guard_rc)
Pry.config.hooks.add_hook :when_started, :load_project_guard_rc do
_pry_config.hooks.add_hook :when_started, :load_project_guard_rc do
load guard_rc if guard_rc.exist?
end
end

# Add a `after_eval` hook that restores visibility after a command is
# eval.
def _add_restore_visibility_hook
Pry.config.hooks.add_hook :after_eval, :restore_visibility do
_pry_config.hooks.add_hook :after_eval, :restore_visibility do
@terminal_settings.echo
end
end
Expand All @@ -198,7 +216,7 @@ def _setup_commands
# instead restarts guard.
#
def _replace_reset_command
Pry.commands.command "reset", "Reset the Guard to a clean state." do
_pry_commands.command "reset", "Reset the Guard to a clean state." do
output.puts "Guard reset."
exec "guard"
end
Expand All @@ -209,7 +227,7 @@ def _replace_reset_command
# beginning of a line).
#
def _create_run_all_command
Pry.commands.block_command(/^$/, "Hit enter to run all") do
_pry_commands.block_command(/^$/, "Hit enter to run all") do
Pry.run_command "all"
end
end
Expand All @@ -220,7 +238,7 @@ def _create_run_all_command
#
def _create_command_aliases
SHORTCUTS.each do |command, shortcut|
Pry.commands.alias_command shortcut, command.to_s
_pry_commands.alias_command shortcut, command.to_s
end
end

Expand All @@ -232,7 +250,7 @@ def _create_command_aliases
def _create_guard_commands
Guard.state.session.plugins.all.each do |guard_plugin|
cmd = "Run all #{guard_plugin.title}"
Pry.commands.create_command guard_plugin.name, cmd do
_pry_commands.create_command guard_plugin.name, cmd do
group "Guard"

def process # rubocop:disable Lint/NestedMethodDefinition
Expand All @@ -252,7 +270,7 @@ def _create_group_commands
next if group.name == :default

cmd = "Run all #{group.title}"
Pry.commands.create_command group.name.to_s, cmd do
_pry_commands.create_command group.name.to_s, cmd do
group "Guard"

def process # rubocop:disable Lint/NestedMethodDefinition
Expand All @@ -266,7 +284,15 @@ def process # rubocop:disable Lint/NestedMethodDefinition
# `pry`.
#
def _configure_prompt
Pry.config.prompt = [_prompt(">"), _prompt("*")]
prompt_procs = [_prompt(">"), _prompt("*")]
prompt =
if Pry::Prompt.is_a?(Class)
Pry::Prompt.new("Guard", "Guard Pry prompt", prompt_procs)
else
prompt_procs
end

_pry_config.prompt = prompt
end

# Returns the plugins scope, or the groups scope ready for display in the
Expand Down Expand Up @@ -295,12 +321,11 @@ def _clip_name(target)
end

def _history(pry)
# https://github.com/pry/pry/blob/5bf2585d0a49a4a3666a9eae80ee31153e3ffcf4/CHANGELOG.md#v0120-november-5-2018
if Gem::Version.new(Pry::VERSION) < Gem::Version.new("0.12.0")
return pry.input_array.size
if pry.respond_to?(:input_ring)
pry.input_ring.size
else
pry.input_array.size
end

pry.input_ring.size
end
end
end
Expand Down
137 changes: 84 additions & 53 deletions spec/lib/guard/jobs/pry_wrapper_spec.rb
Expand Up @@ -5,10 +5,15 @@
RSpec.describe Guard::Jobs::PryWrapper do
subject { described_class.new({}) }
let(:listener) { instance_double("Listen::Listener") }
let(:pry_config) { double("pry_config") }
let(:pry_hooks) { double("pry_hooks", add_hook: true) }
let(:pry_config) do
double("pry_config", "history_file=" => true, command_prefix: true, "prompt=" => true, "should_load_rc=" => true,
"should_load_local_rc=" => true, hooks: pry_hooks)
end
let(:pry_history) { double("pry_history") }
let(:pry_commands) { double("pry_commands") }
let(:pry_hooks) { double("pry_hooks") }
let(:pry_commands) do
double("pry_commands", alias_command: true, create_command: true, command: true, block_command: true)
end
let(:terminal_settings) { instance_double("Guard::Jobs::TerminalSettings") }

let(:session) { instance_double("Guard::Internals::Session") }
Expand All @@ -18,22 +23,9 @@
let(:scope) { instance_double("Guard::Internals::Scope") }

before do
# TODO: this are here to mock out Pry completely
allow(pry_config).to receive(:prompt=)
allow(pry_config).to receive(:should_load_rc=)
allow(pry_config).to receive(:should_load_local_rc=)
allow(pry_config).to receive(:hooks).and_return(pry_hooks)
allow(pry_config).to receive(:history).and_return(pry_history)
allow(pry_config).to receive(:commands).and_return(pry_commands)
allow(pry_history).to receive(:file=)
allow(pry_commands).to receive(:alias_command)
allow(pry_commands).to receive(:create_command)
allow(pry_commands).to receive(:command)
allow(pry_commands).to receive(:block_command)
allow(pry_hooks).to receive(:add_hook)

allow(Guard).to receive(:listener).and_return(listener)
allow(Pry).to receive(:config).and_return(pry_config)
allow(Pry).to receive(:commands).and_return(pry_commands)
allow(Shellany::Sheller).to receive(:run).with("hash", "stty") { false }

allow(groups).to receive(:all).and_return([])
Expand Down Expand Up @@ -61,6 +53,30 @@
allow(terminal_settings).to receive(:restore)
end

describe "#_setup" do
context "Guard is using Pry >= 0.13" do
it "calls Pry.config.history_file=" do
expect(pry_config).to receive(:history_file=)

subject
end
end

context "Guard is using Pry < 0.13" do
let(:pry_config) do
double("pry_config", "history" => true, command_prefix: true, "prompt=" => true, "should_load_rc=" => true,
"should_load_local_rc=" => true, hooks: pry_hooks)
end

it "calls Pry.config.history.file=" do
expect(pry_config).to receive(:history).and_return(pry_history)
expect(pry_history).to receive(:file=)

subject
end
end
end

describe "#foreground" do
before do
allow(Pry).to receive(:start) do
Expand Down Expand Up @@ -136,60 +152,75 @@
allow(scope).to receive(:titles).and_return(["all"])

allow(listener).to receive(:paused?).and_return(false)

expect(Pry).to receive(:view_clip).and_return("main")
allow(Pry).to receive(:view_clip).and_return("main")
end

let(:pry) { instance_double(Pry, input_ring: []) }
context "Guard is using Pry >= 0.13" do
let(:pry) { double("Pry", input_ring: []) }
let(:pry_prompt) { double }

context "Guard is not paused" do
it 'displays "guard"' do
expect(prompt.call(double, 0, pry))
.to eq "[0] guard(main)> "
it "calls Pry::Prompt.new" do
expect(Pry::Prompt).to receive(:is_a?).with(Class).and_return(true)
expect(Pry::Prompt).to receive(:new).with("Guard", "Guard Pry prompt", an_instance_of(Array)).and_return(pry_prompt)
expect(pry_config).to receive(:prompt=).with(pry_prompt)

subject
end
end

context "Guard is using a lower version of Pry" do
let(:pry) { instance_double(Pry, input_array: []) }
context "Guard is not paused" do
it "displays 'guard'" do
expect(prompt.call(double, 0, pry))
.to eq "[0] guard(main)> "
end
end

it 'displays "guard"' do
stub_const("Pry::VERSION", "0.11.0")
context "Guard is paused" do
before do
allow(listener).to receive(:paused?).and_return(true)
end

expect(prompt.call(double, 0, pry))
.to eq "[0] guard(main)> "
it "displays 'pause'" do
expect(prompt.call(double, 0, pry))
.to eq "[0] pause(main)> "
end
end
end

context "Guard is paused" do
before do
allow(listener).to receive(:paused?).and_return(true)
end
context "with a groups scope" do
before do
allow(scope).to receive(:titles).and_return(%w[Backend Frontend])
end

it 'displays "pause"' do
expect(prompt.call(double, 0, pry))
.to eq "[0] pause(main)> "
it "displays the group scope title in the prompt" do
expect(prompt.call(double, 0, pry))
.to eq "[0] Backend,Frontend guard(main)> "
end
end
end

context "with a groups scope" do
before do
allow(scope).to receive(:titles).and_return(%w[Backend Frontend])
end
context "with a plugins scope" do
before do
allow(scope).to receive(:titles).and_return(%w[RSpec Ronn])
end

it "displays the group scope title in the prompt" do
expect(prompt.call(double, 0, pry))
.to eq "[0] Backend,Frontend guard(main)> "
it "displays the group scope title in the prompt" do
result = prompt.call(double, 0, pry)
expect(result).to eq "[0] RSpec,Ronn guard(main)> "
end
end
end

context "with a plugins scope" do
before do
allow(scope).to receive(:titles).and_return(%w[RSpec Ronn])
context "Guard is using Pry < 0.13" do
let(:pry) { double("Pry", input_array: []) }

it "does not call Pry::Prompt.new" do
expect(Pry::Prompt).to receive(:is_a?).with(Class).and_return(false)
expect(pry_config).to receive(:prompt=).with(an_instance_of(Array))

subject
end

it "displays the group scope title in the prompt" do
result = prompt.call(double, 0, pry)
expect(result).to eq "[0] RSpec,Ronn guard(main)> "
it "displays 'guard'" do
expect(prompt.call(double, 0, pry))
.to eq "[0] guard(main)> "
end
end
end
Expand Down

0 comments on commit 32e2d7f

Please sign in to comment.