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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +794 -570
- data/LICENSE.md +18 -19
- data/README.md +9 -8
- data/bundler.gemspec +8 -25
- data/exe/bundle +19 -3
- data/lib/bundler.rb +202 -87
- data/lib/bundler/build_metadata.rb +3 -3
- data/lib/bundler/capistrano.rb +4 -4
- data/lib/bundler/cli.rb +178 -140
- 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 +1 -1
- 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 +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/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 +35 -26
- data/lib/bundler/dependency.rb +16 -4
- data/lib/bundler/deployment.rb +1 -1
- data/lib/bundler/dsl.rb +16 -40
- data/lib/bundler/env.rb +8 -13
- data/lib/bundler/environment_preserver.rb +0 -1
- data/lib/bundler/feature_flag.rb +23 -34
- data/lib/bundler/fetcher.rb +16 -13
- data/lib/bundler/fetcher/compact_index.rb +26 -12
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +5 -2
- data/lib/bundler/fetcher/index.rb +5 -3
- data/lib/bundler/friendly_errors.rb +6 -7
- data/lib/bundler/gem_helper.rb +40 -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 +40 -30
- 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 -3
- data/lib/bundler/lockfile_parser.rb +14 -21
- data/lib/bundler/match_platform.rb +1 -1
- data/lib/bundler/mirror.rb +3 -3
- data/lib/bundler/plugin.rb +42 -29
- data/lib/bundler/plugin/api.rb +1 -1
- data/lib/bundler/plugin/api/source.rb +4 -6
- 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/remote_specification.rb +0 -2
- 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 -8
- data/lib/bundler/rubygems_integration.rb +148 -400
- data/lib/bundler/runtime.rb +2 -9
- data/lib/bundler/settings.rb +22 -51
- data/lib/bundler/setup.rb +11 -12
- data/lib/bundler/shared_helpers.rb +51 -77
- data/lib/bundler/similarity_detector.rb +2 -2
- data/lib/bundler/source.rb +5 -5
- data/lib/bundler/source/git.rb +24 -17
- data/lib/bundler/source/git/git_proxy.rb +38 -41
- data/lib/bundler/source/metadata.rb +7 -2
- data/lib/bundler/source/path.rb +13 -8
- data/lib/bundler/source/rubygems.rb +14 -8
- data/lib/bundler/source/rubygems/remote.rb +2 -3
- 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/uri_credentials_filter.rb +7 -3
- 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/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 +273 -304
- 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 +19 -4
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +27 -12
- 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 +54 -43
- 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/nested_context.rb +29 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +20 -7
- 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 +15 -14
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +62 -8
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +6 -2
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/util.rb +18 -2
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +744 -0
- data/lib/bundler/vendor/uri/lib/uri/file.rb +94 -0
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +1568 -0
- data/lib/bundler/vendor/uri/lib/uri/http.rb +88 -0
- data/lib/bundler/vendor/uri/lib/uri/https.rb +23 -0
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +261 -0
- data/lib/bundler/vendor/uri/lib/uri/ldaps.rb +21 -0
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +294 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +125 -0
- data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
- 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/vendored_uri.rb +4 -0
- 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-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 +3 -3
- data/man/bundle.1.txt +8 -8
- data/man/bundle.ronn +2 -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 +34 -110
- 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/gem_remote_fetcher.rb +0 -43
- 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/io_binary_read.rb +0 -12
- 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
@@ -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
|
-
|
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
|
-
|
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
|
@@ -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
|
-
#
|
49
|
-
#
|
50
|
-
# <tt>:
|
51
|
-
#
|
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
|
74
|
+
# There are some `low level' methods, which do not accept keyword arguments:
|
58
75
|
#
|
59
|
-
# Bundler::FileUtils.copy_entry(src, dest, preserve = 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
|
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('/', :
|
131
|
+
# Bundler::FileUtils.cd('/', verbose: true) # change directory and report it
|
113
132
|
#
|
114
|
-
# Bundler::FileUtils.cd('/') do #
|
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(
|
157
|
-
# Bundler::FileUtils.mkdir 'notexist', :
|
158
|
-
# Bundler::FileUtils.mkdir 'tmp', :
|
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
|
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', :
|
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
|
-
|
249
|
-
|
250
|
-
|
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
|
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
|
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', :
|
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', :
|
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', :
|
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
|
-
|
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', :
|
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', :
|
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', :
|
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, :
|
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', :
|
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
|
542
|
-
# Default is :
|
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
|
545
|
-
# See also
|
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, :
|
639
|
+
# Bundler::FileUtils.rm_r(list, force: true)
|
565
640
|
#
|
566
641
|
# WARNING: This method causes local vulnerability.
|
567
|
-
# Read the documentation of
|
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
|
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
|
-
# *
|
605
|
-
# *
|
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
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
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
|
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
|
-
|
746
|
-
|
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', :
|
762
|
-
# Bundler::FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', :
|
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', :
|
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', :
|
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/*'), :
|
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', :
|
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
|
-
|
1071
|
-
|
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
|
-
|
1197
|
-
|
1198
|
-
|
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"
|
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)
|