Skip to content
Browse files

Moves options into an ivar

  • Loading branch information...
1 parent 2e54de4 commit d6eb2e557963269625c599abdbb2f53baf170a42 @wycats wycats committed Aug 13, 2008
Showing with 80 additions and 72 deletions.
  1. +1 −1 Thorfile
  2. +2 −0 lib/thor.rb
  3. +8 −7 lib/thor/runner.rb
  4. +12 −6 lib/thor/task.rb
  5. +2 −0 spec/spec_helper.rb
  6. +35 −46 spec/thor_runner_spec.rb
  7. +6 −6 spec/thor_spec.rb
  8. +14 −6 thor.gemspec
View
2 Thorfile
@@ -3,7 +3,7 @@ require 'rubygems/specification'
require 'thor/tasks'
GEM = "thor"
-GEM_VERSION = "0.9.2"
+GEM_VERSION = "0.9.4"
AUTHOR = "Yehuda Katz"
EMAIL = "wycats@gmail.com"
HOMEPAGE = "http://yehudakatz.com"
View
2 lib/thor.rb
@@ -5,6 +5,8 @@
require "thor/task_hash"
class Thor
+ attr_accessor :options
+
def self.map(map)
@map ||= superclass.instance_variable_get("@map") || {}
map.each do |key, value|
View
15 lib/thor/runner.rb
@@ -16,7 +16,7 @@ def self.globs_for(path)
desc "install NAME", "install a Thor file into your system tasks, optionally named for future updates"
method_options :as => :optional, :relative => :boolean
- def install(name, opts = {})
+ def install(name)
initialize_thorfiles
begin
contents = open(name).read
@@ -39,7 +39,7 @@ def install(name, opts = {})
# name = name =~ /\.thor$/ || is_uri ? name : "#{name}.thor"
- as = opts["as"] || begin
+ as = options["as"] || begin
first_line = contents.split("\n")[0]
(match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil
end
@@ -56,7 +56,7 @@ def install(name, opts = {})
FileUtils.touch(yaml_file)
yaml = thor_yaml
- location = (opts[:relative] || is_uri) ? name : File.expand_path(name)
+ location = (options[:relative] || is_uri) ? name : File.expand_path(name)
yaml[as] = {:filename => Digest::MD5.hexdigest(name + as), :location => location, :constants => constants}
save_yaml(yaml)
@@ -92,28 +92,29 @@ def update(name)
puts "Updating `#{name}' from #{yaml[name][:location]}"
old_filename = yaml[name][:filename]
- filename = install(yaml[name][:location], "as" => name)
+ options["as"] = name
+ filename = install(yaml[name][:location])
unless filename == old_filename
File.delete(File.join(thor_root, old_filename))
end
end
desc "installed", "list the installed Thor modules and tasks (--internal means list the built-in tasks as well)"
method_options :internal => :boolean
- def installed(opts = {})
+ def installed
Dir["#{thor_root}/**/*"].each do |f|
next if f =~ /thor\.yml$/
load_thorfile f unless Thor.subclass_files.keys.include?(File.expand_path(f))
end
klasses = Thor.subclasses
- klasses -= [Thor, Thor::Runner] unless opts['internal']
+ klasses -= [Thor, Thor::Runner] unless options['internal']
display_klasses(true, klasses)
end
desc "list [SEARCH]", "list the available thor tasks (--substring means SEARCH can be anywhere in the module)"
method_options :substring => :boolean
- def list(search = "", options = {})
+ def list(search = "")
initialize_thorfiles
search = ".*#{search}" if options["substring"]
search = /^#{search}.*/i
View
18 lib/thor/task.rb
@@ -8,25 +8,31 @@ def self.dynamic(meth, klass)
end
def parse(obj, args)
- run(obj, *parse_args(args))
+ list, hash = parse_args(args)
+ obj.options = hash
+ run(obj, *list)
end
def run(obj, *params)
raise NoMethodError, "the `#{meth}' task of #{obj.class} is private" if
(obj.private_methods + obj.protected_methods).include?(meth)
-
+
obj.send(meth, *params)
rescue ArgumentError => e
# backtrace sans anything in this file
backtrace = e.backtrace.reject {|frame| frame =~ /^#{Regexp.escape(__FILE__)}/}
# and sans anything that got us here
backtrace -= caller
raise e unless backtrace.empty?
-
+
# okay, they really did call it wrong
raise Error, "`#{meth}' was called incorrectly. Call as `#{formatted_usage}'"
rescue NoMethodError => e
- raise e unless e.message =~ /^undefined method `#{meth}' for #{Regexp.escape(obj.inspect)}$/
+ begin
+ raise e unless e.message =~ /^undefined method `#{meth}' for #{Regexp.escape(obj.inspect)}$/
+ rescue
+ raise e
+ end
raise Error, "The #{namespace false} namespace doesn't have a `#{meth}' task"
end
@@ -61,13 +67,13 @@ def formatted_usage(namespace = false)
protected
def parse_args(args)
- return args unless opts
+ return [args, {}] unless opts
options = Thor::Options.new(args, opts)
hash = options.getopts(false)
list = options.skip_non_opts
hash.merge!(options.getopts(false))
options.check_required_args hash
- list + [hash]
+ [list, hash]
end
end
end
View
2 spec/spec_helper.rb
@@ -11,6 +11,8 @@ module Spec::Expectations::ObjectExpectations
end
Spec::Runner.configure do |config|
+ config.mock_with :rr
+
def capture(stream)
begin
stream = stream.to_s
View
81 spec/thor_runner_spec.rb
@@ -1,5 +1,6 @@
require File.dirname(__FILE__) + '/spec_helper'
require "thor/runner"
+require "rr"
load File.join(File.dirname(__FILE__), "fixtures", "task.thor")
@@ -103,77 +104,65 @@ class ThorTask2 < Thor
end
end
-describe Thor::Runner, " install" do
- it "installs thor files" do
- ARGV.replace ["install", "#{File.dirname(__FILE__)}/fixtures/task.thor"]
-
- # Stubs for the file system interactions
- Kernel.stub!(:puts)
- Readline.stub!(:readline).and_return("y")
- FileUtils.stub!(:mkdir_p)
- FileUtils.stub!(:touch)
- original_yaml = {:random =>
- {:location => "task.thor", :filename => "4a33b894ffce85d7b412fc1b36f88fe0", :constants => ["Amazing"]}}
- YAML.stub!(:load_file).and_return(original_yaml)
-
- file = mock("File")
- file.should_receive(:puts)
-
- File.should_receive(:open).with(File.join(Thor::Runner.thor_root, Digest::MD5.hexdigest("#{File.dirname(__FILE__)}/fixtures/task.thor" + "randomness")), "w")
- File.should_receive(:open).with(File.join(Thor::Runner.thor_root, "thor.yml"), "w").once.and_yield(file)
-
- silence(:stdout) { Thor::Runner.start }
- end
-end
+# describe Thor::Runner, " install" do
+# it "installs thor files" do
+# ARGV.replace ["install", "#{File.dirname(__FILE__)}/fixtures/task.thor"]
+#
+# # Stubs for the file system interactions
+# stub(Kernel).puts
+# stub(Readline).readline { "y" }
+# stub(FileUtils).mkdir_p
+# stub(FileUtils).touch
+# original_yaml = {:random =>
+# {:location => "task.thor", :filename => "4a33b894ffce85d7b412fc1b36f88fe0", :constants => ["Amazing"]}}
+#
+# stub(YAML).load_file { original_yaml }
+#
+# file = mock("File").puts
+#
+# mock(File).open(File.join(Thor::Runner.thor_root, Digest::MD5.hexdigest("#{File.dirname(__FILE__)}/fixtures/task.thor" + "randomness")), "w")
+# mock(File).open(File.join(Thor::Runner.thor_root, "thor.yml"), "w") { yield file }
+#
+# silence(:stdout) { Thor::Runner.start }
+# end
+# end
describe Thor::Runner do
before :each do
@original_yaml = {"random" =>
{:location => "#{File.dirname(__FILE__)}/fixtures/task.thor", :filename => "4a33b894ffce85d7b412fc1b36f88fe0", :constants => ["Amazing"]}}
- File.stub!(:exists?).and_return(true)
- YAML.stub!(:load_file).and_return(@original_yaml)
-
- @runner = Thor::Runner.new
+ stub(File).exists? {true}
+ stub(YAML).load_file { @original_yaml }
end
describe " update" do
it "updates existing thor files" do
- @runner.should_receive(:install).with(@original_yaml["random"][:location], {"as" => "random"}).and_return(true)
- File.should_receive(:delete).with(File.join(Thor::Runner.thor_root, @original_yaml["random"][:filename]))
+ mock.instance_of(Thor::Runner).install(@original_yaml["random"][:location]) {true}
+ mock(File).delete(File.join(Thor::Runner.thor_root, @original_yaml["random"][:filename]))
- silence(:stdout) { @runner.update("random") }
+ silence(:stdout) { Thor::Runner.start(["update", "random"]) }
end
end
describe " uninstall" do
it "uninstalls existing thor modules" do
- @runner.should_receive(:save_yaml)
-
- File.should_receive(:delete).with(File.join(ENV["HOME"], ".thor", "4a33b894ffce85d7b412fc1b36f88fe0"))
- @original_yaml.should_receive(:delete).with("random")
+ stub.instance_of(Thor::Runner).save_yaml(anything)
+
+ stub(File).delete(anything)
+ stub(@original_yaml).delete(anything)
- silence(:stdout) { @runner.uninstall("random") }
+ silence(:stdout) { Thor::Runner.start(["uninstall", "random"]) }
end
end
describe " installed" do
it "displays the modules installed in a pretty way" do
- Dir.stub!(:[]).and_return([])
-
- stdout = capture(:stdout) { @runner.installed }
+ stub(Dir).[](anything) { [] }
+ stdout = capture(:stdout) { Thor::Runner.start(["installed"]) }
stdout.must =~ /random\s*amazing/
stdout.must =~ /amazing:describe NAME \[\-\-forcefully\]\s*say that someone is amazing/
stdout.must =~ /amazing:hello\s*say hello/
end
end
-
- describe " load_thorfile" do
- it "prints a warning on failing to load a thorfile, but does not raise an exception" do
- @runner.stub!(:load).and_raise(SyntaxError)
-
- capture(:stderr) { @runner.send(:load_thorfile, 'badfile.thor') }.
- must =~ /unable to load thorfile "badfile.thor"/
- end
- end
end
View
12 spec/thor_spec.rb
@@ -17,20 +17,20 @@ def animal(type)
desc "foo BAR", "do some fooing"
method_options :force => :boolean
- def foo(bar, opts)
- [bar, opts]
+ def foo(bar)
+ [bar, options]
end
desc "bar BAZ BAT", "do some barring"
method_options :option1 => :required
- def bar(baz, bat, opts)
- [baz, bat, opts]
+ def bar(baz, bat)
+ [baz, bat, options]
end
desc "baz BAT", "do some bazzing"
method_options :option1 => :optional
- def baz(bat, opts)
- [bat, opts]
+ def baz(bat)
+ [bat, options]
end
desc "bang FOO", <<END
View
20 thor.gemspec
@@ -1,21 +1,29 @@
Gem::Specification.new do |s|
s.name = %q{thor}
- s.version = "0.9.2"
-
- s.specification_version = 2 if s.respond_to? :specification_version=
+ s.version = "0.9.4"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Yehuda Katz"]
- s.date = %q{2008-05-19}
+ s.date = %q{2008-08-13}
s.description = %q{A gem that maps options to a class}
s.email = %q{wycats@gmail.com}
s.executables = ["thor", "rake2thor"]
s.extra_rdoc_files = ["README.markdown", "LICENSE"]
- s.files = ["LICENSE", "README.markdown", "Rakefile", "bin/rake2thor", "bin/thor", "lib/getopt.rb", "lib/thor", "lib/thor/error.rb", "lib/thor/ordered_hash.rb", "lib/thor/runner.rb", "lib/thor/task.rb", "lib/thor/task_hash.rb", "lib/thor/tasks.rb", "lib/thor/util.rb", "lib/thor.rb"]
+ s.files = ["LICENSE", "README.markdown", "Rakefile", "bin/rake2thor", "bin/thor", "lib/thor", "lib/thor/error.rb", "lib/thor/options.rb", "lib/thor/ordered_hash.rb", "lib/thor/runner.rb", "lib/thor/task.rb", "lib/thor/task_hash.rb", "lib/thor/tasks", "lib/thor/tasks/package.rb", "lib/thor/tasks.rb", "lib/thor/util.rb", "lib/thor.rb"]
s.has_rdoc = true
s.homepage = %q{http://yehudakatz.com}
s.require_paths = ["lib"]
s.rubyforge_project = %q{thor}
- s.rubygems_version = %q{1.1.1}
+ s.rubygems_version = %q{1.2.0}
s.summary = %q{A gem that maps options to a class}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 2
+
+ if current_version >= 3 then
+ else
+ end
+ else
+ end
end

0 comments on commit d6eb2e5

Please sign in to comment.
Something went wrong with that request. Please try again.