bundler 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3111 -0
- data/LICENSE.md +23 -0
- data/README.md +63 -0
- data/bundler.gemspec +65 -0
- data/exe/bundle +31 -0
- data/exe/bundle_ruby +60 -0
- data/exe/bundler +4 -0
- data/lib/bundler.rb +567 -0
- data/lib/bundler/build_metadata.rb +53 -0
- data/lib/bundler/capistrano.rb +22 -0
- data/lib/bundler/cli.rb +792 -0
- data/lib/bundler/cli/add.rb +35 -0
- data/lib/bundler/cli/binstubs.rb +49 -0
- data/lib/bundler/cli/cache.rb +36 -0
- data/lib/bundler/cli/check.rb +38 -0
- data/lib/bundler/cli/clean.rb +25 -0
- data/lib/bundler/cli/common.rb +102 -0
- data/lib/bundler/cli/config.rb +119 -0
- data/lib/bundler/cli/console.rb +43 -0
- data/lib/bundler/cli/doctor.rb +140 -0
- data/lib/bundler/cli/exec.rb +105 -0
- data/lib/bundler/cli/gem.rb +252 -0
- data/lib/bundler/cli/info.rb +50 -0
- data/lib/bundler/cli/init.rb +47 -0
- data/lib/bundler/cli/inject.rb +60 -0
- data/lib/bundler/cli/install.rb +218 -0
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/list.rb +58 -0
- data/lib/bundler/cli/lock.rb +63 -0
- data/lib/bundler/cli/open.rb +26 -0
- data/lib/bundler/cli/outdated.rb +266 -0
- data/lib/bundler/cli/package.rb +49 -0
- data/lib/bundler/cli/platform.rb +46 -0
- data/lib/bundler/cli/plugin.rb +24 -0
- data/lib/bundler/cli/pristine.rb +47 -0
- data/lib/bundler/cli/remove.rb +18 -0
- data/lib/bundler/cli/show.rb +75 -0
- data/lib/bundler/cli/update.rb +91 -0
- data/lib/bundler/cli/viz.rb +31 -0
- data/lib/bundler/compact_index_client.rb +109 -0
- data/lib/bundler/compact_index_client/cache.rb +118 -0
- data/lib/bundler/compact_index_client/updater.rb +116 -0
- data/lib/bundler/compatibility_guard.rb +13 -0
- data/lib/bundler/constants.rb +7 -0
- data/lib/bundler/current_ruby.rb +94 -0
- data/lib/bundler/definition.rb +995 -0
- data/lib/bundler/dep_proxy.rb +48 -0
- data/lib/bundler/dependency.rb +139 -0
- data/lib/bundler/deployment.rb +69 -0
- data/lib/bundler/deprecate.rb +44 -0
- data/lib/bundler/dsl.rb +615 -0
- data/lib/bundler/endpoint_specification.rb +141 -0
- data/lib/bundler/env.rb +149 -0
- data/lib/bundler/environment_preserver.rb +59 -0
- data/lib/bundler/errors.rb +158 -0
- data/lib/bundler/feature_flag.rb +75 -0
- data/lib/bundler/fetcher.rb +312 -0
- data/lib/bundler/fetcher/base.rb +52 -0
- data/lib/bundler/fetcher/compact_index.rb +126 -0
- data/lib/bundler/fetcher/dependency.rb +82 -0
- data/lib/bundler/fetcher/downloader.rb +84 -0
- data/lib/bundler/fetcher/index.rb +52 -0
- data/lib/bundler/friendly_errors.rb +131 -0
- data/lib/bundler/gem_helper.rb +217 -0
- data/lib/bundler/gem_helpers.rb +101 -0
- data/lib/bundler/gem_remote_fetcher.rb +43 -0
- data/lib/bundler/gem_tasks.rb +7 -0
- data/lib/bundler/gem_version_promoter.rb +190 -0
- data/lib/bundler/gemdeps.rb +29 -0
- data/lib/bundler/graph.rb +152 -0
- data/lib/bundler/index.rb +213 -0
- data/lib/bundler/injector.rb +253 -0
- data/lib/bundler/inline.rb +74 -0
- data/lib/bundler/installer.rb +318 -0
- data/lib/bundler/installer/gem_installer.rb +85 -0
- data/lib/bundler/installer/parallel_installer.rb +229 -0
- data/lib/bundler/installer/standalone.rb +53 -0
- data/lib/bundler/lazy_specification.rb +123 -0
- data/lib/bundler/lockfile_generator.rb +95 -0
- data/lib/bundler/lockfile_parser.rb +256 -0
- data/lib/bundler/match_platform.rb +24 -0
- data/lib/bundler/mirror.rb +223 -0
- data/lib/bundler/plugin.rb +294 -0
- data/lib/bundler/plugin/api.rb +81 -0
- data/lib/bundler/plugin/api/source.rb +306 -0
- data/lib/bundler/plugin/dsl.rb +53 -0
- data/lib/bundler/plugin/events.rb +61 -0
- data/lib/bundler/plugin/index.rb +165 -0
- data/lib/bundler/plugin/installer.rb +96 -0
- data/lib/bundler/plugin/installer/git.rb +38 -0
- data/lib/bundler/plugin/installer/rubygems.rb +27 -0
- data/lib/bundler/plugin/source_list.rb +27 -0
- data/lib/bundler/process_lock.rb +24 -0
- data/lib/bundler/psyched_yaml.rb +37 -0
- data/lib/bundler/remote_specification.rb +114 -0
- data/lib/bundler/resolver.rb +373 -0
- data/lib/bundler/resolver/spec_group.rb +106 -0
- data/lib/bundler/retry.rb +66 -0
- data/lib/bundler/ruby_dsl.rb +18 -0
- data/lib/bundler/ruby_version.rb +152 -0
- data/lib/bundler/rubygems_ext.rb +209 -0
- data/lib/bundler/rubygems_gem_installer.rb +99 -0
- data/lib/bundler/rubygems_integration.rb +915 -0
- data/lib/bundler/runtime.rb +322 -0
- data/lib/bundler/settings.rb +464 -0
- data/lib/bundler/settings/validator.rb +102 -0
- data/lib/bundler/setup.rb +28 -0
- data/lib/bundler/shared_helpers.rb +386 -0
- data/lib/bundler/similarity_detector.rb +63 -0
- data/lib/bundler/source.rb +94 -0
- data/lib/bundler/source/gemspec.rb +18 -0
- data/lib/bundler/source/git.rb +329 -0
- data/lib/bundler/source/git/git_proxy.rb +262 -0
- data/lib/bundler/source/metadata.rb +62 -0
- data/lib/bundler/source/path.rb +249 -0
- data/lib/bundler/source/path/installer.rb +74 -0
- data/lib/bundler/source/rubygems.rb +539 -0
- data/lib/bundler/source/rubygems/remote.rb +69 -0
- data/lib/bundler/source_list.rb +186 -0
- data/lib/bundler/spec_set.rb +208 -0
- data/lib/bundler/ssl_certs/.document +1 -0
- data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
- data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
- data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
- data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
- data/lib/bundler/stub_specification.rb +108 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +29 -0
- data/lib/bundler/templates/Executable.bundler +105 -0
- data/lib/bundler/templates/Executable.standalone +14 -0
- data/lib/bundler/templates/Gemfile +7 -0
- data/lib/bundler/templates/gems.rb +8 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
- data/lib/bundler/templates/newgem/README.md.tt +47 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
- data/lib/bundler/templates/newgem/bin/console.tt +14 -0
- data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
- data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
- data/lib/bundler/templates/newgem/gitignore.tt +20 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
- data/lib/bundler/templates/newgem/rspec.tt +3 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
- data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
- data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
- data/lib/bundler/ui.rb +9 -0
- data/lib/bundler/ui/rg_proxy.rb +19 -0
- data/lib/bundler/ui/shell.rb +146 -0
- data/lib/bundler/ui/silent.rb +69 -0
- data/lib/bundler/uri_credentials_filter.rb +37 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +101 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
- data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
- data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +114 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
- data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
- data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/bundler/vendored_fileutils.rb +9 -0
- data/lib/bundler/vendored_molinillo.rb +4 -0
- data/lib/bundler/vendored_persistent.rb +52 -0
- data/lib/bundler/vendored_thor.rb +8 -0
- data/lib/bundler/version.rb +28 -0
- data/lib/bundler/version_ranges.rb +76 -0
- data/lib/bundler/vlad.rb +17 -0
- data/lib/bundler/worker.rb +106 -0
- data/lib/bundler/yaml_serializer.rb +90 -0
- data/man/bundle-add.1 +58 -0
- data/man/bundle-add.1.txt +52 -0
- data/man/bundle-add.ronn +40 -0
- data/man/bundle-binstubs.1 +40 -0
- data/man/bundle-binstubs.1.txt +48 -0
- data/man/bundle-binstubs.ronn +43 -0
- data/man/bundle-check.1 +31 -0
- data/man/bundle-check.1.txt +33 -0
- data/man/bundle-check.ronn +26 -0
- data/man/bundle-clean.1 +24 -0
- data/man/bundle-clean.1.txt +26 -0
- data/man/bundle-clean.ronn +18 -0
- data/man/bundle-config.1 +497 -0
- data/man/bundle-config.1.txt +529 -0
- data/man/bundle-config.ronn +397 -0
- data/man/bundle-doctor.1 +44 -0
- data/man/bundle-doctor.1.txt +44 -0
- data/man/bundle-doctor.ronn +33 -0
- data/man/bundle-exec.1 +165 -0
- data/man/bundle-exec.1.txt +178 -0
- data/man/bundle-exec.ronn +152 -0
- data/man/bundle-gem.1 +80 -0
- data/man/bundle-gem.1.txt +91 -0
- data/man/bundle-gem.ronn +78 -0
- data/man/bundle-info.1 +20 -0
- data/man/bundle-info.1.txt +21 -0
- data/man/bundle-info.ronn +17 -0
- data/man/bundle-init.1 +25 -0
- data/man/bundle-init.1.txt +34 -0
- data/man/bundle-init.ronn +29 -0
- data/man/bundle-inject.1 +33 -0
- data/man/bundle-inject.1.txt +32 -0
- data/man/bundle-inject.ronn +22 -0
- data/man/bundle-install.1 +308 -0
- data/man/bundle-install.1.txt +396 -0
- data/man/bundle-install.ronn +378 -0
- data/man/bundle-list.1 +50 -0
- data/man/bundle-list.1.txt +43 -0
- data/man/bundle-list.ronn +33 -0
- data/man/bundle-lock.1 +84 -0
- data/man/bundle-lock.1.txt +93 -0
- data/man/bundle-lock.ronn +94 -0
- data/man/bundle-open.1 +32 -0
- data/man/bundle-open.1.txt +29 -0
- data/man/bundle-open.ronn +19 -0
- data/man/bundle-outdated.1 +155 -0
- data/man/bundle-outdated.1.txt +131 -0
- data/man/bundle-outdated.ronn +111 -0
- data/man/bundle-package.1 +55 -0
- data/man/bundle-package.1.txt +79 -0
- data/man/bundle-package.ronn +72 -0
- data/man/bundle-platform.1 +61 -0
- data/man/bundle-platform.1.txt +57 -0
- data/man/bundle-platform.ronn +42 -0
- data/man/bundle-pristine.1 +34 -0
- data/man/bundle-pristine.1.txt +44 -0
- data/man/bundle-pristine.ronn +34 -0
- data/man/bundle-remove.1 +31 -0
- data/man/bundle-remove.1.txt +34 -0
- data/man/bundle-remove.ronn +23 -0
- data/man/bundle-show.1 +23 -0
- data/man/bundle-show.1.txt +27 -0
- data/man/bundle-show.ronn +21 -0
- data/man/bundle-update.1 +394 -0
- data/man/bundle-update.1.txt +391 -0
- data/man/bundle-update.ronn +350 -0
- data/man/bundle-viz.1 +39 -0
- data/man/bundle-viz.1.txt +39 -0
- data/man/bundle-viz.ronn +30 -0
- data/man/bundle.1 +136 -0
- data/man/bundle.1.txt +116 -0
- data/man/bundle.ronn +111 -0
- data/man/gemfile.5 +689 -0
- data/man/gemfile.5.ronn +521 -0
- data/man/gemfile.5.txt +653 -0
- data/man/index.txt +25 -0
- metadata +463 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class FeatureFlag
|
5
|
+
def self.settings_flag(flag, &default)
|
6
|
+
unless Bundler::Settings::BOOL_KEYS.include?(flag.to_s)
|
7
|
+
raise "Cannot use `#{flag}` as a settings feature flag since it isn't a bool key"
|
8
|
+
end
|
9
|
+
|
10
|
+
settings_method("#{flag}?", flag, &default)
|
11
|
+
end
|
12
|
+
private_class_method :settings_flag
|
13
|
+
|
14
|
+
def self.settings_option(key, &default)
|
15
|
+
settings_method(key, key, &default)
|
16
|
+
end
|
17
|
+
private_class_method :settings_option
|
18
|
+
|
19
|
+
def self.settings_method(name, key, &default)
|
20
|
+
define_method(name) do
|
21
|
+
value = Bundler.settings[key]
|
22
|
+
value = instance_eval(&default) if value.nil?
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
private_class_method :settings_method
|
27
|
+
|
28
|
+
(1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
|
29
|
+
|
30
|
+
settings_flag(:allow_bundler_dependency_conflicts) { bundler_3_mode? }
|
31
|
+
settings_flag(:allow_offline_install) { bundler_3_mode? }
|
32
|
+
settings_flag(:auto_clean_without_path) { bundler_3_mode? }
|
33
|
+
settings_flag(:auto_config_jobs) { bundler_3_mode? }
|
34
|
+
settings_flag(:cache_all) { bundler_3_mode? }
|
35
|
+
settings_flag(:cache_command_is_package) { bundler_3_mode? }
|
36
|
+
settings_flag(:console_command) { !bundler_3_mode? }
|
37
|
+
settings_flag(:default_install_uses_path) { bundler_3_mode? }
|
38
|
+
settings_flag(:deployment_means_frozen) { bundler_3_mode? }
|
39
|
+
settings_flag(:disable_multisource) { bundler_3_mode? }
|
40
|
+
settings_flag(:error_on_stderr) { bundler_2_mode? }
|
41
|
+
settings_flag(:forget_cli_options) { bundler_3_mode? }
|
42
|
+
settings_flag(:global_path_appends_ruby_scope) { bundler_3_mode? }
|
43
|
+
settings_flag(:global_gem_cache) { bundler_3_mode? }
|
44
|
+
settings_flag(:init_gems_rb) { bundler_3_mode? }
|
45
|
+
settings_flag(:list_command) { bundler_3_mode? }
|
46
|
+
settings_flag(:lockfile_uses_separate_rubygems_sources) { bundler_3_mode? }
|
47
|
+
settings_flag(:lockfile_upgrade_warning) { bundler_3_mode? }
|
48
|
+
settings_flag(:only_update_to_newer_versions) { bundler_3_mode? }
|
49
|
+
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
|
50
|
+
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
|
51
|
+
settings_flag(:prefer_gems_rb) { bundler_3_mode? }
|
52
|
+
settings_flag(:print_only_version_number) { bundler_3_mode? }
|
53
|
+
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
|
54
|
+
settings_flag(:skip_default_git_sources) { bundler_3_mode? }
|
55
|
+
settings_flag(:specific_platform) { bundler_3_mode? }
|
56
|
+
settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
|
57
|
+
settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
|
58
|
+
settings_flag(:update_requires_all_flag) { bundler_3_mode? }
|
59
|
+
settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }
|
60
|
+
settings_flag(:viz_command) { !bundler_3_mode? }
|
61
|
+
|
62
|
+
settings_option(:default_cli_command) { bundler_3_mode? ? :cli_help : :install }
|
63
|
+
|
64
|
+
settings_method(:github_https?, "github.https") { bundler_2_mode? }
|
65
|
+
|
66
|
+
def initialize(bundler_version)
|
67
|
+
@bundler_version = Gem::Version.create(bundler_version)
|
68
|
+
end
|
69
|
+
|
70
|
+
def major_version
|
71
|
+
@bundler_version.segments.first
|
72
|
+
end
|
73
|
+
private :major_version
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/vendored_persistent"
|
4
|
+
require "cgi"
|
5
|
+
require "securerandom"
|
6
|
+
require "zlib"
|
7
|
+
|
8
|
+
module Bundler
|
9
|
+
# Handles all the fetching with the rubygems server
|
10
|
+
class Fetcher
|
11
|
+
autoload :CompactIndex, "bundler/fetcher/compact_index"
|
12
|
+
autoload :Downloader, "bundler/fetcher/downloader"
|
13
|
+
autoload :Dependency, "bundler/fetcher/dependency"
|
14
|
+
autoload :Index, "bundler/fetcher/index"
|
15
|
+
|
16
|
+
# This error is raised when it looks like the network is down
|
17
|
+
class NetworkDownError < HTTPError; end
|
18
|
+
# This error is raised if the API returns a 413 (only printed in verbose)
|
19
|
+
class FallbackError < HTTPError; end
|
20
|
+
# This is the error raised if OpenSSL fails the cert verification
|
21
|
+
class CertificateFailureError < HTTPError
|
22
|
+
def initialize(remote_uri)
|
23
|
+
remote_uri = filter_uri(remote_uri)
|
24
|
+
super "Could not verify the SSL certificate for #{remote_uri}.\nThere" \
|
25
|
+
" is a chance you are experiencing a man-in-the-middle attack, but" \
|
26
|
+
" most likely your system doesn't have the CA certificates needed" \
|
27
|
+
" for verification. For information about OpenSSL certificates, see" \
|
28
|
+
" http://bit.ly/ruby-ssl. To connect without using SSL, edit your Gemfile" \
|
29
|
+
" sources and change 'https' to 'http'."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# This is the error raised when a source is HTTPS and OpenSSL didn't load
|
33
|
+
class SSLError < HTTPError
|
34
|
+
def initialize(msg = nil)
|
35
|
+
super msg || "Could not load OpenSSL.\n" \
|
36
|
+
"You must recompile Ruby with OpenSSL support or change the sources in your " \
|
37
|
+
"Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL " \
|
38
|
+
"using RVM are available at rvm.io/packages/openssl."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
# This error is raised if HTTP authentication is required, but not provided.
|
42
|
+
class AuthenticationRequiredError < HTTPError
|
43
|
+
def initialize(remote_uri)
|
44
|
+
remote_uri = filter_uri(remote_uri)
|
45
|
+
super "Authentication is required for #{remote_uri}.\n" \
|
46
|
+
"Please supply credentials for this source. You can do this by running:\n" \
|
47
|
+
" bundle config #{remote_uri} username:password"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
# This error is raised if HTTP authentication is provided, but incorrect.
|
51
|
+
class BadAuthenticationError < HTTPError
|
52
|
+
def initialize(remote_uri)
|
53
|
+
remote_uri = filter_uri(remote_uri)
|
54
|
+
super "Bad username or password for #{remote_uri}.\n" \
|
55
|
+
"Please double-check your credentials and correct them."
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Exceptions classes that should bypass retry attempts. If your password didn't work the
|
60
|
+
# first time, it's not going to the third time.
|
61
|
+
NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency,
|
62
|
+
:HTTPForbidden, :HTTPInsufficientStorage, :HTTPMethodNotAllowed,
|
63
|
+
:HTTPMovedPermanently, :HTTPNoContent, :HTTPNotFound,
|
64
|
+
:HTTPNotImplemented, :HTTPPreconditionFailed, :HTTPRequestEntityTooLarge,
|
65
|
+
:HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity,
|
66
|
+
:HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
|
67
|
+
FAIL_ERRORS = begin
|
68
|
+
fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
|
69
|
+
fail_errors << Gem::Requirement::BadRequirementError if defined?(Gem::Requirement::BadRequirementError)
|
70
|
+
fail_errors.concat(NET_ERRORS.map {|e| SharedHelpers.const_get_safely(e, Net) }.compact)
|
71
|
+
end.freeze
|
72
|
+
|
73
|
+
class << self
|
74
|
+
attr_accessor :disable_endpoint, :api_timeout, :redirect_limit, :max_retries
|
75
|
+
end
|
76
|
+
|
77
|
+
self.redirect_limit = Bundler.settings[:redirect] # How many redirects to allow in one request
|
78
|
+
self.api_timeout = Bundler.settings[:timeout] # How long to wait for each API call
|
79
|
+
self.max_retries = Bundler.settings[:retry] # How many retries for the API call
|
80
|
+
|
81
|
+
def initialize(remote)
|
82
|
+
@remote = remote
|
83
|
+
|
84
|
+
Socket.do_not_reverse_lookup = true
|
85
|
+
connection # create persistent connection
|
86
|
+
end
|
87
|
+
|
88
|
+
def uri
|
89
|
+
@remote.anonymized_uri
|
90
|
+
end
|
91
|
+
|
92
|
+
# fetch a gem specification
|
93
|
+
def fetch_spec(spec)
|
94
|
+
spec -= [nil, "ruby", ""]
|
95
|
+
spec_file_name = "#{spec.join "-"}.gemspec"
|
96
|
+
|
97
|
+
uri = URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz")
|
98
|
+
if uri.scheme == "file"
|
99
|
+
Bundler.load_marshal Bundler.rubygems.inflate(Gem.read_binary(uri.path))
|
100
|
+
elsif cached_spec_path = gemspec_cached_path(spec_file_name)
|
101
|
+
Bundler.load_gemspec(cached_spec_path)
|
102
|
+
else
|
103
|
+
Bundler.load_marshal Bundler.rubygems.inflate(downloader.fetch(uri).body)
|
104
|
+
end
|
105
|
+
rescue MarshalError
|
106
|
+
raise HTTPError, "Gemspec #{spec} contained invalid data.\n" \
|
107
|
+
"Your network or your gem server is probably having issues right now."
|
108
|
+
end
|
109
|
+
|
110
|
+
# return the specs in the bundler format as an index with retries
|
111
|
+
def specs_with_retry(gem_names, source)
|
112
|
+
Bundler::Retry.new("fetcher", FAIL_ERRORS).attempts do
|
113
|
+
specs(gem_names, source)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# return the specs in the bundler format as an index
|
118
|
+
def specs(gem_names, source)
|
119
|
+
old = Bundler.rubygems.sources
|
120
|
+
index = Bundler::Index.new
|
121
|
+
|
122
|
+
if Bundler::Fetcher.disable_endpoint
|
123
|
+
@use_api = false
|
124
|
+
specs = fetchers.last.specs(gem_names)
|
125
|
+
else
|
126
|
+
specs = []
|
127
|
+
fetchers.shift until fetchers.first.available? || fetchers.empty?
|
128
|
+
fetchers.dup.each do |f|
|
129
|
+
break unless f.api_fetcher? && !gem_names || !specs = f.specs(gem_names)
|
130
|
+
fetchers.delete(f)
|
131
|
+
end
|
132
|
+
@use_api = false if fetchers.none?(&:api_fetcher?)
|
133
|
+
end
|
134
|
+
|
135
|
+
specs.each do |name, version, platform, dependencies, metadata|
|
136
|
+
next if name == "bundler"
|
137
|
+
spec = if dependencies
|
138
|
+
EndpointSpecification.new(name, version, platform, dependencies, metadata)
|
139
|
+
else
|
140
|
+
RemoteSpecification.new(name, version, platform, self)
|
141
|
+
end
|
142
|
+
spec.source = source
|
143
|
+
spec.remote = @remote
|
144
|
+
index << spec
|
145
|
+
end
|
146
|
+
|
147
|
+
index
|
148
|
+
rescue CertificateFailureError
|
149
|
+
Bundler.ui.info "" if gem_names && use_api # newline after dots
|
150
|
+
raise
|
151
|
+
ensure
|
152
|
+
Bundler.rubygems.sources = old
|
153
|
+
end
|
154
|
+
|
155
|
+
def use_api
|
156
|
+
return @use_api if defined?(@use_api)
|
157
|
+
|
158
|
+
fetchers.shift until fetchers.first.available?
|
159
|
+
|
160
|
+
@use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
161
|
+
false
|
162
|
+
else
|
163
|
+
fetchers.first.api_fetcher?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def user_agent
|
168
|
+
@user_agent ||= begin
|
169
|
+
ruby = Bundler::RubyVersion.system
|
170
|
+
|
171
|
+
agent = String.new("bundler/#{Bundler::VERSION}")
|
172
|
+
agent << " rubygems/#{Gem::VERSION}"
|
173
|
+
agent << " ruby/#{ruby.versions_string(ruby.versions)}"
|
174
|
+
agent << " (#{ruby.host})"
|
175
|
+
agent << " command/#{ARGV.first}"
|
176
|
+
|
177
|
+
if ruby.engine != "ruby"
|
178
|
+
# engine_version raises on unknown engines
|
179
|
+
engine_version = begin
|
180
|
+
ruby.engine_versions
|
181
|
+
rescue RuntimeError
|
182
|
+
"???"
|
183
|
+
end
|
184
|
+
agent << " #{ruby.engine}/#{ruby.versions_string(engine_version)}"
|
185
|
+
end
|
186
|
+
|
187
|
+
agent << " options/#{Bundler.settings.all.join(",")}"
|
188
|
+
|
189
|
+
agent << " ci/#{cis.join(",")}" if cis.any?
|
190
|
+
|
191
|
+
# add a random ID so we can consolidate runs server-side
|
192
|
+
agent << " " << SecureRandom.hex(8)
|
193
|
+
|
194
|
+
# add any user agent strings set in the config
|
195
|
+
extra_ua = Bundler.settings[:user_agent]
|
196
|
+
agent << " " << extra_ua if extra_ua
|
197
|
+
|
198
|
+
agent
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def fetchers
|
203
|
+
@fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
|
204
|
+
end
|
205
|
+
|
206
|
+
def http_proxy
|
207
|
+
return unless uri = connection.proxy_uri
|
208
|
+
uri.to_s
|
209
|
+
end
|
210
|
+
|
211
|
+
def inspect
|
212
|
+
"#<#{self.class}:0x#{object_id} uri=#{uri}>"
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
FETCHERS = [CompactIndex, Dependency, Index].freeze
|
218
|
+
|
219
|
+
def cis
|
220
|
+
env_cis = {
|
221
|
+
"TRAVIS" => "travis",
|
222
|
+
"CIRCLECI" => "circle",
|
223
|
+
"SEMAPHORE" => "semaphore",
|
224
|
+
"JENKINS_URL" => "jenkins",
|
225
|
+
"BUILDBOX" => "buildbox",
|
226
|
+
"GO_SERVER_URL" => "go",
|
227
|
+
"SNAP_CI" => "snap",
|
228
|
+
"CI_NAME" => ENV["CI_NAME"],
|
229
|
+
"CI" => "ci"
|
230
|
+
}
|
231
|
+
env_cis.find_all {|env, _| ENV[env] }.map {|_, ci| ci }
|
232
|
+
end
|
233
|
+
|
234
|
+
def connection
|
235
|
+
@connection ||= begin
|
236
|
+
needs_ssl = remote_uri.scheme == "https" ||
|
237
|
+
Bundler.settings[:ssl_verify_mode] ||
|
238
|
+
Bundler.settings[:ssl_client_cert]
|
239
|
+
raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
|
240
|
+
|
241
|
+
con = PersistentHTTP.new "bundler", :ENV
|
242
|
+
if gem_proxy = Bundler.rubygems.configuration[:http_proxy]
|
243
|
+
con.proxy = URI.parse(gem_proxy) if gem_proxy != :no_proxy
|
244
|
+
end
|
245
|
+
|
246
|
+
if remote_uri.scheme == "https"
|
247
|
+
con.verify_mode = (Bundler.settings[:ssl_verify_mode] ||
|
248
|
+
OpenSSL::SSL::VERIFY_PEER)
|
249
|
+
con.cert_store = bundler_cert_store
|
250
|
+
end
|
251
|
+
|
252
|
+
ssl_client_cert = Bundler.settings[:ssl_client_cert] ||
|
253
|
+
(Bundler.rubygems.configuration.ssl_client_cert if
|
254
|
+
Bundler.rubygems.configuration.respond_to?(:ssl_client_cert))
|
255
|
+
if ssl_client_cert
|
256
|
+
pem = File.read(ssl_client_cert)
|
257
|
+
con.cert = OpenSSL::X509::Certificate.new(pem)
|
258
|
+
con.key = OpenSSL::PKey::RSA.new(pem)
|
259
|
+
end
|
260
|
+
|
261
|
+
con.read_timeout = Fetcher.api_timeout
|
262
|
+
con.open_timeout = Fetcher.api_timeout
|
263
|
+
con.override_headers["User-Agent"] = user_agent
|
264
|
+
con.override_headers["X-Gemfile-Source"] = @remote.original_uri.to_s if @remote.original_uri
|
265
|
+
con
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# cached gem specification path, if one exists
|
270
|
+
def gemspec_cached_path(spec_file_name)
|
271
|
+
paths = Bundler.rubygems.spec_cache_dirs.map {|dir| File.join(dir, spec_file_name) }
|
272
|
+
paths = paths.select {|path| File.file? path }
|
273
|
+
paths.first
|
274
|
+
end
|
275
|
+
|
276
|
+
HTTP_ERRORS = [
|
277
|
+
Timeout::Error, EOFError, SocketError, Errno::ENETDOWN, Errno::ENETUNREACH,
|
278
|
+
Errno::EINVAL, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EAGAIN,
|
279
|
+
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
|
280
|
+
PersistentHTTP::Error, Zlib::BufError, Errno::EHOSTUNREACH
|
281
|
+
].freeze
|
282
|
+
|
283
|
+
def bundler_cert_store
|
284
|
+
store = OpenSSL::X509::Store.new
|
285
|
+
ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
|
286
|
+
(Bundler.rubygems.configuration.ssl_ca_cert if
|
287
|
+
Bundler.rubygems.configuration.respond_to?(:ssl_ca_cert))
|
288
|
+
if ssl_ca_cert
|
289
|
+
if File.directory? ssl_ca_cert
|
290
|
+
store.add_path ssl_ca_cert
|
291
|
+
else
|
292
|
+
store.add_file ssl_ca_cert
|
293
|
+
end
|
294
|
+
else
|
295
|
+
store.set_default_paths
|
296
|
+
certs = File.expand_path("../ssl_certs/*/*.pem", __FILE__)
|
297
|
+
Dir.glob(certs).each {|c| store.add_file c }
|
298
|
+
end
|
299
|
+
store
|
300
|
+
end
|
301
|
+
|
302
|
+
private
|
303
|
+
|
304
|
+
def remote_uri
|
305
|
+
@remote.uri
|
306
|
+
end
|
307
|
+
|
308
|
+
def downloader
|
309
|
+
@downloader ||= Downloader.new(connection, self.class.redirect_limit)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class Fetcher
|
5
|
+
class Base
|
6
|
+
attr_reader :downloader
|
7
|
+
attr_reader :display_uri
|
8
|
+
attr_reader :remote
|
9
|
+
|
10
|
+
def initialize(downloader, remote, display_uri)
|
11
|
+
raise "Abstract class" if self.class == Base
|
12
|
+
@downloader = downloader
|
13
|
+
@remote = remote
|
14
|
+
@display_uri = display_uri
|
15
|
+
end
|
16
|
+
|
17
|
+
def remote_uri
|
18
|
+
@remote.uri
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch_uri
|
22
|
+
@fetch_uri ||= begin
|
23
|
+
if remote_uri.host == "rubygems.org"
|
24
|
+
uri = remote_uri.dup
|
25
|
+
uri.host = "index.rubygems.org"
|
26
|
+
uri
|
27
|
+
else
|
28
|
+
remote_uri
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def available?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def api_fetcher?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def log_specs(debug_msg)
|
44
|
+
if Bundler.ui.debug?
|
45
|
+
Bundler.ui.debug debug_msg
|
46
|
+
else
|
47
|
+
Bundler.ui.info ".", false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/fetcher/base"
|
4
|
+
require "bundler/worker"
|
5
|
+
|
6
|
+
module Bundler
|
7
|
+
autoload :CompactIndexClient, "bundler/compact_index_client"
|
8
|
+
|
9
|
+
class Fetcher
|
10
|
+
class CompactIndex < Base
|
11
|
+
def self.compact_index_request(method_name)
|
12
|
+
method = instance_method(method_name)
|
13
|
+
undef_method(method_name)
|
14
|
+
define_method(method_name) do |*args, &blk|
|
15
|
+
begin
|
16
|
+
method.bind(self).call(*args, &blk)
|
17
|
+
rescue NetworkDownError, CompactIndexClient::Updater::MisMatchedChecksumError => e
|
18
|
+
raise HTTPError, e.message
|
19
|
+
rescue AuthenticationRequiredError
|
20
|
+
# Fail since we got a 401 from the server.
|
21
|
+
raise
|
22
|
+
rescue HTTPError => e
|
23
|
+
Bundler.ui.trace(e)
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def specs(gem_names)
|
30
|
+
specs_for_names(gem_names)
|
31
|
+
end
|
32
|
+
compact_index_request :specs
|
33
|
+
|
34
|
+
def specs_for_names(gem_names)
|
35
|
+
gem_info = []
|
36
|
+
complete_gems = []
|
37
|
+
remaining_gems = gem_names.dup
|
38
|
+
|
39
|
+
until remaining_gems.empty?
|
40
|
+
log_specs "Looking up gems #{remaining_gems.inspect}"
|
41
|
+
|
42
|
+
deps = compact_index_client.dependencies(remaining_gems)
|
43
|
+
next_gems = deps.map {|d| d[3].map(&:first).flatten(1) }.flatten(1).uniq
|
44
|
+
deps.each {|dep| gem_info << dep }
|
45
|
+
complete_gems.concat(deps.map(&:first)).uniq!
|
46
|
+
remaining_gems = next_gems - complete_gems
|
47
|
+
end
|
48
|
+
@bundle_worker.stop if @bundle_worker
|
49
|
+
@bundle_worker = nil # reset it. Not sure if necessary
|
50
|
+
|
51
|
+
gem_info
|
52
|
+
end
|
53
|
+
|
54
|
+
def fetch_spec(spec)
|
55
|
+
spec -= [nil, "ruby", ""]
|
56
|
+
contents = compact_index_client.spec(*spec)
|
57
|
+
return nil if contents.nil?
|
58
|
+
contents.unshift(spec.first)
|
59
|
+
contents[3].map! {|d| Gem::Dependency.new(*d) }
|
60
|
+
EndpointSpecification.new(*contents)
|
61
|
+
end
|
62
|
+
compact_index_request :fetch_spec
|
63
|
+
|
64
|
+
def available?
|
65
|
+
return nil unless SharedHelpers.md5_available?
|
66
|
+
user_home = Bundler.user_home
|
67
|
+
return nil unless user_home.directory? && user_home.writable?
|
68
|
+
# Read info file checksums out of /versions, so we can know if gems are up to date
|
69
|
+
fetch_uri.scheme != "file" && compact_index_client.update_and_parse_checksums!
|
70
|
+
rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
|
71
|
+
Bundler.ui.debug(e.message)
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
compact_index_request :available?
|
75
|
+
|
76
|
+
def api_fetcher?
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def compact_index_client
|
83
|
+
@compact_index_client ||= begin
|
84
|
+
SharedHelpers.filesystem_access(cache_path) do
|
85
|
+
CompactIndexClient.new(cache_path, client_fetcher)
|
86
|
+
end.tap do |client|
|
87
|
+
client.in_parallel = lambda do |inputs, &blk|
|
88
|
+
func = lambda {|object, _index| blk.call(object) }
|
89
|
+
worker = bundle_worker(func)
|
90
|
+
inputs.each {|input| worker.enq(input) }
|
91
|
+
inputs.map { worker.deq }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def bundle_worker(func = nil)
|
98
|
+
@bundle_worker ||= begin
|
99
|
+
worker_name = "Compact Index (#{display_uri.host})"
|
100
|
+
Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
|
101
|
+
end
|
102
|
+
@bundle_worker.tap do |worker|
|
103
|
+
worker.instance_variable_set(:@func, func) if func
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def cache_path
|
108
|
+
Bundler.user_cache.join("compact_index", remote.cache_slug)
|
109
|
+
end
|
110
|
+
|
111
|
+
def client_fetcher
|
112
|
+
ClientFetcher.new(self, Bundler.ui)
|
113
|
+
end
|
114
|
+
|
115
|
+
ClientFetcher = Struct.new(:fetcher, :ui) do
|
116
|
+
def call(path, headers)
|
117
|
+
fetcher.downloader.fetch(fetcher.fetch_uri + path, headers)
|
118
|
+
rescue NetworkDownError => e
|
119
|
+
raise unless Bundler.feature_flag.allow_offline_install? && headers["If-None-Match"]
|
120
|
+
ui.warn "Using the cached data for the new index because of a network error: #{e}"
|
121
|
+
Net::HTTPNotModified.new(nil, nil, nil)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|