bundler 1.17.0.pre.2 → 2.1.0.pre.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 (218) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +769 -570
  3. data/LICENSE.md +18 -19
  4. data/README.md +9 -8
  5. data/bundler.gemspec +12 -23
  6. data/exe/bundle +19 -3
  7. data/lib/bundler.rb +121 -68
  8. data/lib/bundler/build_metadata.rb +14 -7
  9. data/lib/bundler/capistrano.rb +4 -4
  10. data/lib/bundler/cli.rb +129 -121
  11. data/lib/bundler/cli/add.rb +27 -16
  12. data/lib/bundler/cli/common.rb +11 -12
  13. data/lib/bundler/cli/config.rb +161 -86
  14. data/lib/bundler/cli/console.rb +1 -1
  15. data/lib/bundler/cli/doctor.rb +4 -4
  16. data/lib/bundler/cli/exec.rb +4 -9
  17. data/lib/bundler/cli/gem.rb +5 -5
  18. data/lib/bundler/cli/info.rb +17 -5
  19. data/lib/bundler/cli/init.rb +1 -1
  20. data/lib/bundler/cli/install.rb +11 -10
  21. data/lib/bundler/cli/issue.rb +3 -3
  22. data/lib/bundler/cli/open.rb +10 -6
  23. data/lib/bundler/cli/outdated.rb +85 -81
  24. data/lib/bundler/cli/package.rb +8 -9
  25. data/lib/bundler/cli/plugin.rb +9 -2
  26. data/lib/bundler/cli/pristine.rb +1 -1
  27. data/lib/bundler/cli/show.rb +1 -1
  28. data/lib/bundler/cli/update.rb +31 -11
  29. data/lib/bundler/compact_index_client.rb +25 -9
  30. data/lib/bundler/compact_index_client/updater.rb +2 -6
  31. data/lib/bundler/current_ruby.rb +9 -7
  32. data/lib/bundler/definition.rb +35 -26
  33. data/lib/bundler/dependency.rb +16 -4
  34. data/lib/bundler/deployment.rb +1 -1
  35. data/lib/bundler/dsl.rb +15 -39
  36. data/lib/bundler/env.rb +8 -13
  37. data/lib/bundler/environment_preserver.rb +0 -1
  38. data/lib/bundler/feature_flag.rb +23 -32
  39. data/lib/bundler/fetcher.rb +14 -11
  40. data/lib/bundler/fetcher/compact_index.rb +26 -12
  41. data/lib/bundler/fetcher/dependency.rb +1 -1
  42. data/lib/bundler/fetcher/downloader.rb +4 -1
  43. data/lib/bundler/fetcher/index.rb +4 -2
  44. data/lib/bundler/friendly_errors.rb +4 -5
  45. data/lib/bundler/gem_helper.rb +39 -24
  46. data/lib/bundler/gem_helpers.rb +2 -4
  47. data/lib/bundler/gem_tasks.rb +1 -1
  48. data/lib/bundler/gem_version_promoter.rb +3 -3
  49. data/lib/bundler/graph.rb +2 -2
  50. data/lib/bundler/injector.rb +10 -8
  51. data/lib/bundler/inline.rb +19 -18
  52. data/lib/bundler/installer.rb +7 -14
  53. data/lib/bundler/installer/gem_installer.rb +5 -1
  54. data/lib/bundler/installer/parallel_installer.rb +4 -8
  55. data/lib/bundler/installer/standalone.rb +1 -2
  56. data/lib/bundler/lazy_specification.rb +2 -2
  57. data/lib/bundler/lockfile_parser.rb +13 -21
  58. data/lib/bundler/match_platform.rb +1 -1
  59. data/lib/bundler/plugin.rb +42 -29
  60. data/lib/bundler/plugin/api.rb +1 -1
  61. data/lib/bundler/plugin/api/source.rb +2 -2
  62. data/lib/bundler/plugin/index.rb +14 -3
  63. data/lib/bundler/plugin/installer.rb +28 -15
  64. data/lib/bundler/psyched_yaml.rb +1 -1
  65. data/lib/bundler/resolver.rb +72 -24
  66. data/lib/bundler/resolver/spec_group.rb +3 -2
  67. data/lib/bundler/retry.rb +2 -2
  68. data/lib/bundler/ruby_version.rb +4 -19
  69. data/lib/bundler/rubygems_ext.rb +10 -66
  70. data/lib/bundler/rubygems_gem_installer.rb +1 -1
  71. data/lib/bundler/rubygems_integration.rb +144 -395
  72. data/lib/bundler/runtime.rb +2 -9
  73. data/lib/bundler/settings.rb +15 -47
  74. data/lib/bundler/setup.rb +6 -5
  75. data/lib/bundler/shared_helpers.rb +64 -67
  76. data/lib/bundler/similarity_detector.rb +2 -2
  77. data/lib/bundler/source.rb +5 -5
  78. data/lib/bundler/source/git.rb +19 -12
  79. data/lib/bundler/source/git/git_proxy.rb +35 -39
  80. data/lib/bundler/source/metadata.rb +9 -5
  81. data/lib/bundler/source/path.rb +13 -8
  82. data/lib/bundler/source/rubygems.rb +11 -5
  83. data/lib/bundler/source/rubygems/remote.rb +1 -2
  84. data/lib/bundler/source_list.rb +9 -12
  85. data/lib/bundler/spec_set.rb +23 -12
  86. data/lib/bundler/stub_specification.rb +18 -30
  87. data/lib/bundler/templates/Executable.bundler +23 -14
  88. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
  89. data/lib/bundler/templates/newgem/Gemfile.tt +8 -2
  90. data/lib/bundler/templates/newgem/README.md.tt +4 -3
  91. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -27
  92. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +1 -1
  93. data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
  94. data/lib/bundler/ui.rb +3 -3
  95. data/lib/bundler/ui/rg_proxy.rb +1 -1
  96. data/lib/bundler/ui/shell.rb +4 -8
  97. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  98. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  99. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  101. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +151 -48
  102. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  103. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
  104. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  105. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  107. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  108. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  109. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
  110. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  111. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  112. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  115. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
  116. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +248 -279
  117. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  118. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  119. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  120. data/lib/bundler/vendor/thor/lib/thor.rb +7 -2
  121. data/lib/bundler/vendor/thor/lib/thor/actions.rb +21 -11
  122. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  123. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  124. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
  125. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +11 -2
  126. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -1
  127. data/lib/bundler/vendor/thor/lib/thor/base.rb +16 -17
  128. data/lib/bundler/vendor/thor/lib/thor/error.rb +82 -0
  129. data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
  130. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  131. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  132. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +7 -2
  133. data/lib/bundler/vendor/thor/lib/thor/runner.rb +6 -6
  134. data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
  135. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +52 -7
  136. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
  137. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
  138. data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
  139. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  140. data/lib/bundler/vendored_fileutils.rb +1 -6
  141. data/lib/bundler/vendored_molinillo.rb +1 -1
  142. data/lib/bundler/vendored_persistent.rb +7 -5
  143. data/lib/bundler/vendored_thor.rb +2 -2
  144. data/lib/bundler/version.rb +1 -20
  145. data/lib/bundler/version_ranges.rb +51 -5
  146. data/lib/bundler/vlad.rb +2 -2
  147. data/lib/bundler/worker.rb +1 -3
  148. data/lib/bundler/yaml_serializer.rb +2 -3
  149. data/man/bundle-add.1 +10 -2
  150. data/man/bundle-add.1.txt +11 -5
  151. data/man/bundle-add.ronn +7 -1
  152. data/man/bundle-binstubs.1 +2 -2
  153. data/man/bundle-binstubs.1.txt +2 -2
  154. data/man/bundle-binstubs.ronn +1 -1
  155. data/man/bundle-check.1 +1 -1
  156. data/man/bundle-check.1.txt +6 -6
  157. data/man/bundle-clean.1 +1 -1
  158. data/man/bundle-clean.1.txt +1 -1
  159. data/man/bundle-config.1 +52 -36
  160. data/man/bundle-config.1.txt +82 -67
  161. data/man/bundle-config.ronn +56 -40
  162. data/man/bundle-doctor.1 +1 -1
  163. data/man/bundle-doctor.1.txt +1 -1
  164. data/man/bundle-exec.1 +2 -2
  165. data/man/bundle-exec.1.txt +2 -2
  166. data/man/bundle-exec.ronn +1 -1
  167. data/man/bundle-gem.1 +1 -1
  168. data/man/bundle-gem.1.txt +3 -3
  169. data/man/bundle-info.1 +1 -1
  170. data/man/bundle-info.1.txt +1 -1
  171. data/man/bundle-init.1 +2 -2
  172. data/man/bundle-init.1.txt +2 -2
  173. data/man/bundle-init.ronn +1 -1
  174. data/man/bundle-inject.1 +1 -1
  175. data/man/bundle-inject.1.txt +1 -1
  176. data/man/bundle-install.1 +8 -5
  177. data/man/bundle-install.1.txt +56 -51
  178. data/man/bundle-install.ronn +9 -4
  179. data/man/bundle-list.1 +1 -1
  180. data/man/bundle-list.1.txt +1 -1
  181. data/man/bundle-lock.1 +1 -1
  182. data/man/bundle-lock.1.txt +16 -16
  183. data/man/bundle-open.1 +1 -1
  184. data/man/bundle-open.1.txt +1 -1
  185. data/man/bundle-outdated.1 +1 -1
  186. data/man/bundle-outdated.1.txt +1 -1
  187. data/man/bundle-package.1 +1 -1
  188. data/man/bundle-package.1.txt +1 -1
  189. data/man/bundle-platform.1 +1 -1
  190. data/man/bundle-platform.1.txt +1 -1
  191. data/man/bundle-pristine.1 +1 -1
  192. data/man/bundle-pristine.1.txt +1 -1
  193. data/man/bundle-remove.1 +1 -1
  194. data/man/bundle-remove.1.txt +1 -1
  195. data/man/bundle-show.1 +1 -1
  196. data/man/bundle-show.1.txt +1 -1
  197. data/man/bundle-update.1 +4 -4
  198. data/man/bundle-update.1.txt +64 -65
  199. data/man/bundle-update.ronn +3 -3
  200. data/man/bundle-viz.1 +1 -1
  201. data/man/bundle-viz.1.txt +1 -1
  202. data/man/bundle.1 +7 -3
  203. data/man/bundle.1.txt +11 -8
  204. data/man/bundle.ronn +5 -2
  205. data/man/gemfile.5 +17 -20
  206. data/man/gemfile.5.ronn +14 -18
  207. data/man/gemfile.5.txt +108 -112
  208. metadata +17 -104
  209. data/exe/bundle_ruby +0 -60
  210. data/lib/bundler/cli/cache.rb +0 -36
  211. data/lib/bundler/compatibility_guard.rb +0 -14
  212. data/lib/bundler/ssl_certs/.document +0 -1
  213. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  214. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  215. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  216. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  217. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  218. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
@@ -0,0 +1,66 @@
1
+ # Global monotonic clock from Concurrent Ruby 1.0.
2
+ # Copyright (c) Jerry D'Antonio -- released under the MIT license.
3
+ # Slightly modified; used with permission.
4
+ # https://github.com/ruby-concurrency/concurrent-ruby
5
+
6
+ require 'thread'
7
+
8
+ class Bundler::ConnectionPool
9
+
10
+ class_definition = Class.new do
11
+
12
+ if defined?(Process::CLOCK_MONOTONIC)
13
+
14
+ # @!visibility private
15
+ def get_time
16
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
17
+ end
18
+
19
+ elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
20
+
21
+ # @!visibility private
22
+ def get_time
23
+ java.lang.System.nanoTime() / 1_000_000_000.0
24
+ end
25
+
26
+ else
27
+
28
+ # @!visibility private
29
+ def initialize
30
+ @mutex = Mutex.new
31
+ @last_time = Time.now.to_f
32
+ end
33
+
34
+ # @!visibility private
35
+ def get_time
36
+ @mutex.synchronize do
37
+ now = Time.now.to_f
38
+ if @last_time < now
39
+ @last_time = now
40
+ else # clock has moved back in time
41
+ @last_time += 0.000_001
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ ##
49
+ # Clock that cannot be set and represents monotonic time since
50
+ # some unspecified starting point.
51
+ #
52
+ # @!visibility private
53
+ GLOBAL_MONOTONIC_CLOCK = class_definition.new
54
+ private_constant :GLOBAL_MONOTONIC_CLOCK
55
+
56
+ class << self
57
+ ##
58
+ # Returns the current time a tracked by the application monotonic clock.
59
+ #
60
+ # @return [Float] The current monotonic time when `since` not given else
61
+ # the elapsed monotonic time between `since` and the current time
62
+ def monotonic_time
63
+ GLOBAL_MONOTONIC_CLOCK.get_time
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,176 @@
1
+ require 'thread'
2
+ require 'timeout'
3
+ require_relative 'monotonic_time'
4
+
5
+ ##
6
+ # Raised when you attempt to retrieve a connection from a pool that has been
7
+ # shut down.
8
+
9
+ class Bundler::ConnectionPool::PoolShuttingDownError < RuntimeError; end
10
+
11
+ ##
12
+ # The TimedStack manages a pool of homogeneous connections (or any resource
13
+ # you wish to manage). Connections are created lazily up to a given maximum
14
+ # number.
15
+
16
+ # Examples:
17
+ #
18
+ # ts = TimedStack.new(1) { MyConnection.new }
19
+ #
20
+ # # fetch a connection
21
+ # conn = ts.pop
22
+ #
23
+ # # return a connection
24
+ # ts.push conn
25
+ #
26
+ # conn = ts.pop
27
+ # ts.pop timeout: 5
28
+ # #=> raises Timeout::Error after 5 seconds
29
+
30
+ class Bundler::ConnectionPool::TimedStack
31
+ attr_reader :max
32
+
33
+ ##
34
+ # Creates a new pool with +size+ connections that are created from the given
35
+ # +block+.
36
+
37
+ def initialize(size = 0, &block)
38
+ @create_block = block
39
+ @created = 0
40
+ @que = []
41
+ @max = size
42
+ @mutex = Mutex.new
43
+ @resource = ConditionVariable.new
44
+ @shutdown_block = nil
45
+ end
46
+
47
+ ##
48
+ # Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
49
+ # used by subclasses that extend TimedStack.
50
+
51
+ def push(obj, options = {})
52
+ @mutex.synchronize do
53
+ if @shutdown_block
54
+ @shutdown_block.call(obj)
55
+ else
56
+ store_connection obj, options
57
+ end
58
+
59
+ @resource.broadcast
60
+ end
61
+ end
62
+ alias_method :<<, :push
63
+
64
+ ##
65
+ # Retrieves a connection from the stack. If a connection is available it is
66
+ # immediately returned. If no connection is available within the given
67
+ # timeout a Timeout::Error is raised.
68
+ #
69
+ # +:timeout+ is the only checked entry in +options+ and is preferred over
70
+ # the +timeout+ argument (which will be removed in a future release). Other
71
+ # options may be used by subclasses that extend TimedStack.
72
+
73
+ def pop(timeout = 0.5, options = {})
74
+ options, timeout = timeout, 0.5 if Hash === timeout
75
+ timeout = options.fetch :timeout, timeout
76
+
77
+ deadline = Bundler::ConnectionPool.monotonic_time + timeout
78
+ @mutex.synchronize do
79
+ loop do
80
+ raise Bundler::ConnectionPool::PoolShuttingDownError if @shutdown_block
81
+ return fetch_connection(options) if connection_stored?(options)
82
+
83
+ connection = try_create(options)
84
+ return connection if connection
85
+
86
+ to_wait = deadline - Bundler::ConnectionPool.monotonic_time
87
+ raise Timeout::Error, "Waited #{timeout} sec" if to_wait <= 0
88
+ @resource.wait(@mutex, to_wait)
89
+ end
90
+ end
91
+ end
92
+
93
+ ##
94
+ # Shuts down the TimedStack which prevents connections from being checked
95
+ # out. The +block+ is called once for each connection on the stack.
96
+
97
+ def shutdown(&block)
98
+ raise ArgumentError, "shutdown must receive a block" unless block_given?
99
+
100
+ @mutex.synchronize do
101
+ @shutdown_block = block
102
+ @resource.broadcast
103
+
104
+ shutdown_connections
105
+ end
106
+ end
107
+
108
+ ##
109
+ # Returns +true+ if there are no available connections.
110
+
111
+ def empty?
112
+ (@created - @que.length) >= @max
113
+ end
114
+
115
+ ##
116
+ # The number of connections available on the stack.
117
+
118
+ def length
119
+ @max - @created + @que.length
120
+ end
121
+
122
+ private
123
+
124
+ ##
125
+ # This is an extension point for TimedStack and is called with a mutex.
126
+ #
127
+ # This method must returns true if a connection is available on the stack.
128
+
129
+ def connection_stored?(options = nil)
130
+ !@que.empty?
131
+ end
132
+
133
+ ##
134
+ # This is an extension point for TimedStack and is called with a mutex.
135
+ #
136
+ # This method must return a connection from the stack.
137
+
138
+ def fetch_connection(options = nil)
139
+ @que.pop
140
+ end
141
+
142
+ ##
143
+ # This is an extension point for TimedStack and is called with a mutex.
144
+ #
145
+ # This method must shut down all connections on the stack.
146
+
147
+ def shutdown_connections(options = nil)
148
+ while connection_stored?(options)
149
+ conn = fetch_connection(options)
150
+ @shutdown_block.call(conn)
151
+ end
152
+ end
153
+
154
+ ##
155
+ # This is an extension point for TimedStack and is called with a mutex.
156
+ #
157
+ # This method must return +obj+ to the stack.
158
+
159
+ def store_connection(obj, options = nil)
160
+ @que.push obj
161
+ end
162
+
163
+ ##
164
+ # This is an extension point for TimedStack and is called with a mutex.
165
+ #
166
+ # This method must create a connection if and only if the total number of
167
+ # connections allowed has not been met.
168
+
169
+ def try_create(options = nil)
170
+ unless @created == @max
171
+ object = @create_block.call
172
+ @created += 1
173
+ object
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,3 @@
1
+ class Bundler::ConnectionPool
2
+ VERSION = "2.2.2"
3
+ end
@@ -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_relative "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