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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +769 -570
- data/LICENSE.md +18 -19
- data/README.md +9 -8
- data/bundler.gemspec +12 -23
- data/exe/bundle +19 -3
- data/lib/bundler.rb +121 -68
- data/lib/bundler/build_metadata.rb +14 -7
- data/lib/bundler/capistrano.rb +4 -4
- data/lib/bundler/cli.rb +129 -121
- data/lib/bundler/cli/add.rb +27 -16
- data/lib/bundler/cli/common.rb +11 -12
- data/lib/bundler/cli/config.rb +161 -86
- data/lib/bundler/cli/console.rb +1 -1
- data/lib/bundler/cli/doctor.rb +4 -4
- data/lib/bundler/cli/exec.rb +4 -9
- data/lib/bundler/cli/gem.rb +5 -5
- data/lib/bundler/cli/info.rb +17 -5
- data/lib/bundler/cli/init.rb +1 -1
- data/lib/bundler/cli/install.rb +11 -10
- data/lib/bundler/cli/issue.rb +3 -3
- data/lib/bundler/cli/open.rb +10 -6
- data/lib/bundler/cli/outdated.rb +85 -81
- data/lib/bundler/cli/package.rb +8 -9
- data/lib/bundler/cli/plugin.rb +9 -2
- data/lib/bundler/cli/pristine.rb +1 -1
- data/lib/bundler/cli/show.rb +1 -1
- data/lib/bundler/cli/update.rb +31 -11
- data/lib/bundler/compact_index_client.rb +25 -9
- data/lib/bundler/compact_index_client/updater.rb +2 -6
- data/lib/bundler/current_ruby.rb +9 -7
- data/lib/bundler/definition.rb +35 -26
- data/lib/bundler/dependency.rb +16 -4
- data/lib/bundler/deployment.rb +1 -1
- data/lib/bundler/dsl.rb +15 -39
- data/lib/bundler/env.rb +8 -13
- data/lib/bundler/environment_preserver.rb +0 -1
- data/lib/bundler/feature_flag.rb +23 -32
- data/lib/bundler/fetcher.rb +14 -11
- data/lib/bundler/fetcher/compact_index.rb +26 -12
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +4 -1
- data/lib/bundler/fetcher/index.rb +4 -2
- data/lib/bundler/friendly_errors.rb +4 -5
- data/lib/bundler/gem_helper.rb +39 -24
- data/lib/bundler/gem_helpers.rb +2 -4
- data/lib/bundler/gem_tasks.rb +1 -1
- data/lib/bundler/gem_version_promoter.rb +3 -3
- data/lib/bundler/graph.rb +2 -2
- data/lib/bundler/injector.rb +10 -8
- data/lib/bundler/inline.rb +19 -18
- data/lib/bundler/installer.rb +7 -14
- data/lib/bundler/installer/gem_installer.rb +5 -1
- data/lib/bundler/installer/parallel_installer.rb +4 -8
- data/lib/bundler/installer/standalone.rb +1 -2
- data/lib/bundler/lazy_specification.rb +2 -2
- data/lib/bundler/lockfile_parser.rb +13 -21
- data/lib/bundler/match_platform.rb +1 -1
- data/lib/bundler/plugin.rb +42 -29
- data/lib/bundler/plugin/api.rb +1 -1
- data/lib/bundler/plugin/api/source.rb +2 -2
- data/lib/bundler/plugin/index.rb +14 -3
- data/lib/bundler/plugin/installer.rb +28 -15
- data/lib/bundler/psyched_yaml.rb +1 -1
- data/lib/bundler/resolver.rb +72 -24
- data/lib/bundler/resolver/spec_group.rb +3 -2
- data/lib/bundler/retry.rb +2 -2
- data/lib/bundler/ruby_version.rb +4 -19
- data/lib/bundler/rubygems_ext.rb +10 -66
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +144 -395
- data/lib/bundler/runtime.rb +2 -9
- data/lib/bundler/settings.rb +15 -47
- data/lib/bundler/setup.rb +6 -5
- data/lib/bundler/shared_helpers.rb +64 -67
- data/lib/bundler/similarity_detector.rb +2 -2
- data/lib/bundler/source.rb +5 -5
- data/lib/bundler/source/git.rb +19 -12
- data/lib/bundler/source/git/git_proxy.rb +35 -39
- data/lib/bundler/source/metadata.rb +9 -5
- data/lib/bundler/source/path.rb +13 -8
- data/lib/bundler/source/rubygems.rb +11 -5
- data/lib/bundler/source/rubygems/remote.rb +1 -2
- data/lib/bundler/source_list.rb +9 -12
- data/lib/bundler/spec_set.rb +23 -12
- data/lib/bundler/stub_specification.rb +18 -30
- data/lib/bundler/templates/Executable.bundler +23 -14
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +3 -3
- data/lib/bundler/templates/newgem/Gemfile.tt +8 -2
- data/lib/bundler/templates/newgem/README.md.tt +4 -3
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -27
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +1 -1
- data/lib/bundler/templates/newgem/travis.yml.tt +0 -1
- data/lib/bundler/ui.rb +3 -3
- data/lib/bundler/ui/rg_proxy.rb +1 -1
- data/lib/bundler/ui/shell.rb +4 -8
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +161 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +66 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +176 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +151 -48
- data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +6 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +6 -6
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +30 -8
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +1 -1
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +4 -4
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +2 -2
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +248 -279
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +40 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +53 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +79 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +7 -2
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +21 -11
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +11 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/base.rb +16 -17
- data/lib/bundler/vendor/thor/lib/thor/error.rb +82 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +7 -2
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +6 -6
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +52 -7
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendored_fileutils.rb +1 -6
- data/lib/bundler/vendored_molinillo.rb +1 -1
- data/lib/bundler/vendored_persistent.rb +7 -5
- data/lib/bundler/vendored_thor.rb +2 -2
- data/lib/bundler/version.rb +1 -20
- data/lib/bundler/version_ranges.rb +51 -5
- data/lib/bundler/vlad.rb +2 -2
- data/lib/bundler/worker.rb +1 -3
- data/lib/bundler/yaml_serializer.rb +2 -3
- data/man/bundle-add.1 +10 -2
- data/man/bundle-add.1.txt +11 -5
- data/man/bundle-add.ronn +7 -1
- data/man/bundle-binstubs.1 +2 -2
- data/man/bundle-binstubs.1.txt +2 -2
- data/man/bundle-binstubs.ronn +1 -1
- data/man/bundle-check.1 +1 -1
- data/man/bundle-check.1.txt +6 -6
- data/man/bundle-clean.1 +1 -1
- data/man/bundle-clean.1.txt +1 -1
- data/man/bundle-config.1 +52 -36
- data/man/bundle-config.1.txt +82 -67
- data/man/bundle-config.ronn +56 -40
- data/man/bundle-doctor.1 +1 -1
- data/man/bundle-doctor.1.txt +1 -1
- data/man/bundle-exec.1 +2 -2
- data/man/bundle-exec.1.txt +2 -2
- data/man/bundle-exec.ronn +1 -1
- data/man/bundle-gem.1 +1 -1
- data/man/bundle-gem.1.txt +3 -3
- data/man/bundle-info.1 +1 -1
- data/man/bundle-info.1.txt +1 -1
- data/man/bundle-init.1 +2 -2
- data/man/bundle-init.1.txt +2 -2
- data/man/bundle-init.ronn +1 -1
- data/man/bundle-inject.1 +1 -1
- data/man/bundle-inject.1.txt +1 -1
- data/man/bundle-install.1 +8 -5
- data/man/bundle-install.1.txt +56 -51
- data/man/bundle-install.ronn +9 -4
- data/man/bundle-list.1 +1 -1
- data/man/bundle-list.1.txt +1 -1
- data/man/bundle-lock.1 +1 -1
- data/man/bundle-lock.1.txt +16 -16
- data/man/bundle-open.1 +1 -1
- data/man/bundle-open.1.txt +1 -1
- data/man/bundle-outdated.1 +1 -1
- data/man/bundle-outdated.1.txt +1 -1
- data/man/bundle-package.1 +1 -1
- data/man/bundle-package.1.txt +1 -1
- data/man/bundle-platform.1 +1 -1
- data/man/bundle-platform.1.txt +1 -1
- data/man/bundle-pristine.1 +1 -1
- data/man/bundle-pristine.1.txt +1 -1
- data/man/bundle-remove.1 +1 -1
- data/man/bundle-remove.1.txt +1 -1
- data/man/bundle-show.1 +1 -1
- data/man/bundle-show.1.txt +1 -1
- data/man/bundle-update.1 +4 -4
- data/man/bundle-update.1.txt +64 -65
- data/man/bundle-update.ronn +3 -3
- data/man/bundle-viz.1 +1 -1
- data/man/bundle-viz.1.txt +1 -1
- data/man/bundle.1 +7 -3
- data/man/bundle.1.txt +11 -8
- data/man/bundle.ronn +5 -2
- data/man/gemfile.5 +17 -20
- data/man/gemfile.5.ronn +14 -18
- data/man/gemfile.5.txt +108 -112
- metadata +17 -104
- data/exe/bundle_ruby +0 -60
- data/lib/bundler/cli/cache.rb +0 -36
- data/lib/bundler/compatibility_guard.rb +0 -14
- data/lib/bundler/ssl_certs/.document +0 -1
- data/lib/bundler/ssl_certs/certificate_manager.rb +0 -66
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +0 -21
- data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +0 -27
- 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
|
@@ -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,
|
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
|
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('/'
|
120
|
+
# Bundler::FileUtils.cd('/') # change directory
|
113
121
|
#
|
114
|
-
# Bundler::FileUtils.cd('/')
|
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
|
-
|
249
|
-
|
250
|
-
|
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
|
-
# *
|
605
|
-
# *
|
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
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
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
|
-
|
746
|
-
|
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
|
-
|
1071
|
-
|
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
|
-
|
1197
|
-
|
1198
|
-
|
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
|