bin/gems
#!/usr/bin/env ruby
require 'gli'
require 'gems-cli'
include GLI::App
program_desc 'Interact with Rubygems.org from the command line. Yay!'
version GemsCli::VERSION
# Use argument validation
arguments :strict
subcommand_option_handling :normal
def display_gem data, index, prefix=''
puts "#{prefix}#{index}: gem '#{data['name']}', '~> #{data['version']}'"
end
desc 'Search Rubygems.org for a gem'
arg_name 'Name of a gem'
command [:search, :s] do |c|
c.desc 'Number of results returned per page'
c.default_value 7
c.flag :n
c.action do |global_options, options, args|
query = args[0]
if query.nil? || query.empty?
raise ArgumentError, 'Please supply a search term.'
end
puts "Running your search for #{query}...".color(:green)
search_results = Gems.search(query)
limit = options[:n].to_i
paged_results = Paginator.new(ary: search_results, per_page: limit)
paged_results.first_page.each_with_index do |e, i|
display_gem e, i
end
@answer = ''
versions = {}
letters = ('a'..'c').to_a
until @answer == 'q'
puts "Page: #{paged_results.page}/#{paged_results.pages}\n".color(:green)
can_get_more_versions = versions.size < 1
choices = "Select from 0..#{paged_results.per_page - 1}, (n)ext, (p)revious, "
choices += "(m)ore versions, " if can_get_more_versions
choices += "or (q)uit #=> "
@answer = ask(choices.color(:green), String) do |q|
q.case = :downcase
if can_get_more_versions
q.validate = /\A\d+\w?|q|n|m|p\Z/
else
q.validate = /\A\d+\w?|q|n|p\Z/
end
end
case @answer
when /\d+\w?/
gem_list = paged_results.current_page
chosen_index, chosen_version = @answer.scan(/\d+|\D+/)
chosen_index = chosen_index.to_i
if chosen_gem=gem_list[chosen_index]
gem_name = chosen_gem['name']
gem_version = chosen_gem['version']
if chosen_version
gem_version_index = letters.index(chosen_version)
unless gem_version_index
puts 'Invalid gem and version choice'
next
end
selected_version = versions[gem_name][gem_version_index]
gem_version = selected_version['number']
end
Clipboard.copy "gem '#{gem_name}', '~> #{gem_version}'"
puts "Copied #{gem_name} #{gem_version} to your clipboard!".color(:green)
break
else
puts "Your choice, #@answer, is not in the list 0..#{gem_list.size - 1}"
end
when 'm'
paged_results.current_page.each_with_index do |e, i|
display_gem e, i
gem_name = e['name']
versions[gem_name] = Gems.versions(gem_name).sort {|a, b|
b['built_at'] <=> a['built_at']
}.reject {|v| v['number'] == e['version'] }
versions[gem_name][0...letters.length].each_with_index do |v, j|
version_data = {'name' => gem_name, 'version' => v['number']}
display_gem version_data, "#{i}#{letters[j]}", ' '
end
end
when 'n'
versions = {}
paged_results.next_page.each_with_index do |e, i|
display_gem e, i
end
when 'p'
versions = {}
paged_results.previous_page.each_with_index do |e, i|
display_gem e, i
end
when 'q'
puts 'Later.'
else
puts "Sorry. Unknown option: #{@answer.chomp}"
end
end
end
end
pre do |global, command, options, args|
# Pre logic here
# Return true to proceed; false to abort and not call the
# chosen command
# Use skips_pre before a command to skip this block
# on that command only
true
end
post do |global, command, options, args|
# Post logic here
# Use skips_post before a command to skip this
# block on that command only
end
on_error do |exception|
# Error logic here
# return false to skip default error handling
true
end
exit run(ARGV)