Skip to content

Commit

Permalink
Open changelog url when o key is pressed (#32)
Browse files Browse the repository at this point in the history
Add a key binding for opening the changelog URL. Now you can navigate to
a gem with up/down and press `o` (lower-case letter o) to open the URL
in your default web browser.

This implementation depends on the
[launchy](https://github.com/copiousfreetime/launchy) gem. Refer to its
README for information on configuring which browser is used.

TODO

- [x] PR description
- [x] Unit test
- [x] Update README image
- [x] Fix failing Ruby head test due to undeclared launchy →
childprocess → logger dependency

Closes #30
  • Loading branch information
mattbrictson authored Aug 4, 2024
1 parent 5c5ce37 commit 373374c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 9 deletions.
1 change: 1 addition & 0 deletions bundle_update_interactive.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
# Runtime dependencies
spec.add_dependency "bundler", "~> 2.0"
spec.add_dependency "bundler-audit", ">= 0.9.1"
spec.add_dependency "launchy", ">= 2.5.0"
spec.add_dependency "pastel", ">= 0.8.0"
spec.add_dependency "tty-prompt", ">= 0.23.1"
spec.add_dependency "tty-screen", ">= 0.8.2"
Expand Down
Binary file modified images/update-interactive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 17 additions & 5 deletions lib/bundle_update_interactive/cli/multi_select.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "launchy"
require "pastel"
require "tty/prompt"
require "tty/screen"
Expand All @@ -8,6 +9,7 @@ class BundleUpdateInteractive::CLI
class MultiSelect
class List < TTY::Prompt::MultiList
def initialize(prompt, **options)
@opener = options.delete(:opener)
defaults = {
cycle: true,
help_color: :itself.to_proc,
Expand All @@ -34,20 +36,30 @@ def keypress(event)
when "j", "n" then keydown
when "a" then select_all
when "r" then reverse_selection
when "o" then opener&.call(choices[@active - 1].value)
end
end

private

attr_reader :opener
end

def self.prompt_for_gems_to_update(outdated_gems, prompt: nil)
table = Table.new(outdated_gems)
title = "#{outdated_gems.length} gems can be updated."
chosen = new(title: title, table: table, prompt: prompt).prompt
opener = lambda do |gem|
url = outdated_gems[gem].changelog_uri
Launchy.open(url) unless url.nil?
end
chosen = new(title: title, table: table, prompt: prompt, opener: opener).prompt
outdated_gems.slice(*chosen)
end

def initialize(title:, table:, prompt: nil)
def initialize(title:, table:, opener: nil, prompt: nil)
@title = title
@table = table
@opener = opener
@tty_prompt = prompt || TTY::Prompt.new(
interrupt: lambda {
puts
Expand All @@ -59,16 +71,16 @@ def initialize(title:, table:, prompt: nil)

def prompt
choices = table.gem_names.to_h { |name| [table.render_gem(name), name] }
tty_prompt.invoke_select(List, title, choices, help: help)
tty_prompt.invoke_select(List, title, choices, help: help, opener: opener)
end

private

attr_reader :pastel, :table, :tty_prompt, :title
attr_reader :pastel, :table, :opener, :tty_prompt, :title

def help
[
pastel.dim("\nPress <space> to select, ↑/↓ move, <a> all, <r> reverse, <enter> to finish."),
pastel.dim("\nPress <space> to select, ↑/↓ move, <a> all, <r> reverse, <o> open url, <enter> to finish."),
"\n ",
table.render_header
].join
Expand Down
2 changes: 1 addition & 1 deletion lib/bundle_update_interactive/outdated_gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class OutdatedGem
:updated_version,
:updated_git_version

attr_writer :rubygems_source, :vulnerable
attr_writer :changelog_uri, :rubygems_source, :vulnerable

def initialize(**attrs)
@vulnerable = nil
Expand Down
19 changes: 16 additions & 3 deletions test/bundle_update_interactive/cli/multi_select_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "test_helper"
require "launchy"
require "tty/prompt/test"

class BundleUpdateInteractive::CLI
Expand All @@ -12,9 +13,9 @@ class MultiSelectTest < Minitest::Test

def setup
@outdated_gems = {
"a" => build(:outdated_gem, name: "a", rubygems_source: false),
"b" => build(:outdated_gem, name: "b", rubygems_source: false),
"c" => build(:outdated_gem, name: "c", rubygems_source: false)
"a" => build(:outdated_gem, name: "a", changelog_uri: nil),
"b" => build(:outdated_gem, name: "b", changelog_uri: "https://b.example.com/"),
"c" => build(:outdated_gem, name: "c", changelog_uri: "https://c.example.com/")
}
end

Expand Down Expand Up @@ -66,6 +67,18 @@ def test_pressing_ctrl_r_has_no_effect
assert_empty selected
end

def test_pressing_down_then_o_opens_changelog_uri_of_second_gem_in_browser
Launchy.expects(:open).with("https://b.example.com/").once

use_menu_with_keypress ARROW_DOWN, "o"
end

def test_pressing_o_for_gem_with_no_changelog_does_nothing
Launchy.expects(:open).never

use_menu_with_keypress "o"
end

private

def use_menu_with_keypress(*keys)
Expand Down

0 comments on commit 373374c

Please sign in to comment.