class Thor
def self.[](task)
def self.[](task) namespaces = task.split(":") klass = Thor::Util.constant_from_thor_path(namespaces[0...-1].join(":")) raise Error, "`#{klass}' is not a Thor class" unless klass <= Thor klass.tasks[namespaces.last] end
def self.convert_task_options(opts)
def self.convert_task_options(opts) opts.map do |key, value| case value when true "--#{key}" when Array value.map {|v| "--#{key} #{v.inspect}"}.join(" ") when nil, false "" else "--#{key} #{value.inspect}" end end.join(" ") end
def self.desc(usage, description)
def self.desc(usage, description) @usage, @desc = usage, description end
def self.group(name)
def self.group(name) @group_name = name.to_s end
def self.group_name
def self.group_name @group_name || 'standard' end
def self.install_task(spec)
def self.install_task(spec) package_task spec null, sudo, gem = RUBY_PLATFORM =~ /w(in)?32$/ ? ['NUL', '', 'gem.bat'] : ['/dev/null', 'sudo', 'gem'] desc "install", "install the gem" define_method :install do old_stderr, $stderr = $stderr.dup, File.open(null, "w") package $stderr = old_stderr system %{#{sudo} #{Gem.ruby} -S #{gem} install pkg/#{spec.name}-#{spec.version} --no-rdoc --no-ri --no-update-sources} end end
def self.map(map)
def self.map(map) @map ||= superclass.instance_variable_get("@map") || {} map.each do |key, value| if key.respond_to?(:each) key.each {|subkey| @map[subkey] = value} else @map[key] = value end end end
def self.maxima
def self.maxima @maxima ||= begin max_usage = tasks.map {|_, t| t.usage}.max {|x,y| x.to_s.size <=> y.to_s.size}.size max_desc = tasks.map {|_, t| t.description}.max {|x,y| x.to_s.size <=> y.to_s.size}.size max_opts = tasks.map {|_, t| t.opts ? t.opts.formatted_usage : ""}.max {|x,y| x.to_s.size <=> y.to_s.size}.size Struct.new(:description, :usage, :opt).new(max_desc, max_usage, max_opts) end end
def self.method_options(opts)
def self.method_options(opts) @method_options = opts end
def self.opts
def self.opts (@opts || {}).merge(self == Thor ? {} : superclass.opts) end
def self.package_task(spec)
def self.package_task(spec) desc "package", "package up the gem" define_method :package do FileUtils.mkdir_p(File.join(Dir.pwd, "pkg")) Gem::Builder.new(spec).build FileUtils.mv(spec.file_name, File.join(Dir.pwd, "pkg", spec.file_name)) end end
def self.spec_task(file_list, opts = {})
def self.spec_task(file_list, opts = {}) name = opts.delete(:name) || "spec" rcov_dir = opts.delete(:rcov_dir) || "coverage" file_list = file_list.map {|f| %["#{f}"]}.join(" ") verbose = opts.delete(:verbose) opts = {:format => "specdoc", :color => true}.merge(opts) rcov_opts = convert_task_options(opts.delete(:rcov) || {}) rcov = !rcov_opts.empty? options = convert_task_options(opts) if rcov FileUtils.rm_rf(File.join(Dir.pwd, rcov_dir)) end desc(name, "spec task") define_method(name) do cmd = "ruby " if rcov cmd << "-S rcov -o #{rcov_dir} #{rcov_opts} " end cmd << `which spec`.chomp cmd << " -- " if rcov cmd << " " cmd << file_list cmd << " " cmd << options puts cmd if verbose system(cmd) exit($?.exitstatus) end end
def self.start(args = ARGV)
def self.start(args = ARGV) options = Thor::Options.new(self.opts) opts = options.parse(args, false) args = options.trailing_non_opts meth = args.first meth = @map[meth].to_s if @map && @map[meth] meth ||= "help" tasks[meth].parse new(opts, *args), args[1..-1] rescue Thor::Error => e $stderr.puts e.message end
def self.subclass_files
def self.subclass_files @subclass_files ||= Hash.new {|h,k| h[k] = []} end
def self.subclasses
def self.subclasses @subclasses ||= [] end
def self.tasks
def self.tasks @tasks ||= TaskHash.new(self) end
def help(task = nil)
def help(task = nil) if task if task.include? ?: task = self.class[task] namespace = true else task = self.class.tasks[task] end puts task.formatted_usage(namespace) puts task.description else puts "Options" puts "-------" self.class.tasks.each do |_, task| format = "%-" + (self.class.maxima.usage + self.class.maxima.opt + 4).to_s + "s" print format % ("#{task.formatted_usage}") puts task.description.split("\n").first end end end
def inherited(klass)
def inherited(klass) register_klass_file klass end
def initialize(opts = {}, *args)
def initialize(opts = {}, *args) end
def method_added(meth)
def method_added(meth) meth = meth.to_s if meth == "initialize" @opts = @method_options @method_options = nil return end return if !public_instance_methods.include?(meth) || !@usage register_klass_file self tasks[meth] = Task.new(meth, @desc, @usage, @method_options) @usage, @desc, @method_options = nil end
def register_klass_file(klass, file = caller[1].split(":")[0])
def register_klass_file(klass, file = caller[1].split(":")[0]) unless self == Thor superclass.register_klass_file(klass, file) return end file_subclasses = subclass_files[File.expand_path(file)] file_subclasses << klass unless file_subclasses.include?(klass) subclasses << klass unless subclasses.include?(klass) end