rubygems-update 3.4.22 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +99 -2
- data/Manifest.txt +34 -221
- data/README.md +1 -3
- data/bundler/CHANGELOG.md +53 -0
- data/bundler/bundler.gemspec +4 -2
- data/bundler/exe/bundle +1 -10
- data/bundler/lib/bundler/build_metadata.rb +3 -3
- data/bundler/lib/bundler/capistrano.rb +1 -1
- data/bundler/lib/bundler/checksum.rb +245 -0
- data/bundler/lib/bundler/ci_detector.rb +75 -0
- data/bundler/lib/bundler/cli/add.rb +3 -3
- data/bundler/lib/bundler/cli/binstubs.rb +4 -4
- data/bundler/lib/bundler/cli/cache.rb +1 -1
- data/bundler/lib/bundler/cli/check.rb +1 -1
- data/bundler/lib/bundler/cli/common.rb +9 -1
- data/bundler/lib/bundler/cli/config.rb +8 -7
- data/bundler/lib/bundler/cli/console.rb +3 -2
- data/bundler/lib/bundler/cli/doctor.rb +2 -2
- data/bundler/lib/bundler/cli/exec.rb +1 -1
- data/bundler/lib/bundler/cli/gem.rb +28 -23
- data/bundler/lib/bundler/cli/info.rb +2 -13
- data/bundler/lib/bundler/cli/install.rb +5 -4
- data/bundler/lib/bundler/cli/issue.rb +1 -1
- data/bundler/lib/bundler/cli/lock.rb +4 -4
- data/bundler/lib/bundler/cli/open.rb +1 -1
- data/bundler/lib/bundler/cli/outdated.rb +6 -6
- data/bundler/lib/bundler/cli/plugin.rb +7 -14
- data/bundler/lib/bundler/cli/pristine.rb +38 -30
- data/bundler/lib/bundler/cli/show.rb +2 -2
- data/bundler/lib/bundler/cli/update.rb +5 -5
- data/bundler/lib/bundler/cli.rb +215 -263
- data/bundler/lib/bundler/compact_index_client/cache.rb +29 -9
- data/bundler/lib/bundler/compact_index_client/cache_file.rb +153 -0
- data/bundler/lib/bundler/compact_index_client/gem_parser.rb +7 -3
- data/bundler/lib/bundler/compact_index_client/updater.rb +79 -81
- data/bundler/lib/bundler/compact_index_client.rb +14 -7
- data/bundler/lib/bundler/constants.rb +1 -1
- data/bundler/lib/bundler/current_ruby.rb +5 -21
- data/bundler/lib/bundler/definition.rb +42 -15
- data/bundler/lib/bundler/dependency.rb +16 -12
- data/bundler/lib/bundler/digest.rb +2 -2
- data/bundler/lib/bundler/dsl.rb +43 -25
- data/bundler/lib/bundler/endpoint_specification.rb +5 -1
- data/bundler/lib/bundler/env.rb +1 -3
- data/bundler/lib/bundler/errors.rb +43 -0
- data/bundler/lib/bundler/fetcher/base.rb +3 -1
- data/bundler/lib/bundler/fetcher/compact_index.rb +4 -4
- data/bundler/lib/bundler/fetcher/downloader.rb +13 -11
- data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
- data/bundler/lib/bundler/fetcher/index.rb +1 -1
- data/bundler/lib/bundler/fetcher.rb +28 -25
- data/bundler/lib/bundler/friendly_errors.rb +5 -5
- data/bundler/lib/bundler/gem_helper.rb +1 -1
- data/bundler/lib/bundler/gem_helpers.rb +5 -2
- data/bundler/lib/bundler/graph.rb +9 -9
- data/bundler/lib/bundler/index.rb +1 -2
- data/bundler/lib/bundler/injector.rb +1 -1
- data/bundler/lib/bundler/inline.rb +3 -3
- data/bundler/lib/bundler/installer/gem_installer.rb +5 -5
- data/bundler/lib/bundler/installer/parallel_installer.rb +16 -8
- data/bundler/lib/bundler/installer/standalone.rb +2 -3
- data/bundler/lib/bundler/installer.rb +9 -9
- data/bundler/lib/bundler/lazy_specification.rb +24 -17
- data/bundler/lib/bundler/lockfile_generator.rb +9 -0
- data/bundler/lib/bundler/lockfile_parser.rb +81 -10
- data/bundler/lib/bundler/man/bundle-add.1 +3 -26
- data/bundler/lib/bundler/man/bundle-binstubs.1 +4 -16
- data/bundler/lib/bundler/man/bundle-cache.1 +3 -24
- data/bundler/lib/bundler/man/bundle-check.1 +3 -12
- data/bundler/lib/bundler/man/bundle-clean.1 +3 -10
- data/bundler/lib/bundler/man/bundle-config.1 +20 -211
- data/bundler/lib/bundler/man/bundle-config.1.ronn +6 -0
- data/bundler/lib/bundler/man/bundle-console.1 +4 -22
- data/bundler/lib/bundler/man/bundle-doctor.1 +4 -18
- data/bundler/lib/bundler/man/bundle-exec.1 +12 -73
- data/bundler/lib/bundler/man/bundle-gem.1 +13 -49
- data/bundler/lib/bundler/man/bundle-help.1 +3 -7
- data/bundler/lib/bundler/man/bundle-info.1 +3 -9
- data/bundler/lib/bundler/man/bundle-init.1 +3 -12
- data/bundler/lib/bundler/man/bundle-inject.1 +6 -19
- data/bundler/lib/bundler/man/bundle-install.1 +27 -125
- data/bundler/lib/bundler/man/bundle-install.1.ronn +1 -0
- data/bundler/lib/bundler/man/bundle-list.1 +4 -19
- data/bundler/lib/bundler/man/bundle-lock.1 +5 -29
- data/bundler/lib/bundler/man/bundle-open.1 +7 -27
- data/bundler/lib/bundler/man/bundle-outdated.1 +3 -55
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -0
- data/bundler/lib/bundler/man/bundle-platform.1 +5 -27
- data/bundler/lib/bundler/man/bundle-plugin.1 +3 -29
- data/bundler/lib/bundler/man/bundle-pristine.1 +5 -16
- data/bundler/lib/bundler/man/bundle-remove.1 +4 -14
- data/bundler/lib/bundler/man/bundle-show.1 +3 -10
- data/bundler/lib/bundler/man/bundle-update.1 +18 -137
- data/bundler/lib/bundler/man/bundle-version.1 +3 -16
- data/bundler/lib/bundler/man/bundle-viz.1 +4 -16
- data/bundler/lib/bundler/man/bundle.1 +5 -44
- data/bundler/lib/bundler/man/gemfile.5 +24 -301
- data/bundler/lib/bundler/man/gemfile.5.ronn +4 -0
- data/bundler/lib/bundler/match_metadata.rb +4 -0
- data/bundler/lib/bundler/match_platform.rb +1 -1
- data/bundler/lib/bundler/plugin/api/source.rb +3 -2
- data/bundler/lib/bundler/plugin/installer.rb +1 -1
- data/bundler/lib/bundler/plugin.rb +3 -3
- data/bundler/lib/bundler/resolver/base.rb +1 -1
- data/bundler/lib/bundler/resolver/incompatibility.rb +1 -1
- data/bundler/lib/bundler/resolver/spec_group.rb +1 -4
- data/bundler/lib/bundler/resolver.rb +16 -16
- data/bundler/lib/bundler/ruby_dsl.rb +20 -12
- data/bundler/lib/bundler/ruby_version.rb +1 -1
- data/bundler/lib/bundler/rubygems_ext.rb +24 -50
- data/bundler/lib/bundler/rubygems_gem_installer.rb +6 -56
- data/bundler/lib/bundler/rubygems_integration.rb +25 -94
- data/bundler/lib/bundler/runtime.rb +2 -2
- data/bundler/lib/bundler/self_manager.rb +23 -7
- data/bundler/lib/bundler/settings.rb +27 -7
- data/bundler/lib/bundler/setup.rb +4 -1
- data/bundler/lib/bundler/shared_helpers.rb +35 -13
- data/bundler/lib/bundler/source/git/git_proxy.rb +15 -15
- data/bundler/lib/bundler/source/git.rb +4 -3
- data/bundler/lib/bundler/source/metadata.rb +15 -15
- data/bundler/lib/bundler/source/path.rb +7 -6
- data/bundler/lib/bundler/source/rubygems.rb +21 -14
- data/bundler/lib/bundler/source.rb +2 -0
- data/bundler/lib/bundler/spec_set.rb +38 -10
- data/bundler/lib/bundler/stub_specification.rb +1 -0
- data/bundler/lib/bundler/templates/Executable.bundler +1 -1
- data/bundler/lib/bundler/templates/newgem/README.md.tt +3 -3
- data/bundler/lib/bundler/templates/newgem/Rakefile.tt +2 -6
- data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/bundler/lib/bundler/templates/newgem/standard.yml.tt +1 -1
- data/bundler/lib/bundler/ui/shell.rb +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +53 -6
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +8 -20
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +3 -3
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +2 -2
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +35 -35
- data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +3 -0
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +256 -132
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +1 -0
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +95 -31
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/vendored_net_http.rb +8 -0
- data/bundler/lib/bundler/vendored_persistent.rb +0 -4
- data/bundler/lib/bundler/vendored_timeout.rb +8 -0
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler/vlad.rb +1 -1
- data/bundler/lib/bundler/yaml_serializer.rb +3 -3
- data/bundler/lib/bundler.rb +38 -27
- data/lib/rubygems/available_set.rb +4 -4
- data/lib/rubygems/basic_specification.rb +35 -37
- data/lib/rubygems/bundler_version_finder.rb +4 -4
- data/lib/rubygems/ci_detector.rb +75 -0
- data/lib/rubygems/command.rb +13 -15
- data/lib/rubygems/command_manager.rb +5 -4
- data/lib/rubygems/commands/build_command.rb +2 -2
- data/lib/rubygems/commands/cert_command.rb +1 -2
- data/lib/rubygems/commands/check_command.rb +4 -4
- data/lib/rubygems/commands/cleanup_command.rb +12 -14
- data/lib/rubygems/commands/contents_command.rb +4 -4
- data/lib/rubygems/commands/dependency_command.rb +4 -5
- data/lib/rubygems/commands/environment_command.rb +1 -3
- data/lib/rubygems/commands/exec_command.rb +1 -1
- data/lib/rubygems/commands/fetch_command.rb +2 -2
- data/lib/rubygems/commands/generate_index_command.rb +39 -74
- data/lib/rubygems/commands/help_command.rb +3 -3
- data/lib/rubygems/commands/info_command.rb +2 -2
- data/lib/rubygems/commands/install_command.rb +8 -16
- data/lib/rubygems/commands/list_command.rb +2 -2
- data/lib/rubygems/commands/lock_command.rb +1 -1
- data/lib/rubygems/commands/open_command.rb +1 -1
- data/lib/rubygems/commands/owner_command.rb +1 -1
- data/lib/rubygems/commands/pristine_command.rb +13 -15
- data/lib/rubygems/commands/push_command.rb +2 -2
- data/lib/rubygems/commands/query_command.rb +4 -5
- data/lib/rubygems/commands/rdoc_command.rb +2 -2
- data/lib/rubygems/commands/search_command.rb +2 -2
- data/lib/rubygems/commands/setup_command.rb +31 -34
- data/lib/rubygems/commands/sources_command.rb +12 -12
- data/lib/rubygems/commands/specification_command.rb +10 -10
- data/lib/rubygems/commands/stale_command.rb +1 -1
- data/lib/rubygems/commands/uninstall_command.rb +9 -10
- data/lib/rubygems/commands/unpack_command.rb +4 -4
- data/lib/rubygems/commands/update_command.rb +10 -12
- data/lib/rubygems/commands/which_command.rb +1 -1
- data/lib/rubygems/commands/yank_command.rb +1 -1
- data/lib/rubygems/compatibility.rb +5 -6
- data/lib/rubygems/config_file.rb +4 -4
- data/lib/rubygems/core_ext/kernel_gem.rb +0 -2
- data/lib/rubygems/core_ext/kernel_require.rb +19 -48
- data/lib/rubygems/core_ext/kernel_warn.rb +1 -1
- data/lib/rubygems/core_ext/tcpsocket_init.rb +1 -1
- data/lib/rubygems/defaults.rb +15 -3
- data/lib/rubygems/dependency.rb +12 -14
- data/lib/rubygems/dependency_installer.rb +29 -30
- data/lib/rubygems/dependency_list.rb +1 -1
- data/lib/rubygems/deprecate.rb +16 -15
- data/lib/rubygems/doctor.rb +5 -5
- data/lib/rubygems/errors.rb +2 -6
- data/lib/rubygems/exceptions.rb +2 -1
- data/lib/rubygems/ext/builder.rb +15 -10
- data/lib/rubygems/ext/cargo_builder.rb +5 -5
- data/lib/rubygems/ext/ext_conf_builder.rb +1 -3
- data/lib/rubygems/gem_runner.rb +4 -4
- data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +3 -3
- data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -3
- data/lib/rubygems/gemcutter_utilities.rb +18 -19
- data/lib/rubygems/install_update_options.rb +18 -19
- data/lib/rubygems/installer.rb +59 -33
- data/lib/rubygems/installer_uninstaller_utils.rb +0 -2
- data/lib/rubygems/local_remote_options.rb +7 -10
- data/lib/rubygems/name_tuple.rb +7 -9
- data/lib/rubygems/net/http.rb +3 -0
- data/lib/rubygems/net-http/LICENSE.txt +22 -0
- data/lib/rubygems/net-http/lib/net/http/backward.rb +40 -0
- data/lib/rubygems/net-http/lib/net/http/exceptions.rb +34 -0
- data/lib/rubygems/net-http/lib/net/http/generic_request.rb +414 -0
- data/lib/rubygems/net-http/lib/net/http/header.rb +981 -0
- data/lib/rubygems/net-http/lib/net/http/proxy_delta.rb +17 -0
- data/lib/rubygems/net-http/lib/net/http/request.rb +88 -0
- data/lib/rubygems/net-http/lib/net/http/requests.rb +425 -0
- data/lib/rubygems/net-http/lib/net/http/response.rb +738 -0
- data/lib/rubygems/net-http/lib/net/http/responses.rb +1174 -0
- data/lib/rubygems/net-http/lib/net/http/status.rb +84 -0
- data/lib/rubygems/net-http/lib/net/http.rb +2496 -0
- data/lib/rubygems/net-http/lib/net/https.rb +23 -0
- data/lib/rubygems/net-protocol/LICENSE.txt +22 -0
- data/lib/rubygems/net-protocol/lib/net/protocol.rb +544 -0
- data/lib/rubygems/optparse/lib/optparse.rb +39 -17
- data/lib/rubygems/package/old.rb +2 -2
- data/lib/rubygems/package/tar_header.rb +45 -39
- data/lib/rubygems/package/tar_reader/entry.rb +5 -4
- data/lib/rubygems/package/tar_reader.rb +5 -3
- data/lib/rubygems/package/tar_writer.rb +19 -17
- data/lib/rubygems/package.rb +27 -26
- data/lib/rubygems/package_task.rb +2 -2
- data/lib/rubygems/path_support.rb +9 -10
- data/lib/rubygems/platform.rb +60 -45
- data/lib/rubygems/query_utils.rb +7 -9
- data/lib/rubygems/remote_fetcher.rb +15 -15
- data/lib/rubygems/request/connection_pools.rb +3 -3
- data/lib/rubygems/request.rb +20 -17
- data/lib/rubygems/request_set/gem_dependency_api.rb +119 -122
- data/lib/rubygems/request_set/lockfile/parser.rb +9 -9
- data/lib/rubygems/request_set/lockfile/tokenizer.rb +20 -12
- data/lib/rubygems/request_set/lockfile.rb +6 -11
- data/lib/rubygems/request_set.rb +5 -5
- data/lib/rubygems/requirement.rb +7 -7
- data/lib/rubygems/resolv/LICENSE.txt +22 -0
- data/lib/rubygems/resolv/lib/resolv.rb +3387 -0
- data/lib/rubygems/resolver/activation_request.rb +1 -3
- data/lib/rubygems/resolver/api_set/gem_parser.rb +7 -3
- data/lib/rubygems/resolver/best_set.rb +1 -1
- data/lib/rubygems/resolver/composed_set.rb +1 -1
- data/lib/rubygems/resolver/conflict.rb +4 -12
- data/lib/rubygems/resolver/index_set.rb +4 -4
- data/lib/rubygems/resolver/index_specification.rb +2 -2
- data/lib/rubygems/resolver/installer_set.rb +5 -6
- data/lib/rubygems/resolver/lock_set.rb +1 -1
- data/lib/rubygems/resolver.rb +3 -10
- data/lib/rubygems/s3_uri_signer.rb +6 -6
- data/lib/rubygems/safe_marshal/elements.rb +138 -0
- data/lib/rubygems/safe_marshal/reader.rb +306 -0
- data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
- data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +385 -0
- data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
- data/lib/rubygems/safe_marshal.rb +74 -0
- data/lib/rubygems/safe_yaml.rb +5 -28
- data/lib/rubygems/security/policies.rb +36 -38
- data/lib/rubygems/security/policy.rb +7 -11
- data/lib/rubygems/security/signer.rb +1 -1
- data/lib/rubygems/security/trust_dir.rb +3 -3
- data/lib/rubygems/security.rb +8 -22
- data/lib/rubygems/source/git.rb +1 -3
- data/lib/rubygems/source/installed.rb +0 -2
- data/lib/rubygems/source/local.rb +5 -8
- data/lib/rubygems/source/lock.rb +1 -3
- data/lib/rubygems/source/specific_file.rb +0 -1
- data/lib/rubygems/source/vendor.rb +0 -2
- data/lib/rubygems/source.rb +12 -12
- data/lib/rubygems/source_list.rb +4 -4
- data/lib/rubygems/spec_fetcher.rb +29 -29
- data/lib/rubygems/specification.rb +125 -138
- data/lib/rubygems/specification_policy.rb +55 -25
- data/lib/rubygems/stub_specification.rb +4 -5
- data/lib/rubygems/text.rb +1 -2
- data/lib/rubygems/timeout/LICENSE.txt +22 -0
- data/lib/rubygems/timeout/lib/timeout.rb +199 -0
- data/lib/rubygems/timeout.rb +3 -0
- data/lib/rubygems/tsort/lib/tsort.rb +3 -0
- data/lib/rubygems/uninstaller.rb +7 -9
- data/lib/rubygems/update_suggestion.rb +5 -18
- data/lib/rubygems/uri_formatter.rb +1 -1
- data/lib/rubygems/user_interaction.rb +15 -21
- data/lib/rubygems/util/licenses.rb +65 -35
- data/lib/rubygems/util/list.rb +3 -1
- data/lib/rubygems/util.rb +2 -4
- data/lib/rubygems/validator.rb +5 -3
- data/lib/rubygems/version.rb +34 -28
- data/lib/rubygems/version_option.rb +2 -5
- data/lib/rubygems/yaml_serializer.rb +3 -3
- data/lib/rubygems.rb +37 -37
- data/rubygems-update.gemspec +4 -4
- data/setup.rb +2 -2
- metadata +38 -225
- data/lib/rubygems/indexer.rb +0 -428
- data/lib/rubygems/mock_gem_ui.rb +0 -86
- data/test/rubygems/alternate_cert.pem +0 -19
- data/test/rubygems/alternate_cert_32.pem +0 -19
- data/test/rubygems/alternate_key.pem +0 -27
- data/test/rubygems/bad_rake.rb +0 -3
- data/test/rubygems/bundler_test_gem.rb +0 -424
- data/test/rubygems/ca_cert.pem +0 -77
- data/test/rubygems/child_cert.pem +0 -19
- data/test/rubygems/child_cert_32.pem +0 -19
- data/test/rubygems/child_key.pem +0 -27
- data/test/rubygems/client.pem +0 -107
- data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
- data/test/rubygems/data/gem-private_key.pem +0 -27
- data/test/rubygems/data/gem-public_cert.pem +0 -20
- data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
- data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
- data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
- data/test/rubygems/encrypted_private_key.pem +0 -30
- data/test/rubygems/expired_cert.pem +0 -19
- data/test/rubygems/fake_certlib/openssl.rb +0 -9
- data/test/rubygems/foo/discover.rb +0 -1
- data/test/rubygems/future_cert.pem +0 -19
- data/test/rubygems/future_cert_32.pem +0 -19
- data/test/rubygems/good_rake.rb +0 -3
- data/test/rubygems/grandchild_cert.pem +0 -19
- data/test/rubygems/grandchild_cert_32.pem +0 -19
- data/test/rubygems/grandchild_key.pem +0 -27
- data/test/rubygems/helper.rb +0 -1649
- data/test/rubygems/installer_test_case.rb +0 -248
- data/test/rubygems/invalid_client.pem +0 -49
- data/test/rubygems/invalid_issuer_cert.pem +0 -20
- data/test/rubygems/invalid_issuer_cert_32.pem +0 -20
- data/test/rubygems/invalid_key.pem +0 -27
- data/test/rubygems/invalid_signer_cert.pem +0 -19
- data/test/rubygems/invalid_signer_cert_32.pem +0 -19
- data/test/rubygems/invalidchild_cert.pem +0 -19
- data/test/rubygems/invalidchild_cert_32.pem +0 -19
- data/test/rubygems/invalidchild_key.pem +0 -27
- data/test/rubygems/multifactor_auth_utilities.rb +0 -111
- data/test/rubygems/package/tar_test_case.rb +0 -175
- data/test/rubygems/packages/Bluebie-legs-0.6.2.gem +0 -0
- data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
- data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
- data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -4
- data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -5
- data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -4
- data/test/rubygems/private3072_key.pem +0 -40
- data/test/rubygems/private_ec_key.pem +0 -9
- data/test/rubygems/private_key.pem +0 -27
- data/test/rubygems/public3072_cert.pem +0 -25
- data/test/rubygems/public_cert.pem +0 -20
- data/test/rubygems/public_cert_32.pem +0 -19
- data/test/rubygems/public_key.pem +0 -9
- data/test/rubygems/rubygems/commands/crash_command.rb +0 -5
- data/test/rubygems/rubygems_plugin.rb +0 -24
- data/test/rubygems/sff/discover.rb +0 -1
- data/test/rubygems/simple_gem.rb +0 -68
- data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -9
- data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
- data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +0 -14
- data/test/rubygems/ssl_cert.pem +0 -80
- data/test/rubygems/ssl_key.pem +0 -27
- data/test/rubygems/test_bundled_ca.rb +0 -61
- data/test/rubygems/test_config.rb +0 -28
- data/test/rubygems/test_deprecate.rb +0 -158
- data/test/rubygems/test_exit.rb +0 -17
- data/test/rubygems/test_gem.rb +0 -1799
- data/test/rubygems/test_gem_available_set.rb +0 -130
- data/test/rubygems/test_gem_bundler_version_finder.rb +0 -127
- data/test/rubygems/test_gem_command.rb +0 -403
- data/test/rubygems/test_gem_command_manager.rb +0 -400
- data/test/rubygems/test_gem_commands_build_command.rb +0 -739
- data/test/rubygems/test_gem_commands_cert_command.rb +0 -866
- data/test/rubygems/test_gem_commands_check_command.rb +0 -68
- data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -292
- data/test/rubygems/test_gem_commands_contents_command.rb +0 -271
- data/test/rubygems/test_gem_commands_dependency_command.rb +0 -228
- data/test/rubygems/test_gem_commands_environment_command.rb +0 -169
- data/test/rubygems/test_gem_commands_exec_command.rb +0 -857
- data/test/rubygems/test_gem_commands_fetch_command.rb +0 -258
- data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -81
- data/test/rubygems/test_gem_commands_help_command.rb +0 -94
- data/test/rubygems/test_gem_commands_info_command.rb +0 -70
- data/test/rubygems/test_gem_commands_install_command.rb +0 -1573
- data/test/rubygems/test_gem_commands_list_command.rb +0 -33
- data/test/rubygems/test_gem_commands_lock_command.rb +0 -67
- data/test/rubygems/test_gem_commands_mirror.rb +0 -20
- data/test/rubygems/test_gem_commands_open_command.rb +0 -101
- data/test/rubygems/test_gem_commands_outdated_command.rb +0 -50
- data/test/rubygems/test_gem_commands_owner_command.rb +0 -503
- data/test/rubygems/test_gem_commands_pristine_command.rb +0 -708
- data/test/rubygems/test_gem_commands_push_command.rb +0 -603
- data/test/rubygems/test_gem_commands_query_command.rb +0 -858
- data/test/rubygems/test_gem_commands_search_command.rb +0 -16
- data/test/rubygems/test_gem_commands_server_command.rb +0 -20
- data/test/rubygems/test_gem_commands_setup_command.rb +0 -474
- data/test/rubygems/test_gem_commands_signin_command.rb +0 -259
- data/test/rubygems/test_gem_commands_signout_command.rb +0 -30
- data/test/rubygems/test_gem_commands_sources_command.rb +0 -534
- data/test/rubygems/test_gem_commands_specification_command.rb +0 -277
- data/test/rubygems/test_gem_commands_stale_command.rb +0 -43
- data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -542
- data/test/rubygems/test_gem_commands_unpack_command.rb +0 -224
- data/test/rubygems/test_gem_commands_update_command.rb +0 -836
- data/test/rubygems/test_gem_commands_which_command.rb +0 -85
- data/test/rubygems/test_gem_commands_yank_command.rb +0 -299
- data/test/rubygems/test_gem_config_file.rb +0 -551
- data/test/rubygems/test_gem_dependency.rb +0 -398
- data/test/rubygems/test_gem_dependency_installer.rb +0 -1190
- data/test/rubygems/test_gem_dependency_list.rb +0 -265
- data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -27
- data/test/rubygems/test_gem_doctor.rb +0 -195
- data/test/rubygems/test_gem_ext_builder.rb +0 -337
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +0 -1
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock +0 -249
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs +0 -27
- data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +0 -3
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +0 -1
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +0 -249
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +0 -10
- data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +0 -51
- data/test/rubygems/test_gem_ext_cargo_builder.rb +0 -167
- data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +0 -34
- data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -60
- data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -84
- data/test/rubygems/test_gem_ext_configure_builder.rb +0 -80
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -229
- data/test/rubygems/test_gem_ext_rake_builder.rb +0 -113
- data/test/rubygems/test_gem_gem_runner.rb +0 -119
- data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -361
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -60
- data/test/rubygems/test_gem_indexer.rb +0 -381
- data/test/rubygems/test_gem_install_update_options.rb +0 -208
- data/test/rubygems/test_gem_installer.rb +0 -2512
- data/test/rubygems/test_gem_local_remote_options.rb +0 -133
- data/test/rubygems/test_gem_name_tuple.rb +0 -43
- data/test/rubygems/test_gem_package.rb +0 -1306
- data/test/rubygems/test_gem_package_old.rb +0 -91
- data/test/rubygems/test_gem_package_tar_header.rb +0 -226
- data/test/rubygems/test_gem_package_tar_reader.rb +0 -150
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -350
- data/test/rubygems/test_gem_package_tar_writer.rb +0 -331
- data/test/rubygems/test_gem_package_task.rb +0 -118
- data/test/rubygems/test_gem_path_support.rb +0 -139
- data/test/rubygems/test_gem_platform.rb +0 -497
- data/test/rubygems/test_gem_rdoc.rb +0 -137
- data/test/rubygems/test_gem_remote_fetcher.rb +0 -1227
- data/test/rubygems/test_gem_request.rb +0 -547
- data/test/rubygems/test_gem_request_connection_pools.rb +0 -152
- data/test/rubygems/test_gem_request_set.rb +0 -672
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -853
- data/test/rubygems/test_gem_request_set_lockfile.rb +0 -469
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -544
- data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -307
- data/test/rubygems/test_gem_requirement.rb +0 -505
- data/test/rubygems/test_gem_resolver.rb +0 -859
- data/test/rubygems/test_gem_resolver_activation_request.rb +0 -43
- data/test/rubygems/test_gem_resolver_api_set.rb +0 -210
- data/test/rubygems/test_gem_resolver_api_specification.rb +0 -167
- data/test/rubygems/test_gem_resolver_best_set.rb +0 -159
- data/test/rubygems/test_gem_resolver_composed_set.rb +0 -44
- data/test/rubygems/test_gem_resolver_conflict.rb +0 -82
- data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -83
- data/test/rubygems/test_gem_resolver_git_set.rb +0 -188
- data/test/rubygems/test_gem_resolver_git_specification.rb +0 -114
- data/test/rubygems/test_gem_resolver_index_set.rb +0 -88
- data/test/rubygems/test_gem_resolver_index_specification.rb +0 -93
- data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -47
- data/test/rubygems/test_gem_resolver_installer_set.rb +0 -320
- data/test/rubygems/test_gem_resolver_local_specification.rb +0 -44
- data/test/rubygems/test_gem_resolver_lock_set.rb +0 -62
- data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -98
- data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -19
- data/test/rubygems/test_gem_resolver_specification.rb +0 -63
- data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -82
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -82
- data/test/rubygems/test_gem_security.rb +0 -341
- data/test/rubygems/test_gem_security_policy.rb +0 -535
- data/test/rubygems/test_gem_security_signer.rb +0 -218
- data/test/rubygems/test_gem_security_trust_dir.rb +0 -99
- data/test/rubygems/test_gem_silent_ui.rb +0 -123
- data/test/rubygems/test_gem_source.rb +0 -254
- data/test/rubygems/test_gem_source_fetch_problem.rb +0 -37
- data/test/rubygems/test_gem_source_git.rb +0 -310
- data/test/rubygems/test_gem_source_installed.rb +0 -35
- data/test/rubygems/test_gem_source_list.rb +0 -119
- data/test/rubygems/test_gem_source_local.rb +0 -107
- data/test/rubygems/test_gem_source_lock.rb +0 -113
- data/test/rubygems/test_gem_source_specific_file.rb +0 -76
- data/test/rubygems/test_gem_source_subpath_problem.rb +0 -50
- data/test/rubygems/test_gem_source_vendor.rb +0 -30
- data/test/rubygems/test_gem_spec_fetcher.rb +0 -338
- data/test/rubygems/test_gem_specification.rb +0 -3856
- data/test/rubygems/test_gem_stream_ui.rb +0 -255
- data/test/rubygems/test_gem_stub_specification.rb +0 -278
- data/test/rubygems/test_gem_text.rb +0 -103
- data/test/rubygems/test_gem_uninstaller.rb +0 -675
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -31
- data/test/rubygems/test_gem_update_suggestion.rb +0 -209
- data/test/rubygems/test_gem_uri.rb +0 -41
- data/test/rubygems/test_gem_uri_formatter.rb +0 -27
- data/test/rubygems/test_gem_util.rb +0 -91
- data/test/rubygems/test_gem_validator.rb +0 -42
- data/test/rubygems/test_gem_version.rb +0 -305
- data/test/rubygems/test_gem_version_option.rb +0 -165
- data/test/rubygems/test_kernel.rb +0 -124
- data/test/rubygems/test_project_sanity.rb +0 -49
- data/test/rubygems/test_remote_fetch_error.rb +0 -20
- data/test/rubygems/test_require.rb +0 -732
- data/test/rubygems/test_rubygems.rb +0 -76
- data/test/rubygems/test_webauthn_listener.rb +0 -143
- data/test/rubygems/test_webauthn_listener_response.rb +0 -93
- data/test/rubygems/test_webauthn_poller.rb +0 -124
- data/test/rubygems/utilities.rb +0 -436
- data/test/rubygems/wrong_key_cert.pem +0 -19
- data/test/rubygems/wrong_key_cert_32.pem +0 -19
- data/test/test_changelog_generator.rb +0 -17
@@ -9,11 +9,8 @@ module Bundler
|
|
9
9
|
|
10
10
|
def initialize(directory)
|
11
11
|
@directory = Pathname.new(directory).expand_path
|
12
|
-
info_roots.each
|
13
|
-
|
14
|
-
FileUtils.mkdir_p(dir)
|
15
|
-
end
|
16
|
-
end
|
12
|
+
info_roots.each {|dir| mkdir(dir) }
|
13
|
+
mkdir(info_etag_root)
|
17
14
|
end
|
18
15
|
|
19
16
|
def names
|
@@ -24,6 +21,10 @@ module Bundler
|
|
24
21
|
directory.join("names")
|
25
22
|
end
|
26
23
|
|
24
|
+
def names_etag_path
|
25
|
+
directory.join("names.etag")
|
26
|
+
end
|
27
|
+
|
27
28
|
def versions
|
28
29
|
versions_by_name = Hash.new {|hash, key| hash[key] = [] }
|
29
30
|
info_checksums_by_name = {}
|
@@ -31,12 +32,12 @@ module Bundler
|
|
31
32
|
lines(versions_path).each do |line|
|
32
33
|
name, versions_string, info_checksum = line.split(" ", 3)
|
33
34
|
info_checksums_by_name[name] = info_checksum || ""
|
34
|
-
versions_string.split(",")
|
35
|
-
|
36
|
-
|
35
|
+
versions_string.split(",") do |version|
|
36
|
+
delete = version.delete_prefix!("-")
|
37
|
+
version = version.split("-", 2).unshift(name)
|
38
|
+
if delete
|
37
39
|
versions_by_name[name].delete(version)
|
38
40
|
else
|
39
|
-
version = version.split("-", 2).unshift(name)
|
40
41
|
versions_by_name[name] << version
|
41
42
|
end
|
42
43
|
end
|
@@ -49,6 +50,10 @@ module Bundler
|
|
49
50
|
directory.join("versions")
|
50
51
|
end
|
51
52
|
|
53
|
+
def versions_etag_path
|
54
|
+
directory.join("versions.etag")
|
55
|
+
end
|
56
|
+
|
52
57
|
def checksums
|
53
58
|
checksums = {}
|
54
59
|
|
@@ -76,8 +81,19 @@ module Bundler
|
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
84
|
+
def info_etag_path(name)
|
85
|
+
name = name.to_s
|
86
|
+
info_etag_root.join("#{name}-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}")
|
87
|
+
end
|
88
|
+
|
79
89
|
private
|
80
90
|
|
91
|
+
def mkdir(dir)
|
92
|
+
SharedHelpers.filesystem_access(dir) do
|
93
|
+
FileUtils.mkdir_p(dir)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
81
97
|
def lines(path)
|
82
98
|
return [] unless path.file?
|
83
99
|
lines = SharedHelpers.filesystem_access(path, :read, &:read).split("\n")
|
@@ -96,6 +112,10 @@ module Bundler
|
|
96
112
|
directory.join("info-special-characters"),
|
97
113
|
]
|
98
114
|
end
|
115
|
+
|
116
|
+
def info_etag_root
|
117
|
+
directory.join("info-etags")
|
118
|
+
end
|
99
119
|
end
|
100
120
|
end
|
101
121
|
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../vendored_fileutils"
|
4
|
+
require "rubygems/package"
|
5
|
+
|
6
|
+
module Bundler
|
7
|
+
class CompactIndexClient
|
8
|
+
# write cache files in a way that is robust to concurrent modifications
|
9
|
+
# if digests are given, the checksums will be verified
|
10
|
+
class CacheFile
|
11
|
+
DEFAULT_FILE_MODE = 0o644
|
12
|
+
private_constant :DEFAULT_FILE_MODE
|
13
|
+
|
14
|
+
class Error < RuntimeError; end
|
15
|
+
class ClosedError < Error; end
|
16
|
+
|
17
|
+
class DigestMismatchError < Error
|
18
|
+
def initialize(digests, expected_digests)
|
19
|
+
super "Calculated checksums #{digests.inspect} did not match expected #{expected_digests.inspect}."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Initialize with a copy of the original file, then yield the instance.
|
24
|
+
def self.copy(path, &block)
|
25
|
+
new(path) do |file|
|
26
|
+
file.initialize_digests
|
27
|
+
|
28
|
+
SharedHelpers.filesystem_access(path, :read) do
|
29
|
+
path.open("rb") do |s|
|
30
|
+
file.open {|f| IO.copy_stream(s, f) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
yield file
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Write data to a temp file, then replace the original file with it verifying the digests if given.
|
39
|
+
def self.write(path, data, digests = nil)
|
40
|
+
return unless data
|
41
|
+
new(path) do |file|
|
42
|
+
file.digests = digests
|
43
|
+
file.write(data)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :original_path, :path
|
48
|
+
|
49
|
+
def initialize(original_path, &block)
|
50
|
+
@original_path = original_path
|
51
|
+
@perm = original_path.file? ? original_path.stat.mode : DEFAULT_FILE_MODE
|
52
|
+
@path = original_path.sub(/$/, ".#{$$}.tmp")
|
53
|
+
return unless block_given?
|
54
|
+
begin
|
55
|
+
yield self
|
56
|
+
ensure
|
57
|
+
close
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def size
|
62
|
+
path.size
|
63
|
+
end
|
64
|
+
|
65
|
+
# initialize the digests using CompactIndexClient::SUPPORTED_DIGESTS, or a subset based on keys.
|
66
|
+
def initialize_digests(keys = nil)
|
67
|
+
@digests = keys ? SUPPORTED_DIGESTS.slice(*keys) : SUPPORTED_DIGESTS.dup
|
68
|
+
@digests.transform_values! {|algo_class| SharedHelpers.digest(algo_class).new }
|
69
|
+
end
|
70
|
+
|
71
|
+
# reset the digests so they don't contain any previously read data
|
72
|
+
def reset_digests
|
73
|
+
@digests&.each_value(&:reset)
|
74
|
+
end
|
75
|
+
|
76
|
+
# set the digests that will be verified at the end
|
77
|
+
def digests=(expected_digests)
|
78
|
+
@expected_digests = expected_digests
|
79
|
+
|
80
|
+
if @expected_digests.nil?
|
81
|
+
@digests = nil
|
82
|
+
elsif @digests
|
83
|
+
@digests = @digests.slice(*@expected_digests.keys)
|
84
|
+
else
|
85
|
+
initialize_digests(@expected_digests.keys)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# remove this method when we stop generating md5 digests for legacy etags
|
90
|
+
def md5
|
91
|
+
@digests && @digests["md5"]
|
92
|
+
end
|
93
|
+
|
94
|
+
def digests?
|
95
|
+
@digests&.any?
|
96
|
+
end
|
97
|
+
|
98
|
+
# Open the temp file for writing, reusing original permissions, yielding the IO object.
|
99
|
+
def open(write_mode = "wb", perm = @perm, &block)
|
100
|
+
raise ClosedError, "Cannot reopen closed file" if @closed
|
101
|
+
SharedHelpers.filesystem_access(path, :write) do
|
102
|
+
path.open(write_mode, perm) do |f|
|
103
|
+
yield digests? ? Gem::Package::DigestIO.new(f, @digests) : f
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns false without appending when no digests since appending is too error prone to do without digests.
|
109
|
+
def append(data)
|
110
|
+
return false unless digests?
|
111
|
+
open("a") {|f| f.write data }
|
112
|
+
verify && commit
|
113
|
+
end
|
114
|
+
|
115
|
+
def write(data)
|
116
|
+
reset_digests
|
117
|
+
open {|f| f.write data }
|
118
|
+
commit!
|
119
|
+
end
|
120
|
+
|
121
|
+
def commit!
|
122
|
+
verify || raise(DigestMismatchError.new(@base64digests, @expected_digests))
|
123
|
+
commit
|
124
|
+
end
|
125
|
+
|
126
|
+
# Verify the digests, returning true on match, false on mismatch.
|
127
|
+
def verify
|
128
|
+
return true unless @expected_digests && digests?
|
129
|
+
@base64digests = @digests.transform_values!(&:base64digest)
|
130
|
+
@digests = nil
|
131
|
+
@base64digests.all? {|algo, digest| @expected_digests[algo] == digest }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Replace the original file with the temp file without verifying digests.
|
135
|
+
# The file is permanently closed.
|
136
|
+
def commit
|
137
|
+
raise ClosedError, "Cannot commit closed file" if @closed
|
138
|
+
SharedHelpers.filesystem_access(original_path, :write) do
|
139
|
+
FileUtils.mv(path, original_path)
|
140
|
+
end
|
141
|
+
@closed = true
|
142
|
+
end
|
143
|
+
|
144
|
+
# Remove the temp file without replacing the original file.
|
145
|
+
# The file is permanently closed.
|
146
|
+
def close
|
147
|
+
return if @closed
|
148
|
+
FileUtils.remove_file(path) if @path&.file?
|
149
|
+
@closed = true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -6,12 +6,15 @@ module Bundler
|
|
6
6
|
GemParser = Gem::Resolver::APISet::GemParser
|
7
7
|
else
|
8
8
|
class GemParser
|
9
|
+
EMPTY_ARRAY = [].freeze
|
10
|
+
private_constant :EMPTY_ARRAY
|
11
|
+
|
9
12
|
def parse(line)
|
10
13
|
version_and_platform, rest = line.split(" ", 2)
|
11
14
|
version, platform = version_and_platform.split("-", 2)
|
12
|
-
dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
|
13
|
-
dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } :
|
14
|
-
requirements = requirements ? requirements.map {|d| parse_dependency(d) } :
|
15
|
+
dependencies, requirements = rest.split("|", 2).map! {|s| s.split(",") } if rest
|
16
|
+
dependencies = dependencies ? dependencies.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
|
17
|
+
requirements = requirements ? requirements.map! {|d| parse_dependency(d) } : EMPTY_ARRAY
|
15
18
|
[version, platform, dependencies, requirements]
|
16
19
|
end
|
17
20
|
|
@@ -20,6 +23,7 @@ module Bundler
|
|
20
23
|
def parse_dependency(string)
|
21
24
|
dependency = string.split(":")
|
22
25
|
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
|
26
|
+
dependency[0] = -dependency[0]
|
23
27
|
dependency
|
24
28
|
end
|
25
29
|
end
|
@@ -1,20 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "../vendored_fileutils"
|
4
|
-
|
5
3
|
module Bundler
|
6
4
|
class CompactIndexClient
|
7
5
|
class Updater
|
8
|
-
class
|
9
|
-
def initialize(path,
|
10
|
-
|
11
|
-
@server_checksum = server_checksum
|
12
|
-
@local_checksum = local_checksum
|
13
|
-
end
|
14
|
-
|
15
|
-
def message
|
16
|
-
"The checksum of /#{@path} does not match the checksum provided by the server! Something is wrong " \
|
17
|
-
"(local checksum is #{@local_checksum.inspect}, was expecting #{@server_checksum.inspect})."
|
6
|
+
class MismatchedChecksumError < Error
|
7
|
+
def initialize(path, message)
|
8
|
+
super "The checksum of /#{path} does not match the checksum provided by the server! Something is wrong. #{message}"
|
18
9
|
end
|
19
10
|
end
|
20
11
|
|
@@ -22,95 +13,102 @@ module Bundler
|
|
22
13
|
@fetcher = fetcher
|
23
14
|
end
|
24
15
|
|
25
|
-
def update(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# first try to fetch any new bytes on the existing file
|
33
|
-
if retrying.nil? && local_path.file?
|
34
|
-
copy_file local_path, local_temp_path
|
16
|
+
def update(remote_path, local_path, etag_path)
|
17
|
+
append(remote_path, local_path, etag_path) || replace(remote_path, local_path, etag_path)
|
18
|
+
rescue CacheFile::DigestMismatchError => e
|
19
|
+
raise MismatchedChecksumError.new(remote_path, e.message)
|
20
|
+
rescue Zlib::GzipFile::Error
|
21
|
+
raise Bundler::HTTPError
|
22
|
+
end
|
35
23
|
|
36
|
-
|
37
|
-
headers["Range"] =
|
38
|
-
if local_temp_path.size.nonzero?
|
39
|
-
# Subtract a byte to ensure the range won't be empty.
|
40
|
-
# Avoids 416 (Range Not Satisfiable) responses.
|
41
|
-
"bytes=#{local_temp_path.size - 1}-"
|
42
|
-
else
|
43
|
-
"bytes=#{local_temp_path.size}-"
|
44
|
-
end
|
45
|
-
end
|
24
|
+
private
|
46
25
|
|
47
|
-
|
48
|
-
return
|
26
|
+
def append(remote_path, local_path, etag_path)
|
27
|
+
return false unless local_path.file? && local_path.size.nonzero?
|
49
28
|
|
50
|
-
|
29
|
+
CacheFile.copy(local_path) do |file|
|
30
|
+
etag = etag_path.read.tap(&:chomp!) if etag_path.file?
|
31
|
+
etag ||= generate_etag(etag_path, file) # Remove this after 2.5.0 has been out for a while.
|
51
32
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
33
|
+
# Subtract a byte to ensure the range won't be empty.
|
34
|
+
# Avoids 416 (Range Not Satisfiable) responses.
|
35
|
+
response = @fetcher.call(remote_path, request_headers(etag, file.size - 1))
|
36
|
+
break true if response.is_a?(Gem::Net::HTTPNotModified)
|
56
37
|
|
57
|
-
|
38
|
+
file.digests = parse_digests(response)
|
39
|
+
# server may ignore Range and return the full response
|
40
|
+
if response.is_a?(Gem::Net::HTTPPartialContent)
|
41
|
+
break false unless file.append(response.body.byteslice(1..-1))
|
58
42
|
else
|
59
|
-
|
60
|
-
|
61
|
-
etag.length.zero? || etag_for(local_temp_path) == etag
|
43
|
+
file.write(response.body)
|
62
44
|
end
|
45
|
+
CacheFile.write(etag_path, etag(response))
|
46
|
+
true
|
63
47
|
end
|
48
|
+
end
|
64
49
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
50
|
+
# request without range header to get the full file or a 304 Not Modified
|
51
|
+
def replace(remote_path, local_path, etag_path)
|
52
|
+
etag = etag_path.read.tap(&:chomp!) if etag_path.file?
|
53
|
+
response = @fetcher.call(remote_path, request_headers(etag))
|
54
|
+
return true if response.is_a?(Gem::Net::HTTPNotModified)
|
55
|
+
CacheFile.write(local_path, response.body, parse_digests(response))
|
56
|
+
CacheFile.write(etag_path, etag(response))
|
57
|
+
end
|
71
58
|
|
72
|
-
|
73
|
-
|
74
|
-
|
59
|
+
def request_headers(etag, range_start = nil)
|
60
|
+
headers = {}
|
61
|
+
headers["Range"] = "bytes=#{range_start}-" if range_start
|
62
|
+
headers["If-None-Match"] = etag if etag
|
63
|
+
headers
|
64
|
+
end
|
75
65
|
|
76
|
-
|
77
|
-
|
78
|
-
raise Bundler::HTTPError
|
79
|
-
ensure
|
80
|
-
FileUtils.remove_file(local_temp_path) if File.exist?(local_temp_path)
|
66
|
+
def etag_for_request(etag_path)
|
67
|
+
etag_path.read.tap(&:chomp!) if etag_path.file?
|
81
68
|
end
|
82
69
|
|
83
|
-
|
84
|
-
|
85
|
-
|
70
|
+
# When first releasing this opaque etag feature, we want to generate the old MD5 etag
|
71
|
+
# based on the content of the file. After that it will always use the saved opaque etag.
|
72
|
+
# This transparently saves existing users with good caches from updating a bunch of files.
|
73
|
+
# Remove this behavior after 2.5.0 has been out for a while.
|
74
|
+
def generate_etag(etag_path, file)
|
75
|
+
etag = file.md5.hexdigest
|
76
|
+
CacheFile.write(etag_path, etag)
|
77
|
+
etag
|
86
78
|
end
|
87
79
|
|
88
|
-
def
|
89
|
-
|
80
|
+
def etag(response)
|
81
|
+
return unless response["ETag"]
|
82
|
+
etag = response["ETag"].delete_prefix("W/")
|
83
|
+
return if etag.delete_prefix!('"') && !etag.delete_suffix!('"')
|
84
|
+
etag
|
90
85
|
end
|
91
86
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
87
|
+
# Unwraps and returns a Hash of digest algorithms and base64 values
|
88
|
+
# according to RFC 8941 Structured Field Values for HTTP.
|
89
|
+
# https://www.rfc-editor.org/rfc/rfc8941#name-parsing-a-byte-sequence
|
90
|
+
# Ignores unsupported algorithms.
|
91
|
+
def parse_digests(response)
|
92
|
+
return unless header = response["Repr-Digest"] || response["Digest"]
|
93
|
+
digests = {}
|
94
|
+
header.split(",") do |param|
|
95
|
+
algorithm, value = param.split("=", 2)
|
96
|
+
algorithm.strip!
|
97
|
+
algorithm.downcase!
|
98
|
+
next unless SUPPORTED_DIGESTS.key?(algorithm)
|
99
|
+
next unless value = byte_sequence(value)
|
100
|
+
digests[algorithm] = value
|
99
101
|
end
|
102
|
+
digests.empty? ? nil : digests
|
100
103
|
end
|
101
104
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
IO.copy_stream(s, f)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
105
|
+
# Unwrap surrounding colons (byte sequence)
|
106
|
+
# The wrapping characters must be matched or we return nil.
|
107
|
+
# Also handles quotes because right now rubygems.org sends them.
|
108
|
+
def byte_sequence(value)
|
109
|
+
return if value.delete_prefix!(":") && !value.delete_suffix!(":")
|
110
|
+
return if value.delete_prefix!('"') && !value.delete_suffix!('"')
|
111
|
+
value
|
114
112
|
end
|
115
113
|
end
|
116
114
|
end
|
@@ -5,7 +5,13 @@ require "set"
|
|
5
5
|
|
6
6
|
module Bundler
|
7
7
|
class CompactIndexClient
|
8
|
+
# NOTE: MD5 is here not because we expect a server to respond with it, but
|
9
|
+
# because we use it to generate the etag on first request during the upgrade
|
10
|
+
# to the compact index client that uses opaque etags saved to files.
|
11
|
+
# Remove once 2.5.0 has been out for a while.
|
12
|
+
SUPPORTED_DIGESTS = { "sha-256" => :SHA256, "md5" => :MD5 }.freeze
|
8
13
|
DEBUG_MUTEX = Thread::Mutex.new
|
14
|
+
|
9
15
|
def self.debug
|
10
16
|
return unless ENV["DEBUG_COMPACT_INDEX"]
|
11
17
|
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
|
@@ -14,6 +20,7 @@ module Bundler
|
|
14
20
|
class Error < StandardError; end
|
15
21
|
|
16
22
|
require_relative "compact_index_client/cache"
|
23
|
+
require_relative "compact_index_client/cache_file"
|
17
24
|
require_relative "compact_index_client/updater"
|
18
25
|
|
19
26
|
attr_reader :directory
|
@@ -54,13 +61,13 @@ module Bundler
|
|
54
61
|
|
55
62
|
def names
|
56
63
|
Bundler::CompactIndexClient.debug { "/names" }
|
57
|
-
update(@cache.names_path,
|
64
|
+
update("names", @cache.names_path, @cache.names_etag_path)
|
58
65
|
@cache.names
|
59
66
|
end
|
60
67
|
|
61
68
|
def versions
|
62
69
|
Bundler::CompactIndexClient.debug { "/versions" }
|
63
|
-
update(@cache.versions_path,
|
70
|
+
update("versions", @cache.versions_path, @cache.versions_etag_path)
|
64
71
|
versions, @info_checksums_by_name = @cache.versions
|
65
72
|
versions
|
66
73
|
end
|
@@ -76,36 +83,36 @@ module Bundler
|
|
76
83
|
def update_and_parse_checksums!
|
77
84
|
Bundler::CompactIndexClient.debug { "update_and_parse_checksums!" }
|
78
85
|
return @info_checksums_by_name if @parsed_checksums
|
79
|
-
update(@cache.versions_path,
|
86
|
+
update("versions", @cache.versions_path, @cache.versions_etag_path)
|
80
87
|
@info_checksums_by_name = @cache.checksums
|
81
88
|
@parsed_checksums = true
|
82
89
|
end
|
83
90
|
|
84
91
|
private
|
85
92
|
|
86
|
-
def update(local_path,
|
93
|
+
def update(remote_path, local_path, local_etag_path)
|
87
94
|
Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
|
88
95
|
unless synchronize { @endpoints.add?(remote_path) }
|
89
96
|
Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
|
90
97
|
return
|
91
98
|
end
|
92
|
-
@updater.update(
|
99
|
+
@updater.update(url(remote_path), local_path, local_etag_path)
|
93
100
|
end
|
94
101
|
|
95
102
|
def update_info(name)
|
96
103
|
Bundler::CompactIndexClient.debug { "update_info(#{name})" }
|
97
104
|
path = @cache.info_path(name)
|
98
|
-
checksum = @updater.checksum_for_file(path)
|
99
105
|
unless existing = @info_checksums_by_name[name]
|
100
106
|
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" }
|
101
107
|
return
|
102
108
|
end
|
109
|
+
checksum = SharedHelpers.checksum_for_file(path, :MD5)
|
103
110
|
if checksum == existing
|
104
111
|
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" }
|
105
112
|
return
|
106
113
|
end
|
107
114
|
Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" }
|
108
|
-
update(
|
115
|
+
update("info/#{name}", path, @cache.info_etag_path(name))
|
109
116
|
end
|
110
117
|
|
111
118
|
def url(path)
|
@@ -43,7 +43,7 @@ module Bundler
|
|
43
43
|
].freeze
|
44
44
|
|
45
45
|
def ruby?
|
46
|
-
return true if Bundler::GemHelpers.
|
46
|
+
return true if Bundler::GemHelpers.generic_local_platform_is_ruby?
|
47
47
|
|
48
48
|
!windows? && (RUBY_ENGINE == "ruby" || RUBY_ENGINE == "rbx" || RUBY_ENGINE == "maglev" || RUBY_ENGINE == "truffleruby")
|
49
49
|
end
|
@@ -71,26 +71,10 @@ module Bundler
|
|
71
71
|
def windows?
|
72
72
|
Gem.win_platform?
|
73
73
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
# TODO: This should correctly be:
|
80
|
-
# windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin32" && Bundler.local_platform.cpu == "x86"
|
81
|
-
end
|
82
|
-
|
83
|
-
def mswin64?
|
84
|
-
windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mswin64" && Bundler.local_platform.cpu == "x64"
|
85
|
-
end
|
86
|
-
|
87
|
-
def mingw?
|
88
|
-
windows? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os == "mingw32" && Bundler.local_platform.cpu != "x64"
|
89
|
-
end
|
90
|
-
|
91
|
-
def x64_mingw?
|
92
|
-
Gem.win_platform? && Bundler.local_platform != Gem::Platform::RUBY && Bundler.local_platform.os.start_with?("mingw") && Bundler.local_platform.cpu == "x64"
|
93
|
-
end
|
74
|
+
alias_method :mswin?, :windows?
|
75
|
+
alias_method :mswin64?, :windows?
|
76
|
+
alias_method :mingw?, :windows?
|
77
|
+
alias_method :x64_mingw?, :windows?
|
94
78
|
|
95
79
|
(KNOWN_MINOR_VERSIONS + KNOWN_MAJOR_VERSIONS).each do |version|
|
96
80
|
trimmed_version = version.tr(".", "")
|