bundler 2.0.0.pre.1 → 2.1.0.pre.3
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 +774 -574
- data/LICENSE.md +18 -19
- data/README.md +9 -8
- data/bundler.gemspec +12 -23
- data/exe/bundle +19 -3
- data/lib/bundler.rb +203 -87
- data/lib/bundler/build_metadata.rb +14 -7
- data/lib/bundler/capistrano.rb +5 -5
- data/lib/bundler/cli.rb +181 -143
- data/lib/bundler/cli/add.rb +28 -16
- data/lib/bundler/cli/cache.rb +25 -13
- data/lib/bundler/cli/common.rb +11 -12
- data/lib/bundler/cli/config.rb +161 -86
- data/lib/bundler/cli/console.rb +2 -2
- data/lib/bundler/cli/doctor.rb +4 -4
- data/lib/bundler/cli/exec.rb +4 -16
- 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 +12 -11
- 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/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 +32 -12
- 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 +36 -27
- data/lib/bundler/dependency.rb +16 -4
- data/lib/bundler/deployment.rb +2 -2
- data/lib/bundler/dsl.rb +18 -42
- data/lib/bundler/env.rb +8 -13
- data/lib/bundler/environment_preserver.rb +0 -1
- data/lib/bundler/feature_flag.rb +1 -11
- 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 +5 -6
- data/lib/bundler/gem_helper.rb +38 -25
- 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 +25 -20
- 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 +14 -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 +11 -67
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +143 -395
- data/lib/bundler/runtime.rb +2 -9
- data/lib/bundler/settings.rb +15 -48
- data/lib/bundler/setup.rb +7 -13
- data/lib/bundler/shared_helpers.rb +57 -73
- 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 +36 -40
- 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 +273 -147
- 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 +12 -4
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +22 -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 +7 -17
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +16 -7
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +19 -8
- data/lib/bundler/vendor/thor/lib/thor/base.rb +25 -24
- data/lib/bundler/vendor/thor/lib/thor/command.rb +21 -14
- data/lib/bundler/vendor/thor/lib/thor/error.rb +78 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +6 -6
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +8 -6
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +20 -5
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +1 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +8 -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 +6 -2
- 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 +3 -3
- 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-cache.1 +55 -0
- data/man/bundle-cache.1.txt +78 -0
- data/man/{bundle-package.ronn → bundle-cache.ronn} +15 -15
- 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 +36 -36
- data/man/bundle-config.1.txt +66 -67
- data/man/bundle-config.ronn +42 -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-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
- data/man/index.txt +1 -1
- metadata +19 -107
- data/exe/bundle_ruby +0 -60
- data/lib/bundler/cli/package.rb +0 -49
- 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
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -129
- data/man/bundle-package.1 +0 -55
- data/man/bundle-package.1.txt +0 -79
@@ -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
|
#
|
@@ -15,48 +24,58 @@
|
|
15
24
|
#
|
16
25
|
# require 'bundler/vendor/fileutils/lib/fileutils'
|
17
26
|
#
|
18
|
-
# Bundler::FileUtils.cd(dir, options)
|
19
|
-
# Bundler::FileUtils.cd(dir, options) {|dir| block }
|
27
|
+
# Bundler::FileUtils.cd(dir, **options)
|
28
|
+
# Bundler::FileUtils.cd(dir, **options) {|dir| block }
|
20
29
|
# 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)
|
30
|
+
# Bundler::FileUtils.mkdir(dir, **options)
|
31
|
+
# Bundler::FileUtils.mkdir(list, **options)
|
32
|
+
# Bundler::FileUtils.mkdir_p(dir, **options)
|
33
|
+
# Bundler::FileUtils.mkdir_p(list, **options)
|
34
|
+
# Bundler::FileUtils.rmdir(dir, **options)
|
35
|
+
# Bundler::FileUtils.rmdir(list, **options)
|
36
|
+
# Bundler::FileUtils.ln(target, link, **options)
|
37
|
+
# Bundler::FileUtils.ln(targets, dir, **options)
|
38
|
+
# Bundler::FileUtils.ln_s(target, link, **options)
|
39
|
+
# Bundler::FileUtils.ln_s(targets, dir, **options)
|
40
|
+
# Bundler::FileUtils.ln_sf(target, link, **options)
|
41
|
+
# Bundler::FileUtils.cp(src, dest, **options)
|
42
|
+
# Bundler::FileUtils.cp(list, dir, **options)
|
43
|
+
# Bundler::FileUtils.cp_r(src, dest, **options)
|
44
|
+
# Bundler::FileUtils.cp_r(list, dir, **options)
|
45
|
+
# Bundler::FileUtils.mv(src, dest, **options)
|
46
|
+
# Bundler::FileUtils.mv(list, dir, **options)
|
47
|
+
# Bundler::FileUtils.rm(list, **options)
|
48
|
+
# Bundler::FileUtils.rm_r(list, **options)
|
49
|
+
# Bundler::FileUtils.rm_rf(list, **options)
|
50
|
+
# Bundler::FileUtils.install(src, dest, **options)
|
51
|
+
# Bundler::FileUtils.chmod(mode, list, **options)
|
52
|
+
# Bundler::FileUtils.chmod_R(mode, list, **options)
|
53
|
+
# Bundler::FileUtils.chown(user, group, list, **options)
|
54
|
+
# Bundler::FileUtils.chown_R(user, group, list, **options)
|
55
|
+
# Bundler::FileUtils.touch(list, **options)
|
47
56
|
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# <tt>:
|
51
|
-
#
|
57
|
+
# Possible <tt>options</tt> are:
|
58
|
+
#
|
59
|
+
# <tt>:force</tt> :: forced operation (rewrite files if exist, remove
|
60
|
+
# directories if not empty, etc.);
|
61
|
+
# <tt>:verbose</tt> :: print command to be run, in bash syntax, before
|
62
|
+
# performing it;
|
63
|
+
# <tt>:preserve</tt> :: preserve object's group, user and modification
|
64
|
+
# time on copying;
|
65
|
+
# <tt>:noop</tt> :: no changes are made (usable in combination with
|
66
|
+
# <tt>:verbose</tt> which will print the command to run)
|
67
|
+
#
|
68
|
+
# Each method documents the options that it honours. See also ::commands,
|
69
|
+
# ::options and ::options_of methods to introspect which command have which
|
70
|
+
# options.
|
52
71
|
#
|
53
72
|
# All methods that have the concept of a "source" file or directory can take
|
54
73
|
# either one file or a list of files in that argument. See the method
|
55
74
|
# documentation for examples.
|
56
75
|
#
|
57
|
-
# There are some `low level' methods, which do not accept
|
76
|
+
# There are some `low level' methods, which do not accept keyword arguments:
|
58
77
|
#
|
59
|
-
# Bundler::FileUtils.copy_entry(src, dest, preserve = false,
|
78
|
+
# Bundler::FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
|
60
79
|
# Bundler::FileUtils.copy_file(src, dest, preserve = false, dereference = true)
|
61
80
|
# Bundler::FileUtils.copy_stream(srcstream, deststream)
|
62
81
|
# Bundler::FileUtils.remove_entry(path, force = false)
|
@@ -84,7 +103,6 @@
|
|
84
103
|
# files/directories. This equates to passing the <tt>:noop</tt> and
|
85
104
|
# <tt>:verbose</tt> flags to methods in Bundler::FileUtils.
|
86
105
|
#
|
87
|
-
|
88
106
|
module Bundler::FileUtils
|
89
107
|
|
90
108
|
def self.private_module_function(name) #:nodoc:
|
@@ -106,19 +124,22 @@ module Bundler::FileUtils
|
|
106
124
|
#
|
107
125
|
# Changes the current directory to the directory +dir+.
|
108
126
|
#
|
109
|
-
# If this method is called with block, resumes to the
|
110
|
-
# working directory after the block execution finished.
|
127
|
+
# If this method is called with block, resumes to the previous
|
128
|
+
# working directory after the block execution has finished.
|
111
129
|
#
|
112
|
-
# Bundler::FileUtils.cd('/'
|
130
|
+
# Bundler::FileUtils.cd('/') # change directory
|
113
131
|
#
|
114
|
-
# Bundler::FileUtils.cd('/')
|
132
|
+
# Bundler::FileUtils.cd('/', verbose: true) # change directory and report it
|
133
|
+
#
|
134
|
+
# Bundler::FileUtils.cd('/') do # change directory
|
115
135
|
# # ... # do something
|
116
136
|
# end # return to original directory
|
117
137
|
#
|
118
138
|
def cd(dir, verbose: nil, &block) # :yield: dir
|
119
139
|
fu_output_message "cd #{dir}" if verbose
|
120
|
-
Dir.chdir(dir, &block)
|
140
|
+
result = Dir.chdir(dir, &block)
|
121
141
|
fu_output_message 'cd -' if verbose and block
|
142
|
+
result
|
122
143
|
end
|
123
144
|
module_function :cd
|
124
145
|
|
@@ -153,9 +174,9 @@ module Bundler::FileUtils
|
|
153
174
|
# Creates one or more directories.
|
154
175
|
#
|
155
176
|
# Bundler::FileUtils.mkdir 'test'
|
156
|
-
# Bundler::FileUtils.mkdir %w(
|
157
|
-
# Bundler::FileUtils.mkdir 'notexist', :
|
158
|
-
# Bundler::FileUtils.mkdir 'tmp', :
|
177
|
+
# Bundler::FileUtils.mkdir %w(tmp data)
|
178
|
+
# Bundler::FileUtils.mkdir 'notexist', noop: true # Does not really create.
|
179
|
+
# Bundler::FileUtils.mkdir 'tmp', mode: 0700
|
159
180
|
#
|
160
181
|
def mkdir(list, mode: nil, noop: nil, verbose: nil)
|
161
182
|
list = fu_list(list)
|
@@ -174,7 +195,7 @@ module Bundler::FileUtils
|
|
174
195
|
#
|
175
196
|
# Bundler::FileUtils.mkdir_p '/usr/local/lib/ruby'
|
176
197
|
#
|
177
|
-
# causes to make following directories, if
|
198
|
+
# causes to make following directories, if they do not exist.
|
178
199
|
#
|
179
200
|
# * /usr
|
180
201
|
# * /usr/local
|
@@ -238,22 +259,22 @@ module Bundler::FileUtils
|
|
238
259
|
# Bundler::FileUtils.rmdir 'somedir'
|
239
260
|
# Bundler::FileUtils.rmdir %w(somedir anydir otherdir)
|
240
261
|
# # Does not really remove directory; outputs message.
|
241
|
-
# Bundler::FileUtils.rmdir 'somedir', :
|
262
|
+
# Bundler::FileUtils.rmdir 'somedir', verbose: true, noop: true
|
242
263
|
#
|
243
264
|
def rmdir(list, parents: nil, noop: nil, verbose: nil)
|
244
265
|
list = fu_list(list)
|
245
266
|
fu_output_message "rmdir #{parents ? '-p ' : ''}#{list.join ' '}" if verbose
|
246
267
|
return if noop
|
247
268
|
list.each do |dir|
|
248
|
-
|
249
|
-
|
250
|
-
|
269
|
+
Dir.rmdir(dir = remove_trailing_slash(dir))
|
270
|
+
if parents
|
271
|
+
begin
|
251
272
|
until (parent = File.dirname(dir)) == '.' or parent == dir
|
252
273
|
dir = parent
|
253
274
|
Dir.rmdir(dir)
|
254
275
|
end
|
276
|
+
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
|
255
277
|
end
|
256
|
-
rescue Errno::ENOTEMPTY, Errno::EEXIST, Errno::ENOENT
|
257
278
|
end
|
258
279
|
end
|
259
280
|
end
|
@@ -267,7 +288,7 @@ module Bundler::FileUtils
|
|
267
288
|
#
|
268
289
|
# In the first form, creates a hard link +link+ which points to +target+.
|
269
290
|
# If +link+ already exists, raises Errno::EEXIST.
|
270
|
-
# But if the
|
291
|
+
# But if the +force+ option is set, overwrites +link+.
|
271
292
|
#
|
272
293
|
# Bundler::FileUtils.ln 'gcc', 'cc', verbose: true
|
273
294
|
# Bundler::FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
|
@@ -293,6 +314,39 @@ module Bundler::FileUtils
|
|
293
314
|
alias link ln
|
294
315
|
module_function :link
|
295
316
|
|
317
|
+
#
|
318
|
+
# Hard link +src+ to +dest+. If +src+ is a directory, this method links
|
319
|
+
# all its contents recursively. If +dest+ is a directory, links
|
320
|
+
# +src+ to +dest/src+.
|
321
|
+
#
|
322
|
+
# +src+ can be a list of files.
|
323
|
+
#
|
324
|
+
# If +dereference_root+ is true, this method dereference tree root.
|
325
|
+
#
|
326
|
+
# If +remove_destination+ is true, this method removes each destination file before copy.
|
327
|
+
#
|
328
|
+
# Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
|
329
|
+
# Bundler::FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
|
330
|
+
#
|
331
|
+
# # Examples of linking several files to target directory.
|
332
|
+
# Bundler::FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
|
333
|
+
# Bundler::FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
|
334
|
+
#
|
335
|
+
# # If you want to link all contents of a directory instead of the
|
336
|
+
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
|
337
|
+
# # use the following code.
|
338
|
+
# Bundler::FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
|
339
|
+
#
|
340
|
+
def cp_lr(src, dest, noop: nil, verbose: nil,
|
341
|
+
dereference_root: true, remove_destination: false)
|
342
|
+
fu_output_message "cp -lr#{remove_destination ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if verbose
|
343
|
+
return if noop
|
344
|
+
fu_each_src_dest(src, dest) do |s, d|
|
345
|
+
link_entry s, d, dereference_root, remove_destination
|
346
|
+
end
|
347
|
+
end
|
348
|
+
module_function :cp_lr
|
349
|
+
|
296
350
|
#
|
297
351
|
# :call-seq:
|
298
352
|
# Bundler::FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
|
@@ -301,7 +355,7 @@ module Bundler::FileUtils
|
|
301
355
|
#
|
302
356
|
# In the first form, creates a symbolic link +link+ which points to +target+.
|
303
357
|
# If +link+ already exists, raises Errno::EEXIST.
|
304
|
-
# But if the
|
358
|
+
# But if the <tt>force</tt> option is set, overwrites +link+.
|
305
359
|
#
|
306
360
|
# Bundler::FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
|
307
361
|
# Bundler::FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
|
@@ -339,6 +393,26 @@ module Bundler::FileUtils
|
|
339
393
|
end
|
340
394
|
module_function :ln_sf
|
341
395
|
|
396
|
+
#
|
397
|
+
# Hard links a file system entry +src+ to +dest+.
|
398
|
+
# If +src+ is a directory, this method links its contents recursively.
|
399
|
+
#
|
400
|
+
# Both of +src+ and +dest+ must be a path name.
|
401
|
+
# +src+ must exist, +dest+ must not exist.
|
402
|
+
#
|
403
|
+
# If +dereference_root+ is true, this method dereferences the tree root.
|
404
|
+
#
|
405
|
+
# If +remove_destination+ is true, this method removes each destination file before copy.
|
406
|
+
#
|
407
|
+
def link_entry(src, dest, dereference_root = false, remove_destination = false)
|
408
|
+
Entry_.new(src, nil, dereference_root).traverse do |ent|
|
409
|
+
destent = Entry_.new(dest, ent.rel, false)
|
410
|
+
File.unlink destent.path if remove_destination && File.file?(destent.path)
|
411
|
+
ent.link destent.path
|
412
|
+
end
|
413
|
+
end
|
414
|
+
module_function :link_entry
|
415
|
+
|
342
416
|
#
|
343
417
|
# Copies a file content +src+ to +dest+. If +dest+ is a directory,
|
344
418
|
# copies +src+ to +dest/src+.
|
@@ -347,7 +421,7 @@ module Bundler::FileUtils
|
|
347
421
|
#
|
348
422
|
# Bundler::FileUtils.cp 'eval.c', 'eval.c.org'
|
349
423
|
# 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', :
|
424
|
+
# Bundler::FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
|
351
425
|
# Bundler::FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
|
352
426
|
#
|
353
427
|
def cp(src, dest, preserve: nil, noop: nil, verbose: nil)
|
@@ -369,13 +443,17 @@ module Bundler::FileUtils
|
|
369
443
|
#
|
370
444
|
# +src+ can be a list of files.
|
371
445
|
#
|
446
|
+
# If +dereference_root+ is true, this method dereference tree root.
|
447
|
+
#
|
448
|
+
# If +remove_destination+ is true, this method removes each destination file before copy.
|
449
|
+
#
|
372
450
|
# # Installing Ruby library "mylib" under the site_ruby
|
373
|
-
# Bundler::FileUtils.rm_r site_ruby + '/mylib', :
|
451
|
+
# Bundler::FileUtils.rm_r site_ruby + '/mylib', force: true
|
374
452
|
# Bundler::FileUtils.cp_r 'lib/', site_ruby + '/mylib'
|
375
453
|
#
|
376
454
|
# # Examples of copying several files to target directory.
|
377
455
|
# 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', :
|
456
|
+
# Bundler::FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
|
379
457
|
#
|
380
458
|
# # If you want to copy all contents of a directory instead of the
|
381
459
|
# # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
|
@@ -410,9 +488,13 @@ module Bundler::FileUtils
|
|
410
488
|
# If +remove_destination+ is true, this method removes each destination file before copy.
|
411
489
|
#
|
412
490
|
def copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
|
413
|
-
|
491
|
+
if dereference_root
|
492
|
+
src = File.realpath(src)
|
493
|
+
end
|
494
|
+
|
495
|
+
Entry_.new(src, nil, false).wrap_traverse(proc do |ent|
|
414
496
|
destent = Entry_.new(dest, ent.rel, false)
|
415
|
-
File.unlink destent.path if remove_destination && File.file?(destent.path)
|
497
|
+
File.unlink destent.path if remove_destination && (File.file?(destent.path) || File.symlink?(destent.path))
|
416
498
|
ent.copy destent.path
|
417
499
|
end, proc do |ent|
|
418
500
|
destent = Entry_.new(dest, ent.rel, false)
|
@@ -447,10 +529,10 @@ module Bundler::FileUtils
|
|
447
529
|
# disk partition, the file is copied then the original file is removed.
|
448
530
|
#
|
449
531
|
# Bundler::FileUtils.mv 'badname.rb', 'goodname.rb'
|
450
|
-
# Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', :
|
532
|
+
# Bundler::FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
|
451
533
|
#
|
452
534
|
# Bundler::FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
|
453
|
-
# Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', :
|
535
|
+
# Bundler::FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
|
454
536
|
#
|
455
537
|
def mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
|
456
538
|
fu_output_message "mv#{force ? ' -f' : ''} #{[src,dest].flatten.join ' '}" if verbose
|
@@ -461,13 +543,12 @@ module Bundler::FileUtils
|
|
461
543
|
if destent.exist?
|
462
544
|
if destent.directory?
|
463
545
|
raise Errno::EEXIST, d
|
464
|
-
else
|
465
|
-
destent.remove_file if rename_cannot_overwrite_file?
|
466
546
|
end
|
467
547
|
end
|
468
548
|
begin
|
469
549
|
File.rename s, d
|
470
|
-
rescue Errno::EXDEV
|
550
|
+
rescue Errno::EXDEV,
|
551
|
+
Errno::EPERM # move from unencrypted to encrypted dir (ext4)
|
471
552
|
copy_entry s, d, true
|
472
553
|
if secure
|
473
554
|
remove_entry_secure s, force
|
@@ -485,18 +566,13 @@ module Bundler::FileUtils
|
|
485
566
|
alias move mv
|
486
567
|
module_function :move
|
487
568
|
|
488
|
-
def rename_cannot_overwrite_file? #:nodoc:
|
489
|
-
/emx/ =~ RUBY_PLATFORM
|
490
|
-
end
|
491
|
-
private_module_function :rename_cannot_overwrite_file?
|
492
|
-
|
493
569
|
#
|
494
570
|
# Remove file(s) specified in +list+. This method cannot remove directories.
|
495
571
|
# All StandardErrors are ignored when the :force option is set.
|
496
572
|
#
|
497
573
|
# Bundler::FileUtils.rm %w( junk.txt dust.txt )
|
498
574
|
# Bundler::FileUtils.rm Dir.glob('*.so')
|
499
|
-
# Bundler::FileUtils.rm 'NotExistFile', :
|
575
|
+
# Bundler::FileUtils.rm 'NotExistFile', force: true # never raises exception
|
500
576
|
#
|
501
577
|
def rm(list, force: nil, noop: nil, verbose: nil)
|
502
578
|
list = fu_list(list)
|
@@ -515,7 +591,7 @@ module Bundler::FileUtils
|
|
515
591
|
#
|
516
592
|
# Equivalent to
|
517
593
|
#
|
518
|
-
# Bundler::FileUtils.rm(list, :
|
594
|
+
# Bundler::FileUtils.rm(list, force: true)
|
519
595
|
#
|
520
596
|
def rm_f(list, noop: nil, verbose: nil)
|
521
597
|
rm list, force: true, noop: noop, verbose: verbose
|
@@ -531,18 +607,18 @@ module Bundler::FileUtils
|
|
531
607
|
# StandardError when :force option is set.
|
532
608
|
#
|
533
609
|
# Bundler::FileUtils.rm_r Dir.glob('/tmp/*')
|
534
|
-
# Bundler::FileUtils.rm_r 'some_dir', :
|
610
|
+
# Bundler::FileUtils.rm_r 'some_dir', force: true
|
535
611
|
#
|
536
612
|
# WARNING: This method causes local vulnerability
|
537
613
|
# if one of parent directories or removing directory tree are world
|
538
614
|
# writable (including /tmp, whose permission is 1777), and the current
|
539
615
|
# process has strong privilege such as Unix super user (root), and the
|
540
616
|
# system has symbolic link. For secure removing, read the documentation
|
541
|
-
# of
|
542
|
-
# Default is :
|
617
|
+
# of remove_entry_secure carefully, and set :secure option to true.
|
618
|
+
# Default is <tt>secure: false</tt>.
|
543
619
|
#
|
544
|
-
# NOTE: This method calls
|
545
|
-
# See also
|
620
|
+
# NOTE: This method calls remove_entry_secure if :secure option is set.
|
621
|
+
# See also remove_entry_secure.
|
546
622
|
#
|
547
623
|
def rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
|
548
624
|
list = fu_list(list)
|
@@ -561,10 +637,10 @@ module Bundler::FileUtils
|
|
561
637
|
#
|
562
638
|
# Equivalent to
|
563
639
|
#
|
564
|
-
# Bundler::FileUtils.rm_r(list, :
|
640
|
+
# Bundler::FileUtils.rm_r(list, force: true)
|
565
641
|
#
|
566
642
|
# WARNING: This method causes local vulnerability.
|
567
|
-
# Read the documentation of
|
643
|
+
# Read the documentation of rm_r first.
|
568
644
|
#
|
569
645
|
def rm_rf(list, noop: nil, verbose: nil, secure: nil)
|
570
646
|
rm_r list, force: true, noop: noop, verbose: verbose, secure: secure
|
@@ -578,7 +654,7 @@ module Bundler::FileUtils
|
|
578
654
|
# This method removes a file system entry +path+. +path+ shall be a
|
579
655
|
# regular file, a directory, or something. If +path+ is a directory,
|
580
656
|
# remove it recursively. This method is required to avoid TOCTTOU
|
581
|
-
# (time-of-check-to-time-of-use) local security vulnerability of
|
657
|
+
# (time-of-check-to-time-of-use) local security vulnerability of rm_r.
|
582
658
|
# #rm_r causes security hole when:
|
583
659
|
#
|
584
660
|
# * Parent directory is world writable (including /tmp).
|
@@ -601,8 +677,8 @@ module Bundler::FileUtils
|
|
601
677
|
#
|
602
678
|
# For details of this security vulnerability, see Perl's case:
|
603
679
|
#
|
604
|
-
# *
|
605
|
-
# *
|
680
|
+
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
|
681
|
+
# * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
|
606
682
|
#
|
607
683
|
# For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
|
608
684
|
#
|
@@ -626,22 +702,38 @@ module Bundler::FileUtils
|
|
626
702
|
unless parent_st.sticky?
|
627
703
|
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
704
|
end
|
705
|
+
|
629
706
|
# freeze tree root
|
630
707
|
euid = Process.euid
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
708
|
+
dot_file = fullpath + "/."
|
709
|
+
begin
|
710
|
+
File.open(dot_file) {|f|
|
711
|
+
unless fu_stat_identical_entry?(st, f.stat)
|
712
|
+
# symlink (TOC-to-TOU attack?)
|
713
|
+
File.unlink fullpath
|
714
|
+
return
|
715
|
+
end
|
716
|
+
f.chown euid, -1
|
717
|
+
f.chmod 0700
|
718
|
+
}
|
719
|
+
rescue Errno::EISDIR # JRuby in non-native mode can't open files as dirs
|
720
|
+
File.lstat(dot_file).tap {|fstat|
|
721
|
+
unless fu_stat_identical_entry?(st, fstat)
|
722
|
+
# symlink (TOC-to-TOU attack?)
|
723
|
+
File.unlink fullpath
|
724
|
+
return
|
725
|
+
end
|
726
|
+
File.chown euid, -1, dot_file
|
727
|
+
File.chmod 0700, dot_file
|
728
|
+
}
|
729
|
+
end
|
730
|
+
|
731
|
+
unless fu_stat_identical_entry?(st, File.lstat(fullpath))
|
732
|
+
# TOC-to-TOU attack?
|
733
|
+
File.unlink fullpath
|
734
|
+
return
|
735
|
+
end
|
736
|
+
|
645
737
|
# ---- tree root is frozen ----
|
646
738
|
root = Entry_.new(path)
|
647
739
|
root.preorder_traverse do |ent|
|
@@ -681,7 +773,7 @@ module Bundler::FileUtils
|
|
681
773
|
# +path+ might be a regular file, a directory, or something.
|
682
774
|
# If +path+ is a directory, remove it recursively.
|
683
775
|
#
|
684
|
-
# See also
|
776
|
+
# See also remove_entry_secure.
|
685
777
|
#
|
686
778
|
def remove_entry(path, force = false)
|
687
779
|
Entry_.new(path).postorder_traverse do |ent|
|
@@ -742,8 +834,15 @@ module Bundler::FileUtils
|
|
742
834
|
#
|
743
835
|
def compare_stream(a, b)
|
744
836
|
bsize = fu_stream_blksize(a, b)
|
745
|
-
|
746
|
-
|
837
|
+
|
838
|
+
if RUBY_VERSION > "2.4"
|
839
|
+
sa = String.new(capacity: bsize)
|
840
|
+
sb = String.new(capacity: bsize)
|
841
|
+
else
|
842
|
+
sa = String.new
|
843
|
+
sb = String.new
|
844
|
+
end
|
845
|
+
|
747
846
|
begin
|
748
847
|
a.read(bsize, sa)
|
749
848
|
b.read(bsize, sb)
|
@@ -758,8 +857,8 @@ module Bundler::FileUtils
|
|
758
857
|
# mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
|
759
858
|
# This method removes destination before copy.
|
760
859
|
#
|
761
|
-
# Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', :
|
762
|
-
# Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :
|
860
|
+
# Bundler::FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
|
861
|
+
# Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
|
763
862
|
#
|
764
863
|
def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
|
765
864
|
noop: nil, verbose: nil)
|
@@ -889,12 +988,12 @@ module Bundler::FileUtils
|
|
889
988
|
# Absolute mode is
|
890
989
|
# Bundler::FileUtils.chmod 0755, 'somecommand'
|
891
990
|
# Bundler::FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
|
892
|
-
# Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', :
|
991
|
+
# Bundler::FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
|
893
992
|
#
|
894
993
|
# Symbolic mode is
|
895
994
|
# Bundler::FileUtils.chmod "u=wrx,go=rx", 'somecommand'
|
896
995
|
# 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', :
|
996
|
+
# Bundler::FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
|
898
997
|
#
|
899
998
|
# "a" :: is user, group, other mask.
|
900
999
|
# "u" :: is user's mask.
|
@@ -954,7 +1053,7 @@ module Bundler::FileUtils
|
|
954
1053
|
# the attribute.
|
955
1054
|
#
|
956
1055
|
# Bundler::FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
|
957
|
-
# Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :
|
1056
|
+
# Bundler::FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
|
958
1057
|
#
|
959
1058
|
def chown(user, group, list, noop: nil, verbose: nil)
|
960
1059
|
list = fu_list(list)
|
@@ -978,7 +1077,7 @@ module Bundler::FileUtils
|
|
978
1077
|
# method does not change the attribute.
|
979
1078
|
#
|
980
1079
|
# Bundler::FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
|
981
|
-
# Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', :
|
1080
|
+
# Bundler::FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
|
982
1081
|
#
|
983
1082
|
def chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
|
984
1083
|
list = fu_list(list)
|
@@ -1001,11 +1100,6 @@ module Bundler::FileUtils
|
|
1001
1100
|
end
|
1002
1101
|
module_function :chown_R
|
1003
1102
|
|
1004
|
-
begin
|
1005
|
-
require 'etc'
|
1006
|
-
rescue LoadError # rescue LoadError for miniruby
|
1007
|
-
end
|
1008
|
-
|
1009
1103
|
def fu_get_uid(user) #:nodoc:
|
1010
1104
|
return nil unless user
|
1011
1105
|
case user
|
@@ -1014,6 +1108,7 @@ module Bundler::FileUtils
|
|
1014
1108
|
when /\A\d+\z/
|
1015
1109
|
user.to_i
|
1016
1110
|
else
|
1111
|
+
require 'etc'
|
1017
1112
|
Etc.getpwnam(user) ? Etc.getpwnam(user).uid : nil
|
1018
1113
|
end
|
1019
1114
|
end
|
@@ -1027,6 +1122,7 @@ module Bundler::FileUtils
|
|
1027
1122
|
when /\A\d+\z/
|
1028
1123
|
group.to_i
|
1029
1124
|
else
|
1125
|
+
require 'etc'
|
1030
1126
|
Etc.getgrnam(group) ? Etc.getgrnam(group).gid : nil
|
1031
1127
|
end
|
1032
1128
|
end
|
@@ -1067,8 +1163,11 @@ module Bundler::FileUtils
|
|
1067
1163
|
module StreamUtils_
|
1068
1164
|
private
|
1069
1165
|
|
1070
|
-
|
1071
|
-
|
1166
|
+
case (defined?(::RbConfig) ? ::RbConfig::CONFIG['host_os'] : ::RUBY_PLATFORM)
|
1167
|
+
when /mswin|mingw/
|
1168
|
+
def fu_windows?; true end
|
1169
|
+
else
|
1170
|
+
def fu_windows?; false end
|
1072
1171
|
end
|
1073
1172
|
|
1074
1173
|
def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
|
@@ -1193,9 +1292,15 @@ module Bundler::FileUtils
|
|
1193
1292
|
def entries
|
1194
1293
|
opts = {}
|
1195
1294
|
opts[:encoding] = ::Encoding::UTF_8 if fu_windows?
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1295
|
+
|
1296
|
+
files = if Dir.respond_to?(:children)
|
1297
|
+
Dir.children(path, **opts)
|
1298
|
+
else
|
1299
|
+
Dir.entries(path(), **opts)
|
1300
|
+
.reject {|n| n == '.' or n == '..' }
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
files.map {|n| Entry_.new(prefix(), join(rel(), n.tap{|x| x.untaint if RUBY_VERSION < "2.7" })) }
|
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"
|
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
|
-
|
1277
|
-
|
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,
|
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
|
-
|
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
|
1404
|
-
|
1527
|
+
if @@fileutils_rb_have_lchmod == nil
|
1528
|
+
@@fileutils_rb_have_lchmod = check_have_lchmod?
|
1405
1529
|
end
|
1406
|
-
|
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
|
-
|
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
|
1422
|
-
|
1545
|
+
if @@fileutils_rb_have_lchown == nil
|
1546
|
+
@@fileutils_rb_have_lchown = check_have_lchown?
|
1423
1547
|
end
|
1424
|
-
|
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
|
-
|
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
|
1493
|
-
|
1494
|
-
|
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
|
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
|
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
|
-
|
1554
|
-
|
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)
|