thor 0.13.4 → 0.13.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -270,7 +270,7 @@ argument for our generator to run.
270
270
 
271
271
  The <tt>create_lib_file</tt> uses an ERB template. This is what it looks like:
272
272
 
273
- class <%= name.camelize %>
273
+ class <%= name.capitalize %>
274
274
  end
275
275
 
276
276
  The arguments that you set in your generator will automatically be passed in
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'uri'
2
3
  require 'thor/core_ext/file_binary_read'
3
4
 
4
5
  Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action|
@@ -115,7 +116,7 @@ class Thor
115
116
  @source_paths ||= self.class.source_paths_for_search
116
117
  end
117
118
 
118
- # Receives a file or directory and search for it in the source paths.
119
+ # Receives a file or directory and search for it in the source paths.
119
120
  #
120
121
  def find_in_source_paths(file)
121
122
  relative_root = relative_to_original_destination_root(destination_root, false)
@@ -129,7 +130,7 @@ class Thor
129
130
  raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
130
131
  "you can define a source_root in your class."
131
132
  else
132
- raise Error, "Could not find #{file.inspect} in source paths."
133
+ raise Error, "Could not find #{file.inspect} in source paths: \n#{source_paths.join("\n")}"
133
134
  end
134
135
  end
135
136
 
@@ -180,7 +181,14 @@ class Thor
180
181
 
181
182
  say_status :apply, path, verbose
182
183
  shell.padding += 1 if verbose
183
- instance_eval(open(path).read)
184
+
185
+ if URI(path).is_a?(URI::HTTP)
186
+ contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
187
+ else
188
+ contents = open(path) {|io| io.read }
189
+ end
190
+
191
+ instance_eval(contents, path)
184
192
  shell.padding -= 1 if verbose
185
193
  end
186
194
 
@@ -223,7 +231,7 @@ class Thor
223
231
  run command, config.merge(:with => Thor::Util.ruby_command)
224
232
  end
225
233
 
226
- # Run a thor command. A hash of options can be given and it's converted to
234
+ # Run a thor command. A hash of options can be given and it's converted to
227
235
  # switches.
228
236
  #
229
237
  # ==== Parameters
@@ -48,7 +48,7 @@ class Thor
48
48
  #
49
49
  def get(source, destination=nil, config={}, &block)
50
50
  source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\//
51
- render = open(source).binmode.read
51
+ render = open(source) {|input| input.binmode.read }
52
52
 
53
53
  destination ||= if block_given?
54
54
  block.arity == 1 ? block.call(render) : block.call
@@ -11,7 +11,7 @@ class Thor
11
11
  def prepare_for_invocation(key, name) #:nodoc:
12
12
  case name
13
13
  when Symbol, String
14
- Thor::Util.find_class_and_task_by_namespace(name.to_s)
14
+ Thor::Util.find_class_and_task_by_namespace(name.to_s, !key)
15
15
  else
16
16
  name
17
17
  end
@@ -16,7 +16,7 @@ class Thor::Runner < Thor #:nodoc:
16
16
  def help(meth=nil)
17
17
  if meth && !self.respond_to?(meth)
18
18
  initialize_thorfiles(meth)
19
- klass, task = Thor::Util.find_class_and_task_by_namespace!(meth)
19
+ klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
20
20
  klass.start(["-h", task].compact, :shell => self.shell)
21
21
  else
22
22
  super
@@ -29,7 +29,7 @@ class Thor::Runner < Thor #:nodoc:
29
29
  def method_missing(meth, *args)
30
30
  meth = meth.to_s
31
31
  initialize_thorfiles(meth)
32
- klass, task = Thor::Util.find_class_and_task_by_namespace!(meth)
32
+ klass, task = Thor::Util.find_class_and_task_by_namespace(meth)
33
33
  args.unshift(task) if task
34
34
  klass.start(args, :shell => self.shell)
35
35
  end
@@ -44,10 +44,10 @@ class Thor::Runner < Thor #:nodoc:
44
44
  begin
45
45
  if File.directory?(File.expand_path(name))
46
46
  base, package = File.join(name, "main.thor"), :directory
47
- contents = open(base).read
47
+ contents = open(base) {|input| input.read }
48
48
  else
49
49
  base, package = name, :file
50
- contents = open(name).read
50
+ contents = open(name) {|input| input.read }
51
51
  end
52
52
  rescue OpenURI::HTTPError
53
53
  raise Error, "Error opening URI '#{name}'"
@@ -128,25 +128,19 @@ class Thor
128
128
  # ==== Parameters
129
129
  # namespace<String>
130
130
  #
131
- def self.find_class_and_task_by_namespace(namespace)
132
- if namespace.include?(?:)
131
+ def self.find_class_and_task_by_namespace(namespace, fallback = true)
132
+ if namespace.include?(?:) # look for a namespaced task
133
133
  pieces = namespace.split(":")
134
134
  task = pieces.pop
135
135
  klass = Thor::Util.find_by_namespace(pieces.join(":"))
136
136
  end
137
-
138
- unless klass
137
+ unless klass # look for a Thor::Group with the right name
139
138
  klass, task = Thor::Util.find_by_namespace(namespace), nil
140
139
  end
141
-
142
- return klass, task
143
- end
144
-
145
- # The same as namespace_to_thor_class_and_task!, but raises an error if a klass
146
- # could not be found.
147
- def self.find_class_and_task_by_namespace!(namespace)
148
- klass, task = find_class_and_task_by_namespace(namespace)
149
- raise Error, "Could not find namespace or task #{namespace.inspect}." unless klass
140
+ if !klass && fallback # try a task in the default namespace
141
+ task = namespace
142
+ klass = Thor::Util.find_by_namespace('')
143
+ end
150
144
  return klass, task
151
145
  end
152
146
 
@@ -1,3 +1,3 @@
1
1
  class Thor
2
- VERSION = "0.13.4".freeze
2
+ VERSION = "0.13.5".freeze
3
3
  end
@@ -195,7 +195,7 @@ describe Thor::Actions do
195
195
  @template.instance_eval "def read; self; end" # Make the string respond to read
196
196
 
197
197
  @file = "http://gist.github.com/103208.txt"
198
- runner.should_receive(:open).and_return(@template)
198
+ runner.should_receive(:open).with(@file, "Accept" => "application/x-thor-template").and_return(@template)
199
199
  end
200
200
 
201
201
  it "opens a file and executes its content in the instance binding" do
@@ -20,7 +20,7 @@ class MyCounter < Thor::Group
20
20
 
21
21
  desc <<-FOO
22
22
  Description:
23
- This generator run three tasks: one, two and three.
23
+ This generator runs three tasks: one, two and three.
24
24
  FOO
25
25
 
26
26
  def one
@@ -81,3 +81,10 @@ class WhinyGenerator < Thor::Group
81
81
  def wrong_arity(required)
82
82
  end
83
83
  end
84
+
85
+ class TaskConflict < Thor::Group
86
+ desc "A group with the same name as a default task"
87
+ def group
88
+ puts "group"
89
+ end
90
+ end
@@ -127,9 +127,14 @@ module Scripts
127
127
 
128
128
  class MyDefaults < Thor
129
129
  namespace :default
130
- desc "test", "prints 'test'"
131
- def test
132
- puts "test"
130
+ desc "cow", "prints 'moo'"
131
+ def cow
132
+ puts "moo"
133
+ end
134
+
135
+ desc "task_conflict", "only gets called when prepended with a colon"
136
+ def task_conflict
137
+ puts "task"
133
138
  end
134
139
  end
135
140
 
@@ -36,11 +36,11 @@ describe Thor::Group do
36
36
 
37
37
  describe "#desc" do
38
38
  it "sets the description for a given class" do
39
- MyCounter.desc.must == "Description:\n This generator run three tasks: one, two and three.\n"
39
+ MyCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
40
40
  end
41
41
 
42
42
  it "can be inherited" do
43
- BrokenCounter.desc.must == "Description:\n This generator run three tasks: one, two and three.\n"
43
+ BrokenCounter.desc.must == "Description:\n This generator runs three tasks: one, two and three.\n"
44
44
  end
45
45
 
46
46
  it "can be nil" do
@@ -59,7 +59,7 @@ describe Thor::Group do
59
59
 
60
60
  it "shows description" do
61
61
  @content.must =~ /Description:/
62
- @content.must =~ /This generator run three tasks: one, two and three./
62
+ @content.must =~ /This generator runs three tasks: one, two and three./
63
63
  end
64
64
 
65
65
  it "shows options information" do
@@ -30,9 +30,8 @@ describe Thor::Runner do
30
30
  end
31
31
 
32
32
  it "raises error if a class/task cannot be found" do
33
- Thor::Runner.should_receive(:exit).with(1)
34
33
  content = capture(:stderr){ Thor::Runner.start(["help", "unknown"]) }
35
- content.strip.must == 'Could not find namespace or task "unknown".'
34
+ content.strip.must == 'Could not find task "unknown" in "default" namespace.'
36
35
  end
37
36
  end
38
37
 
@@ -68,10 +67,9 @@ describe Thor::Runner do
68
67
  end
69
68
 
70
69
  it "raises an error if class/task can't be found" do
71
- Thor::Runner.should_receive(:exit).with(1)
72
70
  ARGV.replace ["unknown"]
73
71
  content = capture(:stderr){ Thor::Runner.start }
74
- content.strip.must == 'Could not find namespace or task "unknown".'
72
+ content.strip.must == 'Could not find task "unknown" in "default" namespace.'
75
73
  end
76
74
 
77
75
  it "does not swallow NoMethodErrors that occur inside the called method" do
@@ -145,12 +143,22 @@ describe Thor::Runner do
145
143
 
146
144
  it "presents tasks in the default namespace with an empty namespace" do
147
145
  ARGV.replace ["list"]
148
- capture(:stdout) { Thor::Runner.start }.must =~ /^thor :test\s+# prints 'test'/m
146
+ capture(:stdout) { Thor::Runner.start }.must =~ /^thor :cow\s+# prints 'moo'/m
149
147
  end
150
148
 
151
149
  it "runs tasks with an empty namespace from the default namespace" do
152
- ARGV.replace [":test"]
153
- capture(:stdout) { Thor::Runner.start }.must == "test\n"
150
+ ARGV.replace [":task_conflict"]
151
+ capture(:stdout) { Thor::Runner.start }.must == "task\n"
152
+ end
153
+
154
+ it "runs groups even when there is a task with the same name" do
155
+ ARGV.replace ["task_conflict"]
156
+ capture(:stdout) { Thor::Runner.start }.must == "group\n"
157
+ end
158
+
159
+ it "runs tasks with no colon in the default namespace" do
160
+ ARGV.replace ["cow"]
161
+ capture(:stdout) { Thor::Runner.start }.must == "moo\n"
154
162
  end
155
163
  end
156
164
 
@@ -100,18 +100,14 @@ describe Thor::Util do
100
100
  Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
101
101
  end
102
102
 
103
- it "fallbacks in the namespace:task look up even if a full namespace does not match" do
103
+ it "falls back in the namespace:task look up even if a full namespace does not match" do
104
104
  Thor.const_set(:Help, Module.new)
105
105
  Thor::Util.find_class_and_task_by_namespace("thor:help").must == [Thor, "help"]
106
106
  Thor.send :remove_const, :Help
107
107
  end
108
108
 
109
- describe 'errors' do
110
- it "raises an error if the Thor class or task can't be found" do
111
- lambda {
112
- Thor::Util.find_class_and_task_by_namespace!("foobar")
113
- }.must raise_error(Thor::Error, 'Could not find namespace or task "foobar".')
114
- end
109
+ it "falls back on the default namespace class if nothing else matches" do
110
+ Thor::Util.find_class_and_task_by_namespace("test").must == [Scripts::MyDefaults, "test"]
115
111
  end
116
112
  end
117
113
 
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.4
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 13
8
+ - 5
9
+ version: 0.13.5
5
10
  platform: ruby
6
11
  authors:
7
12
  - Yehuda Katz
@@ -10,7 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-02-26 00:00:00 +01:00
18
+ date: 2010-04-29 00:00:00 +02:00
14
19
  default_executable:
15
20
  dependencies: []
16
21
 
@@ -73,18 +78,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
78
  requirements:
74
79
  - - ">="
75
80
  - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
76
83
  version: "0"
77
- version:
78
84
  required_rubygems_version: !ruby/object:Gem::Requirement
79
85
  requirements:
80
86
  - - ">="
81
87
  - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
82
90
  version: "0"
83
- version:
84
91
  requirements: []
85
92
 
86
93
  rubyforge_project: textmate
87
- rubygems_version: 1.3.5
94
+ rubygems_version: 1.3.6
88
95
  signing_key:
89
96
  specification_version: 3
90
97
  summary: A scripting framework that replaces rake, sake and rubigen