Refactored gist command to take advantage of class-based commands.

@cirwin and @ryanf should take a look at it to either improve refactor
or to design the Pry::CommandContext subclass proper.
This commit is contained in:
John Mair 2011-12-31 00:05:36 +13:00
parent 09d8dad700
commit 45e9bf33b5
1 changed files with 131 additions and 94 deletions

View File

@ -59,14 +59,27 @@ class Pry
command("gist", "Gist a method or expression history to github. Type `gist --help` for more info.",{:requires_gem => "gist", :shellwords => false, :definition => Pry::CommandContext.new{
def call(*args)
require 'gist'
class << self
attr_accessor :opts
attr_accessor :content
attr_accessor :code_type
attr_accessor :input_ranges
end
target = target()
input_ranges = []
def call(*args)
require 'gist'
opts = parse_options!(args) do |opt|
opt.banner unindent <<-USAGE
self.opts = options(args)
process_options
perform_gist
end
def options(args)
self.input_ranges = []
parse_options!(args) do |opt|
opt.banner unindent <<-USAGE
Usage: gist [OPTIONS] [METH]
Gist method (doc or source) or input expression to github.
Ensure the `gist` gem is properly working before use. http://github.com/defunkt/gist for instructions.
@ -75,97 +88,121 @@ class Pry
e.g: gist -i 1..10
USAGE
opt.on :d, :doc, "Gist a method's documentation.", true
opt.on :m, :method, "Gist a method's source.", true
opt.on :f, :file, "Gist a file.", true
opt.on :p, :public, "Create a public gist (default: false)", :default => false
opt.on :l, :lines, "Only gist a subset of lines (only works with -m and -f)", :optional => true, :as => Range, :default => 1..-1
opt.on :i, :in, "Gist entries from Pry's input expression history. Takes an index or range.", :optional => true,
:as => Range, :default => -5..-1 do |range|
input_ranges << absolute_index_range(range, _pry_.input_array.length)
end
end
opt.on :d, :doc, "Gist a method's documentation.", true
opt.on :m, :method, "Gist a method's source.", true
opt.on :f, :file, "Gist a file.", true
opt.on :p, :public, "Create a public gist (default: false)", :default => false
opt.on :l, :lines, "Only gist a subset of lines (only works with -m and -f)", :optional => true, :as => Range, :default => 1..-1
opt.on :i, :in, "Gist entries from Pry's input expression history. Takes an index or range.", :optional => true,
:as => Range, :default => -5..-1 do |range|
input_ranges << absolute_index_range(range, _pry_.input_array.length)
end
end
end
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
if opts.present?(:in)
code_type = :ruby
content = ""
def in_option
self.code_type = :ruby
self.content = ""
input_ranges.each do |range|
input_expressions = _pry_.input_array[range] || []
input_expressions.each_with_index.map do |code, index|
corrected_index = index + range.first
if code && code != ""
content << code
content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}" if code !~ /;\Z/
input_ranges.each do |range|
input_expressions = _pry_.input_array[range] || []
input_expressions.each_with_index.map do |code, index|
corrected_index = index + range.first
if code && code != ""
self.content << code
if code !~ /;\Z/
self.content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
end
end
end
end
end
def file_option
whole_file = File.read(File.expand_path(opts[:f]))
if opts.present?(:lines)
self.content = restrict_to_lines(whole_file, opts[:l])
else
self.content = whole_file
end
end
def doc_option
meth = get_method_or_raise(opts[:d], target, {})
self.content = meth.doc
self.code_type = meth.source_type
text.no_color do
self.content = process_comment_markup(self.content, self.code_type)
end
self.code_type = :plain
end
def method_option
meth = get_method_or_raise(opts[:m], target, {})
method_source = meth.source
if opts.present?(:lines)
self.content = restrict_to_lines(method_source, opts[:l])
else
self.content = method_source
end
self.code_type = meth.source_type
end
def process_options
if opts.present?(:in)
in_option
elsif opts.present?(:file)
file_option
elsif opts.present?(:doc)
doc_option
elsif opts.present?(:method)
method_option
end
end
def perform_gist
type_map = { :ruby => "rb", :c => "c", :plain => "plain" }
# prevent Gist from exiting the session on error
begin
extname = opts.present?(:file) ? ".#{gist_file_extension(opts[:f])}" : ".#{type_map[self.code_type]}"
link = Gist.write([:extension => extname,
:input => self.content],
!opts[:p])
rescue SystemExit
end
if link
Gist.copy(link)
output.puts "Gist created at #{link} and added to clipboard."
end
end
def restrict_to_lines(content, lines)
line_range = one_index_range(lines)
content.lines.to_a[line_range].join
end
def gist_file_extension(file_name)
file_name.split(".").last
end
def comment_expression_result_for_gist(result)
content = ""
result.lines.each_with_index do |line, index|
if index == 0
content << "# => #{line}"
else
content << "# #{line}"
end
end
content
end
}})
end
end
end
elsif opts.present?(:file)
whole_file = File.read(File.expand_path(opts[:f]))
if opts.present?(:lines)
content = restrict_to_lines(whole_file, opts[:l])
else
content = whole_file
end
elsif opts.present?(:doc)
meth = get_method_or_raise(opts[:d], target, {})
content = meth.doc
code_type = meth.source_type
text.no_color do
content = process_comment_markup(content, code_type)
end
code_type = :plain
elsif opts.present?(:method)
meth = get_method_or_raise(opts[:m], target, {})
method_source = meth.source
if opts.present?(:lines)
content = restrict_to_lines(method_source, opts[:l])
else
content = method_source
end
code_type = meth.source_type
end
# prevent Gist from exiting the session on error
begin
extname = opts.present?(:file) ? ".#{gist_file_extension(opts[:f])}" : ".#{type_map[code_type]}"
link = Gist.write([:extension => extname,
:input => content],
!opts[:p])
rescue SystemExit
end
if link
Gist.copy(link)
output.puts "Gist created at #{link} and added to clipboard."
end
end
def restrict_to_lines(content, lines)
line_range = one_index_range(lines)
content.lines.to_a[line_range].join
end
def gist_file_extension(file_name)
file_name.split(".").last
end
def comment_expression_result_for_gist(result)
content = ""
result.lines.each_with_index do |line, index|
if index == 0
content << "# => #{line}"
else
content << "# #{line}"
end
end
content
end
}})
end
end
end