bundler 2.0.1 → 2.0.2

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +1 -1
  4. data/bundler.gemspec +6 -5
  5. data/lib/bundler/build_metadata.rb +2 -2
  6. data/lib/bundler/cli.rb +3 -1
  7. data/lib/bundler/cli/common.rb +1 -1
  8. data/lib/bundler/cli/install.rb +9 -8
  9. data/lib/bundler/cli/issue.rb +2 -2
  10. data/lib/bundler/compatibility_guard.rb +0 -1
  11. data/lib/bundler/definition.rb +3 -1
  12. data/lib/bundler/dsl.rb +1 -1
  13. data/lib/bundler/env.rb +2 -8
  14. data/lib/bundler/feature_flag.rb +1 -1
  15. data/lib/bundler/fetcher/downloader.rb +1 -1
  16. data/lib/bundler/gem_helper.rb +37 -22
  17. data/lib/bundler/injector.rb +7 -7
  18. data/lib/bundler/installer/parallel_installer.rb +0 -4
  19. data/lib/bundler/plugin.rb +13 -11
  20. data/lib/bundler/plugin/index.rb +4 -1
  21. data/lib/bundler/rubygems_ext.rb +0 -1
  22. data/lib/bundler/rubygems_integration.rb +19 -2
  23. data/lib/bundler/shared_helpers.rb +7 -5
  24. data/lib/bundler/templates/Executable.bundler +1 -1
  25. data/lib/bundler/templates/newgem/newgem.gemspec.tt +7 -12
  26. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +4 -0
  27. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +151 -48
  28. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  29. data/lib/bundler/vendor/thor/lib/thor/actions.rb +14 -4
  30. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +11 -2
  31. data/lib/bundler/vendor/thor/lib/thor/base.rb +3 -4
  32. data/lib/bundler/vendor/thor/lib/thor/error.rb +82 -0
  33. data/lib/bundler/vendor/thor/lib/thor/group.rb +2 -2
  34. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +7 -2
  35. data/lib/bundler/vendor/thor/lib/thor/runner.rb +2 -2
  36. data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
  37. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +52 -7
  38. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  39. data/lib/bundler/version.rb +1 -1
  40. data/man/bundle-add.1 +1 -1
  41. data/man/bundle-add.1.txt +1 -1
  42. data/man/bundle-binstubs.1 +1 -1
  43. data/man/bundle-binstubs.1.txt +1 -1
  44. data/man/bundle-check.1 +1 -1
  45. data/man/bundle-check.1.txt +1 -1
  46. data/man/bundle-clean.1 +1 -1
  47. data/man/bundle-clean.1.txt +1 -1
  48. data/man/bundle-config.1 +2 -2
  49. data/man/bundle-config.1.txt +3 -3
  50. data/man/bundle-config.ronn +1 -1
  51. data/man/bundle-doctor.1 +1 -1
  52. data/man/bundle-doctor.1.txt +1 -1
  53. data/man/bundle-exec.1 +1 -1
  54. data/man/bundle-exec.1.txt +1 -1
  55. data/man/bundle-gem.1 +1 -1
  56. data/man/bundle-gem.1.txt +1 -1
  57. data/man/bundle-info.1 +1 -1
  58. data/man/bundle-info.1.txt +1 -1
  59. data/man/bundle-init.1 +2 -2
  60. data/man/bundle-init.1.txt +2 -2
  61. data/man/bundle-init.ronn +1 -1
  62. data/man/bundle-inject.1 +1 -1
  63. data/man/bundle-inject.1.txt +1 -1
  64. data/man/bundle-install.1 +1 -1
  65. data/man/bundle-install.1.txt +1 -1
  66. data/man/bundle-list.1 +1 -1
  67. data/man/bundle-list.1.txt +1 -1
  68. data/man/bundle-lock.1 +1 -1
  69. data/man/bundle-lock.1.txt +1 -1
  70. data/man/bundle-open.1 +1 -1
  71. data/man/bundle-open.1.txt +1 -1
  72. data/man/bundle-outdated.1 +1 -1
  73. data/man/bundle-outdated.1.txt +1 -1
  74. data/man/bundle-package.1 +1 -1
  75. data/man/bundle-package.1.txt +1 -1
  76. data/man/bundle-platform.1 +1 -1
  77. data/man/bundle-platform.1.txt +1 -1
  78. data/man/bundle-pristine.1 +1 -1
  79. data/man/bundle-pristine.1.txt +1 -1
  80. data/man/bundle-remove.1 +1 -1
  81. data/man/bundle-remove.1.txt +1 -1
  82. data/man/bundle-show.1 +1 -1
  83. data/man/bundle-show.1.txt +1 -1
  84. data/man/bundle-update.1 +1 -1
  85. data/man/bundle-update.1.txt +1 -1
  86. data/man/bundle-viz.1 +1 -1
  87. data/man/bundle-viz.1.txt +1 -1
  88. data/man/bundle.1 +2 -2
  89. data/man/bundle.1.txt +2 -2
  90. data/man/bundle.ronn +1 -1
  91. data/man/gemfile.5 +2 -2
  92. data/man/gemfile.5.ronn +1 -1
  93. data/man/gemfile.5.txt +2 -2
  94. metadata +23 -8
@@ -58,7 +58,10 @@ module Bundler
58
58
  raise SourceConflict.new(name, common) unless common.empty?
59
59
  sources.each {|k| @sources[k] = name }
60
60
 
61
- hooks.each {|e| (@hooks[e] ||= []) << name }
61
+ hooks.each do |event|
62
+ event_hooks = (@hooks[event] ||= []) << name
63
+ event_hooks.uniq!
64
+ end
62
65
 
63
66
  @plugin_paths[name] = path
64
67
  @load_paths[name] = load_paths
@@ -7,7 +7,6 @@ if defined?(Gem::QuickLoader)
7
7
  Gem::QuickLoader.load_full_rubygems_library
8
8
  end
9
9
 
10
- require "rubygems"
11
10
  require "rubygems/specification"
12
11
 
13
12
  begin
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "monitor"
4
- require "rubygems"
5
- require "rubygems/config_file"
6
4
 
7
5
  module Bundler
8
6
  class RubygemsIntegration
@@ -514,6 +512,15 @@ module Bundler
514
512
  h
515
513
  end
516
514
 
515
+ Bundler.rubygems.default_stubs.each do |stub|
516
+ default_spec = stub.to_spec
517
+ default_spec_name = default_spec.name
518
+ next if specs_by_name.key?(default_spec_name)
519
+
520
+ specs << default_spec
521
+ specs_by_name[default_spec_name] = default_spec
522
+ end
523
+
517
524
  replace_gem(specs, specs_by_name)
518
525
  stub_rubygems(specs)
519
526
  replace_bin_path(specs, specs_by_name)
@@ -850,6 +857,16 @@ module Bundler
850
857
  end
851
858
  end
852
859
 
860
+ if Gem::Specification.respond_to?(:default_stubs)
861
+ def default_stubs
862
+ Gem::Specification.default_stubs("*.gemspec")
863
+ end
864
+ else
865
+ def default_stubs
866
+ Gem::Specification.send(:default_stubs, "*.gemspec")
867
+ end
868
+ end
869
+
853
870
  def use_gemdeps(gemfile)
854
871
  ENV["BUNDLE_GEMFILE"] ||= File.expand_path(gemfile)
855
872
  require "bundler/gemdeps"
@@ -3,6 +3,7 @@
3
3
  require "bundler/compatibility_guard"
4
4
 
5
5
  require "pathname"
6
+ require "rbconfig"
6
7
  require "rubygems"
7
8
 
8
9
  require "bundler/version"
@@ -140,12 +141,13 @@ module Bundler
140
141
  end
141
142
 
142
143
  def major_deprecation(major_version, message)
143
- if Bundler.bundler_major_version >= major_version
144
+ bundler_major_version = Bundler.bundler_major_version
145
+ if bundler_major_version > major_version
144
146
  require "bundler/errors"
145
- raise DeprecatedError, "[REMOVED FROM #{major_version}.0] #{message}"
147
+ raise DeprecatedError, "[REMOVED FROM #{major_version.succ}.0] #{message}"
146
148
  end
147
149
 
148
- return unless prints_major_deprecations?
150
+ return unless bundler_major_version >= major_version || prints_major_deprecations?
149
151
  @major_deprecation_ui ||= Bundler::UI::Shell.new("no-color" => true)
150
152
  ui = Bundler.ui.is_a?(@major_deprecation_ui.class) ? Bundler.ui : @major_deprecation_ui
151
153
  ui.warn("[DEPRECATED FOR #{major_version}.0] #{message}")
@@ -276,7 +278,7 @@ module Bundler
276
278
  # avoid stepping above the tmp directory when testing
277
279
  gemspec = if ENV["BUNDLE_RUBY"] && ENV["BUNDLE_GEM"]
278
280
  # for Ruby Core
279
- "lib/bundler.gemspec"
281
+ "lib/bundler/bundler.gemspec"
280
282
  else
281
283
  "bundler.gemspec"
282
284
  end
@@ -340,7 +342,7 @@ module Bundler
340
342
 
341
343
  def set_rubylib
342
344
  rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR)
343
- rubylib.unshift bundler_ruby_lib
345
+ rubylib.unshift bundler_ruby_lib unless RbConfig::CONFIG["rubylibdir"] == bundler_ruby_lib
344
346
  Bundler::SharedHelpers.set_env "RUBYLIB", rubylib.uniq.join(File::PATH_SEPARATOR)
345
347
  end
346
348
 
@@ -11,7 +11,7 @@
11
11
  require "rubygems"
12
12
 
13
13
  m = Module.new do
14
- module_function
14
+ module_function
15
15
 
16
16
  def invoked_as_script?
17
17
  File.expand_path($0) == File.expand_path(__FILE__)
@@ -1,8 +1,10 @@
1
1
  <%- if RUBY_VERSION < "2.0.0" -%>
2
2
  # coding: utf-8
3
- <%- end -%>
4
3
 
5
4
  lib = File.expand_path("../lib", __FILE__)
5
+ <%- else -%>
6
+ lib = File.expand_path("lib", __dir__)
7
+ <%- end -%>
6
8
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
9
  require "<%= config[:namespaced_path] %>/version"
8
10
 
@@ -19,18 +21,11 @@ Gem::Specification.new do |spec|
19
21
  spec.license = "MIT"
20
22
  <%- end -%>
21
23
 
22
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
23
- # to allow pushing to a single host or delete this section to allow pushing to any host.
24
- if spec.respond_to?(:metadata)
25
- spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
24
+ spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
26
25
 
27
- spec.metadata["homepage_uri"] = spec.homepage
28
- spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
29
- spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
30
- else
31
- raise "RubyGems 2.0 or newer is required to protect against " \
32
- "public gem pushes."
33
- end
26
+ spec.metadata["homepage_uri"] = spec.homepage
27
+ spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
28
+ spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
34
29
 
35
30
  # Specify which files should be added to the gem when it is released.
36
31
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -1,4 +1,8 @@
1
+ <%- if RUBY_VERSION < "2.0.0" -%>
1
2
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
3
+ <%- else -%>
4
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
5
+ <%- end -%>
2
6
  require "<%= config[:namespaced_path] %>"
3
7
 
4
8
  require "minitest/autorun"
@@ -1,4 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'rbconfig'
5
+ rescue LoadError
6
+ # for make mjit-headers
7
+ end
8
+
9
+ require "bundler/vendor/fileutils/lib/fileutils/version"
10
+
2
11
  #
3
12
  # = fileutils.rb
4
13
  #
@@ -56,7 +65,7 @@
56
65
  #
57
66
  # There are some `low level' methods, which do not accept any option:
58
67
  #
59
- # Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
68
+ # Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
60
69
  # Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
61
70
  # Bundler::FileUtils.copy_stream(srcstream, deststream)
62
71
  # Bundler::FileUtils.remove_entry(path, force = false)
@@ -84,7 +93,6 @@
84
93
  # files/directories. This equates to passing the <tt>:noop</tt> and
85
94
  # <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
86
95
  #
87
-
88
96
  module Bundler::FileUtils
89
97
 
90
98
  def self.private_module_function(name) #:nodoc:
@@ -106,19 +114,22 @@ module Bundler::FileUtils
106
114
  #
107
115
  # Changes the current directory to the directory +dir+.
108
116
  #
109
- # If this method is called with block, resumes to the old
110
- # working directory after the block execution finished.
117
+ # If this method is called with block, resumes to the previous
118
+ # working directory after the block execution has finished.
111
119
  #
112
- # Bundler::FileUtils.cd('/', :verbose => true) # chdir and report it
120
+ # Bundler::FileUtils.cd('/') # change directory
113
121
  #
114
- # Bundler::FileUtils.cd('/') do # chdir
122
+ # Bundler::FileUtils.cd('/', :verbose => true) # change directory and report it
123
+ #
124
+ # Bundler::FileUtils.cd('/') do # change directory
115
125
  # # ... # do something
116
126
  # end # return to original directory
117
127
  #
118
128
  def cd(dir, verbose: nil, &block) # :yield: dir
119
129
  fu_output_message "cd #{dir}" if verbose
120
- Dir.chdir(dir, &block)
130
+ result = Dir.chdir(dir, &block)
121
131
  fu_output_message 'cd -' if verbose and block
132
+ result
122
133
  end
123
134
  module_function :cd
124
135
 
@@ -245,15 +256,15 @@ module Bundler::FileUtils
245
256
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
246
257
  return if noop
247
258
  list.each do |dir|
248
- begin
249
- Dir.rmdir(dir = remove_trailing_slash(dir))
250
- if parents
259
+ Dir.rmdir(dir = remove_trailing_slash(dir))
260
+ if parents
261
+ begin
251
262
  until (parent = File.dirname(dir)) == '.' or parent == dir
252
263
  dir = parent
253
264
  Dir.rmdir(dir)
254
265
  end
266
+ rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
255
267
  end
256
- rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
257
268
  end
258
269
  end
259
270
  end
@@ -293,6 +304,39 @@ module Bundler::FileUtils
293
304
  alias link ln
294
305
  module_function :link
295
306
 
307
+ #
308
+ # :call-seq:
309
+ # Bundler::FileUtils.cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
310
+ #
311
+ # Hard link +src+ to +dest+. If +src+ is a directory, this method links
312
+ # all its contents recursively. If +dest+ is a directory, links
313
+ # +src+ to +dest/src+.
314
+ #
315
+ # +src+ can be a list of files.
316
+ #
317
+ # # Installing the library "mylib" under the site_ruby directory.
318
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', :force => true
319
+ # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
320
+ #
321
+ # # Examples of linking several files to target directory.
322
+ # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
323
+ # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', :noop => true, :verbose => true
324
+ #
325
+ # # If you want to link all contents of a directory instead of the
326
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
327
+ # # use the following code.
328
+ # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
329
+ #
330
+ def cp_lr(src, dest, noop: nil, verbose: nil,
331
+ dereference_root: true, remove_destination: false)
332
+ fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
333
+ return if noop
334
+ fu_each_src_dest(src, dest) do |s, d|
335
+ link_entry s, d, dereference_root, remove_destination
336
+ end
337
+ end
338
+ module_function :cp_lr
339
+
296
340
  #
297
341
  # :call-seq:
298
342
  # Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
@@ -339,6 +383,26 @@ module Bundler::FileUtils
339
383
  end
340
384
  module_function :ln_sf
341
385
 
386
+ #
387
+ # Hard links a file system entry +src+ to +dest+.
388
+ # If +src+ is a directory, this method links its contents recursively.
389
+ #
390
+ # Both of +src+ and +dest+ must be a path name.
391
+ # +src+ must exist, +dest+ must not exist.
392
+ #
393
+ # If +dereference_root+ is true, this method dereferences the tree root.
394
+ #
395
+ # If +remove_destination+ is true, this method removes each destination file before copy.
396
+ #
397
+ def link_entry(src, dest, dereference_root = false, remove_destination = false)
398
+ Entry_.new(src, nil, dereference_root).traverse do |ent|
399
+ destent = Entry_.new(dest, ent.rel, false)
400
+ File.unlink destent.path if remove_destination && File.file?(destent.path)
401
+ ent.link destent.path
402
+ end
403
+ end
404
+ module_function :link_entry
405
+
342
406
  #
343
407
  # Copies a file content +src+ to +dest+. If +dest+ is a directory,
344
408
  # copies +src+ to +dest/src+.
@@ -412,7 +476,7 @@ module Bundler::FileUtils
412
476
  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
413
477
  Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
414
478
  destent = Entry_.new(dest, ent.rel, false)
415
- File.unlink destent.path if remove_destination && File.file?(destent.path)
479
+ File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
416
480
  ent.copy destent.path
417
481
  end, proc do |ent|
418
482
  destent = Entry_.new(dest, ent.rel, false)
@@ -461,13 +525,12 @@ module Bundler::FileUtils
461
525
  if destent.exist?
462
526
  if destent.directory?
463
527
  raise Errno::EEXIST, d
464
- else
465
- destent.remove_file if rename_cannot_overwrite_file?
466
528
  end
467
529
  end
468
530
  begin
469
531
  File.rename s, d
470
- rescue Errno::EXDEV
532
+ rescue Errno::EXDEV,
533
+ Errno::EPERM # move from unencrypted to encrypted dir (ext4)
471
534
  copy_entry s, d, true
472
535
  if secure
473
536
  remove_entry_secure s, force
@@ -485,11 +548,6 @@ module Bundler::FileUtils
485
548
  alias move mv
486
549
  module_function :move
487
550
 
488
- def rename_cannot_overwrite_file? #:nodoc:
489
- /emx/ =~ RUBY_PLATFORM
490
- end
491
- private_module_function :rename_cannot_overwrite_file?
492
-
493
551
  #
494
552
  # Remove file(s) specified in +list+. This method cannot remove directories.
495
553
  # All StandardErrors are ignored when the :force option is set.
@@ -601,8 +659,8 @@ module Bundler::FileUtils
601
659
  #
602
660
  # For details of this security vulnerability, see Perl's case:
603
661
  #
604
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
605
- # * http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
662
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
663
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
606
664
  #
607
665
  # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
608
666
  #
@@ -626,22 +684,38 @@ module Bundler::FileUtils
626
684
  unless parent_st.sticky?
627
685
  raise ArgumentError, "parent directory is world writable, Bundler::FileUtils#remove_entry_secure does not work; abort: #{path.inspect} (parent directory mode #{'%o' % parent_st.mode})"
628
686
  end
687
+
629
688
  # freeze tree root
630
689
  euid = Process.euid
631
- File.open(fullpath + '/.') {|f|
632
- unless fu_stat_identical_entry?(st, f.stat)
633
- # symlink (TOC-to-TOU attack?)
634
- File.unlink fullpath
635
- return
636
- end
637
- f.chown euid, -1
638
- f.chmod 0700
639
- unless fu_stat_identical_entry?(st, File.lstat(fullpath))
640
- # TOC-to-TOU attack?
641
- File.unlink fullpath
642
- return
643
- end
644
- }
690
+ dot_file = fullpath + "/."
691
+ begin
692
+ File.open(dot_file) {|f|
693
+ unless fu_stat_identical_entry?(st, f.stat)
694
+ # symlink (TOC-to-TOU attack?)
695
+ File.unlink fullpath
696
+ return
697
+ end
698
+ f.chown euid, -1
699
+ f.chmod 0700
700
+ }
701
+ rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
702
+ File.lstat(dot_file).tap {|fstat|
703
+ unless fu_stat_identical_entry?(st, fstat)
704
+ # symlink (TOC-to-TOU attack?)
705
+ File.unlink fullpath
706
+ return
707
+ end
708
+ File.chown euid, -1, dot_file
709
+ File.chmod 0700, dot_file
710
+ }
711
+ end
712
+
713
+ unless fu_stat_identical_entry?(st, File.lstat(fullpath))
714
+ # TOC-to-TOU attack?
715
+ File.unlink fullpath
716
+ return
717
+ end
718
+
645
719
  # ---- tree root is frozen ----
646
720
  root = Entry_.new(path)
647
721
  root.preorder_traverse do |ent|
@@ -742,8 +816,15 @@ module Bundler::FileUtils
742
816
  #
743
817
  def compare_stream(a, b)
744
818
  bsize = fu_stream_blksize(a, b)
745
- sa = String.new(capacity: bsize)
746
- sb = String.new(capacity: bsize)
819
+
820
+ if RUBY_VERSION > "2.4"
821
+ sa = String.new(capacity: bsize)
822
+ sb = String.new(capacity: bsize)
823
+ else
824
+ sa = String.new
825
+ sb = String.new
826
+ end
827
+
747
828
  begin
748
829
  a.read(bsize, sa)
749
830
  b.read(bsize, sb)
@@ -1001,11 +1082,6 @@ module Bundler::FileUtils
1001
1082
  end
1002
1083
  module_function :chown_R
1003
1084
 
1004
- begin
1005
- require 'etc'
1006
- rescue LoadError # rescue LoadError for miniruby
1007
- end
1008
-
1009
1085
  def fu_get_uid(user) #:nodoc:
1010
1086
  return nil unless user
1011
1087
  case user
@@ -1014,6 +1090,7 @@ module Bundler::FileUtils
1014
1090
  when /\A\d+\z/
1015
1091
  user.to_i
1016
1092
  else
1093
+ require 'etc'
1017
1094
  Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
1018
1095
  end
1019
1096
  end
@@ -1027,6 +1104,7 @@ module Bundler::FileUtils
1027
1104
  when /\A\d+\z/
1028
1105
  group.to_i
1029
1106
  else
1107
+ require 'etc'
1030
1108
  Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
1031
1109
  end
1032
1110
  end
@@ -1067,8 +1145,11 @@ module Bundler::FileUtils
1067
1145
  module StreamUtils_
1068
1146
  private
1069
1147
 
1070
- def fu_windows?
1071
- /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
1148
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
1149
+ when /mswin|mingw/
1150
+ def fu_windows?; true end
1151
+ else
1152
+ def fu_windows?; false end
1072
1153
  end
1073
1154
 
1074
1155
  def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
@@ -1193,9 +1274,15 @@ module Bundler::FileUtils
1193
1274
  def entries
1194
1275
  opts = {}
1195
1276
  opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
1196
- Dir.entries(path(), opts)\
1197
- .reject {|n| n == '.' or n == '..' }\
1198
- .map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
1277
+
1278
+ files = if Dir.respond_to?(:children)
1279
+ Dir.children(path, opts)
1280
+ else
1281
+ Dir.entries(path(), opts)
1282
+ .reject {|n| n == '.' or n == '..' }
1283
+ end
1284
+
1285
+ files.map {|n| Entry_.new(prefix(), join(rel(), n.untaint)) }
1199
1286
  end
1200
1287
 
1201
1288
  def stat
@@ -1250,6 +1337,22 @@ module Bundler::FileUtils
1250
1337
  end
1251
1338
  end
1252
1339
 
1340
+ def link(dest)
1341
+ case
1342
+ when directory?
1343
+ if !File.exist?(dest) and descendant_directory?(dest, path)
1344
+ raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
1345
+ end
1346
+ begin
1347
+ Dir.mkdir dest
1348
+ rescue
1349
+ raise unless File.directory?(dest)
1350
+ end
1351
+ else
1352
+ File.link path(), dest
1353
+ end
1354
+ end
1355
+
1253
1356
  def copy(dest)
1254
1357
  lstat
1255
1358
  case