bundler-clone 4.0.15
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 +7 -0
- data/CHANGELOG.md +5670 -0
- data/LICENSE.md +22 -0
- data/README.md +58 -0
- data/bundler.gemspec +46 -0
- data/exe/bundle +29 -0
- data/exe/bundler +4 -0
- data/lib/bundler/.document +1 -0
- data/lib/bundler/build_metadata.rb +44 -0
- data/lib/bundler/capistrano.rb +4 -0
- data/lib/bundler/checksum.rb +270 -0
- data/lib/bundler/ci_detector.rb +75 -0
- data/lib/bundler/cli/add.rb +62 -0
- data/lib/bundler/cli/binstubs.rb +57 -0
- data/lib/bundler/cli/cache.rb +32 -0
- data/lib/bundler/cli/check.rb +40 -0
- data/lib/bundler/cli/clean.rb +25 -0
- data/lib/bundler/cli/common.rb +161 -0
- data/lib/bundler/cli/config.rb +208 -0
- data/lib/bundler/cli/console.rb +47 -0
- data/lib/bundler/cli/doctor/diagnose.rb +167 -0
- data/lib/bundler/cli/doctor/ssl.rb +249 -0
- data/lib/bundler/cli/doctor.rb +33 -0
- data/lib/bundler/cli/exec.rb +114 -0
- data/lib/bundler/cli/fund.rb +36 -0
- data/lib/bundler/cli/gem.rb +493 -0
- data/lib/bundler/cli/info.rb +83 -0
- data/lib/bundler/cli/init.rb +51 -0
- data/lib/bundler/cli/install.rb +127 -0
- data/lib/bundler/cli/issue.rb +41 -0
- data/lib/bundler/cli/list.rb +97 -0
- data/lib/bundler/cli/lock.rb +94 -0
- data/lib/bundler/cli/open.rb +29 -0
- data/lib/bundler/cli/outdated.rb +337 -0
- data/lib/bundler/cli/platform.rb +48 -0
- data/lib/bundler/cli/plugin.rb +39 -0
- data/lib/bundler/cli/pristine.rb +64 -0
- data/lib/bundler/cli/remove.rb +17 -0
- data/lib/bundler/cli/show.rb +71 -0
- data/lib/bundler/cli/update.rb +125 -0
- data/lib/bundler/cli.rb +829 -0
- data/lib/bundler/compact_index_client/cache.rb +96 -0
- data/lib/bundler/compact_index_client/cache_file.rb +148 -0
- data/lib/bundler/compact_index_client/parser.rb +87 -0
- data/lib/bundler/compact_index_client/updater.rb +105 -0
- data/lib/bundler/compact_index_client.rb +92 -0
- data/lib/bundler/constants.rb +14 -0
- data/lib/bundler/current_ruby.rb +94 -0
- data/lib/bundler/definition.rb +1304 -0
- data/lib/bundler/dependency.rb +151 -0
- data/lib/bundler/deployment.rb +6 -0
- data/lib/bundler/deprecate.rb +44 -0
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +642 -0
- data/lib/bundler/endpoint_specification.rb +184 -0
- data/lib/bundler/env.rb +148 -0
- data/lib/bundler/environment_preserver.rb +69 -0
- data/lib/bundler/errors.rb +277 -0
- data/lib/bundler/feature_flag.rb +20 -0
- data/lib/bundler/fetcher/base.rb +55 -0
- data/lib/bundler/fetcher/compact_index.rb +133 -0
- data/lib/bundler/fetcher/dependency.rb +85 -0
- data/lib/bundler/fetcher/downloader.rb +116 -0
- data/lib/bundler/fetcher/gem_remote_fetcher.rb +24 -0
- data/lib/bundler/fetcher/index.rb +25 -0
- data/lib/bundler/fetcher.rb +365 -0
- data/lib/bundler/force_platform.rb +16 -0
- data/lib/bundler/friendly_errors.rb +127 -0
- data/lib/bundler/gem_helper.rb +237 -0
- data/lib/bundler/gem_tasks.rb +7 -0
- data/lib/bundler/gem_version_promoter.rb +147 -0
- data/lib/bundler/index.rb +203 -0
- data/lib/bundler/injector.rb +284 -0
- data/lib/bundler/inline.rb +106 -0
- data/lib/bundler/installer/gem_installer.rb +88 -0
- data/lib/bundler/installer/parallel_installer.rb +280 -0
- data/lib/bundler/installer/standalone.rb +113 -0
- data/lib/bundler/installer.rb +241 -0
- data/lib/bundler/lazy_specification.rb +270 -0
- data/lib/bundler/lockfile_generator.rb +119 -0
- data/lib/bundler/lockfile_parser.rb +328 -0
- data/lib/bundler/man/.document +1 -0
- data/lib/bundler/man/bundle-add.1 +79 -0
- data/lib/bundler/man/bundle-add.1.ronn +92 -0
- data/lib/bundler/man/bundle-binstubs.1 +30 -0
- data/lib/bundler/man/bundle-binstubs.1.ronn +42 -0
- data/lib/bundler/man/bundle-cache.1 +56 -0
- data/lib/bundler/man/bundle-cache.1.ronn +95 -0
- data/lib/bundler/man/bundle-check.1 +21 -0
- data/lib/bundler/man/bundle-check.1.ronn +26 -0
- data/lib/bundler/man/bundle-clean.1 +17 -0
- data/lib/bundler/man/bundle-clean.1.ronn +18 -0
- data/lib/bundler/man/bundle-config.1 +339 -0
- data/lib/bundler/man/bundle-config.1.ronn +455 -0
- data/lib/bundler/man/bundle-console.1 +33 -0
- data/lib/bundler/man/bundle-console.1.ronn +39 -0
- data/lib/bundler/man/bundle-doctor.1 +69 -0
- data/lib/bundler/man/bundle-doctor.1.ronn +77 -0
- data/lib/bundler/man/bundle-env.1 +9 -0
- data/lib/bundler/man/bundle-env.1.ronn +10 -0
- data/lib/bundler/man/bundle-exec.1 +104 -0
- data/lib/bundler/man/bundle-exec.1.ronn +150 -0
- data/lib/bundler/man/bundle-fund.1 +22 -0
- data/lib/bundler/man/bundle-fund.1.ronn +25 -0
- data/lib/bundler/man/bundle-gem.1 +107 -0
- data/lib/bundler/man/bundle-gem.1.ronn +150 -0
- data/lib/bundler/man/bundle-help.1 +9 -0
- data/lib/bundler/man/bundle-help.1.ronn +12 -0
- data/lib/bundler/man/bundle-info.1 +17 -0
- data/lib/bundler/man/bundle-info.1.ronn +21 -0
- data/lib/bundler/man/bundle-init.1 +20 -0
- data/lib/bundler/man/bundle-init.1.ronn +32 -0
- data/lib/bundler/man/bundle-install.1 +178 -0
- data/lib/bundler/man/bundle-install.1.ronn +314 -0
- data/lib/bundler/man/bundle-issue.1 +45 -0
- data/lib/bundler/man/bundle-issue.1.ronn +37 -0
- data/lib/bundler/man/bundle-licenses.1 +9 -0
- data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
- data/lib/bundler/man/bundle-list.1 +40 -0
- data/lib/bundler/man/bundle-list.1.ronn +41 -0
- data/lib/bundler/man/bundle-lock.1 +75 -0
- data/lib/bundler/man/bundle-lock.1.ronn +115 -0
- data/lib/bundler/man/bundle-open.1 +32 -0
- data/lib/bundler/man/bundle-open.1.ronn +28 -0
- data/lib/bundler/man/bundle-outdated.1 +106 -0
- data/lib/bundler/man/bundle-outdated.1.ronn +117 -0
- data/lib/bundler/man/bundle-platform.1 +49 -0
- data/lib/bundler/man/bundle-platform.1.ronn +49 -0
- data/lib/bundler/man/bundle-plugin.1 +76 -0
- data/lib/bundler/man/bundle-plugin.1.ronn +84 -0
- data/lib/bundler/man/bundle-pristine.1 +23 -0
- data/lib/bundler/man/bundle-pristine.1.ronn +34 -0
- data/lib/bundler/man/bundle-remove.1 +15 -0
- data/lib/bundler/man/bundle-remove.1.ronn +16 -0
- data/lib/bundler/man/bundle-show.1 +16 -0
- data/lib/bundler/man/bundle-show.1.ronn +21 -0
- data/lib/bundler/man/bundle-update.1 +284 -0
- data/lib/bundler/man/bundle-update.1.ronn +367 -0
- data/lib/bundler/man/bundle-version.1 +22 -0
- data/lib/bundler/man/bundle-version.1.ronn +24 -0
- data/lib/bundler/man/bundle.1 +93 -0
- data/lib/bundler/man/bundle.1.ronn +107 -0
- data/lib/bundler/man/gemfile.5 +503 -0
- data/lib/bundler/man/gemfile.5.ronn +586 -0
- data/lib/bundler/man/index.txt +31 -0
- data/lib/bundler/match_metadata.rb +30 -0
- data/lib/bundler/match_platform.rb +42 -0
- data/lib/bundler/match_remote_metadata.rb +29 -0
- data/lib/bundler/materialization.rb +59 -0
- data/lib/bundler/mirror.rb +221 -0
- data/lib/bundler/plugin/api/source.rb +330 -0
- data/lib/bundler/plugin/api.rb +81 -0
- data/lib/bundler/plugin/dsl.rb +53 -0
- data/lib/bundler/plugin/events.rb +85 -0
- data/lib/bundler/plugin/index.rb +203 -0
- data/lib/bundler/plugin/installer/git.rb +34 -0
- data/lib/bundler/plugin/installer/path.rb +26 -0
- data/lib/bundler/plugin/installer/rubygems.rb +19 -0
- data/lib/bundler/plugin/installer.rb +123 -0
- data/lib/bundler/plugin/source_list.rb +31 -0
- data/lib/bundler/plugin/unloaded_source.rb +25 -0
- data/lib/bundler/plugin.rb +387 -0
- data/lib/bundler/process_lock.rb +20 -0
- data/lib/bundler/remote_specification.rb +126 -0
- data/lib/bundler/resolver/base.rb +127 -0
- data/lib/bundler/resolver/candidate.rb +85 -0
- data/lib/bundler/resolver/incompatibility.rb +15 -0
- data/lib/bundler/resolver/package.rb +95 -0
- data/lib/bundler/resolver/root.rb +25 -0
- data/lib/bundler/resolver/spec_group.rb +74 -0
- data/lib/bundler/resolver/strategy.rb +43 -0
- data/lib/bundler/resolver.rb +603 -0
- data/lib/bundler/retry.rb +92 -0
- data/lib/bundler/ruby_dsl.rb +67 -0
- data/lib/bundler/ruby_version.rb +135 -0
- data/lib/bundler/rubygems_ext.rb +503 -0
- data/lib/bundler/rubygems_gem_installer.rb +206 -0
- data/lib/bundler/rubygems_integration.rb +456 -0
- data/lib/bundler/runtime.rb +331 -0
- data/lib/bundler/safe_marshal.rb +31 -0
- data/lib/bundler/self_manager.rb +197 -0
- data/lib/bundler/settings/validator.rb +86 -0
- data/lib/bundler/settings.rb +585 -0
- data/lib/bundler/setup.rb +39 -0
- data/lib/bundler/shared_helpers.rb +392 -0
- data/lib/bundler/source/gemspec.rb +19 -0
- data/lib/bundler/source/git/git_proxy.rb +509 -0
- data/lib/bundler/source/git.rb +451 -0
- data/lib/bundler/source/metadata.rb +67 -0
- data/lib/bundler/source/path/installer.rb +53 -0
- data/lib/bundler/source/path.rb +256 -0
- data/lib/bundler/source/rubygems/remote.rb +86 -0
- data/lib/bundler/source/rubygems.rb +606 -0
- data/lib/bundler/source/rubygems_aggregate.rb +71 -0
- data/lib/bundler/source.rb +120 -0
- data/lib/bundler/source_list.rb +240 -0
- data/lib/bundler/source_map.rb +72 -0
- data/lib/bundler/spec_set.rb +390 -0
- data/lib/bundler/stub_specification.rb +147 -0
- data/lib/bundler/templates/.document +1 -0
- data/lib/bundler/templates/Executable +16 -0
- data/lib/bundler/templates/Executable.standalone +14 -0
- data/lib/bundler/templates/Gemfile +5 -0
- data/lib/bundler/templates/newgem/CHANGELOG.md.tt +5 -0
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +10 -0
- data/lib/bundler/templates/newgem/Cargo.toml.tt +13 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +24 -0
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
- data/lib/bundler/templates/newgem/README.md.tt +49 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +72 -0
- data/lib/bundler/templates/newgem/bin/console.tt +11 -0
- data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
- data/lib/bundler/templates/newgem/circleci/config.yml.tt +37 -0
- data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
- data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +22 -0
- data/lib/bundler/templates/newgem/ext/newgem/build.rs.tt +5 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt +10 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +11 -0
- data/lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt +6 -0
- data/lib/bundler/templates/newgem/ext/newgem/go.mod.tt +5 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +2 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt +31 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
- data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +23 -0
- data/lib/bundler/templates/newgem/github/workflows/build-gems.yml.tt +69 -0
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +48 -0
- data/lib/bundler/templates/newgem/gitignore.tt +23 -0
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +27 -0
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +9 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +15 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +58 -0
- data/lib/bundler/templates/newgem/rspec.tt +3 -0
- data/lib/bundler/templates/newgem/rubocop.yml.tt +8 -0
- data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +19 -0
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +15 -0
- data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
- data/lib/bundler/templates/newgem/test/minitest/test_helper.rb.tt +6 -0
- data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +19 -0
- data/lib/bundler/templates/newgem/test/test-unit/newgem_test.rb.tt +15 -0
- data/lib/bundler/templates/newgem/test/test-unit/test_helper.rb.tt +6 -0
- data/lib/bundler/ui/rg_proxy.rb +19 -0
- data/lib/bundler/ui/shell.rb +191 -0
- data/lib/bundler/ui/silent.rb +96 -0
- data/lib/bundler/ui.rb +9 -0
- data/lib/bundler/uri_credentials_filter.rb +43 -0
- data/lib/bundler/uri_normalizer.rb +23 -0
- data/lib/bundler/vendor/.document +1 -0
- data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +227 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +3 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +56 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +230 -0
- data/lib/bundler/vendor/fileutils/COPYING +56 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +2701 -0
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +41 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +65 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +80 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1153 -0
- data/lib/bundler/vendor/pub_grub/LICENSE.txt +21 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/assignment.rb +20 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +169 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/failure_writer.rb +182 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb +150 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/package.rb +43 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/partial_solution.rb +121 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/rubygems.rb +45 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/solve_failure.rb +19 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +61 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/term.rb +105 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version.rb +3 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb +129 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +423 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +236 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb +178 -0
- data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +31 -0
- data/lib/bundler/vendor/securerandom/COPYING +56 -0
- data/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
- data/lib/bundler/vendor/thor/LICENSE.md +20 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +105 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +61 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +108 -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 +407 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +130 -0
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +340 -0
- data/lib/bundler/vendor/thor/lib/thor/base.rb +825 -0
- data/lib/bundler/vendor/thor/lib/thor/command.rb +151 -0
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +107 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +106 -0
- data/lib/bundler/vendor/thor/lib/thor/group.rb +292 -0
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +178 -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/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +29 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +86 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +195 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +178 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +294 -0
- data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +72 -0
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +335 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +384 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +112 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +81 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +118 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
- data/lib/bundler/vendor/thor/lib/thor/util.rb +285 -0
- data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/bundler/vendor/thor/lib/thor.rb +674 -0
- data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
- data/lib/bundler/vendor/tsort/lib/tsort.rb +455 -0
- data/lib/bundler/vendor/uri/COPYING +56 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +922 -0
- data/lib/bundler/vendor/uri/lib/uri/file.rb +100 -0
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +1592 -0
- data/lib/bundler/vendor/uri/lib/uri/http.rb +137 -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 +22 -0
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +293 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +547 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
- data/lib/bundler/vendor/uri/lib/uri/version.rb +6 -0
- data/lib/bundler/vendor/uri/lib/uri/ws.rb +83 -0
- data/lib/bundler/vendor/uri/lib/uri/wss.rb +23 -0
- data/lib/bundler/vendor/uri/lib/uri.rb +104 -0
- data/lib/bundler/vendored_fileutils.rb +4 -0
- data/lib/bundler/vendored_net_http.rb +23 -0
- data/lib/bundler/vendored_persistent.rb +11 -0
- data/lib/bundler/vendored_pub_grub.rb +4 -0
- data/lib/bundler/vendored_securerandom.rb +12 -0
- data/lib/bundler/vendored_thor.rb +8 -0
- data/lib/bundler/vendored_timeout.rb +12 -0
- data/lib/bundler/vendored_tsort.rb +4 -0
- data/lib/bundler/vendored_uri.rb +21 -0
- data/lib/bundler/version.rb +21 -0
- data/lib/bundler/vlad.rb +4 -0
- data/lib/bundler/worker.rb +125 -0
- data/lib/bundler/yaml_serializer.rb +98 -0
- data/lib/bundler.rb +691 -0
- metadata +409 -0
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rubygems/user_interaction"
|
|
4
|
+
|
|
5
|
+
module Bundler
|
|
6
|
+
class Source
|
|
7
|
+
class Rubygems < Source
|
|
8
|
+
autoload :Remote, File.expand_path("rubygems/remote", __dir__)
|
|
9
|
+
|
|
10
|
+
# Ask for X gems per API request
|
|
11
|
+
API_REQUEST_SIZE = 100
|
|
12
|
+
REQUIRE_MUTEX = Mutex.new
|
|
13
|
+
|
|
14
|
+
attr_accessor :remotes, :remote_cooldowns
|
|
15
|
+
|
|
16
|
+
def initialize(options = {})
|
|
17
|
+
@options = options
|
|
18
|
+
@remotes = []
|
|
19
|
+
@remote_cooldowns = {}
|
|
20
|
+
@dependency_names = []
|
|
21
|
+
@allow_remote = false
|
|
22
|
+
@allow_cached = false
|
|
23
|
+
@allow_local = options["allow_local"] || false
|
|
24
|
+
@prefer_local = false
|
|
25
|
+
@checksum_store = Checksum::Store.new
|
|
26
|
+
@gem_installers = {}
|
|
27
|
+
@gem_installers_mutex = Mutex.new
|
|
28
|
+
@remote_specs_mutex = Mutex.new
|
|
29
|
+
|
|
30
|
+
cooldown = options["cooldown"]
|
|
31
|
+
Array(options["remotes"]).reverse_each {|r| add_remote(r, cooldown: cooldown) }
|
|
32
|
+
|
|
33
|
+
@lockfile_remotes = @remotes if options["from_lockfile"]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def caches
|
|
37
|
+
@caches ||= [cache_path, *Bundler.rubygems.gem_cache]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def prefer_local!
|
|
41
|
+
@prefer_local = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def local_only!
|
|
45
|
+
@specs = nil
|
|
46
|
+
@allow_local = true
|
|
47
|
+
@allow_cached = false
|
|
48
|
+
@allow_remote = false
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def local_only?
|
|
52
|
+
@allow_local && !@allow_remote
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def local!
|
|
56
|
+
return if @allow_local
|
|
57
|
+
|
|
58
|
+
@specs = nil
|
|
59
|
+
@allow_local = true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def remote!
|
|
63
|
+
return if @allow_remote
|
|
64
|
+
|
|
65
|
+
@specs = nil
|
|
66
|
+
@allow_remote = true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def cached!
|
|
70
|
+
return unless File.exist?(cache_path)
|
|
71
|
+
|
|
72
|
+
return if @allow_cached
|
|
73
|
+
|
|
74
|
+
@specs = nil
|
|
75
|
+
@allow_cached = true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def hash
|
|
79
|
+
@remotes.hash
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def eql?(other)
|
|
83
|
+
other.is_a?(Rubygems) && other.credless_remotes == credless_remotes
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
alias_method :==, :eql?
|
|
87
|
+
|
|
88
|
+
def include?(o)
|
|
89
|
+
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def multiple_remotes?
|
|
93
|
+
@remotes.size > 1
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def no_remotes?
|
|
97
|
+
@remotes.size == 0
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def can_lock?(spec)
|
|
101
|
+
return super unless multiple_remotes?
|
|
102
|
+
include?(spec.source)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def options
|
|
106
|
+
{ "remotes" => @remotes.map(&:to_s) }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def self.from_lock(options)
|
|
110
|
+
options["remotes"] = Array(options.delete("remote")).reverse
|
|
111
|
+
new(options.merge("from_lockfile" => true))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def to_lock
|
|
115
|
+
out = String.new("GEM\n")
|
|
116
|
+
lockfile_remotes.reverse_each do |remote|
|
|
117
|
+
out << " remote: #{remote}\n"
|
|
118
|
+
end
|
|
119
|
+
out << " specs:\n"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def to_s
|
|
123
|
+
if remotes.empty?
|
|
124
|
+
"locally installed gems"
|
|
125
|
+
elsif @allow_remote && @allow_cached && @allow_local
|
|
126
|
+
"rubygems repository #{remote_names}, cached gems or installed locally"
|
|
127
|
+
elsif @allow_remote && @allow_local
|
|
128
|
+
"rubygems repository #{remote_names} or installed locally"
|
|
129
|
+
elsif @allow_remote
|
|
130
|
+
"rubygems repository #{remote_names}"
|
|
131
|
+
elsif @allow_cached && @allow_local
|
|
132
|
+
"cached gems or installed locally"
|
|
133
|
+
else
|
|
134
|
+
"locally installed gems"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def identifier
|
|
139
|
+
if remotes.empty?
|
|
140
|
+
"locally installed gems"
|
|
141
|
+
else
|
|
142
|
+
"rubygems repository #{remote_names}"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
alias_method :name, :identifier
|
|
146
|
+
alias_method :to_gemfile, :identifier
|
|
147
|
+
|
|
148
|
+
def specs
|
|
149
|
+
@specs ||= begin
|
|
150
|
+
# remote_specs usually generates a way larger Index than the other
|
|
151
|
+
# sources, and large_idx.merge! small_idx is way faster than
|
|
152
|
+
# small_idx.merge! large_idx.
|
|
153
|
+
index = @allow_remote ? remote_specs.dup : Index.new
|
|
154
|
+
|
|
155
|
+
# Snapshot per-version `created_at` from the remote info before installed
|
|
156
|
+
# / cached specs overwrite the EndpointSpecification objects that carry
|
|
157
|
+
# it. The cooldown filter consults `created_at` on every candidate, so
|
|
158
|
+
# local stubs need the published date back-filled to participate.
|
|
159
|
+
remote_created_at = collect_remote_created_at(index)
|
|
160
|
+
|
|
161
|
+
index.merge!(cached_specs) if @allow_cached
|
|
162
|
+
index.merge!(installed_specs) if @allow_local
|
|
163
|
+
|
|
164
|
+
if @allow_local
|
|
165
|
+
if @prefer_local
|
|
166
|
+
index.merge!(default_specs)
|
|
167
|
+
else
|
|
168
|
+
# complete with default specs, only if not already available in the
|
|
169
|
+
# index through remote, cached, or installed specs
|
|
170
|
+
index.use(default_specs)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
backfill_created_at(index, remote_created_at) unless remote_created_at.empty?
|
|
175
|
+
|
|
176
|
+
index
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def download(spec, options = {})
|
|
181
|
+
if (spec.default_gem? && !cached_built_in_gem(spec, local: options[:local])) || (installed?(spec) && !options[:force])
|
|
182
|
+
return true
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
installer = rubygems_gem_installer(spec, options)
|
|
186
|
+
|
|
187
|
+
if spec.remote
|
|
188
|
+
s = begin
|
|
189
|
+
installer.spec
|
|
190
|
+
rescue Gem::Package::FormatError
|
|
191
|
+
Bundler.rm_rf(installer.gem)
|
|
192
|
+
raise
|
|
193
|
+
rescue Gem::Security::Exception => e
|
|
194
|
+
raise SecurityError,
|
|
195
|
+
"The gem #{installer.gem} can't be installed because " \
|
|
196
|
+
"the security policy didn't allow it, with the message: #{e.message}"
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
spec.__swap__(s)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
spec
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def install(spec, options = {})
|
|
206
|
+
if (spec.default_gem? && !cached_built_in_gem(spec, local: options[:local])) || (installed?(spec) && !options[:force])
|
|
207
|
+
print_using_message "Using #{version_message(spec, options[:previous_spec])}"
|
|
208
|
+
return nil # no post-install message
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
return if Bundler.settings[:no_install]
|
|
212
|
+
|
|
213
|
+
installer = rubygems_gem_installer(spec, options)
|
|
214
|
+
spec.source.checksum_store.register(spec, installer.gem_checksum)
|
|
215
|
+
|
|
216
|
+
message = "Installing #{version_message(spec, options[:previous_spec])}"
|
|
217
|
+
message += " with native extensions" if spec.extensions.any?
|
|
218
|
+
Bundler.ui.confirm message
|
|
219
|
+
|
|
220
|
+
installed_spec = nil
|
|
221
|
+
|
|
222
|
+
Gem.time("Installed #{spec.name} in", 0, true) do
|
|
223
|
+
installed_spec = installer.install
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
spec.full_gem_path = installed_spec.full_gem_path
|
|
227
|
+
spec.loaded_from = installed_spec.loaded_from
|
|
228
|
+
spec.base_dir = installed_spec.base_dir
|
|
229
|
+
|
|
230
|
+
spec.post_install_message
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def cache(spec, custom_path = nil)
|
|
234
|
+
cached_path = Bundler.settings[:cache_all_platforms] ? fetch_gem_if_possible(spec) : cached_gem(spec)
|
|
235
|
+
raise GemNotFound, "Missing gem file '#{spec.file_name}'." unless cached_path
|
|
236
|
+
return if File.dirname(cached_path) == Bundler.app_cache.to_s
|
|
237
|
+
Bundler.ui.info " * #{File.basename(cached_path)}"
|
|
238
|
+
FileUtils.cp(cached_path, Bundler.app_cache(custom_path))
|
|
239
|
+
rescue Errno::EACCES => e
|
|
240
|
+
Bundler.ui.debug(e)
|
|
241
|
+
raise InstallError, e.message
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def cached_built_in_gem(spec, local: false)
|
|
245
|
+
cached_path = cached_gem(spec)
|
|
246
|
+
if cached_path.nil? && !local
|
|
247
|
+
remote_spec = remote_spec_for(spec)
|
|
248
|
+
if remote_spec
|
|
249
|
+
cached_path = fetch_gem(remote_spec)
|
|
250
|
+
spec.remote = remote_spec.remote
|
|
251
|
+
else
|
|
252
|
+
Bundler.ui.warn "#{spec.full_name} is built in to Ruby, and can't be cached because your Gemfile doesn't have any sources that contain it."
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
cached_path
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def add_remote(source, cooldown: nil)
|
|
259
|
+
uri = normalize_uri(source)
|
|
260
|
+
@remotes.unshift(uri) unless @remotes.include?(uri)
|
|
261
|
+
@remote_cooldowns[uri] = cooldown if cooldown
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def cooldown_for(uri)
|
|
265
|
+
@remote_cooldowns[uri]
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def spec_names
|
|
269
|
+
if dependency_api_available?
|
|
270
|
+
remote_specs.spec_names
|
|
271
|
+
else
|
|
272
|
+
[]
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def unmet_deps
|
|
277
|
+
if dependency_api_available?
|
|
278
|
+
remote_specs.unmet_dependency_names
|
|
279
|
+
else
|
|
280
|
+
[]
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def remote_fetchers
|
|
285
|
+
@remote_fetchers ||= remotes.to_h do |uri|
|
|
286
|
+
remote = Source::Rubygems::Remote.new(uri, cooldown: cooldown_for(uri))
|
|
287
|
+
[remote, Bundler::Fetcher.new(remote)]
|
|
288
|
+
end.freeze
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def fetchers
|
|
292
|
+
@fetchers ||= remote_fetchers.values.freeze
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def double_check_for(unmet_dependency_names)
|
|
296
|
+
return unless dependency_api_available?
|
|
297
|
+
|
|
298
|
+
unmet_dependency_names = unmet_dependency_names.call
|
|
299
|
+
unless unmet_dependency_names.nil?
|
|
300
|
+
if api_fetchers.size <= 1
|
|
301
|
+
# can't do this when there are multiple fetchers because then we might not fetch from _all_
|
|
302
|
+
# of them
|
|
303
|
+
unmet_dependency_names -= remote_specs.spec_names # avoid re-fetching things we've already gotten
|
|
304
|
+
end
|
|
305
|
+
return if unmet_dependency_names.empty?
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
|
|
309
|
+
|
|
310
|
+
fetch_names(api_fetchers, unmet_dependency_names, remote_specs)
|
|
311
|
+
|
|
312
|
+
specs.use remote_specs
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def dependency_names_to_double_check
|
|
316
|
+
names = []
|
|
317
|
+
remote_specs.each do |spec|
|
|
318
|
+
case spec
|
|
319
|
+
when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
|
|
320
|
+
names.concat(spec.runtime_dependencies.map(&:name))
|
|
321
|
+
when RemoteSpecification # from the full index
|
|
322
|
+
return nil
|
|
323
|
+
else
|
|
324
|
+
raise "unhandled spec type (#{spec.inspect})"
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
names
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def dependency_api_available?
|
|
331
|
+
@allow_remote && api_fetchers.any?
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def clear_cache
|
|
335
|
+
@specs = nil
|
|
336
|
+
@installed_specs = nil
|
|
337
|
+
@default_specs = nil
|
|
338
|
+
@cached_specs = nil
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def release_resolution_memory!
|
|
342
|
+
@specs = nil
|
|
343
|
+
@remote_specs_mutex.synchronize { @remote_specs = nil }
|
|
344
|
+
@fetchers&.each(&:release_resolution_memory!)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
protected
|
|
348
|
+
|
|
349
|
+
def remote_names
|
|
350
|
+
remotes.map(&:to_s).join(", ")
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def credless_remotes
|
|
354
|
+
remotes.map(&method(:remove_auth))
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def cached_gem(spec)
|
|
358
|
+
global_cache_path = download_cache_path(spec)
|
|
359
|
+
caches << global_cache_path if global_cache_path
|
|
360
|
+
|
|
361
|
+
possibilities = caches.map {|p| package_path(p, spec) }
|
|
362
|
+
possibilities.find {|p| File.exist?(p) }
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def package_path(cache_path, spec)
|
|
366
|
+
"#{cache_path}/#{spec.file_name}"
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def normalize_uri(uri)
|
|
370
|
+
uri = URINormalizer.normalize_suffix(uri.to_s)
|
|
371
|
+
require_relative "../vendored_uri"
|
|
372
|
+
uri = Gem::URI(uri)
|
|
373
|
+
raise ArgumentError, "The source must be an absolute URI. For example:\n" \
|
|
374
|
+
"source 'https://rubygems.org'" if !uri.absolute? || (uri.is_a?(Gem::URI::HTTP) && uri.host.nil?)
|
|
375
|
+
uri
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def remove_auth(remote)
|
|
379
|
+
if remote.user || remote.password
|
|
380
|
+
remote.dup.tap {|uri| uri.user = uri.password = nil }.to_s
|
|
381
|
+
else
|
|
382
|
+
remote.to_s
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def installed_specs
|
|
387
|
+
@installed_specs ||= Index.build do |idx|
|
|
388
|
+
Bundler.rubygems.installed_specs.reverse_each do |spec|
|
|
389
|
+
spec.source = self
|
|
390
|
+
next if spec.ignored?
|
|
391
|
+
idx << spec
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
def default_specs
|
|
397
|
+
@default_specs ||= Index.build do |idx|
|
|
398
|
+
Bundler.rubygems.default_specs.each do |spec|
|
|
399
|
+
spec.source = self
|
|
400
|
+
idx << spec
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def cached_specs
|
|
406
|
+
@cached_specs ||= begin
|
|
407
|
+
idx = Index.new
|
|
408
|
+
|
|
409
|
+
Dir["#{cache_path}/*.gem"].each do |gemfile|
|
|
410
|
+
s ||= Bundler.rubygems.spec_from_gem(gemfile)
|
|
411
|
+
s.source = self
|
|
412
|
+
idx << s
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
idx
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def api_fetchers
|
|
420
|
+
fetchers.select(&:api_fetcher?)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def remote_specs
|
|
424
|
+
@remote_specs ||= @remote_specs_mutex.synchronize do
|
|
425
|
+
@remote_specs ||= Index.build do |idx|
|
|
426
|
+
index_fetchers = fetchers - api_fetchers
|
|
427
|
+
|
|
428
|
+
if index_fetchers.empty?
|
|
429
|
+
fetch_names(api_fetchers, dependency_names, idx)
|
|
430
|
+
else
|
|
431
|
+
fetch_names(fetchers, nil, idx)
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Looks up a single spec in the remote sources, fetching only its own
|
|
438
|
+
# name when the full remote index is not already materialized.
|
|
439
|
+
def remote_spec_for(spec)
|
|
440
|
+
return remote_specs.search(spec).first if @remote_specs || api_fetchers.empty?
|
|
441
|
+
|
|
442
|
+
index = Index.build do |idx|
|
|
443
|
+
fetch_names(api_fetchers, [spec.name], idx)
|
|
444
|
+
end
|
|
445
|
+
index.search(spec).first
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def fetch_names(fetchers, dependency_names, index)
|
|
449
|
+
fetchers.each do |f|
|
|
450
|
+
if dependency_names
|
|
451
|
+
Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
|
|
452
|
+
index.use f.specs_with_retry(dependency_names, self)
|
|
453
|
+
Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
|
|
454
|
+
else
|
|
455
|
+
Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
|
|
456
|
+
index.use f.specs_with_retry(nil, self)
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def fetch_gem_if_possible(spec, previous_spec = nil)
|
|
462
|
+
if spec.remote
|
|
463
|
+
fetch_gem(spec, previous_spec)
|
|
464
|
+
else
|
|
465
|
+
cached_gem(spec)
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def fetch_gem(spec, previous_spec = nil)
|
|
470
|
+
spec.fetch_platform
|
|
471
|
+
|
|
472
|
+
cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir)
|
|
473
|
+
gem_path = package_path(cache_path, spec)
|
|
474
|
+
return gem_path if File.exist?(gem_path)
|
|
475
|
+
|
|
476
|
+
SharedHelpers.filesystem_access(cache_path) do |p|
|
|
477
|
+
FileUtils.mkdir_p(p)
|
|
478
|
+
end
|
|
479
|
+
download_gem(spec, cache_path, previous_spec)
|
|
480
|
+
|
|
481
|
+
gem_path
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def installed?(spec)
|
|
485
|
+
installed_specs[spec].any? && !spec.installation_missing?
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def rubygems_dir
|
|
489
|
+
Bundler.bundle_path
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def default_cache_path_for(dir)
|
|
493
|
+
"#{dir}/cache"
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def cache_path
|
|
497
|
+
Bundler.app_cache
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
private
|
|
501
|
+
|
|
502
|
+
def collect_remote_created_at(index)
|
|
503
|
+
return {} unless @allow_remote
|
|
504
|
+
|
|
505
|
+
snapshot = {}
|
|
506
|
+
index.each do |spec|
|
|
507
|
+
next unless spec.respond_to?(:created_at) && spec.created_at
|
|
508
|
+
# Remember the remote that supplied the date too: when a source has
|
|
509
|
+
# several remotes with different per-URI cooldown settings we must
|
|
510
|
+
# restore the same one during backfill so `effective_cooldown` agrees.
|
|
511
|
+
snapshot[[spec.name, spec.version]] = [spec.created_at, spec.remote]
|
|
512
|
+
end
|
|
513
|
+
snapshot
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def backfill_created_at(index, snapshot)
|
|
517
|
+
index.each do |spec|
|
|
518
|
+
next unless spec.respond_to?(:created_at=)
|
|
519
|
+
next if spec.created_at
|
|
520
|
+
remote_created_at, remote = snapshot[[spec.name, spec.version]]
|
|
521
|
+
next unless remote_created_at
|
|
522
|
+
spec.created_at = remote_created_at
|
|
523
|
+
spec.remote ||= remote if remote && spec.respond_to?(:remote=)
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def lockfile_remotes
|
|
528
|
+
@lockfile_remotes || credless_remotes
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# Checks if the requested spec exists in the global cache. If it does,
|
|
532
|
+
# we copy it to the download path, and if it does not, we download it.
|
|
533
|
+
#
|
|
534
|
+
# @param [Specification] spec
|
|
535
|
+
# the spec we want to download or retrieve from the cache.
|
|
536
|
+
#
|
|
537
|
+
# @param [String] download_cache_path
|
|
538
|
+
# the local directory the .gem will end up in.
|
|
539
|
+
#
|
|
540
|
+
# @param [Specification] previous_spec
|
|
541
|
+
# the spec previously locked
|
|
542
|
+
#
|
|
543
|
+
def download_gem(spec, download_cache_path, previous_spec = nil)
|
|
544
|
+
uri = spec.remote.uri
|
|
545
|
+
Bundler.ui.confirm("Fetching #{version_message(spec, previous_spec)}")
|
|
546
|
+
gem_remote_fetcher = remote_fetchers.fetch(spec.remote).gem_remote_fetcher
|
|
547
|
+
|
|
548
|
+
Gem.time("Downloaded #{spec.name} in", 0, true) do
|
|
549
|
+
Bundler.rubygems.download_gem(spec, uri, download_cache_path, gem_remote_fetcher)
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
# Returns the global cache path of the calling Rubygems::Source object.
|
|
554
|
+
#
|
|
555
|
+
# Note that the Source determines the path's subdirectory. We use this
|
|
556
|
+
# subdirectory in the global cache path so that gems with the same name
|
|
557
|
+
# -- and possibly different versions -- from different sources are saved
|
|
558
|
+
# to their respective subdirectories and do not override one another.
|
|
559
|
+
#
|
|
560
|
+
# @param [Gem::Specification] specification
|
|
561
|
+
#
|
|
562
|
+
# @return [Pathname] The global cache path.
|
|
563
|
+
#
|
|
564
|
+
def download_cache_path(spec)
|
|
565
|
+
return unless Bundler.settings[:global_gem_cache]
|
|
566
|
+
return unless remote = spec.remote
|
|
567
|
+
return unless cache_slug = remote.cache_slug
|
|
568
|
+
|
|
569
|
+
Bundler.user_cache.join("gems", cache_slug)
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def extension_cache_slug(spec)
|
|
573
|
+
return unless remote = spec.remote
|
|
574
|
+
remote.cache_slug
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# We are using a mutex to reaed and write from/to the hash.
|
|
578
|
+
# The reason this double synchronization was added is for performance
|
|
579
|
+
# and to lock the mutex for the shortest possible amount of time. Otherwise,
|
|
580
|
+
# all threads are fighting over this mutex and when it gets acquired it gets locked
|
|
581
|
+
# until a threads finishes downloading a gem, leaving the other threads waiting
|
|
582
|
+
# doing nothing.
|
|
583
|
+
def rubygems_gem_installer(spec, options)
|
|
584
|
+
@gem_installers_mutex.synchronize { @gem_installers[spec.name] } || begin
|
|
585
|
+
path = fetch_gem_if_possible(spec, options[:previous_spec])
|
|
586
|
+
raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path
|
|
587
|
+
|
|
588
|
+
REQUIRE_MUTEX.synchronize { require_relative "../rubygems_gem_installer" }
|
|
589
|
+
|
|
590
|
+
installer = Bundler::RubyGemsGemInstaller.at(
|
|
591
|
+
path,
|
|
592
|
+
security_policy: Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]],
|
|
593
|
+
install_dir: rubygems_dir.to_s,
|
|
594
|
+
bin_dir: Bundler.system_bindir.to_s,
|
|
595
|
+
ignore_dependencies: true,
|
|
596
|
+
wrappers: true,
|
|
597
|
+
env_shebang: true,
|
|
598
|
+
build_args: options[:build_args],
|
|
599
|
+
bundler_extension_cache_path: extension_cache_path(spec)
|
|
600
|
+
)
|
|
601
|
+
@gem_installers_mutex.synchronize { @gem_installers[spec.name] ||= installer }
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bundler
|
|
4
|
+
class Source
|
|
5
|
+
class RubygemsAggregate
|
|
6
|
+
attr_reader :source_map, :sources
|
|
7
|
+
|
|
8
|
+
def initialize(sources, source_map, excluded_sources = [])
|
|
9
|
+
@sources = sources
|
|
10
|
+
@source_map = source_map
|
|
11
|
+
@excluded_sources = excluded_sources
|
|
12
|
+
|
|
13
|
+
@index = build_index
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def specs
|
|
17
|
+
@index
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def identifier
|
|
21
|
+
to_s
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
"any of the sources"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def build_index
|
|
31
|
+
Index.build do |idx|
|
|
32
|
+
dependency_names = source_map.pinned_spec_names
|
|
33
|
+
|
|
34
|
+
sources.all_sources.each do |source|
|
|
35
|
+
next if @excluded_sources.include?(source)
|
|
36
|
+
|
|
37
|
+
source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
|
|
38
|
+
idx.add_source source.specs
|
|
39
|
+
dependency_names.concat(source.unmet_deps).uniq!
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
double_check_for_index(idx, dependency_names)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
|
47
|
+
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
|
48
|
+
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
|
49
|
+
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
|
50
|
+
# each spec we found, we add all possible versions from all sources to the index.
|
|
51
|
+
def double_check_for_index(idx, dependency_names)
|
|
52
|
+
pinned_names = source_map.pinned_spec_names
|
|
53
|
+
|
|
54
|
+
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
|
55
|
+
unmet_dependency_names = lambda do
|
|
56
|
+
return names unless names == :names
|
|
57
|
+
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
|
58
|
+
return names = nil if new_names.compact!
|
|
59
|
+
names = new_names.flatten(1).concat(dependency_names)
|
|
60
|
+
names.uniq!
|
|
61
|
+
names -= pinned_names
|
|
62
|
+
names
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
sources.all_sources.each do |source|
|
|
66
|
+
source.double_check_for(unmet_dependency_names)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|