diff --git a/lib/cask/cli/install.rb b/lib/cask/cli/install.rb index 59a1465473cb..9765196b7668 100644 --- a/lib/cask/cli/install.rb +++ b/lib/cask/cli/install.rb @@ -5,8 +5,19 @@ def self.run(*args) force = args.include? '--force' cask_names.each do |cask_name| odebug "Installing Cask #{cask_name}" - cask = Cask.load(cask_name) - Cask::Installer.new(cask).install(force) + begin + cask = Cask.load(cask_name) + Cask::Installer.new(cask).install(force) + rescue CaskUnavailableError => e + exact_match, partial_matches, search_term = Cask::CLI::Search.search(cask_name) + errmsg = "#{cask_name}" + if exact_match + errmsg.concat(". Did you mean:\n#{exact_match}") + elsif !partial_matches.empty? + errmsg.concat(". Did you mean one of:\n#{stringify_columns(partial_matches.take(20))}\n") + end + raise CaskUnavailableError.new(errmsg) + end end end diff --git a/lib/cask/utils.rb b/lib/cask/utils.rb index 699ca3f1d50e..be7868e8764c 100644 --- a/lib/cask/utils.rb +++ b/lib/cask/utils.rb @@ -2,6 +2,7 @@ # see Homebrew Library/Homebrew/utils.rb require 'yaml' +require 'open3' # monkeypatch Tty class Tty @@ -65,3 +66,28 @@ def odumpcask cask end end end + +# from Homebrew puts_columns +def stringify_columns items, star_items=[] + return if items.empty? + + if star_items && star_items.any? + items = items.map{|item| star_items.include?(item) ? "#{item}*" : item} + end + + if $stdout.tty? + # determine the best width to display for different console sizes + console_width = `/bin/stty size`.chomp.split(" ").last.to_i + console_width = 80 if console_width <= 0 + else + console_width = 80 + end + longest = items.sort_by { |item| item.length }.last + optimal_col_width = (console_width.to_f / (longest.length + 2).to_f).floor + cols = optimal_col_width > 1 ? optimal_col_width : 1 + Open3.popen3('/usr/bin/pr', "-#{cols}", '-t', "-w#{console_width}") do |stdin, stdout, stderr| + stdin.puts(items) + stdin.close + stdout.read + end +end diff --git a/test/cask/cli/install_test.rb b/test/cask/cli/install_test.rb index 6be507d2445d..b422cd7d3861 100644 --- a/test/cask/cli/install_test.rb +++ b/test/cask/cli/install_test.rb @@ -42,6 +42,20 @@ }.must_raise CaskUnavailableError end + it "returns a suggestion for a misspelled Cask" do + e = lambda { + Cask::CLI::Install.run('googlechrome') + }.must_raise CaskUnavailableError + e.message.must_equal "No available cask for googlechrome\. Did you mean:\ngoogle-chrome" + end + + it "returns multiple suggestions for a Cask fragment" do + e = lambda { + Cask::CLI::Install.run('google') + }.must_raise CaskUnavailableError + e.message.must_match %r{^No available cask for google\. Did you mean one of:\ngoogle} + end + it "raises an exception when no cask is specified" do lambda { Cask::CLI::Install.run