rubygems-update 2.7.11 → 3.0.9
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/.rubocop.yml +67 -0
- data/.travis.yml +24 -18
- data/CODE_OF_CONDUCT.md +10 -8
- data/CONTRIBUTING.md +148 -0
- data/History.txt +458 -8
- data/MAINTAINERS.txt +1 -0
- data/Manifest.txt +16 -9
- data/POLICIES.md +92 -0
- data/README.md +53 -26
- data/Rakefile +77 -211
- data/{UPGRADING.rdoc → UPGRADING.md} +31 -32
- data/appveyor.yml +20 -45
- data/bin/gem +1 -2
- data/bin/update_rubygems +2 -3
- data/bundler/CHANGELOG.md +65 -0
- data/bundler/bundler.gemspec +7 -1
- data/bundler/lib/bundler/build_metadata.rb +1 -1
- data/bundler/lib/bundler/cli/add.rb +15 -5
- data/bundler/lib/bundler/cli/binstubs.rb +8 -2
- data/bundler/lib/bundler/cli/doctor.rb +47 -1
- data/bundler/lib/bundler/cli/install.rb +8 -5
- data/bundler/lib/bundler/cli/list.rb +41 -5
- data/bundler/lib/bundler/cli/outdated.rb +7 -1
- data/bundler/lib/bundler/cli/pristine.rb +4 -0
- data/bundler/lib/bundler/cli/remove.rb +18 -0
- data/bundler/lib/bundler/cli.rb +63 -21
- data/bundler/lib/bundler/definition.rb +15 -16
- data/bundler/lib/bundler/dependency.rb +2 -2
- data/bundler/lib/bundler/dsl.rb +19 -3
- data/bundler/lib/bundler/feature_flag.rb +7 -0
- data/bundler/lib/bundler/gem_version_promoter.rb +4 -2
- data/bundler/lib/bundler/injector.rb +168 -9
- data/bundler/lib/bundler/installer/parallel_installer.rb +5 -0
- data/bundler/lib/bundler/installer.rb +29 -6
- data/bundler/lib/bundler/plugin/events.rb +61 -0
- data/bundler/lib/bundler/plugin.rb +10 -3
- data/bundler/lib/bundler/resolver.rb +2 -2
- data/bundler/lib/bundler/rubygems_gem_installer.rb +7 -0
- data/bundler/lib/bundler/runtime.rb +8 -2
- data/bundler/lib/bundler/settings/validator.rb +23 -0
- data/bundler/lib/bundler/settings.rb +24 -3
- data/bundler/lib/bundler/shared_helpers.rb +19 -3
- data/bundler/lib/bundler/source/metadata.rb +2 -3
- data/bundler/lib/bundler/source.rb +9 -9
- data/bundler/lib/bundler/templates/newgem/lib/newgem.rb.tt +1 -0
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler.rb +26 -8
- data/bundler/man/bundle-add.ronn +13 -2
- data/bundler/man/bundle-config.ronn +21 -0
- data/bundler/man/bundle-install.ronn +1 -1
- data/bundler/man/bundle-list.ronn +19 -1
- data/bundler/man/bundle-outdated.ronn +4 -0
- data/bundler/man/bundle-remove.ronn +23 -0
- data/bundler/man/bundle-update.ronn +1 -1
- data/bundler/man/bundle.ronn +3 -0
- data/lib/rubygems/available_set.rb +1 -1
- data/lib/rubygems/basic_specification.rb +12 -12
- data/lib/rubygems/bundler_version_finder.rb +3 -3
- data/lib/rubygems/command.rb +22 -15
- data/lib/rubygems/command_manager.rb +22 -5
- data/lib/rubygems/commands/build_command.rb +41 -7
- data/lib/rubygems/commands/cert_command.rb +45 -24
- data/lib/rubygems/commands/check_command.rb +1 -1
- data/lib/rubygems/commands/cleanup_command.rb +14 -7
- data/lib/rubygems/commands/contents_command.rb +14 -15
- data/lib/rubygems/commands/dependency_command.rb +17 -17
- data/lib/rubygems/commands/environment_command.rb +20 -1
- data/lib/rubygems/commands/fetch_command.rb +2 -3
- data/lib/rubygems/commands/generate_index_command.rb +2 -3
- data/lib/rubygems/commands/help_command.rb +12 -13
- data/lib/rubygems/commands/info_command.rb +33 -0
- data/lib/rubygems/commands/install_command.rb +21 -17
- data/lib/rubygems/commands/list_command.rb +0 -1
- data/lib/rubygems/commands/lock_command.rb +3 -4
- data/lib/rubygems/commands/open_command.rb +16 -10
- data/lib/rubygems/commands/owner_command.rb +21 -7
- data/lib/rubygems/commands/pristine_command.rb +23 -16
- data/lib/rubygems/commands/push_command.rb +19 -8
- data/lib/rubygems/commands/query_command.rb +24 -24
- data/lib/rubygems/commands/rdoc_command.rb +3 -4
- data/lib/rubygems/commands/search_command.rb +0 -1
- data/lib/rubygems/commands/server_command.rb +1 -2
- data/lib/rubygems/commands/setup_command.rb +86 -48
- data/lib/rubygems/commands/signin_command.rb +2 -1
- data/lib/rubygems/commands/signout_command.rb +2 -2
- data/lib/rubygems/commands/sources_command.rb +11 -12
- data/lib/rubygems/commands/specification_command.rb +7 -7
- data/lib/rubygems/commands/uninstall_command.rb +50 -18
- data/lib/rubygems/commands/unpack_command.rb +16 -7
- data/lib/rubygems/commands/update_command.rb +28 -23
- data/lib/rubygems/commands/which_command.rb +5 -8
- data/lib/rubygems/commands/yank_command.rb +1 -2
- data/lib/rubygems/compatibility.rb +1 -21
- data/lib/rubygems/config_file.rb +36 -36
- data/lib/rubygems/core_ext/kernel_require.rb +6 -6
- data/lib/rubygems/core_ext/kernel_warn.rb +45 -0
- data/lib/rubygems/defaults.rb +31 -19
- data/lib/rubygems/dependency.rb +15 -15
- data/lib/rubygems/dependency_installer.rb +30 -33
- data/lib/rubygems/dependency_list.rb +9 -10
- data/lib/rubygems/deprecate.rb +2 -3
- data/lib/rubygems/doctor.rb +5 -6
- data/lib/rubygems/errors.rb +3 -3
- data/lib/rubygems/exceptions.rb +11 -8
- data/lib/rubygems/ext/build_error.rb +0 -1
- data/lib/rubygems/ext/builder.rb +50 -23
- data/lib/rubygems/ext/cmake_builder.rb +2 -2
- data/lib/rubygems/ext/configure_builder.rb +2 -3
- data/lib/rubygems/ext/ext_conf_builder.rb +8 -7
- data/lib/rubygems/ext/rake_builder.rb +16 -18
- data/lib/rubygems/ext.rb +0 -1
- data/lib/rubygems/gem_runner.rb +2 -2
- data/lib/rubygems/gemcutter_utilities.rb +46 -12
- data/lib/rubygems/indexer.rb +19 -12
- data/lib/rubygems/install_default_message.rb +0 -1
- data/lib/rubygems/install_message.rb +0 -1
- data/lib/rubygems/install_update_options.rb +3 -29
- data/lib/rubygems/installer.rb +97 -55
- data/lib/rubygems/installer_test_case.rb +2 -16
- data/lib/rubygems/local_remote_options.rb +5 -4
- data/lib/rubygems/mock_gem_ui.rb +3 -4
- data/lib/rubygems/name_tuple.rb +4 -4
- data/lib/rubygems/package/digest_io.rb +3 -4
- data/lib/rubygems/package/file_source.rb +3 -4
- data/lib/rubygems/package/io_source.rb +1 -2
- data/lib/rubygems/package/old.rb +8 -16
- data/lib/rubygems/package/source.rb +0 -1
- data/lib/rubygems/package/tar_header.rb +13 -4
- data/lib/rubygems/package/tar_reader/entry.rb +20 -4
- data/lib/rubygems/package/tar_reader.rb +2 -4
- data/lib/rubygems/package/tar_test_case.rb +2 -8
- data/lib/rubygems/package/tar_writer.rb +13 -15
- data/lib/rubygems/package.rb +90 -63
- data/lib/rubygems/package_task.rb +0 -1
- data/lib/rubygems/path_support.rb +16 -6
- data/lib/rubygems/platform.rb +4 -5
- data/lib/rubygems/psych_tree.rb +1 -1
- data/lib/rubygems/rdoc.rb +2 -313
- data/lib/rubygems/remote_fetcher.rb +29 -82
- data/lib/rubygems/request/connection_pools.rb +24 -13
- data/lib/rubygems/request/http_pool.rb +3 -4
- data/lib/rubygems/request/https_pool.rb +1 -3
- data/lib/rubygems/request.rb +17 -16
- data/lib/rubygems/request_set/gem_dependency_api.rb +46 -49
- data/lib/rubygems/request_set/lockfile/parser.rb +18 -29
- data/lib/rubygems/request_set/lockfile/tokenizer.rb +9 -9
- data/lib/rubygems/request_set/lockfile.rb +12 -12
- data/lib/rubygems/request_set.rb +52 -25
- data/lib/rubygems/requirement.rb +32 -21
- data/lib/rubygems/resolver/activation_request.rb +6 -6
- data/lib/rubygems/resolver/api_set.rb +5 -6
- data/lib/rubygems/resolver/api_specification.rb +2 -3
- data/lib/rubygems/resolver/best_set.rb +5 -6
- data/lib/rubygems/resolver/composed_set.rb +5 -6
- data/lib/rubygems/resolver/conflict.rb +5 -5
- data/lib/rubygems/resolver/current_set.rb +1 -2
- data/lib/rubygems/resolver/dependency_request.rb +4 -4
- data/lib/rubygems/resolver/git_set.rb +5 -6
- data/lib/rubygems/resolver/git_specification.rb +4 -5
- data/lib/rubygems/resolver/index_set.rb +5 -6
- data/lib/rubygems/resolver/index_specification.rb +3 -4
- data/lib/rubygems/resolver/installed_specification.rb +3 -4
- data/lib/rubygems/resolver/installer_set.rb +12 -12
- data/lib/rubygems/resolver/local_specification.rb +1 -2
- data/lib/rubygems/resolver/lock_set.rb +5 -6
- data/lib/rubygems/resolver/lock_specification.rb +7 -8
- data/lib/rubygems/resolver/requirement_list.rb +1 -1
- data/lib/rubygems/resolver/set.rb +2 -2
- data/lib/rubygems/resolver/source_set.rb +4 -5
- data/lib/rubygems/resolver/spec_specification.rb +1 -2
- data/lib/rubygems/resolver/specification.rb +10 -7
- data/lib/rubygems/resolver/stats.rb +1 -1
- data/lib/rubygems/resolver/vendor_set.rb +4 -5
- data/lib/rubygems/resolver/vendor_specification.rb +2 -3
- data/lib/rubygems/resolver.rb +14 -16
- data/lib/rubygems/s3_uri_signer.rb +183 -0
- data/lib/rubygems/safe_yaml.rb +18 -10
- data/lib/rubygems/security/policies.rb +1 -2
- data/lib/rubygems/security/policy.rb +25 -25
- data/lib/rubygems/security/signer.rb +72 -24
- data/lib/rubygems/security/trust_dir.rb +10 -10
- data/lib/rubygems/security.rb +21 -22
- data/lib/rubygems/security_option.rb +0 -1
- data/lib/rubygems/server.rb +21 -21
- data/lib/rubygems/source/git.rb +9 -10
- data/lib/rubygems/source/installed.rb +3 -4
- data/lib/rubygems/source/local.rb +7 -7
- data/lib/rubygems/source/lock.rb +4 -4
- data/lib/rubygems/source/specific_file.rb +5 -5
- data/lib/rubygems/source/vendor.rb +2 -3
- data/lib/rubygems/source.rb +16 -25
- data/lib/rubygems/source_list.rb +2 -2
- data/lib/rubygems/source_local.rb +0 -1
- data/lib/rubygems/spec_fetcher.rb +5 -6
- data/lib/rubygems/specification.rb +219 -558
- data/lib/rubygems/specification_policy.rb +407 -0
- data/lib/rubygems/stub_specification.rb +12 -17
- data/lib/rubygems/test_case.rb +161 -75
- data/lib/rubygems/test_utilities.rb +20 -35
- data/lib/rubygems/text.rb +6 -6
- data/lib/rubygems/uninstaller.rb +38 -27
- data/lib/rubygems/uri_formatter.rb +1 -2
- data/lib/rubygems/user_interaction.rb +37 -89
- data/lib/rubygems/util/licenses.rb +27 -1
- data/lib/rubygems/util/list.rb +1 -1
- data/lib/rubygems/util.rb +32 -14
- data/lib/rubygems/validator.rb +4 -5
- data/lib/rubygems/version.rb +15 -15
- data/lib/rubygems/version_option.rb +2 -3
- data/lib/rubygems.rb +71 -102
- data/rubygems-update.gemspec +43 -0
- data/setup.rb +2 -8
- data/test/rubygems/ca_cert.pem +74 -65
- data/test/rubygems/client.pem +103 -45
- data/test/rubygems/rubygems_plugin.rb +0 -1
- data/test/rubygems/simple_gem.rb +1 -1
- data/test/rubygems/ssl_cert.pem +78 -17
- data/test/rubygems/ssl_key.pem +25 -13
- data/test/rubygems/test_bundled_ca.rb +1 -1
- data/test/rubygems/test_config.rb +7 -2
- data/test/rubygems/test_gem.rb +205 -132
- data/test/rubygems/test_gem_bundler_version_finder.rb +4 -0
- data/test/rubygems/test_gem_command.rb +0 -1
- data/test/rubygems/test_gem_command_manager.rb +18 -3
- data/test/rubygems/test_gem_commands_build_command.rb +220 -15
- data/test/rubygems/test_gem_commands_cert_command.rb +69 -8
- data/test/rubygems/test_gem_commands_check_command.rb +1 -1
- data/test/rubygems/test_gem_commands_cleanup_command.rb +27 -1
- data/test/rubygems/test_gem_commands_contents_command.rb +1 -2
- data/test/rubygems/test_gem_commands_dependency_command.rb +33 -34
- data/test/rubygems/test_gem_commands_environment_command.rb +1 -0
- data/test/rubygems/test_gem_commands_fetch_command.rb +0 -1
- data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -1
- data/test/rubygems/test_gem_commands_help_command.rb +7 -4
- data/test/rubygems/test_gem_commands_info_command.rb +44 -0
- data/test/rubygems/test_gem_commands_install_command.rb +79 -12
- data/test/rubygems/test_gem_commands_lock_command.rb +0 -1
- data/test/rubygems/test_gem_commands_open_command.rb +29 -0
- data/test/rubygems/test_gem_commands_outdated_command.rb +0 -1
- data/test/rubygems/test_gem_commands_owner_command.rb +93 -57
- data/test/rubygems/test_gem_commands_pristine_command.rb +65 -30
- data/test/rubygems/test_gem_commands_push_command.rb +54 -0
- data/test/rubygems/test_gem_commands_query_command.rb +102 -100
- data/test/rubygems/test_gem_commands_search_command.rb +0 -1
- data/test/rubygems/test_gem_commands_server_command.rb +0 -1
- data/test/rubygems/test_gem_commands_setup_command.rb +50 -15
- data/test/rubygems/test_gem_commands_signin_command.rb +1 -1
- data/test/rubygems/test_gem_commands_sources_command.rb +0 -1
- data/test/rubygems/test_gem_commands_specification_command.rb +2 -3
- data/test/rubygems/test_gem_commands_stale_command.rb +3 -2
- data/test/rubygems/test_gem_commands_uninstall_command.rb +161 -8
- data/test/rubygems/test_gem_commands_unpack_command.rb +17 -1
- data/test/rubygems/test_gem_commands_update_command.rb +19 -2
- data/test/rubygems/test_gem_commands_which_command.rb +0 -1
- data/test/rubygems/test_gem_commands_yank_command.rb +0 -1
- data/test/rubygems/test_gem_config_file.rb +4 -2
- data/test/rubygems/test_gem_dependency.rb +0 -1
- data/test/rubygems/test_gem_dependency_installer.rb +8 -5
- data/test/rubygems/test_gem_dependency_list.rb +6 -7
- data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -1
- data/test/rubygems/test_gem_doctor.rb +1 -2
- data/test/rubygems/test_gem_ext_builder.rb +10 -23
- data/test/rubygems/test_gem_ext_cmake_builder.rb +5 -4
- data/test/rubygems/test_gem_ext_configure_builder.rb +3 -3
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +8 -9
- data/test/rubygems/test_gem_ext_rake_builder.rb +20 -5
- data/test/rubygems/test_gem_gem_runner.rb +0 -1
- data/test/rubygems/test_gem_gemcutter_utilities.rb +32 -6
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -1
- data/test/rubygems/test_gem_indexer.rb +16 -10
- data/test/rubygems/test_gem_install_update_options.rb +1 -20
- data/test/rubygems/test_gem_installer.rb +154 -119
- data/test/rubygems/test_gem_local_remote_options.rb +3 -3
- data/test/rubygems/test_gem_name_tuple.rb +0 -1
- data/test/rubygems/test_gem_package.rb +77 -31
- data/test/rubygems/test_gem_package_old.rb +0 -1
- data/test/rubygems/test_gem_package_tar_header.rb +42 -2
- data/test/rubygems/test_gem_package_tar_reader.rb +0 -1
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +11 -0
- data/test/rubygems/test_gem_package_tar_writer.rb +43 -7
- data/test/rubygems/test_gem_package_task.rb +2 -2
- data/test/rubygems/test_gem_path_support.rb +28 -11
- data/test/rubygems/test_gem_platform.rb +4 -5
- data/test/rubygems/test_gem_rdoc.rb +1 -136
- data/test/rubygems/test_gem_remote_fetcher.rb +241 -141
- data/test/rubygems/test_gem_request.rb +9 -9
- data/test/rubygems/test_gem_request_connection_pools.rb +24 -3
- data/test/rubygems/test_gem_request_set.rb +5 -5
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +82 -64
- data/test/rubygems/test_gem_request_set_lockfile.rb +1 -2
- data/test/rubygems/test_gem_request_set_lockfile_parser.rb +4 -9
- data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +1 -1
- data/test/rubygems/test_gem_requirement.rb +24 -4
- data/test/rubygems/test_gem_resolver.rb +13 -17
- data/test/rubygems/test_gem_resolver_activation_request.rb +0 -1
- data/test/rubygems/test_gem_resolver_api_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_api_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_best_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_composed_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_conflict.rb +0 -1
- data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -1
- data/test/rubygems/test_gem_resolver_git_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_git_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_index_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_index_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_installer_set.rb +2 -3
- data/test/rubygems/test_gem_resolver_local_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_lock_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -1
- data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -1
- data/test/rubygems/test_gem_resolver_specification.rb +1 -2
- data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -1
- data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -1
- data/test/rubygems/test_gem_security.rb +1 -3
- data/test/rubygems/test_gem_security_policy.rb +5 -6
- data/test/rubygems/test_gem_security_signer.rb +4 -3
- data/test/rubygems/test_gem_security_trust_dir.rb +1 -2
- data/test/rubygems/test_gem_server.rb +4 -4
- data/test/rubygems/test_gem_source.rb +0 -13
- data/test/rubygems/test_gem_source_fetch_problem.rb +0 -1
- data/test/rubygems/test_gem_source_git.rb +0 -1
- data/test/rubygems/test_gem_source_installed.rb +0 -1
- data/test/rubygems/test_gem_source_lock.rb +0 -1
- data/test/rubygems/test_gem_source_vendor.rb +0 -1
- data/test/rubygems/test_gem_spec_fetcher.rb +0 -1
- data/test/rubygems/test_gem_specification.rb +366 -198
- data/test/rubygems/test_gem_stream_ui.rb +15 -32
- data/test/rubygems/test_gem_stub_specification.rb +0 -2
- data/test/rubygems/test_gem_text.rb +4 -0
- data/test/rubygems/test_gem_uninstaller.rb +42 -3
- data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -1
- data/test/rubygems/test_gem_uri_formatter.rb +0 -1
- data/test/rubygems/test_gem_util.rb +31 -11
- data/test/rubygems/test_gem_validator.rb +0 -1
- data/test/rubygems/test_gem_version.rb +11 -11
- data/test/rubygems/test_gem_version_option.rb +0 -1
- data/test/rubygems/test_remote_fetch_error.rb +0 -1
- data/test/rubygems/test_require.rb +67 -52
- data/util/CL2notes +1 -2
- data/util/ci +20 -12
- data/util/cops/deprecations.rb +52 -0
- data/util/create_certs.rb +6 -7
- data/util/create_certs.sh +27 -0
- data/util/create_encrypted_key.rb +4 -5
- data/util/patch_with_prs.rb +1 -1
- data/util/rubocop +8 -0
- data/util/update_bundled_ca_certificates.rb +12 -13
- data/util/update_changelog.rb +1 -1
- metadata +61 -51
- data/.autotest +0 -71
- data/.document +0 -5
- data/CONTRIBUTING.rdoc +0 -130
- data/CVE-2013-4287.txt +0 -35
- data/CVE-2013-4363.txt +0 -45
- data/CVE-2015-3900.txt +0 -40
- data/POLICIES.rdoc +0 -74
- data/test/rubygems/fix_openssl_warnings.rb +0 -13
@@ -0,0 +1,407 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
class Gem::SpecificationPolicy < SimpleDelegator
|
5
|
+
VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/.freeze # :nodoc:
|
6
|
+
|
7
|
+
SPECIAL_CHARACTERS = /\A[#{Regexp.escape('.-_')}]+/.freeze # :nodoc:
|
8
|
+
|
9
|
+
VALID_URI_PATTERN = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}.freeze # :nodoc:
|
10
|
+
|
11
|
+
METADATA_LINK_KEYS = %w[
|
12
|
+
bug_tracker_uri
|
13
|
+
changelog_uri
|
14
|
+
documentation_uri
|
15
|
+
homepage_uri
|
16
|
+
mailing_list_uri
|
17
|
+
source_code_uri
|
18
|
+
wiki_uri
|
19
|
+
].freeze # :nodoc:
|
20
|
+
|
21
|
+
def initialize(specification)
|
22
|
+
@warnings = 0
|
23
|
+
|
24
|
+
super(specification)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# If set to true, run packaging-specific checks, as well.
|
29
|
+
|
30
|
+
attr_accessor :packaging
|
31
|
+
|
32
|
+
##
|
33
|
+
# Checks that the specification contains all required fields, and does a
|
34
|
+
# very basic sanity check.
|
35
|
+
#
|
36
|
+
# Raises InvalidSpecificationException if the spec does not pass the
|
37
|
+
# checks.
|
38
|
+
|
39
|
+
def validate(strict = false)
|
40
|
+
validate_nil_attributes
|
41
|
+
|
42
|
+
validate_rubygems_version
|
43
|
+
|
44
|
+
validate_required_attributes
|
45
|
+
|
46
|
+
validate_name
|
47
|
+
|
48
|
+
validate_require_paths
|
49
|
+
|
50
|
+
keep_only_files_and_directories
|
51
|
+
|
52
|
+
validate_non_files
|
53
|
+
|
54
|
+
validate_self_inclusion_in_files_list
|
55
|
+
|
56
|
+
validate_specification_version
|
57
|
+
|
58
|
+
validate_platform
|
59
|
+
|
60
|
+
validate_array_attributes
|
61
|
+
|
62
|
+
validate_authors_field
|
63
|
+
|
64
|
+
validate_metadata
|
65
|
+
|
66
|
+
validate_licenses
|
67
|
+
|
68
|
+
validate_permissions
|
69
|
+
|
70
|
+
validate_lazy_metadata
|
71
|
+
|
72
|
+
validate_values
|
73
|
+
|
74
|
+
validate_dependencies
|
75
|
+
|
76
|
+
if @warnings > 0
|
77
|
+
if strict
|
78
|
+
error "specification has warnings"
|
79
|
+
else
|
80
|
+
alert_warning help_text
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Implementation for Specification#validate_metadata
|
89
|
+
|
90
|
+
def validate_metadata
|
91
|
+
unless Hash === metadata
|
92
|
+
error 'metadata must be a hash'
|
93
|
+
end
|
94
|
+
|
95
|
+
metadata.each do |key, value|
|
96
|
+
if !key.kind_of?(String)
|
97
|
+
error "metadata keys must be a String"
|
98
|
+
end
|
99
|
+
|
100
|
+
if key.size > 128
|
101
|
+
error "metadata key too large (#{key.size} > 128)"
|
102
|
+
end
|
103
|
+
|
104
|
+
if !value.kind_of?(String)
|
105
|
+
error "metadata values must be a String"
|
106
|
+
end
|
107
|
+
|
108
|
+
if value.size > 1024
|
109
|
+
error "metadata value too large (#{value.size} > 1024)"
|
110
|
+
end
|
111
|
+
|
112
|
+
if METADATA_LINK_KEYS.include? key
|
113
|
+
if value !~ VALID_URI_PATTERN
|
114
|
+
error "metadata['#{key}'] has invalid link: #{value.inspect}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
# Implementation for Specification#validate_dependencies
|
122
|
+
|
123
|
+
def validate_dependencies # :nodoc:
|
124
|
+
# NOTE: see REFACTOR note in Gem::Dependency about types - this might be brittle
|
125
|
+
seen = Gem::Dependency::TYPES.inject({}) { |types, type| types.merge({ type => {}}) }
|
126
|
+
|
127
|
+
error_messages = []
|
128
|
+
warning_messages = []
|
129
|
+
dependencies.each do |dep|
|
130
|
+
if prev = seen[dep.type][dep.name]
|
131
|
+
error_messages << <<-MESSAGE
|
132
|
+
duplicate dependency on #{dep}, (#{prev.requirement}) use:
|
133
|
+
add_#{dep.type}_dependency '#{dep.name}', '#{dep.requirement}', '#{prev.requirement}'
|
134
|
+
MESSAGE
|
135
|
+
end
|
136
|
+
|
137
|
+
seen[dep.type][dep.name] = dep
|
138
|
+
|
139
|
+
prerelease_dep = dep.requirements_list.any? do |req|
|
140
|
+
Gem::Requirement.new(req).prerelease?
|
141
|
+
end
|
142
|
+
|
143
|
+
warning_messages << "prerelease dependency on #{dep} is not recommended" if
|
144
|
+
prerelease_dep && !version.prerelease?
|
145
|
+
|
146
|
+
open_ended = dep.requirement.requirements.all? do |op, version|
|
147
|
+
not version.prerelease? and (op == '>' or op == '>=')
|
148
|
+
end
|
149
|
+
|
150
|
+
if open_ended
|
151
|
+
op, dep_version = dep.requirement.requirements.first
|
152
|
+
|
153
|
+
segments = dep_version.segments
|
154
|
+
|
155
|
+
base = segments.first 2
|
156
|
+
|
157
|
+
recommendation = if (op == '>' || op == '>=') && segments == [0]
|
158
|
+
" use a bounded requirement, such as '~> x.y'"
|
159
|
+
else
|
160
|
+
bugfix = if op == '>'
|
161
|
+
", '> #{dep_version}'"
|
162
|
+
elsif op == '>=' and base != segments
|
163
|
+
", '>= #{dep_version}'"
|
164
|
+
end
|
165
|
+
|
166
|
+
" if #{dep.name} is semantically versioned, use:\n" \
|
167
|
+
" add_#{dep.type}_dependency '#{dep.name}', '~> #{base.join '.'}'#{bugfix}"
|
168
|
+
end
|
169
|
+
|
170
|
+
warning_messages << ["open-ended dependency on #{dep} is not recommended", recommendation].join("\n") + "\n"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
if error_messages.any?
|
174
|
+
error error_messages.join
|
175
|
+
end
|
176
|
+
if warning_messages.any?
|
177
|
+
warning_messages.each { |warning_message| warning warning_message }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Issues a warning for each file to be packaged which is world-readable.
|
183
|
+
#
|
184
|
+
# Implementation for Specification#validate_permissions
|
185
|
+
|
186
|
+
def validate_permissions
|
187
|
+
return if Gem.win_platform?
|
188
|
+
|
189
|
+
files.each do |file|
|
190
|
+
next unless File.file?(file)
|
191
|
+
next if File.stat(file).mode & 0444 == 0444
|
192
|
+
warning "#{file} is not world-readable"
|
193
|
+
end
|
194
|
+
|
195
|
+
executables.each do |name|
|
196
|
+
exec = File.join bindir, name
|
197
|
+
next unless File.file?(exec)
|
198
|
+
next if File.stat(exec).executable?
|
199
|
+
warning "#{exec} is not executable"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
|
205
|
+
def validate_nil_attributes
|
206
|
+
nil_attributes = Gem::Specification.non_nil_attributes.select do |attrname|
|
207
|
+
__getobj__.instance_variable_get("@#{attrname}").nil?
|
208
|
+
end
|
209
|
+
return if nil_attributes.empty?
|
210
|
+
error "#{nil_attributes.join ', '} must not be nil"
|
211
|
+
end
|
212
|
+
|
213
|
+
def validate_rubygems_version
|
214
|
+
return unless packaging
|
215
|
+
return if rubygems_version == Gem::VERSION
|
216
|
+
|
217
|
+
error "expected RubyGems version #{Gem::VERSION}, was #{rubygems_version}"
|
218
|
+
end
|
219
|
+
|
220
|
+
def validate_required_attributes
|
221
|
+
Gem::Specification.required_attributes.each do |symbol|
|
222
|
+
unless send symbol
|
223
|
+
error "missing value for attribute #{symbol}"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
def validate_name
|
229
|
+
if !name.is_a?(String)
|
230
|
+
error "invalid value for attribute name: \"#{name.inspect}\" must be a string"
|
231
|
+
elsif name !~ /[a-zA-Z]/
|
232
|
+
error "invalid value for attribute name: #{name.dump} must include at least one letter"
|
233
|
+
elsif name !~ VALID_NAME_PATTERN
|
234
|
+
error "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
|
235
|
+
elsif name =~ SPECIAL_CHARACTERS
|
236
|
+
error "invalid value for attribute name: #{name.dump} can not begin with a period, dash, or underscore"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def validate_require_paths
|
241
|
+
return unless raw_require_paths.empty?
|
242
|
+
|
243
|
+
error 'specification must have at least one require_path'
|
244
|
+
end
|
245
|
+
|
246
|
+
def validate_non_files
|
247
|
+
return unless packaging
|
248
|
+
non_files = files.reject {|x| File.file?(x) || File.symlink?(x)}
|
249
|
+
|
250
|
+
unless non_files.empty?
|
251
|
+
error "[\"#{non_files.join "\", \""}\"] are not files"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def validate_self_inclusion_in_files_list
|
256
|
+
return unless files.include?(file_name)
|
257
|
+
|
258
|
+
error "#{full_name} contains itself (#{file_name}), check your files list"
|
259
|
+
end
|
260
|
+
|
261
|
+
def validate_specification_version
|
262
|
+
return if specification_version.is_a?(Integer)
|
263
|
+
|
264
|
+
error 'specification_version must be an Integer (did you mean version?)'
|
265
|
+
end
|
266
|
+
|
267
|
+
def validate_platform
|
268
|
+
case platform
|
269
|
+
when Gem::Platform, Gem::Platform::RUBY # ok
|
270
|
+
else
|
271
|
+
error "invalid platform #{platform.inspect}, see Gem::Platform"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def validate_array_attributes
|
276
|
+
Gem::Specification.array_attributes.each do |field|
|
277
|
+
validate_array_attribute(field)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def validate_array_attribute(field)
|
282
|
+
val = self.send(field)
|
283
|
+
klass = case field
|
284
|
+
when :dependencies then
|
285
|
+
Gem::Dependency
|
286
|
+
else
|
287
|
+
String
|
288
|
+
end
|
289
|
+
|
290
|
+
unless Array === val and val.all? {|x| x.kind_of?(klass)}
|
291
|
+
raise(Gem::InvalidSpecificationException,
|
292
|
+
"#{field} must be an Array of #{klass}")
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def validate_authors_field
|
297
|
+
return unless authors.empty?
|
298
|
+
|
299
|
+
error "authors may not be empty"
|
300
|
+
end
|
301
|
+
|
302
|
+
def validate_licenses
|
303
|
+
licenses.each { |license|
|
304
|
+
if license.length > 64
|
305
|
+
error "each license must be 64 characters or less"
|
306
|
+
end
|
307
|
+
|
308
|
+
if !Gem::Licenses.match?(license)
|
309
|
+
suggestions = Gem::Licenses.suggestions(license)
|
310
|
+
message = <<-warning
|
311
|
+
license value '#{license}' is invalid. Use a license identifier from
|
312
|
+
http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
|
313
|
+
warning
|
314
|
+
message += "Did you mean #{suggestions.map { |s| "'#{s}'"}.join(', ')}?\n" unless suggestions.nil?
|
315
|
+
warning(message)
|
316
|
+
end
|
317
|
+
}
|
318
|
+
|
319
|
+
warning <<-warning if licenses.empty?
|
320
|
+
licenses is empty, but is recommended. Use a license identifier from
|
321
|
+
http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
|
322
|
+
warning
|
323
|
+
end
|
324
|
+
|
325
|
+
LAZY = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
|
326
|
+
LAZY_PATTERN = /FI XME|TO DO/x.freeze
|
327
|
+
HOMEPAGE_URI_PATTERN = /\A[a-z][a-z\d+.-]*:/i.freeze
|
328
|
+
|
329
|
+
def validate_lazy_metadata
|
330
|
+
unless authors.grep(LAZY_PATTERN).empty?
|
331
|
+
error "#{LAZY} is not an author"
|
332
|
+
end
|
333
|
+
|
334
|
+
unless Array(email).grep(LAZY_PATTERN).empty?
|
335
|
+
error "#{LAZY} is not an email"
|
336
|
+
end
|
337
|
+
|
338
|
+
if description =~ LAZY_PATTERN
|
339
|
+
error "#{LAZY} is not a description"
|
340
|
+
end
|
341
|
+
|
342
|
+
if summary =~ LAZY_PATTERN
|
343
|
+
error "#{LAZY} is not a summary"
|
344
|
+
end
|
345
|
+
|
346
|
+
# Make sure a homepage is valid HTTP/HTTPS URI
|
347
|
+
if homepage and not homepage.empty?
|
348
|
+
begin
|
349
|
+
homepage_uri = URI.parse(homepage)
|
350
|
+
unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
|
351
|
+
error "\"#{homepage}\" is not a valid HTTP URI"
|
352
|
+
end
|
353
|
+
rescue URI::InvalidURIError
|
354
|
+
error "\"#{homepage}\" is not a valid HTTP URI"
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def validate_values
|
360
|
+
%w[author homepage summary files].each do |attribute|
|
361
|
+
validate_attribute_present(attribute)
|
362
|
+
end
|
363
|
+
|
364
|
+
if description == summary
|
365
|
+
warning "description and summary are identical"
|
366
|
+
end
|
367
|
+
|
368
|
+
# TODO: raise at some given date
|
369
|
+
warning "deprecated autorequire specified" if autorequire
|
370
|
+
|
371
|
+
executables.each do |executable|
|
372
|
+
validate_shebang_line_in(executable)
|
373
|
+
end
|
374
|
+
|
375
|
+
files.select { |f| File.symlink?(f) }.each do |file|
|
376
|
+
warning "#{file} is a symlink, which is not supported on all platforms"
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def validate_attribute_present(attribute)
|
381
|
+
value = self.send attribute
|
382
|
+
warning("no #{attribute} specified") if value.nil? || value.empty?
|
383
|
+
end
|
384
|
+
|
385
|
+
def validate_shebang_line_in(executable)
|
386
|
+
executable_path = File.join(bindir, executable)
|
387
|
+
return if File.read(executable_path, 2) == '#!'
|
388
|
+
|
389
|
+
warning "#{executable_path} is missing #! line"
|
390
|
+
end
|
391
|
+
|
392
|
+
def warning(statement) # :nodoc:
|
393
|
+
@warnings += 1
|
394
|
+
|
395
|
+
alert_warning statement
|
396
|
+
end
|
397
|
+
|
398
|
+
def error(statement) # :nodoc:
|
399
|
+
raise Gem::InvalidSpecificationException, statement
|
400
|
+
ensure
|
401
|
+
alert_warning help_text
|
402
|
+
end
|
403
|
+
|
404
|
+
def help_text # :nodoc:
|
405
|
+
"See http://guides.rubygems.org/specification-reference/ for help"
|
406
|
+
end
|
407
|
+
end
|
@@ -6,14 +6,10 @@
|
|
6
6
|
|
7
7
|
class Gem::StubSpecification < Gem::BasicSpecification
|
8
8
|
# :nodoc:
|
9
|
-
PREFIX = "# stub: "
|
9
|
+
PREFIX = "# stub: ".freeze
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
'r:UTF-8:-'
|
14
|
-
else
|
15
|
-
'r'
|
16
|
-
end
|
11
|
+
# :nodoc:
|
12
|
+
OPEN_MODE = 'r:UTF-8:-'.freeze
|
17
13
|
|
18
14
|
class StubLine # :nodoc: all
|
19
15
|
attr_reader :name, :version, :platform, :require_paths, :extensions,
|
@@ -26,7 +22,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
|
26
22
|
'lib' => 'lib'.freeze,
|
27
23
|
'test' => 'test'.freeze,
|
28
24
|
'ext' => 'ext'.freeze,
|
29
|
-
}
|
25
|
+
}.freeze
|
30
26
|
|
31
27
|
# These are common require path lists. This hash is used to optimize
|
32
28
|
# and consolidate require_path objects. Most specs just specify "lib"
|
@@ -34,9 +30,9 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
|
34
30
|
# a require path list for that case.
|
35
31
|
REQUIRE_PATH_LIST = { # :nodoc:
|
36
32
|
'lib' => ['lib'].freeze
|
37
|
-
}
|
33
|
+
}.freeze
|
38
34
|
|
39
|
-
def initialize
|
35
|
+
def initialize(data, extensions)
|
40
36
|
parts = data[PREFIX.length..-1].split(" ".freeze, 4)
|
41
37
|
@name = parts[0].freeze
|
42
38
|
@version = if Gem::Version.correct?(parts[1])
|
@@ -60,17 +56,17 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
|
60
56
|
end
|
61
57
|
end
|
62
58
|
|
63
|
-
def self.default_gemspec_stub
|
59
|
+
def self.default_gemspec_stub(filename, base_dir, gems_dir)
|
64
60
|
new filename, base_dir, gems_dir, true
|
65
61
|
end
|
66
62
|
|
67
|
-
def self.gemspec_stub
|
63
|
+
def self.gemspec_stub(filename, base_dir, gems_dir)
|
68
64
|
new filename, base_dir, gems_dir, false
|
69
65
|
end
|
70
66
|
|
71
67
|
attr_reader :base_dir, :gems_dir
|
72
68
|
|
73
|
-
def initialize
|
69
|
+
def initialize(filename, base_dir, gems_dir, default_gem)
|
74
70
|
super()
|
75
71
|
filename.untaint
|
76
72
|
|
@@ -114,12 +110,11 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
|
114
110
|
begin
|
115
111
|
saved_lineno = $.
|
116
112
|
|
117
|
-
|
118
|
-
open loaded_from, OPEN_MODE do |file|
|
113
|
+
File.open loaded_from, OPEN_MODE do |file|
|
119
114
|
begin
|
120
115
|
file.readline # discard encoding line
|
121
116
|
stubline = file.readline.chomp
|
122
|
-
if stubline.start_with?(PREFIX)
|
117
|
+
if stubline.start_with?(PREFIX)
|
123
118
|
extensions = if /\A#{PREFIX}/ =~ file.readline.chomp
|
124
119
|
$'.split "\0"
|
125
120
|
else
|
@@ -189,7 +184,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
|
|
189
184
|
# The full Gem::Specification for this gem, loaded from evalling its gemspec
|
190
185
|
|
191
186
|
def to_spec
|
192
|
-
@spec ||= if @data
|
187
|
+
@spec ||= if @data
|
193
188
|
loaded = Gem.loaded_specs[name]
|
194
189
|
loaded if loaded && loaded.version == version
|
195
190
|
end
|