bundler 1.2.0.pre.1 → 1.2.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bundler might be problematic. Click here for more details.

Files changed (50) hide show
  1. data/CHANGELOG.md +27 -1
  2. data/ISSUES.md +3 -3
  3. data/lib/bundler.rb +7 -5
  4. data/lib/bundler/cli.rb +17 -20
  5. data/lib/bundler/definition.rb +5 -0
  6. data/lib/bundler/dsl.rb +1 -1
  7. data/lib/bundler/fetcher.rb +5 -6
  8. data/lib/bundler/gem_path_manipulation.rb +8 -0
  9. data/lib/bundler/ruby_version.rb +4 -2
  10. data/lib/bundler/runtime.rb +46 -19
  11. data/lib/bundler/source.rb +25 -10
  12. data/lib/bundler/templates/newgem/{LICENSE.tt → LICENSE.txt.tt} +0 -0
  13. data/lib/bundler/templates/newgem/Rakefile.tt +0 -1
  14. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -4
  15. data/lib/bundler/vendor/thor.rb +49 -28
  16. data/lib/bundler/vendor/thor/actions.rb +7 -3
  17. data/lib/bundler/vendor/thor/actions/create_link.rb +1 -1
  18. data/lib/bundler/vendor/thor/actions/directory.rb +9 -4
  19. data/lib/bundler/vendor/thor/actions/empty_directory.rb +24 -5
  20. data/lib/bundler/vendor/thor/actions/file_manipulation.rb +39 -1
  21. data/lib/bundler/vendor/thor/base.rb +65 -24
  22. data/lib/bundler/vendor/thor/core_ext/dir_escape.rb +0 -0
  23. data/lib/bundler/vendor/thor/error.rb +6 -1
  24. data/lib/bundler/vendor/thor/group.rb +21 -9
  25. data/lib/bundler/vendor/thor/invocation.rb +4 -2
  26. data/lib/bundler/vendor/thor/parser/arguments.rb +4 -0
  27. data/lib/bundler/vendor/thor/parser/option.rb +3 -2
  28. data/lib/bundler/vendor/thor/parser/options.rb +13 -7
  29. data/lib/bundler/vendor/thor/rake_compat.rb +13 -8
  30. data/lib/bundler/vendor/thor/runner.rb +15 -3
  31. data/lib/bundler/vendor/thor/shell.rb +4 -4
  32. data/lib/bundler/vendor/thor/shell/basic.rb +169 -82
  33. data/lib/bundler/vendor/thor/shell/color.rb +40 -4
  34. data/lib/bundler/vendor/thor/shell/html.rb +28 -26
  35. data/lib/bundler/vendor/thor/task.rb +24 -5
  36. data/lib/bundler/vendor/thor/util.rb +43 -6
  37. data/lib/bundler/vendor/thor/version.rb +1 -1
  38. data/lib/bundler/version.rb +1 -1
  39. data/man/bundle-config.ronn +2 -2
  40. data/spec/bundler/definition_spec.rb +25 -0
  41. data/spec/cache/git_spec.rb +47 -0
  42. data/spec/cache/path_spec.rb +18 -0
  43. data/spec/install/git_spec.rb +21 -6
  44. data/spec/lock/lockfile_spec.rb +1 -1
  45. data/spec/other/check_spec.rb +14 -1
  46. data/spec/other/newgem_spec.rb +1 -0
  47. data/spec/other/platform_spec.rb +164 -0
  48. data/spec/runtime/setup_spec.rb +87 -0
  49. data/spec/runtime/with_clean_env_spec.rb +14 -0
  50. metadata +78 -133
@@ -50,10 +50,46 @@ class Thor
50
50
  # on Highline implementation and it automatically appends CLEAR to the end
51
51
  # of the returned String.
52
52
  #
53
- def set_color(string, color, bold=false)
54
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
55
- bold = bold ? BOLD : ""
56
- "#{bold}#{color}#{string}#{CLEAR}"
53
+ # Pass foreground, background and bold options to this method as
54
+ # symbols.
55
+ #
56
+ # Example:
57
+ #
58
+ # set_color "Hi!", :red, :on_white, :bold
59
+ #
60
+ # The available colors are:
61
+ #
62
+ # :bold
63
+ # :black
64
+ # :red
65
+ # :green
66
+ # :yellow
67
+ # :blue
68
+ # :magenta
69
+ # :cyan
70
+ # :white
71
+ # :on_black
72
+ # :on_red
73
+ # :on_green
74
+ # :on_yellow
75
+ # :on_blue
76
+ # :on_magenta
77
+ # :on_cyan
78
+ # :on_white
79
+ def set_color(string, *colors)
80
+ if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
81
+ ansi_colors = colors.map { |color| lookup_color(color) }
82
+ "#{ansi_colors.join}#{string}#{CLEAR}"
83
+ else
84
+ # The old API was `set_color(color, bold=boolean)`. We
85
+ # continue to support the old API because you should never
86
+ # break old APIs unnecessarily :P
87
+ foreground, bold = colors
88
+ foreground = self.class.const_get(foreground.to_s.upcase) if foreground.is_a?(Symbol)
89
+
90
+ bold = bold ? BOLD : ""
91
+ "#{bold}#{foreground}#{string}#{CLEAR}"
92
+ end
57
93
  end
58
94
 
59
95
  protected
@@ -7,56 +7,58 @@ class Thor
7
7
  #
8
8
  class HTML < Basic
9
9
  # The start of an HTML bold sequence.
10
- BOLD = "<strong>"
11
- # The end of an HTML bold sequence.
12
- END_BOLD = "</strong>"
13
-
14
- # Embed in a String to clear previous color selection.
15
- CLEAR = "</span>"
10
+ BOLD = "font-weight: bold"
16
11
 
17
12
  # Set the terminal's foreground HTML color to black.
18
- BLACK = '<span style="color: black;">'
13
+ BLACK = 'color: black'
19
14
  # Set the terminal's foreground HTML color to red.
20
- RED = '<span style="color: red;">'
15
+ RED = 'color: red'
21
16
  # Set the terminal's foreground HTML color to green.
22
- GREEN = '<span style="color: green;">'
17
+ GREEN = 'color: green'
23
18
  # Set the terminal's foreground HTML color to yellow.
24
- YELLOW = '<span style="color: yellow;">'
19
+ YELLOW = 'color: yellow'
25
20
  # Set the terminal's foreground HTML color to blue.
26
- BLUE = '<span style="color: blue;">'
21
+ BLUE = 'color: blue'
27
22
  # Set the terminal's foreground HTML color to magenta.
28
- MAGENTA = '<span style="color: magenta;">'
23
+ MAGENTA = 'color: magenta'
29
24
  # Set the terminal's foreground HTML color to cyan.
30
- CYAN = '<span style="color: cyan;">'
25
+ CYAN = 'color: cyan'
31
26
  # Set the terminal's foreground HTML color to white.
32
- WHITE = '<span style="color: white;">'
27
+ WHITE = 'color: white'
33
28
 
34
29
  # Set the terminal's background HTML color to black.
35
- ON_BLACK = '<span style="background-color: black">'
30
+ ON_BLACK = 'background-color: black'
36
31
  # Set the terminal's background HTML color to red.
37
- ON_RED = '<span style="background-color: red">'
32
+ ON_RED = 'background-color: red'
38
33
  # Set the terminal's background HTML color to green.
39
- ON_GREEN = '<span style="background-color: green">'
34
+ ON_GREEN = 'background-color: green'
40
35
  # Set the terminal's background HTML color to yellow.
41
- ON_YELLOW = '<span style="background-color: yellow">'
36
+ ON_YELLOW = 'background-color: yellow'
42
37
  # Set the terminal's background HTML color to blue.
43
- ON_BLUE = '<span style="background-color: blue">'
38
+ ON_BLUE = 'background-color: blue'
44
39
  # Set the terminal's background HTML color to magenta.
45
- ON_MAGENTA = '<span style="background-color: magenta">'
40
+ ON_MAGENTA = 'background-color: magenta'
46
41
  # Set the terminal's background HTML color to cyan.
47
- ON_CYAN = '<span style="background-color: cyan">'
42
+ ON_CYAN = 'background-color: cyan'
48
43
  # Set the terminal's background HTML color to white.
49
- ON_WHITE = '<span style="background-color: white">'
44
+ ON_WHITE = 'background-color: white'
50
45
 
51
46
  # Set color by using a string or one of the defined constants. If a third
52
47
  # option is set to true, it also adds bold to the string. This is based
53
48
  # on Highline implementation and it automatically appends CLEAR to the end
54
49
  # of the returned String.
55
50
  #
56
- def set_color(string, color, bold=false)
57
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
58
- bold, end_bold = bold ? [BOLD, END_BOLD] : ['', '']
59
- "#{bold}#{color}#{string}#{CLEAR}#{end_bold}"
51
+ def set_color(string, *colors)
52
+ if colors.all? { |color| color.is_a?(Symbol) || color.is_a?(String) }
53
+ html_colors = colors.map { |color| lookup_color(color) }
54
+ "<span style=\"#{html_colors.join("; ")};\">#{string}</span>"
55
+ else
56
+ color, bold = colors
57
+ html_color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
58
+ styles = [html_color]
59
+ styles << BOLD if bold
60
+ "<span style=\"#{styles.join("; ")};\">#{string}</span>"
61
+ end
60
62
  end
61
63
 
62
64
  # Ask something to the user and receives a response.
@@ -18,11 +18,21 @@ class Thor
18
18
  # By default, a task invokes a method in the thor class. You can change this
19
19
  # implementation to create custom tasks.
20
20
  def run(instance, args=[])
21
- public_method?(instance) ?
22
- instance.send(name, *args) : instance.class.handle_no_task_error(name)
21
+ arity = nil
22
+
23
+ if private_method?(instance)
24
+ instance.class.handle_no_task_error(name)
25
+ elsif public_method?(instance)
26
+ arity = instance.method(name).arity
27
+ instance.send(name, *args)
28
+ elsif local_method?(instance, :method_missing)
29
+ instance.send(:method_missing, name.to_sym, *args)
30
+ else
31
+ instance.class.handle_no_task_error(name)
32
+ end
23
33
  rescue ArgumentError => e
24
34
  handle_argument_error?(instance, e, caller) ?
25
- instance.class.handle_argument_error(self, e) : (raise e)
35
+ instance.class.handle_argument_error(self, e, arity) : (raise e)
26
36
  rescue NoMethodError => e
27
37
  handle_no_method_error?(instance, e, caller) ?
28
38
  instance.class.handle_no_task_error(name) : (raise e)
@@ -34,8 +44,8 @@ class Thor
34
44
  if namespace
35
45
  namespace = klass.namespace
36
46
  formatted = "#{namespace.gsub(/^(default)/,'')}:"
37
- formatted.sub!(/.$/, ' ') if subcommand
38
47
  end
48
+ formatted = "#{klass.namespace.split(':').last} " if subcommand
39
49
 
40
50
  formatted ||= ""
41
51
 
@@ -70,8 +80,17 @@ class Thor
70
80
  !(instance.public_methods & [name.to_s, name.to_sym]).empty?
71
81
  end
72
82
 
83
+ def private_method?(instance)
84
+ !(instance.private_methods & [name.to_s, name.to_sym]).empty?
85
+ end
86
+
87
+ def local_method?(instance, name)
88
+ methods = instance.public_methods(false) + instance.private_methods(false) + instance.protected_methods(false)
89
+ !(methods & [name.to_s, name.to_sym]).empty?
90
+ end
91
+
73
92
  def sans_backtrace(backtrace, caller) #:nodoc:
74
- saned = backtrace.reject { |frame| frame =~ FILE_REGEXP }
93
+ saned = backtrace.reject { |frame| frame =~ FILE_REGEXP || (frame =~ /\.java:/ && RUBY_PLATFORM =~ /java/) }
75
94
  saned -= caller
76
95
  end
77
96
 
@@ -153,11 +153,11 @@ class Thor
153
153
  begin
154
154
  Thor::Sandbox.class_eval(content, path)
155
155
  rescue Exception => e
156
- $stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}"
156
+ $stderr.puts("WARNING: unable to load thorfile #{path.inspect}: #{e.message}")
157
157
  if debug
158
- $stderr.puts *e.backtrace
158
+ $stderr.puts(*e.backtrace)
159
159
  else
160
- $stderr.puts e.backtrace.first
160
+ $stderr.puts(e.backtrace.first)
161
161
  end
162
162
  end
163
163
  end
@@ -184,7 +184,7 @@ class Thor
184
184
  end
185
185
  end
186
186
 
187
- # Returns the root where thor files are located, dependending on the OS.
187
+ # Returns the root where thor files are located, depending on the OS.
188
188
  #
189
189
  def self.thor_root
190
190
  File.join(user_home, ".thor").gsub(/\\/, '/')
@@ -198,7 +198,7 @@ class Thor
198
198
  # If we don't #gsub the \ character, Dir.glob will fail.
199
199
  #
200
200
  def self.thor_root_glob
201
- files = Dir["#{thor_root}/*"]
201
+ files = Dir["#{escape_globs(thor_root)}/*"]
202
202
 
203
203
  files.map! do |file|
204
204
  File.directory?(file) ? File.join(file, "main.thor") : file
@@ -208,6 +208,7 @@ class Thor
208
208
  # Where to look for Thor files.
209
209
  #
210
210
  def self.globs_for(path)
211
+ path = escape_globs(path)
211
212
  ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
212
213
  end
213
214
 
@@ -216,14 +217,50 @@ class Thor
216
217
  #
217
218
  def self.ruby_command
218
219
  @ruby_command ||= begin
219
- ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
220
+ ruby_name = RbConfig::CONFIG['ruby_install_name']
221
+ ruby = File.join(RbConfig::CONFIG['bindir'], ruby_name)
220
222
  ruby << RbConfig::CONFIG['EXEEXT']
221
223
 
224
+ # avoid using different name than ruby (on platforms supporting links)
225
+ if ruby_name != 'ruby' && File.respond_to?(:readlink)
226
+ begin
227
+ alternate_ruby = File.join(RbConfig::CONFIG['bindir'], 'ruby')
228
+ alternate_ruby << RbConfig::CONFIG['EXEEXT']
229
+
230
+ # ruby is a symlink
231
+ if File.symlink? alternate_ruby
232
+ linked_ruby = File.readlink alternate_ruby
233
+
234
+ # symlink points to 'ruby_install_name'
235
+ ruby = alternate_ruby if linked_ruby == ruby_name || linked_ruby == ruby
236
+ end
237
+ rescue NotImplementedError
238
+ # just ignore on windows
239
+ end
240
+ end
241
+
222
242
  # escape string in case path to ruby executable contain spaces.
223
243
  ruby.sub!(/.*\s.*/m, '"\&"')
224
244
  ruby
225
245
  end
226
246
  end
227
247
 
248
+ # Returns a string that has had any glob characters escaped.
249
+ # The glob characters are `* ? { } [ ]`.
250
+ #
251
+ # ==== Examples
252
+ #
253
+ # Thor::Util.escape_globs('[apps]') # => '\[apps\]'
254
+ #
255
+ # ==== Parameters
256
+ # String
257
+ #
258
+ # ==== Returns
259
+ # String
260
+ #
261
+ def self.escape_globs(path)
262
+ path.to_s.gsub(/[*?{}\[\]]/, '\\\\\\&')
263
+ end
264
+
228
265
  end
229
266
  end
@@ -1,3 +1,3 @@
1
1
  class Thor
2
- VERSION = "0.14.6".freeze
2
+ VERSION = "0.15.2"
3
3
  end
@@ -2,5 +2,5 @@ module Bundler
2
2
  # We're doing this because we might write tests that deal
3
3
  # with other versions of bundler and we are unsure how to
4
4
  # handle this better.
5
- VERSION = "1.2.0.pre.1" unless defined?(::Bundler::VERSION)
5
+ VERSION = "1.2.0.rc" unless defined?(::Bundler::VERSION)
6
6
  end
@@ -122,8 +122,8 @@ invalid references. Particularly, we force a developer to specify
122
122
  a branch in the `Gemfile` in order to use this feature. If the branch
123
123
  specified in the `Gemfile` and the current branch in the local git
124
124
  repository do not match, Bundler will abort. This ensures that
125
- a developer is always working against the correct branches, avoiding
126
- a reference to be accidentally updated.
125
+ a developer is always working against the correct branches, and prevents
126
+ accidental locking to a different branch.
127
127
 
128
128
  Finally, Bundler also ensures that the current revision in the
129
129
  `Gemfile.lock` exists in the local git repository. By doing this, Bundler
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'bundler/definition'
3
+
4
+ describe Bundler::Definition do
5
+ before do
6
+ Bundler.stub(:settings){ Bundler::Settings.new(".") }
7
+ end
8
+
9
+ describe "#lock" do
10
+ context "when it's not possible to write to the file" do
11
+ subject{ Bundler::Definition.new(nil, [], [], []) }
12
+
13
+ before do
14
+ File.should_receive(:open).with("Gemfile.lock", "wb").
15
+ and_raise(Errno::EACCES)
16
+ end
17
+
18
+ it "raises an InstallError with explanation" do
19
+ expect{ subject.lock("Gemfile.lock") }.
20
+ to raise_error(Bundler::InstallError)
21
+ end
22
+ end
23
+ end
24
+
25
+ end
@@ -23,6 +23,25 @@ end
23
23
  G
24
24
 
25
25
  bundle "#{cmd} --all"
26
+ bundled_app("vendor/cache/foo-1.0-#{ref}").should exist
27
+ bundled_app("vendor/cache/foo-1.0-#{ref}/.git").should_not exist
28
+ bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache").should be_file
29
+
30
+ FileUtils.rm_rf lib_path("foo-1.0")
31
+ should_be_installed "foo 1.0"
32
+ end
33
+
34
+ it "copies repository to vendor cache and uses it even when installed with bundle --path" do
35
+ git = build_git "foo"
36
+ ref = git.ref_for("master", 11)
37
+
38
+ install_gemfile <<-G
39
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
40
+ G
41
+
42
+ bundle "install --path vendor/bundle"
43
+ bundle "#{cmd} --all"
44
+
26
45
  bundled_app("vendor/cache/foo-1.0-#{ref}").should exist
27
46
  bundled_app("vendor/cache/foo-1.0-#{ref}/.git").should_not exist
28
47
 
@@ -66,6 +85,7 @@ end
66
85
  bundle "#{cmd} --all"
67
86
 
68
87
  bundled_app("vendor/cache/foo-1.0-#{ref}").should exist
88
+ bundled_app("vendor/cache/foo-1.0-#{old_ref}").should_not exist
69
89
 
70
90
  FileUtils.rm_rf lib_path("foo-1.0")
71
91
  run "require 'foo'"
@@ -120,5 +140,32 @@ end
120
140
  bundled_app("vendor/cache/has_submodule-1.0-#{ref}/submodule-1.0").should exist
121
141
  should_be_installed "has_submodule 1.0"
122
142
  end
143
+
144
+ it "displays warning message when detecting git repo in Gemfile" do
145
+ git = build_git "foo"
146
+ ref = git.ref_for("master", 11)
147
+
148
+ install_gemfile <<-G
149
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
150
+ G
151
+
152
+ bundle "#{cmd}"
153
+
154
+ out.should include("Your Gemfile contains path and git dependencies.")
155
+ end
156
+
157
+ it "does not display warning message if cache_all is set in bundle config" do
158
+ git = build_git "foo"
159
+ ref = git.ref_for("master", 11)
160
+
161
+ install_gemfile <<-G
162
+ gem "foo", :git => '#{lib_path("foo-1.0")}'
163
+ G
164
+
165
+ bundle "#{cmd} --all"
166
+ bundle "#{cmd}"
167
+
168
+ out.should_not include("Your Gemfile contains path and git dependencies.")
169
+ end
123
170
  end
124
171
  end
@@ -23,6 +23,7 @@ require "spec_helper"
23
23
 
24
24
  bundle "#{cmd} --all"
25
25
  bundled_app("vendor/cache/foo-1.0").should exist
26
+ bundled_app("vendor/cache/foo-1.0/.bundlecache").should be_file
26
27
 
27
28
  FileUtils.rm_rf lib_path("foo-1.0")
28
29
  should_be_installed "foo 1.0"
@@ -50,6 +51,23 @@ require "spec_helper"
50
51
  out.should == "CACHE"
51
52
  end
52
53
 
54
+ it "removes stale entries cache" do
55
+ build_lib "foo"
56
+
57
+ install_gemfile <<-G
58
+ gem "foo", :path => '#{lib_path("foo-1.0")}'
59
+ G
60
+
61
+ bundle "#{cmd} --all"
62
+
63
+ install_gemfile <<-G
64
+ gem "bar", :path => '#{lib_path("bar-1.0")}'
65
+ G
66
+
67
+ bundle "#{cmd} --all"
68
+ bundled_app("vendor/cache/bar-1.0").should_not exist
69
+ end
70
+
53
71
  it "raises a warning without --all" do
54
72
  build_lib "foo"
55
73
 
@@ -156,7 +156,7 @@ describe "bundle install with git sources" do
156
156
  end
157
157
  end
158
158
 
159
- describe "when specifying local" do
159
+ describe "when specifying local override" do
160
160
  it "uses the local repository instead of checking a new one out" do
161
161
  # We don't generate it because we actually don't need it
162
162
  # build_git "rack", "0.8"
@@ -241,7 +241,7 @@ describe "bundle install with git sources" do
241
241
  lockfile1.should_not == lockfile0
242
242
  end
243
243
 
244
- it "explodes if given path does not exist" do
244
+ it "explodes if given path does not exist on install" do
245
245
  build_git "rack", "0.8"
246
246
 
247
247
  install_gemfile <<-G
@@ -254,7 +254,7 @@ describe "bundle install with git sources" do
254
254
  out.should =~ /Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/
255
255
  end
256
256
 
257
- it "explodes if branch is not given" do
257
+ it "explodes if branch is not given on install" do
258
258
  build_git "rack", "0.8"
259
259
  FileUtils.cp_r("#{lib_path('rack-0.8')}/.", lib_path('local-rack'))
260
260
 
@@ -265,10 +265,25 @@ describe "bundle install with git sources" do
265
265
 
266
266
  bundle %|config local.rack #{lib_path('local-rack')}|
267
267
  bundle :install
268
- out.should =~ /because :branch is not specified in Gemfile/
268
+ out.should =~ /cannot use local override/i
269
269
  end
270
270
 
271
- it "explodes on different branches" do
271
+ it "does not explode if disable_local_branch_check is given" do
272
+ build_git "rack", "0.8"
273
+ FileUtils.cp_r("#{lib_path('rack-0.8')}/.", lib_path('local-rack'))
274
+
275
+ install_gemfile <<-G
276
+ source "file://#{gem_repo1}"
277
+ gem "rack", :git => "#{lib_path('rack-0.8')}"
278
+ G
279
+
280
+ bundle %|config local.rack #{lib_path('local-rack')}|
281
+ bundle %|config disable_local_branch_check true|
282
+ bundle :install
283
+ out.should =~ /Your bundle is complete!/
284
+ end
285
+
286
+ it "explodes on different branches on install" do
272
287
  build_git "rack", "0.8"
273
288
 
274
289
  FileUtils.cp_r("#{lib_path('rack-0.8')}/.", lib_path('local-rack'))
@@ -287,7 +302,7 @@ describe "bundle install with git sources" do
287
302
  out.should =~ /is using branch another but Gemfile specifies master/
288
303
  end
289
304
 
290
- it "explodes on invalid revision" do
305
+ it "explodes on invalid revision on install" do
291
306
  build_git "rack", "0.8"
292
307
 
293
308
  build_git "rack", "0.8", :path => lib_path('local-rack') do |s|