rubygems-update 3.5.3 → 3.7.1
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 +1410 -686
- data/CODE_OF_CONDUCT.md +79 -28
- data/CONTRIBUTING.md +4 -226
- data/Manifest.txt +107 -83
- data/README.md +16 -11
- data/SECURITY.md +7 -0
- data/bundler/CHANGELOG.md +1525 -931
- data/bundler/README.md +9 -9
- data/bundler/bundler.gemspec +2 -2
- data/bundler/lib/bundler/build_metadata.rb +10 -11
- data/bundler/lib/bundler/checksum.rb +22 -12
- data/bundler/lib/bundler/cli/add.rb +3 -1
- data/bundler/lib/bundler/cli/binstubs.rb +1 -1
- data/bundler/lib/bundler/cli/check.rb +3 -3
- data/bundler/lib/bundler/cli/common.rb +1 -1
- data/bundler/lib/bundler/cli/config.rb +2 -2
- data/bundler/lib/bundler/cli/console.rb +8 -10
- data/bundler/lib/bundler/cli/doctor/diagnose.rb +167 -0
- data/bundler/lib/bundler/cli/doctor/ssl.rb +249 -0
- data/bundler/lib/bundler/cli/doctor.rb +27 -151
- data/bundler/lib/bundler/cli/exec.rb +1 -0
- data/bundler/lib/bundler/cli/fund.rb +1 -1
- data/bundler/lib/bundler/cli/gem.rb +74 -46
- data/bundler/lib/bundler/cli/info.rb +6 -6
- data/bundler/lib/bundler/cli/inject.rb +3 -3
- data/bundler/lib/bundler/cli/install.rb +19 -10
- data/bundler/lib/bundler/cli/issue.rb +3 -3
- data/bundler/lib/bundler/cli/lock.rb +32 -11
- data/bundler/lib/bundler/cli/outdated.rb +23 -23
- data/bundler/lib/bundler/cli/plugin.rb +3 -2
- data/bundler/lib/bundler/cli/pristine.rb +1 -1
- data/bundler/lib/bundler/cli/show.rb +3 -3
- data/bundler/lib/bundler/cli/update.rb +3 -3
- data/bundler/lib/bundler/cli.rb +75 -145
- data/bundler/lib/bundler/compact_index_client/cache.rb +48 -73
- data/bundler/lib/bundler/compact_index_client/cache_file.rb +0 -5
- data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
- data/bundler/lib/bundler/compact_index_client/updater.rb +6 -16
- data/bundler/lib/bundler/compact_index_client.rb +52 -85
- data/bundler/lib/bundler/constants.rb +8 -1
- data/bundler/lib/bundler/current_ruby.rb +48 -34
- data/bundler/lib/bundler/definition.rb +501 -328
- data/bundler/lib/bundler/dependency.rb +93 -47
- data/bundler/lib/bundler/dsl.rb +147 -103
- data/bundler/lib/bundler/endpoint_specification.rb +30 -3
- data/bundler/lib/bundler/env.rb +1 -1
- data/bundler/lib/bundler/environment_preserver.rb +5 -23
- data/bundler/lib/bundler/errors.rb +53 -5
- data/bundler/lib/bundler/feature_flag.rb +18 -18
- data/bundler/lib/bundler/fetcher/compact_index.rb +16 -25
- data/bundler/lib/bundler/fetcher/dependency.rb +2 -1
- data/bundler/lib/bundler/fetcher/downloader.rb +34 -8
- data/bundler/lib/bundler/fetcher.rb +63 -26
- data/bundler/lib/bundler/force_platform.rb +0 -2
- data/bundler/lib/bundler/friendly_errors.rb +3 -2
- data/bundler/lib/bundler/gem_helper.rb +1 -1
- data/bundler/lib/bundler/gem_version_promoter.rb +42 -40
- data/bundler/lib/bundler/index.rb +7 -2
- data/bundler/lib/bundler/injector.rb +14 -16
- data/bundler/lib/bundler/inline.rb +42 -17
- data/bundler/lib/bundler/installer/gem_installer.rb +4 -3
- data/bundler/lib/bundler/installer/parallel_installer.rb +3 -2
- data/bundler/lib/bundler/installer/standalone.rb +2 -5
- data/bundler/lib/bundler/installer.rb +22 -45
- data/bundler/lib/bundler/lazy_specification.rb +121 -48
- data/bundler/lib/bundler/lockfile_generator.rb +1 -1
- data/bundler/lib/bundler/lockfile_parser.rb +36 -9
- data/bundler/lib/bundler/man/bundle-add.1 +44 -27
- data/bundler/lib/bundler/man/bundle-add.1.ronn +52 -23
- data/bundler/lib/bundler/man/bundle-binstubs.1 +9 -6
- data/bundler/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
- data/bundler/lib/bundler/man/bundle-cache.1 +32 -4
- data/bundler/lib/bundler/man/bundle-cache.1.ronn +31 -2
- data/bundler/lib/bundler/man/bundle-check.1 +7 -5
- data/bundler/lib/bundler/man/bundle-check.1.ronn +7 -2
- data/bundler/lib/bundler/man/bundle-clean.1 +3 -3
- data/bundler/lib/bundler/man/bundle-config.1 +180 -138
- data/bundler/lib/bundler/man/bundle-config.1.ronn +96 -99
- data/bundler/lib/bundler/man/bundle-console.1 +4 -6
- data/bundler/lib/bundler/man/bundle-console.1.ronn +2 -7
- data/bundler/lib/bundler/man/bundle-doctor.1 +46 -7
- data/bundler/lib/bundler/man/bundle-doctor.1.ronn +49 -5
- data/bundler/lib/bundler/man/bundle-env.1 +9 -0
- data/bundler/lib/bundler/man/bundle-env.1.ronn +10 -0
- data/bundler/lib/bundler/man/bundle-exec.1 +9 -6
- data/bundler/lib/bundler/man/bundle-exec.1.ronn +6 -3
- data/bundler/lib/bundler/man/bundle-fund.1 +22 -0
- data/bundler/lib/bundler/man/bundle-fund.1.ronn +25 -0
- data/bundler/lib/bundler/man/bundle-gem.1 +69 -28
- data/bundler/lib/bundler/man/bundle-gem.1.ronn +42 -6
- data/bundler/lib/bundler/man/bundle-help.1 +3 -3
- data/bundler/lib/bundler/man/bundle-info.1 +7 -4
- data/bundler/lib/bundler/man/bundle-info.1.ronn +6 -2
- data/bundler/lib/bundler/man/bundle-init.1 +5 -5
- data/bundler/lib/bundler/man/bundle-init.1.ronn +3 -2
- data/bundler/lib/bundler/man/bundle-inject.1 +13 -5
- data/bundler/lib/bundler/man/bundle-inject.1.ronn +10 -2
- data/bundler/lib/bundler/man/bundle-install.1 +20 -17
- data/bundler/lib/bundler/man/bundle-install.1.ronn +26 -23
- data/bundler/lib/bundler/man/bundle-issue.1 +45 -0
- data/bundler/lib/bundler/man/bundle-issue.1.ronn +37 -0
- data/bundler/lib/bundler/man/bundle-licenses.1 +9 -0
- data/bundler/lib/bundler/man/bundle-licenses.1.ronn +10 -0
- data/bundler/lib/bundler/man/bundle-list.1 +3 -3
- data/bundler/lib/bundler/man/bundle-list.1.ronn +4 -1
- data/bundler/lib/bundler/man/bundle-lock.1 +23 -8
- data/bundler/lib/bundler/man/bundle-lock.1.ronn +25 -4
- data/bundler/lib/bundler/man/bundle-open.1 +4 -4
- data/bundler/lib/bundler/man/bundle-open.1.ronn +2 -1
- data/bundler/lib/bundler/man/bundle-outdated.1 +10 -7
- data/bundler/lib/bundler/man/bundle-outdated.1.ronn +8 -4
- data/bundler/lib/bundler/man/bundle-platform.1 +3 -3
- data/bundler/lib/bundler/man/bundle-plugin.1 +9 -6
- data/bundler/lib/bundler/man/bundle-plugin.1.ronn +7 -3
- data/bundler/lib/bundler/man/bundle-pristine.1 +3 -3
- data/bundler/lib/bundler/man/bundle-pristine.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-remove.1 +3 -3
- data/bundler/lib/bundler/man/bundle-remove.1.ronn +1 -1
- data/bundler/lib/bundler/man/bundle-show.1 +7 -4
- data/bundler/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/bundler/lib/bundler/man/bundle-update.1 +17 -11
- data/bundler/lib/bundler/man/bundle-update.1.ronn +17 -9
- data/bundler/lib/bundler/man/bundle-version.1 +3 -3
- data/bundler/lib/bundler/man/bundle-viz.1 +6 -6
- data/bundler/lib/bundler/man/bundle-viz.1.ronn +7 -3
- data/bundler/lib/bundler/man/bundle.1 +3 -3
- data/bundler/lib/bundler/man/gemfile.5 +7 -5
- data/bundler/lib/bundler/man/gemfile.5.ronn +8 -2
- data/bundler/lib/bundler/man/index.txt +4 -0
- data/bundler/lib/bundler/match_metadata.rb +13 -0
- data/bundler/lib/bundler/match_platform.rb +31 -12
- data/bundler/lib/bundler/materialization.rb +59 -0
- data/bundler/lib/bundler/mirror.rb +3 -3
- data/bundler/lib/bundler/plugin/api/source.rb +5 -4
- data/bundler/lib/bundler/plugin/events.rb +24 -0
- data/bundler/lib/bundler/plugin/index.rb +5 -1
- data/bundler/lib/bundler/plugin/installer/path.rb +26 -0
- data/bundler/lib/bundler/plugin/installer.rb +37 -17
- data/bundler/lib/bundler/plugin/source_list.rb +4 -4
- data/bundler/lib/bundler/plugin.rb +21 -2
- data/bundler/lib/bundler/process_lock.rb +10 -14
- data/bundler/lib/bundler/remote_specification.rb +6 -1
- data/bundler/lib/bundler/resolver/base.rb +14 -3
- data/bundler/lib/bundler/resolver/candidate.rb +18 -27
- data/bundler/lib/bundler/resolver/package.rb +20 -3
- data/bundler/lib/bundler/resolver/spec_group.rb +22 -27
- data/bundler/lib/bundler/resolver/strategy.rb +40 -0
- data/bundler/lib/bundler/resolver.rb +114 -52
- data/bundler/lib/bundler/retry.rb +1 -1
- data/bundler/lib/bundler/ruby_dsl.rb +12 -3
- data/bundler/lib/bundler/ruby_version.rb +7 -1
- data/bundler/lib/bundler/rubygems_ext.rb +303 -150
- data/bundler/lib/bundler/rubygems_gem_installer.rb +40 -5
- data/bundler/lib/bundler/rubygems_integration.rb +40 -73
- data/bundler/lib/bundler/runtime.rb +48 -35
- data/bundler/lib/bundler/self_manager.rb +36 -26
- data/bundler/lib/bundler/settings/validator.rb +0 -23
- data/bundler/lib/bundler/settings.rb +36 -27
- data/bundler/lib/bundler/setup.rb +6 -0
- data/bundler/lib/bundler/shared_helpers.rb +45 -25
- data/bundler/lib/bundler/source/gemspec.rb +1 -4
- data/bundler/lib/bundler/source/git/git_proxy.rb +26 -9
- data/bundler/lib/bundler/source/git.rb +113 -41
- data/bundler/lib/bundler/source/metadata.rb +4 -3
- data/bundler/lib/bundler/source/path.rb +14 -18
- data/bundler/lib/bundler/source/rubygems/remote.rb +12 -4
- data/bundler/lib/bundler/source/rubygems.rb +54 -48
- data/bundler/lib/bundler/source.rb +2 -0
- data/bundler/lib/bundler/source_list.rb +54 -12
- data/bundler/lib/bundler/source_map.rb +1 -1
- data/bundler/lib/bundler/spec_set.rb +227 -103
- data/bundler/lib/bundler/stub_specification.rb +29 -2
- data/bundler/lib/bundler/templates/Executable +0 -11
- data/bundler/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +77 -29
- data/bundler/lib/bundler/templates/newgem/Gemfile.tt +1 -3
- data/bundler/lib/bundler/templates/newgem/README.md.tt +7 -3
- data/bundler/lib/bundler/templates/newgem/github/workflows/main.yml.tt +17 -15
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +14 -12
- data/bundler/lib/bundler/templates/newgem/rubocop.yml.tt +0 -5
- data/bundler/lib/bundler/ui/shell.rb +26 -4
- data/bundler/lib/bundler/ui/silent.rb +12 -1
- data/bundler/lib/bundler/uri_credentials_filter.rb +3 -3
- data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +53 -3
- 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 +11 -0
- data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +15 -13
- data/bundler/lib/bundler/vendor/net-http-persistent/README.rdoc +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +2 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +134 -57
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +4 -24
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb +1 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/strategy.rb +42 -0
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb +20 -8
- data/bundler/lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb +17 -29
- data/bundler/lib/bundler/vendor/securerandom/COPYING +56 -0
- data/bundler/lib/bundler/vendor/securerandom/lib/securerandom.rb +102 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +3 -5
- data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +11 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +1 -4
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +2 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +2 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +9 -9
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +5 -21
- data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor.rb +11 -0
- data/bundler/lib/bundler/vendor/uri/COPYING +56 -0
- data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +43 -16
- data/bundler/lib/bundler/vendor/uri/lib/uri/file.rb +3 -3
- data/bundler/lib/bundler/vendor/uri/lib/uri/ftp.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +28 -37
- data/bundler/lib/bundler/vendor/uri/lib/uri/http.rb +2 -2
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +16 -9
- data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +26 -3
- data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/bundler/lib/bundler/vendor/uri/lib/uri.rb +9 -9
- data/bundler/lib/bundler/vendored_net_http.rb +20 -5
- data/bundler/lib/bundler/vendored_securerandom.rb +12 -0
- data/bundler/lib/bundler/vendored_timeout.rb +7 -3
- data/bundler/lib/bundler/vendored_uri.rb +18 -1
- data/bundler/lib/bundler/version.rb +10 -2
- data/bundler/lib/bundler/worker.rb +1 -1
- data/bundler/lib/bundler/yaml_serializer.rb +12 -7
- data/bundler/lib/bundler.rb +101 -61
- data/{bundler → doc/bundler}/UPGRADING.md +132 -127
- data/doc/rubygems/CONTRIBUTING.md +227 -0
- data/{POLICIES.md → doc/rubygems/POLICIES.md} +86 -17
- data/exe/update_rubygems +1 -1
- data/lib/rubygems/basic_specification.rb +50 -10
- data/lib/rubygems/bundler_version_finder.rb +1 -1
- data/lib/rubygems/command.rb +1 -4
- data/lib/rubygems/command_manager.rb +5 -6
- data/lib/rubygems/commands/build_command.rb +2 -11
- data/lib/rubygems/commands/cleanup_command.rb +3 -13
- data/lib/rubygems/commands/contents_command.rb +17 -10
- data/lib/rubygems/commands/environment_command.rb +5 -0
- data/lib/rubygems/commands/exec_command.rb +18 -11
- data/lib/rubygems/commands/fetch_command.rb +14 -0
- data/lib/rubygems/commands/help_command.rb +2 -2
- data/lib/rubygems/commands/install_command.rb +0 -4
- data/lib/rubygems/commands/pristine_command.rb +29 -19
- data/lib/rubygems/commands/push_command.rb +31 -6
- data/lib/rubygems/commands/rdoc_command.rb +3 -10
- data/lib/rubygems/commands/rebuild_command.rb +262 -0
- data/lib/rubygems/commands/setup_command.rb +13 -18
- data/lib/rubygems/commands/sources_command.rb +2 -2
- data/lib/rubygems/commands/uninstall_command.rb +9 -4
- data/lib/rubygems/commands/unpack_command.rb +0 -6
- data/lib/rubygems/commands/update_command.rb +13 -22
- data/lib/rubygems/config_file.rb +45 -16
- data/lib/rubygems/core_ext/kernel_require.rb +15 -3
- data/lib/rubygems/core_ext/kernel_warn.rb +2 -6
- data/lib/rubygems/defaults.rb +7 -7
- data/lib/rubygems/dependency.rb +12 -16
- data/lib/rubygems/dependency_list.rb +1 -1
- data/lib/rubygems/deprecate.rb +79 -77
- data/lib/rubygems/errors.rb +2 -1
- data/lib/rubygems/exceptions.rb +2 -9
- data/lib/rubygems/ext/builder.rb +21 -8
- data/lib/rubygems/ext/cargo_builder.rb +16 -26
- data/lib/rubygems/ext/cmake_builder.rb +7 -2
- data/lib/rubygems/ext/configure_builder.rb +7 -2
- data/lib/rubygems/ext/ext_conf_builder.rb +9 -5
- data/lib/rubygems/ext/rake_builder.rb +7 -4
- data/lib/rubygems/gem_runner.rb +9 -0
- data/lib/rubygems/gemcutter_utilities/webauthn_listener.rb +11 -4
- data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -1
- data/lib/rubygems/gemcutter_utilities.rb +52 -26
- data/lib/rubygems/gemspec_helpers.rb +19 -0
- data/lib/rubygems/install_update_options.rb +5 -0
- data/lib/rubygems/installer.rb +76 -90
- data/lib/rubygems/local_remote_options.rb +8 -8
- data/lib/rubygems/package/tar_header.rb +31 -4
- data/lib/rubygems/package/tar_reader/entry.rb +1 -5
- data/lib/rubygems/package/tar_writer.rb +5 -4
- data/lib/rubygems/package.rb +13 -8
- data/lib/rubygems/platform.rb +148 -43
- data/lib/rubygems/psych_tree.rb +4 -0
- data/lib/rubygems/query_utils.rb +2 -2
- data/lib/rubygems/rdoc.rb +16 -3
- data/lib/rubygems/remote_fetcher.rb +6 -7
- data/lib/rubygems/request.rb +5 -5
- data/lib/rubygems/request_set/gem_dependency_api.rb +1 -1
- data/lib/rubygems/request_set.rb +4 -7
- data/lib/rubygems/requirement.rb +16 -12
- data/lib/rubygems/resolver/activation_request.rb +1 -1
- data/lib/rubygems/resolver/api_set/gem_parser.rb +2 -5
- data/lib/rubygems/resolver/api_set.rb +13 -8
- data/lib/rubygems/resolver/best_set.rb +1 -29
- data/lib/rubygems/resolver/composed_set.rb +3 -3
- data/lib/rubygems/resolver/git_set.rb +0 -1
- data/lib/rubygems/resolver/index_set.rb +2 -2
- data/lib/rubygems/resolver/source_set.rb +1 -1
- data/lib/rubygems/resolver/spec_specification.rb +7 -0
- data/lib/rubygems/resolver.rb +8 -8
- data/lib/rubygems/s3_uri_signer.rb +8 -6
- data/lib/rubygems/safe_marshal/reader.rb +31 -14
- data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +29 -16
- data/lib/rubygems/safe_yaml.rb +10 -1
- data/lib/rubygems/security.rb +1 -1
- data/lib/rubygems/source/git.rb +22 -17
- data/lib/rubygems/source/installed.rb +3 -1
- data/lib/rubygems/source/local.rb +8 -4
- data/lib/rubygems/source/specific_file.rb +5 -3
- data/lib/rubygems/source.rb +37 -29
- data/lib/rubygems/source_list.rb +1 -1
- data/lib/rubygems/spec_fetcher.rb +47 -15
- data/lib/rubygems/specification.rb +110 -183
- data/lib/rubygems/specification_policy.rb +33 -13
- data/lib/rubygems/specification_record.rb +212 -0
- data/lib/rubygems/stub_specification.rb +32 -10
- data/lib/rubygems/target_rbconfig.rb +50 -0
- data/lib/rubygems/uninstaller.rb +42 -22
- data/lib/rubygems/uri.rb +6 -6
- data/lib/rubygems/uri_formatter.rb +2 -1
- data/lib/rubygems/util/licenses.rb +118 -1
- data/lib/rubygems/util.rb +1 -1
- data/lib/rubygems/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/delegates/specification_provider.rb +11 -11
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/action.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/log.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/set_payload.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/tag.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph/vertex.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/dependency_graph.rb +2 -2
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/errors.rb +1 -1
- data/lib/rubygems/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/specification_provider.rb +2 -2
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/modules/ui.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolution.rb +4 -4
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/resolver.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo/state.rb +1 -1
- data/lib/rubygems/{resolver → vendor}/molinillo/lib/molinillo.rb +2 -2
- data/lib/rubygems/vendor/net-http/COPYING +56 -0
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/generic_request.rb +9 -9
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/header.rb +3 -3
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/request.rb +3 -3
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/requests.rb +35 -30
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/response.rb +2 -2
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/responses.rb +6 -6
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/status.rb +1 -1
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http.rb +149 -70
- data/lib/rubygems/{net-http → vendor/net-http}/lib/net/https.rb +1 -1
- data/lib/rubygems/vendor/optparse/COPYING +56 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/ac.rb +16 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/kwargs.rb +8 -3
- data/lib/rubygems/vendor/optparse/lib/optparse/uri.rb +7 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/version.rb +9 -0
- data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse.rb +158 -62
- data/lib/rubygems/vendor/resolv/COPYING +56 -0
- data/lib/rubygems/{resolv → vendor/resolv}/lib/resolv.rb +165 -69
- data/lib/rubygems/vendor/securerandom/COPYING +56 -0
- data/lib/rubygems/vendor/securerandom/lib/securerandom.rb +102 -0
- data/lib/rubygems/vendor/timeout/COPYING +56 -0
- data/lib/rubygems/{timeout → vendor/timeout}/lib/timeout.rb +10 -11
- data/lib/rubygems/{tsort → vendor/tsort}/lib/tsort.rb +2 -2
- data/lib/rubygems/vendor/uri/COPYING +56 -0
- data/lib/rubygems/vendor/uri/lib/uri/common.rb +880 -0
- data/lib/rubygems/vendor/uri/lib/uri/file.rb +100 -0
- data/lib/rubygems/vendor/uri/lib/uri/ftp.rb +267 -0
- data/lib/rubygems/vendor/uri/lib/uri/generic.rb +1579 -0
- data/lib/rubygems/vendor/uri/lib/uri/http.rb +125 -0
- data/lib/rubygems/vendor/uri/lib/uri/https.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldap.rb +261 -0
- data/lib/rubygems/vendor/uri/lib/uri/ldaps.rb +22 -0
- data/lib/rubygems/vendor/uri/lib/uri/mailto.rb +293 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc2396_parser.rb +546 -0
- data/lib/rubygems/vendor/uri/lib/uri/rfc3986_parser.rb +206 -0
- data/lib/rubygems/vendor/uri/lib/uri/version.rb +6 -0
- data/lib/rubygems/vendor/uri/lib/uri/ws.rb +83 -0
- data/lib/rubygems/vendor/uri/lib/uri/wss.rb +23 -0
- data/lib/rubygems/vendor/uri/lib/uri.rb +104 -0
- data/lib/rubygems/vendored_molinillo.rb +3 -0
- data/lib/rubygems/vendored_net_http.rb +5 -0
- data/lib/rubygems/vendored_optparse.rb +3 -0
- data/lib/rubygems/vendored_securerandom.rb +3 -0
- data/lib/rubygems/vendored_timeout.rb +5 -0
- data/lib/rubygems/vendored_tsort.rb +3 -0
- data/lib/rubygems/version.rb +26 -9
- data/lib/rubygems/yaml_serializer.rb +12 -7
- data/lib/rubygems.rb +160 -53
- data/rubygems-update.gemspec +11 -6
- data/setup.rb +1 -1
- metadata +124 -96
- data/bundler/lib/bundler/compact_index_client/gem_parser.rb +0 -32
- data/bundler/lib/bundler/gem_helpers.rb +0 -127
- data/bundler/lib/bundler/templates/Executable.bundler +0 -109
- data/bundler/lib/bundler/vendor/fileutils/.document +0 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/.document +0 -1
- data/bundler/lib/bundler/vendor/pub_grub/.document +0 -1
- data/bundler/lib/bundler/vendor/thor/.document +0 -1
- data/bundler/lib/bundler/vendor/tsort/.document +0 -1
- data/bundler/lib/bundler/vendor/uri/.document +0 -1
- data/lib/rubygems/net/http.rb +0 -3
- data/lib/rubygems/net-http/.document +0 -1
- data/lib/rubygems/net-http/LICENSE.txt +0 -22
- data/lib/rubygems/net-http/lib/net/http/backward.rb +0 -40
- data/lib/rubygems/net-protocol/.document +0 -1
- data/lib/rubygems/net-protocol/LICENSE.txt +0 -22
- data/lib/rubygems/optparse/.document +0 -1
- data/lib/rubygems/optparse/lib/optparse/uri.rb +0 -7
- data/lib/rubygems/optparse.rb +0 -3
- data/lib/rubygems/resolv/.document +0 -1
- data/lib/rubygems/resolv/LICENSE.txt +0 -22
- data/lib/rubygems/resolver/molinillo/.document +0 -1
- data/lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb +0 -57
- data/lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb +0 -6
- data/lib/rubygems/resolver/molinillo.rb +0 -3
- data/lib/rubygems/shellwords.rb +0 -3
- data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem +0 -21
- data/lib/rubygems/timeout/.document +0 -1
- data/lib/rubygems/timeout/LICENSE.txt +0 -22
- data/lib/rubygems/timeout.rb +0 -3
- data/lib/rubygems/tsort/.document +0 -1
- data/lib/rubygems/tsort/LICENSE.txt +0 -22
- data/lib/rubygems/tsort.rb +0 -3
- /data/{lib/rubygems/optparse → bundler/lib/bundler/vendor/fileutils}/COPYING +0 -0
- /data/{MAINTAINERS.txt → doc/MAINTAINERS.txt} +0 -0
- /data/{UPGRADING.md → doc/rubygems/UPGRADING.md} +0 -0
- /data/lib/rubygems/ssl_certs/rubygems.org/{GlobalSignRootCA_R3.pem → GlobalSign.pem} +0 -0
- /data/{bundler/lib/bundler/vendor/connection_pool → lib/rubygems/vendor}/.document +0 -0
- /data/lib/rubygems/{resolver → vendor}/molinillo/LICENSE +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/exceptions.rb +0 -0
- /data/lib/rubygems/{net-http → vendor/net-http}/lib/net/http/proxy_delta.rb +0 -0
- /data/{bundler/lib/bundler/vendor/fileutils → lib/rubygems/vendor/net-protocol}/LICENSE.txt +0 -0
- /data/lib/rubygems/{net-protocol → vendor/net-protocol}/lib/net/protocol.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optionparser.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/date.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/shellwords.rb +0 -0
- /data/lib/rubygems/{optparse → vendor/optparse}/lib/optparse/time.rb +0 -0
- /data/{bundler/lib/bundler/vendor/uri → lib/rubygems/vendor/tsort}/LICENSE.txt +0 -0
@@ -15,6 +15,7 @@ class Gem::Commands::EnvironmentCommand < Gem::Command
|
|
15
15
|
version display the gem format version
|
16
16
|
remotesources display the remote gem servers
|
17
17
|
platform display the supported gem platforms
|
18
|
+
credentials display the path where credentials are stored
|
18
19
|
<omitted> display everything
|
19
20
|
EOF
|
20
21
|
args.gsub(/^\s+/, "")
|
@@ -88,6 +89,8 @@ lib/rubygems/defaults/operating_system.rb
|
|
88
89
|
Gem.sources.to_a.join("\n")
|
89
90
|
when /^platform/ then
|
90
91
|
Gem.platforms.join(File::PATH_SEPARATOR)
|
92
|
+
when /^credentials/, /^creds/ then
|
93
|
+
Gem.configuration.credentials_path
|
91
94
|
when nil then
|
92
95
|
show_environment
|
93
96
|
else
|
@@ -114,6 +117,8 @@ lib/rubygems/defaults/operating_system.rb
|
|
114
117
|
|
115
118
|
out << " - USER INSTALLATION DIRECTORY: #{Gem.user_dir}\n"
|
116
119
|
|
120
|
+
out << " - CREDENTIALS FILE: #{Gem.configuration.credentials_path}\n"
|
121
|
+
|
117
122
|
out << " - RUBYGEMS PREFIX: #{Gem.prefix}\n" unless Gem.prefix.nil?
|
118
123
|
|
119
124
|
out << " - RUBY EXECUTABLE: #{Gem.ruby}\n"
|
@@ -57,8 +57,6 @@ to the same gem path as user-installed gems.
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def execute
|
60
|
-
gem_paths = { "GEM_HOME" => Gem.paths.home, "GEM_PATH" => Gem.paths.path.join(File::PATH_SEPARATOR), "GEM_SPEC_CACHE" => Gem.paths.spec_cache_dir }.compact
|
61
|
-
|
62
60
|
check_executable
|
63
61
|
|
64
62
|
print_command
|
@@ -74,9 +72,6 @@ to the same gem path as user-installed gems.
|
|
74
72
|
end
|
75
73
|
|
76
74
|
load!
|
77
|
-
ensure
|
78
|
-
ENV.update(gem_paths) if gem_paths
|
79
|
-
Gem.clear_paths
|
80
75
|
end
|
81
76
|
|
82
77
|
private
|
@@ -143,7 +138,7 @@ to the same gem path as user-installed gems.
|
|
143
138
|
end
|
144
139
|
|
145
140
|
def set_gem_exec_install_paths
|
146
|
-
home =
|
141
|
+
home = Gem.dir
|
147
142
|
|
148
143
|
ENV["GEM_PATH"] = ([home] + Gem.path).join(File::PATH_SEPARATOR)
|
149
144
|
ENV["GEM_HOME"] = home
|
@@ -200,7 +195,7 @@ to the same gem path as user-installed gems.
|
|
200
195
|
argv = ARGV.clone
|
201
196
|
ARGV.replace options[:args]
|
202
197
|
|
203
|
-
|
198
|
+
executable = options[:executable]
|
204
199
|
|
205
200
|
contains_executable = Gem.loaded_specs.values.select do |spec|
|
206
201
|
spec.executables.include?(executable)
|
@@ -211,13 +206,22 @@ to the same gem path as user-installed gems.
|
|
211
206
|
end
|
212
207
|
|
213
208
|
if contains_executable.empty?
|
214
|
-
|
215
|
-
|
216
|
-
|
209
|
+
spec = Gem.loaded_specs[executable]
|
210
|
+
|
211
|
+
if spec.nil? || spec.executables.empty?
|
217
212
|
alert_error "Failed to load executable `#{executable}`," \
|
218
213
|
" are you sure the gem `#{options[:gem_name]}` contains it?"
|
219
214
|
terminate_interaction 1
|
220
215
|
end
|
216
|
+
|
217
|
+
if spec.executables.size > 1
|
218
|
+
alert_error "Ambiguous which executable from gem `#{executable}` should be run: " \
|
219
|
+
"the options are #{spec.executables.sort}, specify one via COMMAND, and use `-g` and `-v` to specify gem and version"
|
220
|
+
terminate_interaction 1
|
221
|
+
end
|
222
|
+
|
223
|
+
contains_executable << spec
|
224
|
+
executable = spec.executable
|
221
225
|
end
|
222
226
|
|
223
227
|
if contains_executable.size > 1
|
@@ -227,8 +231,11 @@ to the same gem path as user-installed gems.
|
|
227
231
|
terminate_interaction 1
|
228
232
|
end
|
229
233
|
|
230
|
-
|
234
|
+
old_exe = $0
|
235
|
+
$0 = executable
|
236
|
+
load Gem.activate_bin_path(contains_executable.first.name, executable, ">= 0.a")
|
231
237
|
ensure
|
238
|
+
$0 = old_exe if old_exe
|
232
239
|
ARGV.replace argv
|
233
240
|
end
|
234
241
|
|
@@ -63,6 +63,17 @@ then repackaging it.
|
|
63
63
|
|
64
64
|
def execute
|
65
65
|
check_version
|
66
|
+
|
67
|
+
exit_code = fetch_gems
|
68
|
+
|
69
|
+
terminate_interaction exit_code
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def fetch_gems
|
75
|
+
exit_code = 0
|
76
|
+
|
66
77
|
version = options[:version]
|
67
78
|
|
68
79
|
platform = Gem.platforms.last
|
@@ -86,10 +97,13 @@ then repackaging it.
|
|
86
97
|
|
87
98
|
if spec.nil?
|
88
99
|
show_lookup_failure gem_name, gem_version, errors, suppress_suggestions, options[:domain]
|
100
|
+
exit_code |= 2
|
89
101
|
next
|
90
102
|
end
|
91
103
|
source.download spec
|
92
104
|
say "Downloaded #{spec.full_name}"
|
93
105
|
end
|
106
|
+
|
107
|
+
exit_code
|
94
108
|
end
|
95
109
|
end
|
@@ -59,7 +59,7 @@ multiple environments. The RubyGems implementation is designed to be
|
|
59
59
|
compatible with Bundler's Gemfile format. You can see additional
|
60
60
|
documentation on the format at:
|
61
61
|
|
62
|
-
|
62
|
+
https://bundler.io
|
63
63
|
|
64
64
|
RubyGems automatically looks for these gem dependencies files:
|
65
65
|
|
@@ -172,7 +172,7 @@ and #platforms methods:
|
|
172
172
|
See the bundler Gemfile manual page for a list of platforms supported in a gem
|
173
173
|
dependencies file.:
|
174
174
|
|
175
|
-
|
175
|
+
https://bundler.io/v2.5/man/gemfile.5.html
|
176
176
|
|
177
177
|
Ruby Version and Engine Dependency
|
178
178
|
==================================
|
@@ -224,10 +224,6 @@ You can use `i` command instead of `install`.
|
|
224
224
|
rescue Gem::InstallError => e
|
225
225
|
alert_error "Error installing #{gem_name}:\n\t#{e.message}"
|
226
226
|
exit_code |= 1
|
227
|
-
rescue Gem::GemNotFoundException => e
|
228
|
-
show_lookup_failure e.name, e.version, e.errors, suppress_suggestions
|
229
|
-
|
230
|
-
exit_code |= 2
|
231
227
|
rescue Gem::UnsatisfiableDependencyError => e
|
232
228
|
show_lookup_failure e.name, e.version, e.errors, suppress_suggestions,
|
233
229
|
"'#{gem_name}' (#{gem_version})"
|
@@ -57,7 +57,7 @@ class Gem::Commands::PristineCommand < Gem::Command
|
|
57
57
|
end
|
58
58
|
|
59
59
|
add_option("-i", "--install-dir DIR",
|
60
|
-
"Gem repository to get
|
60
|
+
"Gem repository to get gems restored") do |value, options|
|
61
61
|
options[:install_dir] = File.expand_path(value)
|
62
62
|
end
|
63
63
|
|
@@ -103,22 +103,26 @@ extensions will be restored.
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def execute
|
106
|
+
install_dir = options[:install_dir]
|
107
|
+
|
108
|
+
specification_record = install_dir ? Gem::SpecificationRecord.from_path(install_dir) : Gem::Specification.specification_record
|
109
|
+
|
106
110
|
specs = if options[:all]
|
107
|
-
|
111
|
+
specification_record.map
|
108
112
|
|
109
113
|
# `--extensions` must be explicitly given to pristine only gems
|
110
114
|
# with extensions.
|
111
115
|
elsif options[:extensions_set] &&
|
112
116
|
options[:extensions] && options[:args].empty?
|
113
|
-
|
117
|
+
specification_record.select do |spec|
|
114
118
|
spec.extensions && !spec.extensions.empty?
|
115
119
|
end
|
116
120
|
elsif options[:only_missing_extensions]
|
117
|
-
|
121
|
+
specification_record.select(&:missing_extensions?)
|
118
122
|
else
|
119
|
-
get_all_gem_names.sort.
|
120
|
-
|
121
|
-
end
|
123
|
+
get_all_gem_names.sort.flat_map do |gem_name|
|
124
|
+
specification_record.find_all_by_name(gem_name, options[:version]).reverse
|
125
|
+
end
|
122
126
|
end
|
123
127
|
|
124
128
|
specs = specs.select {|spec| spec.platform == RUBY_ENGINE || Gem::Platform.local === spec.platform || spec.platform == Gem::Platform::RUBY }
|
@@ -130,10 +134,17 @@ extensions will be restored.
|
|
130
134
|
|
131
135
|
say "Restoring gems to pristine condition..."
|
132
136
|
|
133
|
-
specs.each do |
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
+
specs.group_by(&:full_name_with_location).values.each do |grouped_specs|
|
138
|
+
spec = grouped_specs.find {|s| !s.default_gem? } || grouped_specs.first
|
139
|
+
|
140
|
+
only_executables = options[:only_executables]
|
141
|
+
only_plugins = options[:only_plugins]
|
142
|
+
|
143
|
+
unless only_executables || only_plugins
|
144
|
+
# Default gemspecs include changes provided by ruby-core installer that
|
145
|
+
# can't currently be pristined (inclusion of compiled extension targets in
|
146
|
+
# the file list). So stick to resetting executables if it's a default gem.
|
147
|
+
only_executables = true if spec.default_gem?
|
137
148
|
end
|
138
149
|
|
139
150
|
if options.key? :skip
|
@@ -143,17 +154,17 @@ extensions will be restored.
|
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
146
|
-
unless spec.extensions.empty? || options[:extensions] ||
|
147
|
-
say "Skipped #{spec.
|
157
|
+
unless spec.extensions.empty? || options[:extensions] || only_executables || only_plugins
|
158
|
+
say "Skipped #{spec.full_name_with_location}, it needs to compile an extension"
|
148
159
|
next
|
149
160
|
end
|
150
161
|
|
151
162
|
gem = spec.cache_file
|
152
163
|
|
153
|
-
unless File.exist?(gem) ||
|
164
|
+
unless File.exist?(gem) || only_executables || only_plugins
|
154
165
|
require_relative "../remote_fetcher"
|
155
166
|
|
156
|
-
say "Cached gem for #{spec.
|
167
|
+
say "Cached gem for #{spec.full_name_with_location} not found, attempting to fetch..."
|
157
168
|
|
158
169
|
dep = Gem::Dependency.new spec.name, spec.version
|
159
170
|
found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep
|
@@ -176,7 +187,6 @@ extensions will be restored.
|
|
176
187
|
end
|
177
188
|
|
178
189
|
bin_dir = options[:bin_dir] if options[:bin_dir]
|
179
|
-
install_dir = options[:install_dir] if options[:install_dir]
|
180
190
|
|
181
191
|
installer_options = {
|
182
192
|
wrappers: true,
|
@@ -187,10 +197,10 @@ extensions will be restored.
|
|
187
197
|
bin_dir: bin_dir,
|
188
198
|
}
|
189
199
|
|
190
|
-
if
|
200
|
+
if only_executables
|
191
201
|
installer = Gem::Installer.for_spec(spec, installer_options)
|
192
202
|
installer.generate_bin
|
193
|
-
elsif
|
203
|
+
elsif only_plugins
|
194
204
|
installer = Gem::Installer.for_spec(spec, installer_options)
|
195
205
|
installer.generate_plugins
|
196
206
|
else
|
@@ -198,7 +208,7 @@ extensions will be restored.
|
|
198
208
|
installer.install
|
199
209
|
end
|
200
210
|
|
201
|
-
say "Restored #{spec.
|
211
|
+
say "Restored #{spec.full_name_with_location}"
|
202
212
|
end
|
203
213
|
end
|
204
214
|
end
|
@@ -30,7 +30,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def initialize
|
33
|
-
super "push", "Push a gem up to the gem server", host: host
|
33
|
+
super "push", "Push a gem up to the gem server", host: host, attestations: []
|
34
34
|
|
35
35
|
@user_defined_host = false
|
36
36
|
|
@@ -45,6 +45,11 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
|
|
45
45
|
@user_defined_host = true
|
46
46
|
end
|
47
47
|
|
48
|
+
add_option("--attestation FILE",
|
49
|
+
"Push with sigstore attestations") do |value, options|
|
50
|
+
options[:attestations] << value
|
51
|
+
end
|
52
|
+
|
48
53
|
@host = nil
|
49
54
|
end
|
50
55
|
|
@@ -87,11 +92,20 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
|
|
87
92
|
private
|
88
93
|
|
89
94
|
def send_push_request(name, args)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
+
scope = get_push_scope
|
96
|
+
rubygems_api_request(*args, scope: scope) do |request|
|
97
|
+
body = Gem.read_binary name
|
98
|
+
if options[:attestations].any?
|
99
|
+
request.set_form([
|
100
|
+
["gem", body, { filename: name, content_type: "application/octet-stream" }],
|
101
|
+
get_attestations_part,
|
102
|
+
], "multipart/form-data")
|
103
|
+
else
|
104
|
+
request.body = body
|
105
|
+
request.add_field "Content-Type", "application/octet-stream"
|
106
|
+
request.add_field "Content-Length", request.body.size
|
107
|
+
end
|
108
|
+
request.add_field "Authorization", api_key
|
95
109
|
end
|
96
110
|
end
|
97
111
|
|
@@ -107,4 +121,15 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
|
|
107
121
|
def get_push_scope
|
108
122
|
:push_rubygem
|
109
123
|
end
|
124
|
+
|
125
|
+
def get_attestations_part
|
126
|
+
bundles = "[" + options[:attestations].map do |attestation|
|
127
|
+
Gem.read_binary(attestation)
|
128
|
+
end.join(",") + "]"
|
129
|
+
[
|
130
|
+
"attestations",
|
131
|
+
bundles,
|
132
|
+
{ content_type: "application/json" },
|
133
|
+
]
|
134
|
+
end
|
110
135
|
end
|
@@ -64,9 +64,9 @@ Use --overwrite to force rebuilding of documentation.
|
|
64
64
|
specs = if options[:all]
|
65
65
|
Gem::Specification.to_a
|
66
66
|
else
|
67
|
-
get_all_gem_names.
|
67
|
+
get_all_gem_names.flat_map do |name|
|
68
68
|
Gem::Specification.find_by_name name, options[:version]
|
69
|
-
end.
|
69
|
+
end.uniq
|
70
70
|
end
|
71
71
|
|
72
72
|
if specs.empty?
|
@@ -84,14 +84,7 @@ Use --overwrite to force rebuilding of documentation.
|
|
84
84
|
FileUtils.rm_rf File.join(spec.doc_dir, "rdoc")
|
85
85
|
end
|
86
86
|
|
87
|
-
|
88
|
-
doc.generate
|
89
|
-
rescue Errno::ENOENT => e
|
90
|
-
match = / - /.match(e.message)
|
91
|
-
alert_error "Unable to document #{spec.full_name}, " \
|
92
|
-
" #{match.post_match} is missing, skipping"
|
93
|
-
terminate_interaction 1 if specs.length == 1
|
94
|
-
end
|
87
|
+
doc.generate
|
95
88
|
end
|
96
89
|
end
|
97
90
|
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "digest"
|
5
|
+
require "fileutils"
|
6
|
+
require "tmpdir"
|
7
|
+
require_relative "../gemspec_helpers"
|
8
|
+
require_relative "../package"
|
9
|
+
|
10
|
+
class Gem::Commands::RebuildCommand < Gem::Command
|
11
|
+
include Gem::GemspecHelpers
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super "rebuild", "Attempt to reproduce a build of a gem."
|
15
|
+
|
16
|
+
add_option "--diff", "If the files don't match, compare them using diffoscope." do |_value, options|
|
17
|
+
options[:diff] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
add_option "--force", "Skip validation of the spec." do |_value, options|
|
21
|
+
options[:force] = true
|
22
|
+
end
|
23
|
+
|
24
|
+
add_option "--strict", "Consider warnings as errors when validating the spec." do |_value, options|
|
25
|
+
options[:strict] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
add_option "--source GEM_SOURCE", "Specify the source to download the gem from." do |value, options|
|
29
|
+
options[:source] = value
|
30
|
+
end
|
31
|
+
|
32
|
+
add_option "--original GEM_FILE", "Specify a local file to compare against (instead of downloading it)." do |value, options|
|
33
|
+
options[:original_gem_file] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
add_option "--gemspec GEMSPEC_FILE", "Specify the name of the gemspec file." do |value, options|
|
37
|
+
options[:gemspec_file] = value
|
38
|
+
end
|
39
|
+
|
40
|
+
add_option "-C PATH", "Run as if gem build was started in <PATH> instead of the current working directory." do |value, options|
|
41
|
+
options[:build_path] = value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def arguments # :nodoc:
|
46
|
+
"GEM_NAME gem name on gem server\n" \
|
47
|
+
"GEM_VERSION gem version you are attempting to rebuild"
|
48
|
+
end
|
49
|
+
|
50
|
+
def description # :nodoc:
|
51
|
+
<<-EOF
|
52
|
+
The rebuild command allows you to (attempt to) reproduce a build of a gem
|
53
|
+
from a ruby gemspec.
|
54
|
+
|
55
|
+
This command assumes the gemspec can be built with the `gem build` command.
|
56
|
+
If you use any of `gem build`, `rake build`, or`rake release` in the
|
57
|
+
build/release process for a gem, it is a potential candidate.
|
58
|
+
|
59
|
+
You will need to match the RubyGems version used, since this is included in
|
60
|
+
the Gem metadata.
|
61
|
+
|
62
|
+
If the gem includes lockfiles (e.g. Gemfile.lock) and similar, it will
|
63
|
+
require more effort to reproduce a build. For example, it might require
|
64
|
+
more precisely matched versions of Ruby and/or Bundler to be used.
|
65
|
+
EOF
|
66
|
+
end
|
67
|
+
|
68
|
+
def usage # :nodoc:
|
69
|
+
"#{program_name} GEM_NAME GEM_VERSION"
|
70
|
+
end
|
71
|
+
|
72
|
+
def execute
|
73
|
+
gem_name, gem_version = get_gem_name_and_version
|
74
|
+
|
75
|
+
old_dir, new_dir = prep_dirs
|
76
|
+
|
77
|
+
gem_filename = "#{gem_name}-#{gem_version}.gem"
|
78
|
+
old_file = File.join(old_dir, gem_filename)
|
79
|
+
new_file = File.join(new_dir, gem_filename)
|
80
|
+
|
81
|
+
if options[:original_gem_file]
|
82
|
+
FileUtils.copy_file(options[:original_gem_file], old_file)
|
83
|
+
else
|
84
|
+
download_gem(gem_name, gem_version, old_file)
|
85
|
+
end
|
86
|
+
|
87
|
+
rg_version = rubygems_version(old_file)
|
88
|
+
unless rg_version == Gem::VERSION
|
89
|
+
alert_error <<-EOF
|
90
|
+
You need to use the same RubyGems version #{gem_name} v#{gem_version} was built with.
|
91
|
+
|
92
|
+
#{gem_name} v#{gem_version} was built using RubyGems v#{rg_version}.
|
93
|
+
Gem files include the version of RubyGems used to build them.
|
94
|
+
This means in order to reproduce #{gem_filename}, you must also use RubyGems v#{rg_version}.
|
95
|
+
|
96
|
+
You're using RubyGems v#{Gem::VERSION}.
|
97
|
+
|
98
|
+
Please install RubyGems v#{rg_version} and try again.
|
99
|
+
EOF
|
100
|
+
terminate_interaction 1
|
101
|
+
end
|
102
|
+
|
103
|
+
source_date_epoch = get_timestamp(old_file).to_s
|
104
|
+
|
105
|
+
if build_path = options[:build_path]
|
106
|
+
Dir.chdir(build_path) { build_gem(gem_name, source_date_epoch, new_file) }
|
107
|
+
else
|
108
|
+
build_gem(gem_name, source_date_epoch, new_file)
|
109
|
+
end
|
110
|
+
|
111
|
+
compare(source_date_epoch, old_file, new_file)
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def sha256(file)
|
117
|
+
Digest::SHA256.hexdigest(Gem.read_binary(file))
|
118
|
+
end
|
119
|
+
|
120
|
+
def get_timestamp(file)
|
121
|
+
mtime = nil
|
122
|
+
File.open(file, Gem.binary_mode) do |f|
|
123
|
+
Gem::Package::TarReader.new(f) do |tar|
|
124
|
+
mtime = tar.seek("metadata.gz") {|tf| tf.header.mtime }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
mtime
|
129
|
+
end
|
130
|
+
|
131
|
+
def compare(source_date_epoch, old_file, new_file)
|
132
|
+
date = Time.at(source_date_epoch.to_i).strftime("%F %T %Z")
|
133
|
+
|
134
|
+
old_hash = sha256(old_file)
|
135
|
+
new_hash = sha256(new_file)
|
136
|
+
|
137
|
+
say
|
138
|
+
say "Built at: #{date} (#{source_date_epoch})"
|
139
|
+
say "Original build saved to: #{old_file}"
|
140
|
+
say "Reproduced build saved to: #{new_file}"
|
141
|
+
say "Working directory: #{options[:build_path] || Dir.pwd}"
|
142
|
+
say
|
143
|
+
say "Hash comparison:"
|
144
|
+
say " #{old_hash}\t#{old_file}"
|
145
|
+
say " #{new_hash}\t#{new_file}"
|
146
|
+
say
|
147
|
+
|
148
|
+
if old_hash == new_hash
|
149
|
+
say "SUCCESS - original and rebuild hashes matched"
|
150
|
+
else
|
151
|
+
say "FAILURE - original and rebuild hashes did not match"
|
152
|
+
say
|
153
|
+
|
154
|
+
if options[:diff]
|
155
|
+
if system("diffoscope", old_file, new_file).nil?
|
156
|
+
alert_error "error: could not find `diffoscope` executable"
|
157
|
+
end
|
158
|
+
else
|
159
|
+
say "Pass --diff for more details (requires diffoscope to be installed)."
|
160
|
+
end
|
161
|
+
|
162
|
+
terminate_interaction 1
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def prep_dirs
|
167
|
+
rebuild_dir = Dir.mktmpdir("gem_rebuild")
|
168
|
+
old_dir = File.join(rebuild_dir, "old")
|
169
|
+
new_dir = File.join(rebuild_dir, "new")
|
170
|
+
|
171
|
+
FileUtils.mkdir_p(old_dir)
|
172
|
+
FileUtils.mkdir_p(new_dir)
|
173
|
+
|
174
|
+
[old_dir, new_dir]
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_gem_name_and_version
|
178
|
+
args = options[:args] || []
|
179
|
+
if args.length == 2
|
180
|
+
gem_name, gem_version = args
|
181
|
+
elsif args.length > 2
|
182
|
+
raise Gem::CommandLineError, "Too many arguments"
|
183
|
+
else
|
184
|
+
raise Gem::CommandLineError, "Expected GEM_NAME and GEM_VERSION arguments (gem rebuild GEM_NAME GEM_VERSION)"
|
185
|
+
end
|
186
|
+
|
187
|
+
[gem_name, gem_version]
|
188
|
+
end
|
189
|
+
|
190
|
+
def build_gem(gem_name, source_date_epoch, output_file)
|
191
|
+
gemspec = options[:gemspec_file] || find_gemspec("#{gem_name}.gemspec")
|
192
|
+
|
193
|
+
if gemspec
|
194
|
+
build_package(gemspec, source_date_epoch, output_file)
|
195
|
+
else
|
196
|
+
alert_error error_message(gem_name)
|
197
|
+
terminate_interaction(1)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def build_package(gemspec, source_date_epoch, output_file)
|
202
|
+
with_source_date_epoch(source_date_epoch) do
|
203
|
+
spec = Gem::Specification.load(gemspec)
|
204
|
+
if spec
|
205
|
+
Gem::Package.build(
|
206
|
+
spec,
|
207
|
+
options[:force],
|
208
|
+
options[:strict],
|
209
|
+
output_file
|
210
|
+
)
|
211
|
+
else
|
212
|
+
alert_error "Error loading gemspec. Aborting."
|
213
|
+
terminate_interaction 1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def with_source_date_epoch(source_date_epoch)
|
219
|
+
old_sde = ENV["SOURCE_DATE_EPOCH"]
|
220
|
+
ENV["SOURCE_DATE_EPOCH"] = source_date_epoch.to_s
|
221
|
+
|
222
|
+
yield
|
223
|
+
ensure
|
224
|
+
ENV["SOURCE_DATE_EPOCH"] = old_sde
|
225
|
+
end
|
226
|
+
|
227
|
+
def error_message(gem_name)
|
228
|
+
if gem_name
|
229
|
+
"Couldn't find a gemspec file matching '#{gem_name}' in #{Dir.pwd}"
|
230
|
+
else
|
231
|
+
"Couldn't find a gemspec file in #{Dir.pwd}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def download_gem(gem_name, gem_version, old_file)
|
236
|
+
# This code was based loosely off the `gem fetch` command.
|
237
|
+
version = "= #{gem_version}"
|
238
|
+
dep = Gem::Dependency.new gem_name, version
|
239
|
+
|
240
|
+
specs_and_sources, errors =
|
241
|
+
Gem::SpecFetcher.fetcher.spec_for_dependency dep
|
242
|
+
|
243
|
+
# There should never be more than one item in specs_and_sources,
|
244
|
+
# since we search for an exact version.
|
245
|
+
spec, source = specs_and_sources[0]
|
246
|
+
|
247
|
+
if spec.nil?
|
248
|
+
show_lookup_failure gem_name, version, errors, options[:domain]
|
249
|
+
terminate_interaction 1
|
250
|
+
end
|
251
|
+
|
252
|
+
download_path = source.download spec
|
253
|
+
|
254
|
+
FileUtils.move(download_path, old_file)
|
255
|
+
|
256
|
+
say "Downloaded #{gem_name} version #{gem_version} as #{old_file}."
|
257
|
+
end
|
258
|
+
|
259
|
+
def rubygems_version(gem_file)
|
260
|
+
Gem::Package.new(gem_file).spec.rubygems_version
|
261
|
+
end
|
262
|
+
end
|