bundler 1.17.3 → 2.1.1

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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +794 -570
  3. data/LICENSE.md +18 -19
  4. data/README.md +9 -8
  5. data/bundler.gemspec +8 -25
  6. data/exe/bundle +19 -3
  7. data/lib/bundler.rb +202 -87
  8. data/lib/bundler/build_metadata.rb +3 -3
  9. data/lib/bundler/capistrano.rb +4 -4
  10. data/lib/bundler/cli.rb +178 -140
  11. data/lib/bundler/cli/add.rb +28 -16
  12. data/lib/bundler/cli/cache.rb +25 -13
  13. data/lib/bundler/cli/common.rb +11 -12
  14. data/lib/bundler/cli/config.rb +161 -86
  15. data/lib/bundler/cli/console.rb +1 -1
  16. data/lib/bundler/cli/doctor.rb +4 -4
  17. data/lib/bundler/cli/exec.rb +4 -16
  18. data/lib/bundler/cli/gem.rb +5 -5
  19. data/lib/bundler/cli/info.rb +17 -5
  20. data/lib/bundler/cli/init.rb +1 -1
  21. data/lib/bundler/cli/install.rb +11 -10
  22. data/lib/bundler/cli/issue.rb +3 -3
  23. data/lib/bundler/cli/open.rb +10 -6
  24. data/lib/bundler/cli/outdated.rb +85 -81
  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 +32 -12
  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 +16 -40
  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 -34
  39. data/lib/bundler/fetcher.rb +16 -13
  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 +5 -2
  43. data/lib/bundler/fetcher/index.rb +5 -3
  44. data/lib/bundler/friendly_errors.rb +6 -7
  45. data/lib/bundler/gem_helper.rb +40 -25
  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 +40 -30
  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 -3
  57. data/lib/bundler/lockfile_parser.rb +14 -21
  58. data/lib/bundler/match_platform.rb +1 -1
  59. data/lib/bundler/mirror.rb +3 -3
  60. data/lib/bundler/plugin.rb +42 -29
  61. data/lib/bundler/plugin/api.rb +1 -1
  62. data/lib/bundler/plugin/api/source.rb +4 -6
  63. data/lib/bundler/plugin/index.rb +14 -3
  64. data/lib/bundler/plugin/installer.rb +28 -15
  65. data/lib/bundler/psyched_yaml.rb +1 -1
  66. data/lib/bundler/remote_specification.rb +0 -2
  67. data/lib/bundler/resolver.rb +72 -24
  68. data/lib/bundler/resolver/spec_group.rb +3 -2
  69. data/lib/bundler/retry.rb +2 -2
  70. data/lib/bundler/ruby_version.rb +4 -19
  71. data/lib/bundler/rubygems_ext.rb +11 -67
  72. data/lib/bundler/rubygems_gem_installer.rb +1 -8
  73. data/lib/bundler/rubygems_integration.rb +148 -400
  74. data/lib/bundler/runtime.rb +2 -9
  75. data/lib/bundler/settings.rb +22 -51
  76. data/lib/bundler/setup.rb +11 -12
  77. data/lib/bundler/shared_helpers.rb +51 -77
  78. data/lib/bundler/similarity_detector.rb +2 -2
  79. data/lib/bundler/source.rb +5 -5
  80. data/lib/bundler/source/git.rb +24 -17
  81. data/lib/bundler/source/git/git_proxy.rb +38 -41
  82. data/lib/bundler/source/metadata.rb +7 -2
  83. data/lib/bundler/source/path.rb +13 -8
  84. data/lib/bundler/source/rubygems.rb +14 -8
  85. data/lib/bundler/source/rubygems/remote.rb +2 -3
  86. data/lib/bundler/source_list.rb +9 -12
  87. data/lib/bundler/spec_set.rb +23 -12
  88. data/lib/bundler/stub_specification.rb +18 -30
  89. data/lib/bundler/templates/Executable.bundler +23 -14
  90. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
  91. data/lib/bundler/templates/newgem/Gemfile.tt +8 -2
  92. data/lib/bundler/templates/newgem/README.md.tt +4 -3
  93. data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -27
  94. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +1 -1
  95. data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
  96. data/lib/bundler/ui.rb +3 -3
  97. data/lib/bundler/ui/rg_proxy.rb +1 -1
  98. data/lib/bundler/ui/shell.rb +4 -8
  99. data/lib/bundler/uri_credentials_filter.rb +7 -3
  100. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
  101. data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
  102. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
  103. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
  104. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +273 -147
  105. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
  106. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
  107. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
  108. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
  109. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
  110. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
  111. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
  112. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
  113. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
  114. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
  115. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
  116. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
  117. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
  118. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +273 -304
  119. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
  120. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
  121. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  122. data/lib/bundler/vendor/thor/lib/thor.rb +19 -4
  123. data/lib/bundler/vendor/thor/lib/thor/actions.rb +27 -12
  124. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
  125. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
  126. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +7 -17
  127. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +16 -7
  128. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +19 -8
  129. data/lib/bundler/vendor/thor/lib/thor/base.rb +54 -43
  130. data/lib/bundler/vendor/thor/lib/thor/command.rb +21 -14
  131. data/lib/bundler/vendor/thor/lib/thor/error.rb +78 -0
  132. data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
  133. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -0
  134. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
  135. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +1 -1
  136. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
  137. data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
  138. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
  139. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +2 -2
  140. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +20 -7
  141. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +20 -5
  142. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
  143. data/lib/bundler/vendor/thor/lib/thor/runner.rb +15 -14
  144. data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
  145. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +62 -8
  146. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +6 -2
  147. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -3
  148. data/lib/bundler/vendor/thor/lib/thor/util.rb +18 -2
  149. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  150. data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
  151. data/lib/bundler/vendor/uri/lib/uri/common.rb +744 -0
  152. data/lib/bundler/vendor/uri/lib/uri/file.rb +94 -0
  153. data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
  154. data/lib/bundler/vendor/uri/lib/uri/generic.rb +1568 -0
  155. data/lib/bundler/vendor/uri/lib/uri/http.rb +88 -0
  156. data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
  157. data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
  158. data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +21 -0
  159. data/lib/bundler/vendor/uri/lib/uri/mailto.rb +294 -0
  160. data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
  161. data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +125 -0
  162. data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
  163. data/lib/bundler/vendored_fileutils.rb +1 -6
  164. data/lib/bundler/vendored_molinillo.rb +1 -1
  165. data/lib/bundler/vendored_persistent.rb +7 -5
  166. data/lib/bundler/vendored_thor.rb +2 -2
  167. data/lib/bundler/vendored_uri.rb +4 -0
  168. data/lib/bundler/version.rb +1 -20
  169. data/lib/bundler/version_ranges.rb +51 -5
  170. data/lib/bundler/vlad.rb +2 -2
  171. data/lib/bundler/worker.rb +1 -3
  172. data/lib/bundler/yaml_serializer.rb +2 -3
  173. data/man/bundle-add.1 +10 -2
  174. data/man/bundle-add.1.txt +11 -5
  175. data/man/bundle-add.ronn +7 -1
  176. data/man/bundle-binstubs.1 +2 -2
  177. data/man/bundle-binstubs.1.txt +2 -2
  178. data/man/bundle-binstubs.ronn +1 -1
  179. data/man/bundle-cache.1 +55 -0
  180. data/man/bundle-cache.1.txt +78 -0
  181. data/man/{bundle-package.ronn → bundle-cache.ronn} +15 -15
  182. data/man/bundle-check.1 +1 -1
  183. data/man/bundle-check.1.txt +6 -6
  184. data/man/bundle-clean.1 +1 -1
  185. data/man/bundle-clean.1.txt +1 -1
  186. data/man/bundle-config.1 +36 -36
  187. data/man/bundle-config.1.txt +66 -67
  188. data/man/bundle-config.ronn +42 -40
  189. data/man/bundle-doctor.1 +1 -1
  190. data/man/bundle-doctor.1.txt +1 -1
  191. data/man/bundle-exec.1 +2 -2
  192. data/man/bundle-exec.1.txt +2 -2
  193. data/man/bundle-exec.ronn +1 -1
  194. data/man/bundle-gem.1 +1 -1
  195. data/man/bundle-gem.1.txt +3 -3
  196. data/man/bundle-info.1 +1 -1
  197. data/man/bundle-info.1.txt +1 -1
  198. data/man/bundle-init.1 +2 -2
  199. data/man/bundle-init.1.txt +2 -2
  200. data/man/bundle-init.ronn +1 -1
  201. data/man/bundle-inject.1 +1 -1
  202. data/man/bundle-inject.1.txt +1 -1
  203. data/man/bundle-install.1 +8 -5
  204. data/man/bundle-install.1.txt +56 -51
  205. data/man/bundle-install.ronn +9 -4
  206. data/man/bundle-list.1 +1 -1
  207. data/man/bundle-list.1.txt +1 -1
  208. data/man/bundle-lock.1 +1 -1
  209. data/man/bundle-lock.1.txt +16 -16
  210. data/man/bundle-open.1 +1 -1
  211. data/man/bundle-open.1.txt +1 -1
  212. data/man/bundle-outdated.1 +1 -1
  213. data/man/bundle-outdated.1.txt +1 -1
  214. data/man/bundle-platform.1 +1 -1
  215. data/man/bundle-platform.1.txt +1 -1
  216. data/man/bundle-pristine.1 +1 -1
  217. data/man/bundle-pristine.1.txt +1 -1
  218. data/man/bundle-remove.1 +1 -1
  219. data/man/bundle-remove.1.txt +1 -1
  220. data/man/bundle-show.1 +1 -1
  221. data/man/bundle-show.1.txt +1 -1
  222. data/man/bundle-update.1 +4 -4
  223. data/man/bundle-update.1.txt +64 -65
  224. data/man/bundle-update.ronn +3 -3
  225. data/man/bundle-viz.1 +1 -1
  226. data/man/bundle-viz.1.txt +1 -1
  227. data/man/bundle.1 +3 -3
  228. data/man/bundle.1.txt +8 -8
  229. data/man/bundle.ronn +2 -2
  230. data/man/gemfile.5 +17 -20
  231. data/man/gemfile.5.ronn +14 -18
  232. data/man/gemfile.5.txt +108 -112
  233. data/man/index.txt +1 -1
  234. metadata +34 -110
  235. data/exe/bundle_ruby +0 -60
  236. data/lib/bundler/cli/package.rb +0 -49
  237. data/lib/bundler/compatibility_guard.rb +0 -14
  238. data/lib/bundler/gem_remote_fetcher.rb +0 -43
  239. data/lib/bundler/ssl_certs/.document +0 -1
  240. data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
  241. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
  242. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
  243. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
  244. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
  245. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +0 -129
  246. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +0 -12
  247. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -129
  248. data/man/bundle-package.1 +0 -55
  249. data/man/bundle-package.1.txt +0 -79
@@ -7,7 +7,11 @@ module Bundler
7
7
  def credential_filtered_uri(uri_to_anonymize)
8
8
  return uri_to_anonymize if uri_to_anonymize.nil?
9
9
  uri = uri_to_anonymize.dup
10
- uri = URI(uri.to_s) unless uri.is_a?(URI)
10
+ if uri.is_a?(String)
11
+ require_relative "vendored_uri"
12
+ uri = Bundler::URI(uri)
13
+ end
14
+
11
15
  if uri.userinfo
12
16
  # oauth authentication
13
17
  if uri.password == "x-oauth-basic" || uri.password == "x"
@@ -17,9 +21,9 @@ module Bundler
17
21
  end
18
22
  uri.password = nil
19
23
  end
20
- return uri if uri_to_anonymize.is_a?(URI)
21
24
  return uri.to_s if uri_to_anonymize.is_a?(String)
22
- rescue URI::InvalidURIError # uri is not canonical uri scheme
25
+ uri
26
+ rescue Bundler::URI::InvalidURIError # uri is not canonical uri scheme
23
27
  uri
24
28
  end
25
29
 
@@ -0,0 +1,161 @@
1
+ require_relative 'connection_pool/version'
2
+ require_relative 'connection_pool/timed_stack'
3
+
4
+
5
+ # Generic connection pool class for e.g. sharing a limited number of network connections
6
+ # among many threads. Note: Connections are lazily created.
7
+ #
8
+ # Example usage with block (faster):
9
+ #
10
+ # @pool = Bundler::ConnectionPool.new { Redis.new }
11
+ #
12
+ # @pool.with do |redis|
13
+ # redis.lpop('my-list') if redis.llen('my-list') > 0
14
+ # end
15
+ #
16
+ # Using optional timeout override (for that single invocation)
17
+ #
18
+ # @pool.with(timeout: 2.0) do |redis|
19
+ # redis.lpop('my-list') if redis.llen('my-list') > 0
20
+ # end
21
+ #
22
+ # Example usage replacing an existing connection (slower):
23
+ #
24
+ # $redis = Bundler::ConnectionPool.wrap { Redis.new }
25
+ #
26
+ # def do_work
27
+ # $redis.lpop('my-list') if $redis.llen('my-list') > 0
28
+ # end
29
+ #
30
+ # Accepts the following options:
31
+ # - :size - number of connections to pool, defaults to 5
32
+ # - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
33
+ #
34
+ class Bundler::ConnectionPool
35
+ DEFAULTS = {size: 5, timeout: 5}
36
+
37
+ class Error < RuntimeError
38
+ end
39
+
40
+ def self.wrap(options, &block)
41
+ Wrapper.new(options, &block)
42
+ end
43
+
44
+ def initialize(options = {}, &block)
45
+ raise ArgumentError, 'Connection pool requires a block' unless block
46
+
47
+ options = DEFAULTS.merge(options)
48
+
49
+ @size = options.fetch(:size)
50
+ @timeout = options.fetch(:timeout)
51
+
52
+ @available = TimedStack.new(@size, &block)
53
+ @key = :"current-#{@available.object_id}"
54
+ @key_count = :"current-#{@available.object_id}-count"
55
+ end
56
+
57
+ if Thread.respond_to?(:handle_interrupt)
58
+
59
+ # MRI
60
+ def with(options = {})
61
+ Thread.handle_interrupt(Exception => :never) do
62
+ conn = checkout(options)
63
+ begin
64
+ Thread.handle_interrupt(Exception => :immediate) do
65
+ yield conn
66
+ end
67
+ ensure
68
+ checkin
69
+ end
70
+ end
71
+ end
72
+
73
+ else
74
+
75
+ # jruby 1.7.x
76
+ def with(options = {})
77
+ conn = checkout(options)
78
+ begin
79
+ yield conn
80
+ ensure
81
+ checkin
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ def checkout(options = {})
88
+ if ::Thread.current[@key]
89
+ ::Thread.current[@key_count]+= 1
90
+ ::Thread.current[@key]
91
+ else
92
+ ::Thread.current[@key_count]= 1
93
+ ::Thread.current[@key]= @available.pop(options[:timeout] || @timeout)
94
+ end
95
+ end
96
+
97
+ def checkin
98
+ if ::Thread.current[@key]
99
+ if ::Thread.current[@key_count] == 1
100
+ @available.push(::Thread.current[@key])
101
+ ::Thread.current[@key]= nil
102
+ else
103
+ ::Thread.current[@key_count]-= 1
104
+ end
105
+ else
106
+ raise Bundler::ConnectionPool::Error, 'no connections are checked out'
107
+ end
108
+
109
+ nil
110
+ end
111
+
112
+ def shutdown(&block)
113
+ @available.shutdown(&block)
114
+ end
115
+
116
+ # Size of this connection pool
117
+ def size
118
+ @size
119
+ end
120
+
121
+ # Number of pool entries available for checkout at this instant.
122
+ def available
123
+ @available.length
124
+ end
125
+
126
+ private
127
+
128
+ class Wrapper < ::BasicObject
129
+ METHODS = [:with, :pool_shutdown]
130
+
131
+ def initialize(options = {}, &block)
132
+ @pool = options.fetch(:pool) { ::Bundler::ConnectionPool.new(options, &block) }
133
+ end
134
+
135
+ def with(&block)
136
+ @pool.with(&block)
137
+ end
138
+
139
+ def pool_shutdown(&block)
140
+ @pool.shutdown(&block)
141
+ end
142
+
143
+ def pool_size
144
+ @pool.size
145
+ end
146
+
147
+ def pool_available
148
+ @pool.available
149
+ end
150
+
151
+ def respond_to?(id, *args)
152
+ METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
153
+ end
154
+
155
+ def method_missing(name, *args, &block)
156
+ with do |connection|
157
+ connection.send(name, *args, &block)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -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,11 @@
1
1
  # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'rbconfig'
5
+ rescue LoadError
6
+ # for make mjit-headers
7
+ end
8
+
2
9
  #
3
10
  # = fileutils.rb
4
11
  #
@@ -15,48 +22,58 @@
15
22
  #
16
23
  # require 'bundler/vendor/fileutils/lib/fileutils'
17
24
  #
18
- # Bundler::FileUtils.cd(dir, options)
19
- # Bundler::FileUtils.cd(dir, options) {|dir| block }
25
+ # Bundler::FileUtils.cd(dir, **options)
26
+ # Bundler::FileUtils.cd(dir, **options) {|dir| block }
20
27
  # Bundler::FileUtils.pwd()
21
- # Bundler::FileUtils.mkdir(dir, options)
22
- # Bundler::FileUtils.mkdir(list, options)
23
- # Bundler::FileUtils.mkdir_p(dir, options)
24
- # Bundler::FileUtils.mkdir_p(list, options)
25
- # Bundler::FileUtils.rmdir(dir, options)
26
- # Bundler::FileUtils.rmdir(list, options)
27
- # Bundler::FileUtils.ln(target, link, options)
28
- # Bundler::FileUtils.ln(targets, dir, options)
29
- # Bundler::FileUtils.ln_s(target, link, options)
30
- # Bundler::FileUtils.ln_s(targets, dir, options)
31
- # Bundler::FileUtils.ln_sf(target, link, options)
32
- # Bundler::FileUtils.cp(src, dest, options)
33
- # Bundler::FileUtils.cp(list, dir, options)
34
- # Bundler::FileUtils.cp_r(src, dest, options)
35
- # Bundler::FileUtils.cp_r(list, dir, options)
36
- # Bundler::FileUtils.mv(src, dest, options)
37
- # Bundler::FileUtils.mv(list, dir, options)
38
- # Bundler::FileUtils.rm(list, options)
39
- # Bundler::FileUtils.rm_r(list, options)
40
- # Bundler::FileUtils.rm_rf(list, options)
41
- # Bundler::FileUtils.install(src, dest, options)
42
- # Bundler::FileUtils.chmod(mode, list, options)
43
- # Bundler::FileUtils.chmod_R(mode, list, options)
44
- # Bundler::FileUtils.chown(user, group, list, options)
45
- # Bundler::FileUtils.chown_R(user, group, list, options)
46
- # Bundler::FileUtils.touch(list, options)
28
+ # Bundler::FileUtils.mkdir(dir, **options)
29
+ # Bundler::FileUtils.mkdir(list, **options)
30
+ # Bundler::FileUtils.mkdir_p(dir, **options)
31
+ # Bundler::FileUtils.mkdir_p(list, **options)
32
+ # Bundler::FileUtils.rmdir(dir, **options)
33
+ # Bundler::FileUtils.rmdir(list, **options)
34
+ # Bundler::FileUtils.ln(target, link, **options)
35
+ # Bundler::FileUtils.ln(targets, dir, **options)
36
+ # Bundler::FileUtils.ln_s(target, link, **options)
37
+ # Bundler::FileUtils.ln_s(targets, dir, **options)
38
+ # Bundler::FileUtils.ln_sf(target, link, **options)
39
+ # Bundler::FileUtils.cp(src, dest, **options)
40
+ # Bundler::FileUtils.cp(list, dir, **options)
41
+ # Bundler::FileUtils.cp_r(src, dest, **options)
42
+ # Bundler::FileUtils.cp_r(list, dir, **options)
43
+ # Bundler::FileUtils.mv(src, dest, **options)
44
+ # Bundler::FileUtils.mv(list, dir, **options)
45
+ # Bundler::FileUtils.rm(list, **options)
46
+ # Bundler::FileUtils.rm_r(list, **options)
47
+ # Bundler::FileUtils.rm_rf(list, **options)
48
+ # Bundler::FileUtils.install(src, dest, **options)
49
+ # Bundler::FileUtils.chmod(mode, list, **options)
50
+ # Bundler::FileUtils.chmod_R(mode, list, **options)
51
+ # Bundler::FileUtils.chown(user, group, list, **options)
52
+ # Bundler::FileUtils.chown_R(user, group, list, **options)
53
+ # Bundler::FileUtils.touch(list, **options)
54
+ #
55
+ # Possible <tt>options</tt> are:
47
56
  #
48
- # The <tt>options</tt> parameter is a hash of options, taken from the list
49
- # <tt>:force</tt>, <tt>:noop</tt>, <tt>:preserve</tt>, and <tt>:verbose</tt>.
50
- # <tt>:noop</tt> means that no changes are made. The other three are obvious.
51
- # Each method documents the options that it honours.
57
+ # <tt>:force</tt> :: forced operation (rewrite files if exist, remove
58
+ # directories if not empty, etc.);
59
+ # <tt>:verbose</tt> :: print command to be run, in bash syntax, before
60
+ # performing it;
61
+ # <tt>:preserve</tt> :: preserve object's group, user and modification
62
+ # time on copying;
63
+ # <tt>:noop</tt> :: no changes are made (usable in combination with
64
+ # <tt>:verbose</tt> which will print the command to run)
65
+ #
66
+ # Each method documents the options that it honours. See also ::commands,
67
+ # ::options and ::options_of methods to introspect which command have which
68
+ # options.
52
69
  #
53
70
  # All methods that have the concept of a "source" file or directory can take
54
71
  # either one file or a list of files in that argument. See the method
55
72
  # documentation for examples.
56
73
  #
57
- # There are some `low level' methods, which do not accept any option:
74
+ # There are some `low level' methods, which do not accept keyword arguments:
58
75
  #
59
- # Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference = false)
76
+ # Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
60
77
  # Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
61
78
  # Bundler::FileUtils.copy_stream(srcstream, deststream)
62
79
  # Bundler::FileUtils.remove_entry(path, force = false)
@@ -84,8 +101,8 @@
84
101
  # files/directories. This equates to passing the <tt>:noop</tt> and
85
102
  # <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
86
103
  #
87
-
88
104
  module Bundler::FileUtils
105
+ VERSION = "1.4.1"
89
106
 
90
107
  def self.private_module_function(name) #:nodoc:
91
108
  module_function name
@@ -106,19 +123,22 @@ module Bundler::FileUtils
106
123
  #
107
124
  # Changes the current directory to the directory +dir+.
108
125
  #
109
- # If this method is called with block, resumes to the old
110
- # working directory after the block execution finished.
126
+ # If this method is called with block, resumes to the previous
127
+ # working directory after the block execution has finished.
128
+ #
129
+ # Bundler::FileUtils.cd('/') # change directory
111
130
  #
112
- # Bundler::FileUtils.cd('/', :verbose => true) # chdir and report it
131
+ # Bundler::FileUtils.cd('/', verbose: true) # change directory and report it
113
132
  #
114
- # Bundler::FileUtils.cd('/') do # chdir
133
+ # Bundler::FileUtils.cd('/') do # change directory
115
134
  # # ... # do something
116
135
  # end # return to original directory
117
136
  #
118
137
  def cd(dir, verbose: nil, &block) # :yield: dir
119
138
  fu_output_message "cd #{dir}" if verbose
120
- Dir.chdir(dir, &block)
139
+ result = Dir.chdir(dir, &block)
121
140
  fu_output_message 'cd -' if verbose and block
141
+ result
122
142
  end
123
143
  module_function :cd
124
144
 
@@ -153,9 +173,9 @@ module Bundler::FileUtils
153
173
  # Creates one or more directories.
154
174
  #
155
175
  # Bundler::FileUtils.mkdir 'test'
156
- # Bundler::FileUtils.mkdir %w( tmp data )
157
- # Bundler::FileUtils.mkdir 'notexist', :noop => true # Does not really create.
158
- # Bundler::FileUtils.mkdir 'tmp', :mode => 0700
176
+ # Bundler::FileUtils.mkdir %w(tmp data)
177
+ # Bundler::FileUtils.mkdir 'notexist', noop: true # Does not really create.
178
+ # Bundler::FileUtils.mkdir 'tmp', mode: 0700
159
179
  #
160
180
  def mkdir(list, mode: nil, noop: nil, verbose: nil)
161
181
  list = fu_list(list)
@@ -174,7 +194,7 @@ module Bundler::FileUtils
174
194
  #
175
195
  # Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby'
176
196
  #
177
- # causes to make following directories, if it does not exist.
197
+ # causes to make following directories, if they do not exist.
178
198
  #
179
199
  # * /usr
180
200
  # * /usr/local
@@ -238,22 +258,22 @@ module Bundler::FileUtils
238
258
  # Bundler::FileUtils.rmdir 'somedir'
239
259
  # Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
240
260
  # # Does not really remove directory; outputs message.
241
- # Bundler::FileUtils.rmdir 'somedir', :verbose => true, :noop => true
261
+ # Bundler::FileUtils.rmdir 'somedir', verbose: true, noop: true
242
262
  #
243
263
  def rmdir(list, parents: nil, noop: nil, verbose: nil)
244
264
  list = fu_list(list)
245
265
  fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
246
266
  return if noop
247
267
  list.each do |dir|
248
- begin
249
- Dir.rmdir(dir = remove_trailing_slash(dir))
250
- if parents
268
+ Dir.rmdir(dir = remove_trailing_slash(dir))
269
+ if parents
270
+ begin
251
271
  until (parent = File.dirname(dir)) == '.' or parent == dir
252
272
  dir = parent
253
273
  Dir.rmdir(dir)
254
274
  end
275
+ rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
255
276
  end
256
- rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
257
277
  end
258
278
  end
259
279
  end
@@ -267,7 +287,7 @@ module Bundler::FileUtils
267
287
  #
268
288
  # In the first form, creates a hard link +link+ which points to +target+.
269
289
  # If +link+ already exists, raises Errno::EEXIST.
270
- # But if the :force option is set, overwrites +link+.
290
+ # But if the +force+ option is set, overwrites +link+.
271
291
  #
272
292
  # Bundler::FileUtils.ln 'gcc', 'cc', verbose: true
273
293
  # Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
@@ -293,6 +313,39 @@ module Bundler::FileUtils
293
313
  alias link ln
294
314
  module_function :link
295
315
 
316
+ #
317
+ # Hard link +src+ to +dest+. If +src+ is a directory, this method links
318
+ # all its contents recursively. If +dest+ is a directory, links
319
+ # +src+ to +dest/src+.
320
+ #
321
+ # +src+ can be a list of files.
322
+ #
323
+ # If +dereference_root+ is true, this method dereference tree root.
324
+ #
325
+ # If +remove_destination+ is true, this method removes each destination file before copy.
326
+ #
327
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
328
+ # Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
329
+ #
330
+ # # Examples of linking several files to target directory.
331
+ # Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
332
+ # Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
333
+ #
334
+ # # If you want to link all contents of a directory instead of the
335
+ # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
336
+ # # use the following code.
337
+ # Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
338
+ #
339
+ def cp_lr(src, dest, noop: nil, verbose: nil,
340
+ dereference_root: true, remove_destination: false)
341
+ fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
342
+ return if noop
343
+ fu_each_src_dest(src, dest) do |s, d|
344
+ link_entry s, d, dereference_root, remove_destination
345
+ end
346
+ end
347
+ module_function :cp_lr
348
+
296
349
  #
297
350
  # :call-seq:
298
351
  # Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
@@ -301,7 +354,7 @@ module Bundler::FileUtils
301
354
  #
302
355
  # In the first form, creates a symbolic link +link+ which points to +target+.
303
356
  # If +link+ already exists, raises Errno::EEXIST.
304
- # But if the :force option is set, overwrites +link+.
357
+ # But if the <tt>force</tt> option is set, overwrites +link+.
305
358
  #
306
359
  # Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
307
360
  # Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
@@ -339,6 +392,26 @@ module Bundler::FileUtils
339
392
  end
340
393
  module_function :ln_sf
341
394
 
395
+ #
396
+ # Hard links a file system entry +src+ to +dest+.
397
+ # If +src+ is a directory, this method links its contents recursively.
398
+ #
399
+ # Both of +src+ and +dest+ must be a path name.
400
+ # +src+ must exist, +dest+ must not exist.
401
+ #
402
+ # If +dereference_root+ is true, this method dereferences the tree root.
403
+ #
404
+ # If +remove_destination+ is true, this method removes each destination file before copy.
405
+ #
406
+ def link_entry(src, dest, dereference_root = false, remove_destination = false)
407
+ Entry_.new(src, nil, dereference_root).traverse do |ent|
408
+ destent = Entry_.new(dest, ent.rel, false)
409
+ File.unlink destent.path if remove_destination && File.file?(destent.path)
410
+ ent.link destent.path
411
+ end
412
+ end
413
+ module_function :link_entry
414
+
342
415
  #
343
416
  # Copies a file content +src+ to +dest+. If +dest+ is a directory,
344
417
  # copies +src+ to +dest/src+.
@@ -347,7 +420,7 @@ module Bundler::FileUtils
347
420
  #
348
421
  # Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
349
422
  # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
350
- # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', :verbose => true
423
+ # Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
351
424
  # Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
352
425
  #
353
426
  def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
@@ -369,13 +442,17 @@ module Bundler::FileUtils
369
442
  #
370
443
  # +src+ can be a list of files.
371
444
  #
445
+ # If +dereference_root+ is true, this method dereference tree root.
446
+ #
447
+ # If +remove_destination+ is true, this method removes each destination file before copy.
448
+ #
372
449
  # # Installing Ruby library "mylib" under the site_ruby
373
- # Bundler::FileUtils.rm_r site_ruby + '/mylib', :force
450
+ # Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
374
451
  # Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'
375
452
  #
376
453
  # # Examples of copying several files to target directory.
377
454
  # Bundler::FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
378
- # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', :noop => true, :verbose => true
455
+ # Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
379
456
  #
380
457
  # # If you want to copy all contents of a directory instead of the
381
458
  # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
@@ -410,9 +487,13 @@ module Bundler::FileUtils
410
487
  # If +remove_destination+ is true, this method removes each destination file before copy.
411
488
  #
412
489
  def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
413
- Entry_.new(src, nil, dereference_root).wrap_traverse(proc do |ent|
490
+ if dereference_root
491
+ src = File.realpath(src)
492
+ end
493
+
494
+ Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
414
495
  destent = Entry_.new(dest, ent.rel, false)
415
- File.unlink destent.path if remove_destination && File.file?(destent.path)
496
+ File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
416
497
  ent.copy destent.path
417
498
  end, proc do |ent|
418
499
  destent = Entry_.new(dest, ent.rel, false)
@@ -447,10 +528,10 @@ module Bundler::FileUtils
447
528
  # disk partition, the file is copied then the original file is removed.
448
529
  #
449
530
  # Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
450
- # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :force => true # no error
531
+ # Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
451
532
  #
452
533
  # Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
453
- # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', :noop => true, :verbose => true
534
+ # Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
454
535
  #
455
536
  def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
456
537
  fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
@@ -461,13 +542,12 @@ module Bundler::FileUtils
461
542
  if destent.exist?
462
543
  if destent.directory?
463
544
  raise Errno::EEXIST, d
464
- else
465
- destent.remove_file if rename_cannot_overwrite_file?
466
545
  end
467
546
  end
468
547
  begin
469
548
  File.rename s, d
470
- rescue Errno::EXDEV
549
+ rescue Errno::EXDEV,
550
+ Errno::EPERM # move from unencrypted to encrypted dir (ext4)
471
551
  copy_entry s, d, true
472
552
  if secure
473
553
  remove_entry_secure s, force
@@ -485,18 +565,13 @@ module Bundler::FileUtils
485
565
  alias move mv
486
566
  module_function :move
487
567
 
488
- def rename_cannot_overwrite_file? #:nodoc:
489
- /emx/ =~ RUBY_PLATFORM
490
- end
491
- private_module_function :rename_cannot_overwrite_file?
492
-
493
568
  #
494
569
  # Remove file(s) specified in +list+. This method cannot remove directories.
495
570
  # All StandardErrors are ignored when the :force option is set.
496
571
  #
497
572
  # Bundler::FileUtils.rm %w( junk.txt dust.txt )
498
573
  # Bundler::FileUtils.rm Dir.glob('*.so')
499
- # Bundler::FileUtils.rm 'NotExistFile', :force => true # never raises exception
574
+ # Bundler::FileUtils.rm 'NotExistFile', force: true # never raises exception
500
575
  #
501
576
  def rm(list, force: nil, noop: nil, verbose: nil)
502
577
  list = fu_list(list)
@@ -515,7 +590,7 @@ module Bundler::FileUtils
515
590
  #
516
591
  # Equivalent to
517
592
  #
518
- # Bundler::FileUtils.rm(list, :force => true)
593
+ # Bundler::FileUtils.rm(list, force: true)
519
594
  #
520
595
  def rm_f(list, noop: nil, verbose: nil)
521
596
  rm list, force: true, noop: noop, verbose: verbose
@@ -531,18 +606,18 @@ module Bundler::FileUtils
531
606
  # StandardError when :force option is set.
532
607
  #
533
608
  # Bundler::FileUtils.rm_r Dir.glob('/tmp/*')
534
- # Bundler::FileUtils.rm_r 'some_dir', :force => true
609
+ # Bundler::FileUtils.rm_r 'some_dir', force: true
535
610
  #
536
611
  # WARNING: This method causes local vulnerability
537
612
  # if one of parent directories or removing directory tree are world
538
613
  # writable (including /tmp, whose permission is 1777), and the current
539
614
  # process has strong privilege such as Unix super user (root), and the
540
615
  # system has symbolic link. For secure removing, read the documentation
541
- # of #remove_entry_secure carefully, and set :secure option to true.
542
- # Default is :secure=>false.
616
+ # of remove_entry_secure carefully, and set :secure option to true.
617
+ # Default is <tt>secure: false</tt>.
543
618
  #
544
- # NOTE: This method calls #remove_entry_secure if :secure option is set.
545
- # See also #remove_entry_secure.
619
+ # NOTE: This method calls remove_entry_secure if :secure option is set.
620
+ # See also remove_entry_secure.
546
621
  #
547
622
  def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
548
623
  list = fu_list(list)
@@ -561,10 +636,10 @@ module Bundler::FileUtils
561
636
  #
562
637
  # Equivalent to
563
638
  #
564
- # Bundler::FileUtils.rm_r(list, :force => true)
639
+ # Bundler::FileUtils.rm_r(list, force: true)
565
640
  #
566
641
  # WARNING: This method causes local vulnerability.
567
- # Read the documentation of #rm_r first.
642
+ # Read the documentation of rm_r first.
568
643
  #
569
644
  def rm_rf(list, noop: nil, verbose: nil, secure: nil)
570
645
  rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
@@ -578,7 +653,7 @@ module Bundler::FileUtils
578
653
  # This method removes a file system entry +path+. +path+ shall be a
579
654
  # regular file, a directory, or something. If +path+ is a directory,
580
655
  # remove it recursively. This method is required to avoid TOCTTOU
581
- # (time-of-check-to-time-of-use) local security vulnerability of #rm_r.
656
+ # (time-of-check-to-time-of-use) local security vulnerability of rm_r.
582
657
  # #rm_r causes security hole when:
583
658
  #
584
659
  # * Parent directory is world writable (including /tmp).
@@ -601,8 +676,8 @@ module Bundler::FileUtils
601
676
  #
602
677
  # For details of this security vulnerability, see Perl's case:
603
678
  #
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
679
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
680
+ # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
606
681
  #
607
682
  # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
608
683
  #
@@ -626,22 +701,38 @@ module Bundler::FileUtils
626
701
  unless parent_st.sticky?
627
702
  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
703
  end
704
+
629
705
  # freeze tree root
630
706
  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
- }
707
+ dot_file = fullpath + "/."
708
+ begin
709
+ File.open(dot_file) {|f|
710
+ unless fu_stat_identical_entry?(st, f.stat)
711
+ # symlink (TOC-to-TOU attack?)
712
+ File.unlink fullpath
713
+ return
714
+ end
715
+ f.chown euid, -1
716
+ f.chmod 0700
717
+ }
718
+ rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
719
+ File.lstat(dot_file).tap {|fstat|
720
+ unless fu_stat_identical_entry?(st, fstat)
721
+ # symlink (TOC-to-TOU attack?)
722
+ File.unlink fullpath
723
+ return
724
+ end
725
+ File.chown euid, -1, dot_file
726
+ File.chmod 0700, dot_file
727
+ }
728
+ end
729
+
730
+ unless fu_stat_identical_entry?(st, File.lstat(fullpath))
731
+ # TOC-to-TOU attack?
732
+ File.unlink fullpath
733
+ return
734
+ end
735
+
645
736
  # ---- tree root is frozen ----
646
737
  root = Entry_.new(path)
647
738
  root.preorder_traverse do |ent|
@@ -681,7 +772,7 @@ module Bundler::FileUtils
681
772
  # +path+ might be a regular file, a directory, or something.
682
773
  # If +path+ is a directory, remove it recursively.
683
774
  #
684
- # See also #remove_entry_secure.
775
+ # See also remove_entry_secure.
685
776
  #
686
777
  def remove_entry(path, force = false)
687
778
  Entry_.new(path).postorder_traverse do |ent|
@@ -742,8 +833,15 @@ module Bundler::FileUtils
742
833
  #
743
834
  def compare_stream(a, b)
744
835
  bsize = fu_stream_blksize(a, b)
745
- sa = String.new(capacity: bsize)
746
- sb = String.new(capacity: bsize)
836
+
837
+ if RUBY_VERSION > "2.4"
838
+ sa = String.new(capacity: bsize)
839
+ sb = String.new(capacity: bsize)
840
+ else
841
+ sa = String.new
842
+ sb = String.new
843
+ end
844
+
747
845
  begin
748
846
  a.read(bsize, sa)
749
847
  b.read(bsize, sb)
@@ -758,8 +856,8 @@ module Bundler::FileUtils
758
856
  # mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
759
857
  # This method removes destination before copy.
760
858
  #
761
- # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', :mode => 0755, :verbose => true
762
- # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :verbose => true
859
+ # Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
860
+ # Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
763
861
  #
764
862
  def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
765
863
  noop: nil, verbose: nil)
@@ -889,12 +987,12 @@ module Bundler::FileUtils
889
987
  # Absolute mode is
890
988
  # Bundler::FileUtils.chmod 0755, 'somecommand'
891
989
  # Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
892
- # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', :verbose => true
990
+ # Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
893
991
  #
894
992
  # Symbolic mode is
895
993
  # Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
896
994
  # Bundler::FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
897
- # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', :verbose => true
995
+ # Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
898
996
  #
899
997
  # "a" :: is user, group, other mask.
900
998
  # "u" :: is user's mask.
@@ -954,7 +1052,7 @@ module Bundler::FileUtils
954
1052
  # the attribute.
955
1053
  #
956
1054
  # Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
957
- # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true
1055
+ # Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
958
1056
  #
959
1057
  def chown(user, group, list, noop: nil, verbose: nil)
960
1058
  list = fu_list(list)
@@ -978,7 +1076,7 @@ module Bundler::FileUtils
978
1076
  # method does not change the attribute.
979
1077
  #
980
1078
  # Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
981
- # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :verbose => true
1079
+ # Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
982
1080
  #
983
1081
  def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
984
1082
  list = fu_list(list)
@@ -1001,11 +1099,6 @@ module Bundler::FileUtils
1001
1099
  end
1002
1100
  module_function :chown_R
1003
1101
 
1004
- begin
1005
- require 'etc'
1006
- rescue LoadError # rescue LoadError for miniruby
1007
- end
1008
-
1009
1102
  def fu_get_uid(user) #:nodoc:
1010
1103
  return nil unless user
1011
1104
  case user
@@ -1014,6 +1107,7 @@ module Bundler::FileUtils
1014
1107
  when /\A\d+\z/
1015
1108
  user.to_i
1016
1109
  else
1110
+ require 'etc'
1017
1111
  Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
1018
1112
  end
1019
1113
  end
@@ -1027,6 +1121,7 @@ module Bundler::FileUtils
1027
1121
  when /\A\d+\z/
1028
1122
  group.to_i
1029
1123
  else
1124
+ require 'etc'
1030
1125
  Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
1031
1126
  end
1032
1127
  end
@@ -1067,8 +1162,11 @@ module Bundler::FileUtils
1067
1162
  module StreamUtils_
1068
1163
  private
1069
1164
 
1070
- def fu_windows?
1071
- /mswin|mingw|bccwin|emx/ =~ RUBY_PLATFORM
1165
+ case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
1166
+ when /mswin|mingw/
1167
+ def fu_windows?; true end
1168
+ else
1169
+ def fu_windows?; false end
1072
1170
  end
1073
1171
 
1074
1172
  def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
@@ -1193,9 +1291,16 @@ module Bundler::FileUtils
1193
1291
  def entries
1194
1292
  opts = {}
1195
1293
  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)) }
1294
+
1295
+ files = if Dir.respond_to?(:children)
1296
+ Dir.children(path, **opts)
1297
+ else
1298
+ Dir.entries(path(), **opts)
1299
+ .reject {|n| n == '.' or n == '..' }
1300
+ end
1301
+
1302
+ untaint = RUBY_VERSION < '2.7'
1303
+ files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) }
1199
1304
  end
1200
1305
 
1201
1306
  def stat
@@ -1250,6 +1355,22 @@ module Bundler::FileUtils
1250
1355
  end
1251
1356
  end
1252
1357
 
1358
+ def link(dest)
1359
+ case
1360
+ when directory?
1361
+ if !File.exist?(dest) and descendant_directory?(dest, path)
1362
+ raise ArgumentError, "cannot link directory %s to itself %s" % [path, dest]
1363
+ end
1364
+ begin
1365
+ Dir.mkdir dest
1366
+ rescue
1367
+ raise unless File.directory?(dest)
1368
+ end
1369
+ else
1370
+ File.link path(), dest
1371
+ end
1372
+ end
1373
+
1253
1374
  def copy(dest)
1254
1375
  lstat
1255
1376
  case
@@ -1266,18 +1387,21 @@ module Bundler::FileUtils
1266
1387
  end
1267
1388
  when symlink?
1268
1389
  File.symlink File.readlink(path()), dest
1269
- when chardev?
1270
- raise "cannot handle device file" unless File.respond_to?(:mknod)
1271
- mknod dest, ?c, 0666, lstat().rdev
1272
- when blockdev?
1273
- raise "cannot handle device file" unless File.respond_to?(:mknod)
1274
- mknod dest, ?b, 0666, lstat().rdev
1390
+ when chardev?, blockdev?
1391
+ raise "cannot handle device file"
1275
1392
  when socket?
1276
- raise "cannot handle socket" unless File.respond_to?(:mknod)
1277
- mknod dest, nil, lstat().mode, 0
1393
+ begin
1394
+ require 'socket'
1395
+ rescue LoadError
1396
+ raise "cannot handle socket"
1397
+ else
1398
+ raise "cannot handle socket" unless defined?(UNIXServer)
1399
+ end
1400
+ UNIXServer.new(dest).close
1401
+ File.chmod lstat().mode, dest
1278
1402
  when pipe?
1279
1403
  raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
1280
- mkfifo dest, 0666
1404
+ File.mkfifo dest, lstat().mode
1281
1405
  when door?
1282
1406
  raise "cannot handle door: #{path()}"
1283
1407
  else
@@ -1396,14 +1520,14 @@ module Bundler::FileUtils
1396
1520
 
1397
1521
  private
1398
1522
 
1399
- $fileutils_rb_have_lchmod = nil
1523
+ @@fileutils_rb_have_lchmod = nil
1400
1524
 
1401
1525
  def have_lchmod?
1402
1526
  # This is not MT-safe, but it does not matter.
1403
- if $fileutils_rb_have_lchmod == nil
1404
- $fileutils_rb_have_lchmod = check_have_lchmod?
1527
+ if @@fileutils_rb_have_lchmod == nil
1528
+ @@fileutils_rb_have_lchmod = check_have_lchmod?
1405
1529
  end
1406
- $fileutils_rb_have_lchmod
1530
+ @@fileutils_rb_have_lchmod
1407
1531
  end
1408
1532
 
1409
1533
  def check_have_lchmod?
@@ -1414,14 +1538,14 @@ module Bundler::FileUtils
1414
1538
  return false
1415
1539
  end
1416
1540
 
1417
- $fileutils_rb_have_lchown = nil
1541
+ @@fileutils_rb_have_lchown = nil
1418
1542
 
1419
1543
  def have_lchown?
1420
1544
  # This is not MT-safe, but it does not matter.
1421
- if $fileutils_rb_have_lchown == nil
1422
- $fileutils_rb_have_lchown = check_have_lchown?
1545
+ if @@fileutils_rb_have_lchown == nil
1546
+ @@fileutils_rb_have_lchown = check_have_lchown?
1423
1547
  end
1424
- $fileutils_rb_have_lchown
1548
+ @@fileutils_rb_have_lchown
1425
1549
  end
1426
1550
 
1427
1551
  def check_have_lchown?
@@ -1443,10 +1567,13 @@ module Bundler::FileUtils
1443
1567
  else
1444
1568
  DIRECTORY_TERM = "(?=/|\\z)"
1445
1569
  end
1446
- SYSCASE = File::FNM_SYSCASE.nonzero? ? "-i" : ""
1447
1570
 
1448
1571
  def descendant_directory?(descendant, ascendant)
1449
- /\A(?#{SYSCASE}:#{Regexp.quote(ascendant)})#{DIRECTORY_TERM}/ =~ File.dirname(descendant)
1572
+ if File::FNM_SYSCASE.nonzero?
1573
+ File.expand_path(File.dirname(descendant)).casecmp(File.expand_path(ascendant)) == 0
1574
+ else
1575
+ File.expand_path(File.dirname(descendant)) == File.expand_path(ascendant)
1576
+ end
1450
1577
  end
1451
1578
  end # class Entry_
1452
1579
 
@@ -1485,13 +1612,13 @@ module Bundler::FileUtils
1485
1612
  end
1486
1613
  private_module_function :fu_same?
1487
1614
 
1488
- @fileutils_output = $stderr
1489
- @fileutils_label = ''
1490
-
1491
1615
  def fu_output_message(msg) #:nodoc:
1492
- @fileutils_output ||= $stderr
1493
- @fileutils_label ||= ''
1494
- @fileutils_output.puts @fileutils_label + msg
1616
+ output = @fileutils_output if defined?(@fileutils_output)
1617
+ output ||= $stderr
1618
+ if defined?(@fileutils_label)
1619
+ msg = @fileutils_label + msg
1620
+ end
1621
+ output.puts msg
1495
1622
  end
1496
1623
  private_module_function :fu_output_message
1497
1624
 
@@ -1502,8 +1629,11 @@ module Bundler::FileUtils
1502
1629
  tbl
1503
1630
  }
1504
1631
 
1632
+ public
1633
+
1505
1634
  #
1506
- # Returns an Array of method names which have any options.
1635
+ # Returns an Array of names of high-level methods that accept any keyword
1636
+ # arguments.
1507
1637
  #
1508
1638
  # p Bundler::FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
1509
1639
  #
@@ -1542,7 +1672,7 @@ module Bundler::FileUtils
1542
1672
  end
1543
1673
 
1544
1674
  #
1545
- # Returns an Array of method names which have the option +opt+.
1675
+ # Returns an Array of methods names which have the option +opt+.
1546
1676
  #
1547
1677
  # p Bundler::FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
1548
1678
  #
@@ -1550,14 +1680,16 @@ module Bundler::FileUtils
1550
1680
  OPT_TABLE.keys.select {|m| OPT_TABLE[m].include?(opt) }
1551
1681
  end
1552
1682
 
1553
- LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern)
1554
- module LowMethods
1683
+ private
1684
+
1685
+ LOW_METHODS = singleton_methods(false) - collect_method(:noop).map(&:intern) # :nodoc:
1686
+ module LowMethods # :nodoc: internal use only
1555
1687
  private
1556
1688
  def _do_nothing(*)end
1557
1689
  ::Bundler::FileUtils::LOW_METHODS.map {|name| alias_method name, :_do_nothing}
1558
1690
  end
1559
1691
 
1560
- METHODS = singleton_methods() - [:private_module_function,
1692
+ METHODS = singleton_methods() - [:private_module_function, # :nodoc:
1561
1693
  :commands, :options, :have_option?, :options_of, :collect_method]
1562
1694
 
1563
1695
  #
@@ -1567,8 +1699,6 @@ module Bundler::FileUtils
1567
1699
  #
1568
1700
  module Verbose
1569
1701
  include Bundler::FileUtils
1570
- @fileutils_output = $stderr
1571
- @fileutils_label = ''
1572
1702
  names = ::Bundler::FileUtils.collect_method(:verbose)
1573
1703
  names.each do |name|
1574
1704
  module_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -1592,8 +1722,6 @@ module Bundler::FileUtils
1592
1722
  module NoWrite
1593
1723
  include Bundler::FileUtils
1594
1724
  include LowMethods
1595
- @fileutils_output = $stderr
1596
- @fileutils_label = ''
1597
1725
  names = ::Bundler::FileUtils.collect_method(:noop)
1598
1726
  names.each do |name|
1599
1727
  module_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -1618,8 +1746,6 @@ module Bundler::FileUtils
1618
1746
  module DryRun
1619
1747
  include Bundler::FileUtils
1620
1748
  include LowMethods
1621
- @fileutils_output = $stderr
1622
- @fileutils_label = ''
1623
1749
  names = ::Bundler::FileUtils.collect_method(:noop)
1624
1750
  names.each do |name|
1625
1751
  module_eval(<<-EOS, __FILE__, __LINE__ + 1)