From 4c802f0d380f4914e282ec6b4cac15a3fcd3ff39 Mon Sep 17 00:00:00 2001 From: Masafumi Koba <473530+ybiquitous@users.noreply.github.com> Date: Sat, 20 Feb 2021 01:16:40 +0900 Subject: [PATCH 1/2] Add signatures for `Gem` module in `rubygems` gem This change adds signatures of the `Gem` module in the `rubygems` gem. Note that this does not include signatures of `Gem::*` classes or modules like `Gem::Version`. (because it would be a too big PR) See also: - https://github.com/rubygems/rubygems/blob/v3.2.11/lib/rubygems.rb - https://ruby-doc.org/stdlib-3.0.0/libdoc/rubygems/rdoc/Gem.html --- stdlib/rubygems/0/basic_specification.rbs | 3 + stdlib/rubygems/0/config_file.rbs | 3 + stdlib/rubygems/0/dependency_installer.rbs | 5 + stdlib/rubygems/0/installer.rbs | 3 + stdlib/rubygems/0/path_support.rbs | 3 + stdlib/rubygems/0/platform.rbs | 3 + stdlib/rubygems/0/request_set.rbs | 7 + stdlib/rubygems/0/requirement.rbs | 3 + stdlib/rubygems/0/rubygems.rbs | 711 +++++++++++++++++++++ stdlib/rubygems/0/source_list.rbs | 2 + stdlib/rubygems/0/specification.rbs | 3 + stdlib/rubygems/0/stream_ui.rbs | 3 + stdlib/rubygems/0/uninstaller.rbs | 3 + stdlib/rubygems/0/version.rbs | 3 + test/stdlib/rubygems/Gem_test.rb | 597 +++++++++++++++++ 15 files changed, 1352 insertions(+) create mode 100644 stdlib/rubygems/0/basic_specification.rbs create mode 100644 stdlib/rubygems/0/config_file.rbs create mode 100644 stdlib/rubygems/0/dependency_installer.rbs create mode 100644 stdlib/rubygems/0/installer.rbs create mode 100644 stdlib/rubygems/0/path_support.rbs create mode 100644 stdlib/rubygems/0/platform.rbs create mode 100644 stdlib/rubygems/0/request_set.rbs create mode 100644 stdlib/rubygems/0/requirement.rbs create mode 100644 stdlib/rubygems/0/rubygems.rbs create mode 100644 stdlib/rubygems/0/source_list.rbs create mode 100644 stdlib/rubygems/0/specification.rbs create mode 100644 stdlib/rubygems/0/stream_ui.rbs create mode 100644 stdlib/rubygems/0/uninstaller.rbs create mode 100644 stdlib/rubygems/0/version.rbs create mode 100644 test/stdlib/rubygems/Gem_test.rb diff --git a/stdlib/rubygems/0/basic_specification.rbs b/stdlib/rubygems/0/basic_specification.rbs new file mode 100644 index 000000000..10f2c7aa4 --- /dev/null +++ b/stdlib/rubygems/0/basic_specification.rbs @@ -0,0 +1,3 @@ +class Gem::BasicSpecification + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/config_file.rbs b/stdlib/rubygems/0/config_file.rbs new file mode 100644 index 000000000..2f8684590 --- /dev/null +++ b/stdlib/rubygems/0/config_file.rbs @@ -0,0 +1,3 @@ +class Gem::ConfigFile + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/dependency_installer.rbs b/stdlib/rubygems/0/dependency_installer.rbs new file mode 100644 index 000000000..5ddf017cf --- /dev/null +++ b/stdlib/rubygems/0/dependency_installer.rbs @@ -0,0 +1,5 @@ +class Gem::DependencyInstaller + type options = Hash[Symbol, untyped] # TODO: Add options... + + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/installer.rbs b/stdlib/rubygems/0/installer.rbs new file mode 100644 index 000000000..58ac60d90 --- /dev/null +++ b/stdlib/rubygems/0/installer.rbs @@ -0,0 +1,3 @@ +class Gem::Installer + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/path_support.rbs b/stdlib/rubygems/0/path_support.rbs new file mode 100644 index 000000000..8b8b0b106 --- /dev/null +++ b/stdlib/rubygems/0/path_support.rbs @@ -0,0 +1,3 @@ +class Gem::PathSupport + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/platform.rbs b/stdlib/rubygems/0/platform.rbs new file mode 100644 index 000000000..7ebd37487 --- /dev/null +++ b/stdlib/rubygems/0/platform.rbs @@ -0,0 +1,3 @@ +class Gem::Platform + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/request_set.rbs b/stdlib/rubygems/0/request_set.rbs new file mode 100644 index 000000000..2ac80e629 --- /dev/null +++ b/stdlib/rubygems/0/request_set.rbs @@ -0,0 +1,7 @@ +class Gem::RequestSet + # TODO: Add sinatures... +end + +class Gem::RequestSet::GemDependencyAPI + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/requirement.rbs b/stdlib/rubygems/0/requirement.rbs new file mode 100644 index 000000000..d48e3b861 --- /dev/null +++ b/stdlib/rubygems/0/requirement.rbs @@ -0,0 +1,3 @@ +class Gem::Requirement + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/rubygems.rbs b/stdlib/rubygems/0/rubygems.rbs new file mode 100644 index 000000000..09128e136 --- /dev/null +++ b/stdlib/rubygems/0/rubygems.rbs @@ -0,0 +1,711 @@ +# TODO: Is this defined as a built-in type? +interface _HashLike[K, V] + def each_pair: () { ([ K, V ]) -> untyped } -> self +end + +# RubyGems is the Ruby standard for publishing and managing third party +# libraries. +# +# For user documentation, see: +# +# * `gem help` and `gem help [command]` +# * [RubyGems User Guide](https://guides.rubygems.org/) +# * [Frequently Asked Questions](https://guides.rubygems.org/faqs) +# +# +# For gem developer documentation see: +# +# * [Creating Gems](https://guides.rubygems.org/make-your-own-gem) +# * Gem::Specification +# * Gem::Version for version dependency notes +# +# +# Further RubyGems documentation can be found at: +# +# * [RubyGems Guides](https://guides.rubygems.org) +# * [RubyGems API](https://www.rubydoc.info/github/rubygems/rubygems) (also +# available from `gem server`) +# +# +# ## RubyGems Plugins +# +# RubyGems will load plugins in the latest version of each installed gem or +# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and +# placed at the root of your gem's #require_path. Plugins are installed at a +# special location and loaded on boot. +# +# For an example plugin, see the [Graph gem](https://github.com/seattlerb/graph) +# which adds a `gem graph` command. +# +# ## RubyGems Defaults, Packaging +# +# RubyGems defaults are stored in lib/rubygems/defaults.rb. If you're packaging +# RubyGems or implementing Ruby you can change RubyGems' defaults. +# +# For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb and +# override any defaults from lib/rubygems/defaults.rb. +# +# For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and +# override any defaults from lib/rubygems/defaults.rb. +# +# If you need RubyGems to perform extra work on install or uninstall, your +# defaults override file can set pre/post install and uninstall hooks. See +# Gem::pre_install, Gem::pre_uninstall, Gem::post_install, Gem::post_uninstall. +# +# ## Bugs +# +# You can submit bugs to the [RubyGems bug +# tracker](https://github.com/rubygems/rubygems/issues) on GitHub +# +# ## Credits +# +# RubyGems is currently maintained by Eric Hodel. +# +# RubyGems was originally developed at RubyConf 2003 by: +# +# * Rich Kilmer -- rich(at)infoether.com +# * Chad Fowler -- chad(at)chadfowler.com +# * David Black -- dblack(at)wobblini.net +# * Paul Brannan -- paul(at)atdesk.com +# * Jim Weirich -- jim(at)weirichhouse.org +# +# +# Contributors: +# +# * Gavin Sinclair -- gsinclair(at)soyabean.com.au +# * George Marrows -- george.marrows(at)ntlworld.com +# * Dick Davies -- rasputnik(at)hellooperator.net +# * Mauricio Fernandez -- batsman.geo(at)yahoo.com +# * Simon Strandgaard -- neoneye(at)adslhome.dk +# * Dave Glasser -- glasser(at)mit.edu +# * Paul Duncan -- pabs(at)pablotron.org +# * Ville Aine -- vaine(at)cs.helsinki.fi +# * Eric Hodel -- drbrain(at)segment7.net +# * Daniel Berger -- djberg96(at)gmail.com +# * Phil Hagelberg -- technomancy(at)gmail.com +# * Ryan Davis -- ryand-ruby(at)zenspider.com +# * Evan Phoenix -- evan(at)fallingsnow.net +# * Steve Klabnik -- steve(at)steveklabnik.com +# +# +# (If your name is missing, PLEASE let us know!) +# +# ## License +# +# See [LICENSE.txt](rdoc-ref:lib/rubygems/LICENSE.txt) for permissions. +# +# Thanks! +# +# -The RubyGems Team +# +module Gem + DEFAULT_HOST: String + + GEM_DEP_FILES: Array[String] + + # When https://bugs.ruby-lang.org/issues/17259 is available, there is no need to + # override Kernel#warn + # + KERNEL_WARN_IGNORES_INTERNAL_ENTRIES: bool + + LOADED_SPECS_MUTEX: Thread::Mutex + + # Location of Marshal quick gemspecs on remote repositories + # + MARSHAL_SPEC_DIR: String + + # Exception classes used in a Gem.read_binary `rescue` statement + # + READ_BINARY_ERRORS: Array[Class] + + # Subdirectories in a gem repository for default gems + # + REPOSITORY_DEFAULT_GEM_SUBDIRECTORIES: Array[String] + + # Subdirectories in a gem repository + # + REPOSITORY_SUBDIRECTORIES: Array[String] + + RUBYGEMS_DIR: String + + # Taint support is deprecated in Ruby 2.7. This allows switching ".untaint" to + # ".tap(&Gem::UNTAINT)", to avoid deprecation warnings in Ruby 2.7. + # + UNTAINT: Proc + + VERSION: String + + # An Array of Regexps that match windows Ruby platforms. + # + WIN_PATTERNS: Array[Regexp] + + # Exception classes used in Gem.write_binary `rescue` statement + # + WRITE_BINARY_ERRORS: Array[Class] + + # The number of paths in the `$LOAD_PATH` from activated gems. Used to + # prioritize `-I` and `[ENV]('RUBYLIB`)` entries during `require`. + # + def self.activated_gem_paths: () -> Integer + + # Add a list of paths to the $LOAD_PATH at the proper place. + # + def self.add_to_load_path: (*String paths) -> Array[String] + + # Find the full path to the executable for gem `name`. If the `exec_name` is + # not given, an exception will be raised, otherwise the specified executable's + # path is returned. `requirements` allows you to specify specific gem versions. + # + def self.bin_path: (String name, String exec_name, ?Array[Requirement] requirements) -> String + + # The mode needed to read a file as straight binary. + # + def self.binary_mode: () -> String + + # The path where gem executables are to be installed. + # + def self.bindir: (?String install_dir) -> String + + # The path to standard location of the user's cache directory. + # + def self.cache_home: () -> String + + # Clear default gem related variables. It is for test + # + def self.clear_default_specs: () -> void + + # Reset the `dir` and `path` values. The next time `dir` or `path` is + # requested, the values will be calculated from scratch. This is mainly used by + # the unit tests to provide test isolation. + # + def self.clear_paths: () -> void + + # The path to standard location of the user's .gemrc file. + # + def self.config_file: () -> String + + # The path to standard location of the user's configuration directory. + # + def self.config_home: () -> String + + # The standard configuration object for gems. + # + def self.configuration: () -> ConfigFile + + # Use the given configuration object (which implements the ConfigFile protocol) + # as the standard configuration object. + # + def self.configuration=: (ConfigFile config) -> ConfigFile + + # The path to standard location of the user's data directory. + # + def self.data_home: () -> String + + # The path to the data directory specified by the gem name. If the package is + # not available as a gem, return nil. + # + def self.datadir: (String gem_name) -> String? + + # The default directory for binaries + # + def self.default_bindir: () -> String + + # The default signing certificate chain path + # + def self.default_cert_path: () -> String + + # Default home directory path to be used if an alternate value is not specified + # in the environment + # + def self.default_dir: () -> String + + # Deduce Ruby's --program-prefix and --program-suffix from its install name + # + def self.default_exec_format: () -> String + + # Returns binary extensions dir for specified RubyGems base dir or nil if such + # directory cannot be determined. + # + # By default, the binary extensions are located side by side with their Ruby + # counterparts, therefore nil is returned + # + def self.default_ext_dir_for: (String base_dir) -> String? + + # The default signing key path + # + def self.default_key_path: () -> String + + # Default gem load path + # + def self.default_path: () -> Array[String] + + # Paths where RubyGems' .rb files and bin files are installed + # + def self.default_rubygems_dirs: () -> Array[String]? + + # An Array of the default sources that come with RubyGems + # + def self.default_sources: () -> Array[String] + + # Default spec directory path to be used if an alternate value is not specified + # in the environment + # + def self.default_spec_cache_dir: () -> String + + # Path to specification files of default gems. + # + def self.default_specifications_dir: () -> String + + # A Zlib::Deflate.deflate wrapper + # + def self.deflate: (String data) -> String + + # The path where gems are to be installed. + # + def self.dir: () -> String + + # RubyGems distributors (like operating system package managers) can disable + # RubyGems update by setting this to error message printed to end-users on gem + # update --system instead of actual update. + # + def self.disable_system_update_message: () -> String? + + def self.disable_system_update_message=: (String?) -> String? + + # Adds a post-installs hook that will be passed a Gem::DependencyInstaller and a + # list of installed specifications when Gem::DependencyInstaller#install is + # complete + # + def self.done_installing: () { (DependencyInstaller, Array[Specification]) -> untyped } -> Array[Proc] + + # The list of hooks to be run after Gem::DependencyInstaller installs a set of + # gems + # + def self.done_installing_hooks: () -> Array[Proc?] + + # Quietly ensure the Gem directory `dir` contains all the proper subdirectories + # for handling default gems. If we can't create a directory due to a permission + # problem, then we will silently continue. + # + # If `mode` is given, missing directories are created with this mode. + # + # World-writable directories will never be created. + # + def self.ensure_default_gem_subdirectories: (?String dir, ?Integer | String mode) -> Array[String] + + # Quietly ensure the Gem directory `dir` contains all the proper subdirectories. + # If we can't create a directory due to a permission problem, then we will + # silently continue. + # + # If `mode` is given, missing directories are created with this mode. + # + # World-writable directories will never be created. + # + def self.ensure_gem_subdirectories: (?String dir, ?Integer | String mode) -> Array[String] + + def self.env_requirement: (String gem_name) -> Requirement + + # Finds the user's config file + # + def self.find_config_file: () -> String + + # Returns a list of paths matching `glob` that can be used by a gem to pick up + # features from other gems. For example: + # + # Gem.find_files('rdoc/discover').each do |path| load path end + # + # if `check_load_path` is true (the default), then find_files also searches + # $LOAD_PATH for files as well as gems. + # + # Note that find_files will return all files even if they are from different + # versions of the same gem. See also find_latest_files + # + def self.find_files: (String glob, ?boolish check_load_path) -> Array[String] + + # Returns a list of paths matching `glob` from the latest gems that can be used + # by a gem to pick up features from other gems. For example: + # + # Gem.find_latest_files('rdoc/discover').each do |path| load path end + # + # if `check_load_path` is true (the default), then find_latest_files also + # searches $LOAD_PATH for files as well as gems. + # + # Unlike find_files, find_latest_files will return only files from the latest + # version of a gem. + # + def self.find_latest_files: (String glob, ?boolish check_load_path) -> Array[String] + + # Find a Gem::Specification of default gem from `path` + # + def self.find_unresolved_default_spec: (String path) -> Specification? + + def self.finish_resolve: (?RequestSet request_set) -> Array[Specification] + + # GemDependencyAPI object, which is set when .use_gemdeps is called. This + # contains all the information from the Gemfile. + # + def self.gemdeps: () -> RequestSet::GemDependencyAPI? + + # Get the default RubyGems API host. This is normally `https://rubygems.org`. + # + def self.host: () -> String + + # Set the default RubyGems API host. + # + def self.host=: (String host) -> String + + # Top level install helper method. Allows you to install gems interactively: + # + # % irb + # >> Gem.install "minitest" + # Fetching: minitest-5.14.0.gem (100%) + # => [#] + # + def self.install: (String name, ?Gem::Requirement version, *DependencyInstaller::options options) -> Array[Specification] + + # Is this a java platform? + # + def self.java_platform?: () -> bool + + # Returns the latest release version of RubyGems. + # + def self.latest_rubygems_version: () -> Version + + # Returns the latest release-version specification for the gem `name`. + # + def self.latest_spec_for: (String name) -> Specification? + + # Returns the version of the latest release-version of gem `name` + # + def self.latest_version_for: (String name) -> Version? + + # Find all 'rubygems_plugin' files in $LOAD_PATH and load them + # + def self.load_env_plugins: () -> Array[String] + + # The index to insert activated gem paths into the $LOAD_PATH. The activated + # gem's paths are inserted before site lib directory by default. + # + def self.load_path_insert_index: () -> Integer + + # Find rubygems plugin files in the standard location and load them + # + def self.load_plugins: () -> Array[String] + + # Loads YAML, preferring Psych + # + def self.load_yaml: () -> bool? + + # Hash of loaded Gem::Specification keyed by name + # + def self.loaded_specs: () -> Hash[String, BasicSpecification] + + # The file name and line number of the caller of the caller of this method. + # + # `depth` is how many layers up the call stack it should go. + # + # e.g., + # + # def a; Gem.location_of_caller; end a #=> ["x.rb", 2] # (it'll vary depending + # on file name and line number) + # + # def b; c; end def c; Gem.location_of_caller(2); end b #=> ["x.rb", 6] # + # (it'll vary depending on file name and line number) + # + def self.location_of_caller: (?Integer depth) -> [ String, Integer ] + + # The version of the Marshal format for your Ruby. + # + def self.marshal_version: () -> String + + def self.needs: () { (RequestSet) -> untyped } -> Array[Specification] + + # Default options for gem commands for Ruby packagers. + # + # The options here should be structured as an array of string "gem" command + # names as keys and a string of the default options as values. + # + # Example: + # + # def self.operating_system_defaults + # { + # 'install' => '--no-rdoc --no-ri --env-shebang', + # 'update' => '--no-rdoc --no-ri --env-shebang' + # } + # + # end + # + def self.operating_system_defaults: () -> Hash[String, String] + + def self.path: () -> Array[String] + + # How String Gem paths should be split. Overridable for esoteric platforms. + # + def self.path_separator: () -> String + + # Retrieve the PathSupport object that RubyGems uses to lookup files. + # + def self.paths: () -> PathSupport + + # Initialize the filesystem paths to use from `env`. `env` is a hash-like object + # (typically ENV) that is queried for 'GEM_HOME', 'GEM_PATH', and + # 'GEM_SPEC_CACHE' Keys for the `env` hash should be Strings, and values of the + # hash should be Strings or `nil`. + # + def self.paths=: (_HashLike[String, String?] env) -> Array[String] + + # Default options for gem commands for Ruby implementers. + # + # The options here should be structured as an array of string "gem" command + # names as keys and a string of the default options as values. + # + # Example: + # + # def self.platform_defaults + # { + # 'install' => '--no-rdoc --no-ri --env-shebang', + # 'update' => '--no-rdoc --no-ri --env-shebang' + # } + # + # end + # + def self.platform_defaults: () -> Hash[String, String] + + # Array of platforms this RubyGems supports. + # + def self.platforms: () -> Array[String | Platform] + + # Set array of platforms this RubyGems supports (primarily for testing). + # + def self.platforms=: (Array[String | Platform] platforms) -> Array[String | Platform] + + # Glob pattern for require-able plugin suffixes. + # + def self.plugin_suffix_pattern: () -> String + + # Regexp for require-able plugin suffixes. + # + def self.plugin_suffix_regexp: () -> Regexp + + # The path were rubygems plugins are to be installed. + # + def self.plugindir: (?String install_dir) -> String + + # Adds a post-build hook that will be passed an Gem::Installer instance when + # Gem::Installer#install is called. The hook is called after the gem has been + # extracted and extensions have been built but before the executables or gemspec + # has been written. If the hook returns `false` then the gem's files will be + # removed and the install will be aborted. + # + def self.post_build: () { (Installer) -> untyped } -> Array[Proc] + + # The list of hooks to be run after Gem::Installer#install extracts files and + # builds extensions + # + def self.post_build_hooks: () -> Array[Proc] + + # Adds a post-install hook that will be passed an Gem::Installer instance when + # Gem::Installer#install is called + # + def self.post_install: () { (Installer) -> untyped } -> Array[Proc] + + # The list of hooks to be run after Gem::Installer#install completes + # installation + # + def self.post_install_hooks: () -> Array[Proc] + + # Adds a hook that will get run after Gem::Specification.reset is run. + # + def self.post_reset: () { () -> untyped } -> Array[Proc] + + # The list of hooks to be run after Gem::Specification.reset is run. + # + def self.post_reset_hooks: () -> Array[Proc?] + + # Adds a post-uninstall hook that will be passed a Gem::Uninstaller instance and + # the spec that was uninstalled when Gem::Uninstaller#uninstall is called + # + def self.post_uninstall: () { (Uninstaller) -> untyped } -> Array[Proc] + + # The list of hooks to be run after Gem::Uninstaller#uninstall completes + # installation + # + def self.post_uninstall_hooks: () -> Array[Proc?] + + # Adds a pre-install hook that will be passed an Gem::Installer instance when + # Gem::Installer#install is called. If the hook returns `false` then the + # install will be aborted. + # + def self.pre_install: () { (Installer) -> untyped } -> Array[Proc] + + # The list of hooks to be run before Gem::Installer#install does any work + # + def self.pre_install_hooks: () -> Array[Proc?] + + # Adds a hook that will get run before Gem::Specification.reset is run. + # + def self.pre_reset: () { () -> untyped } -> Array[Proc] + + # The list of hooks to be run before Gem::Specification.reset is run. + # + def self.pre_reset_hooks: () -> Array[Proc?] + + # Adds a pre-uninstall hook that will be passed an Gem::Uninstaller instance and + # the spec that will be uninstalled when Gem::Uninstaller#uninstall is called + # + def self.pre_uninstall: () { (Uninstaller) -> untyped } -> Array[Proc] + + # The list of hooks to be run before Gem::Uninstaller#uninstall does any work + # + def self.pre_uninstall_hooks: () -> Array[Proc?] + + # The directory prefix this RubyGems was installed at. If your prefix is in a + # standard location (ie, rubygems is installed where you'd expect it to be), + # then prefix returns nil. + # + def self.prefix: () -> String? + + # Safely read a file in binary mode on all platforms. + # + def self.read_binary: (String path) -> String + + # Refresh available gems from disk. + # + def self.refresh: () -> Array[Proc] + + # Register a Gem::Specification for default gem. + # + # Two formats for the specification are supported: + # + # * MRI 2.0 style, where spec.files contains unprefixed require names. The + # spec's filenames will be registered as-is. + # * New style, where spec.files contains files prefixed with paths from + # spec.require_paths. The prefixes are stripped before registering the + # spec's filenames. Unprefixed files are omitted. + # + def self.register_default_spec: (Specification spec) -> Array[String] + + # The path to the running Ruby interpreter. + # + def self.ruby: () -> String + + # Returns a String containing the API compatibility version of Ruby + # + def self.ruby_api_version: () -> String + + def self.ruby_engine: () -> String + + # A Gem::Version for the currently running Ruby. + # + def self.ruby_version: () -> Version + + # A Gem::Version for the currently running RubyGems + # + def self.rubygems_version: () -> Version + + # Returns the value of Gem.source_date_epoch_string, as a Time object. + # + # This is used throughout RubyGems for enabling reproducible builds. + # + def self.source_date_epoch: () -> Time + + # If the SOURCE_DATE_EPOCH environment variable is set, returns it's value. + # Otherwise, returns the time that `Gem.source_date_epoch_string` was first + # called in the same format as SOURCE_DATE_EPOCH. + # + # NOTE(@duckinator): The implementation is a tad weird because we want to: + # 1. Make builds reproducible by default, by having this function always + # return the same result during a given run. + # 2. Allow changing ENV['SOURCE_DATE_EPOCH'] at runtime, since multiple + # tests that set this variable will be run in a single process. + # + # If you simplify this function and a lot of tests fail, that is likely due to + # #2 above. + # + # Details on SOURCE_DATE_EPOCH: + # https://reproducible-builds.org/specs/source-date-epoch/ + # + def self.source_date_epoch_string: () -> String + + # Returns an Array of sources to fetch remote gems from. Uses default_sources if + # the sources list is empty. + # + def self.sources: () -> SourceList + + # Need to be able to set the sources without calling Gem.sources.replace since + # that would cause an infinite loop. + # + # DOC: This comment is not documentation about the method itself, it's more of a + # code comment about the implementation. + # + def self.sources=: (SourceList? new_sources) -> SourceList? + + def self.spec_cache_dir: () -> String + + # Glob pattern for require-able path suffixes. + # + def self.suffix_pattern: () -> String + + # Regexp for require-able path suffixes. + # + def self.suffix_regexp: () -> Regexp + + # Suffixes for require-able paths. + # + def self.suffixes: () -> Array[String] + + # Prints the amount of time the supplied block takes to run using the debug UI + # output. + # + def self.time: [T] (String msg, ?Integer width, ?boolish display) { () -> T } -> T + + # Try to activate a gem containing `path`. Returns true if activation succeeded + # or wasn't needed because it was already activated. Returns false if it can't + # find the path in a gem. + # + def self.try_activate: (String path) -> bool + + # Lazily loads DefaultUserInteraction and returns the default UI. + # + def self.ui: () -> StreamUI + + # Looks for a gem dependency file at `path` and activates the gems in the file + # if found. If the file is not found an ArgumentError is raised. + # + # If `path` is not given the RUBYGEMS_GEMDEPS environment variable is used, but + # if no file is found no exception is raised. + # + # If '-' is given for `path` RubyGems searches up from the current working + # directory for gem dependency files (gem.deps.rb, Gemfile, Isolate) and + # activates the gems in the first one found. + # + # You can run this automatically when rubygems starts. To enable, set the + # `RUBYGEMS_GEMDEPS` environment variable to either the path of your gem + # dependencies file or "-" to auto-discover in parent directories. + # + # NOTE: Enabling automatic discovery on multiuser systems can lead to execution + # of arbitrary code when used from directories outside your control. + # + def self.use_gemdeps: (?String path) -> Array[Specification]? + + # Use the `home` and `paths` values for Gem.dir and Gem.path. Used mainly by + # the unit tests to provide environment isolation. + # + def self.use_paths: (String home, *String paths) -> Hash[String, String] + + # Path for gems in the user's home directory + # + def self.user_dir: () -> String + + # The home directory for the user. + # + def self.user_home: () -> String + + # Is this a windows platform? + # + def self.win_platform?: () -> bool + + # Safely write a file in binary mode on all platforms. + # + def self.write_binary: (String path, String data) -> Integer +end diff --git a/stdlib/rubygems/0/source_list.rbs b/stdlib/rubygems/0/source_list.rbs new file mode 100644 index 000000000..d64a7a818 --- /dev/null +++ b/stdlib/rubygems/0/source_list.rbs @@ -0,0 +1,2 @@ +class Gem::SourceList +end diff --git a/stdlib/rubygems/0/specification.rbs b/stdlib/rubygems/0/specification.rbs new file mode 100644 index 000000000..4b0c5bcce --- /dev/null +++ b/stdlib/rubygems/0/specification.rbs @@ -0,0 +1,3 @@ +class Gem::Specification < Gem::BasicSpecification + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/stream_ui.rbs b/stdlib/rubygems/0/stream_ui.rbs new file mode 100644 index 000000000..2a2ef742e --- /dev/null +++ b/stdlib/rubygems/0/stream_ui.rbs @@ -0,0 +1,3 @@ +class Gem::StreamUI + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/uninstaller.rbs b/stdlib/rubygems/0/uninstaller.rbs new file mode 100644 index 000000000..154219ed6 --- /dev/null +++ b/stdlib/rubygems/0/uninstaller.rbs @@ -0,0 +1,3 @@ +class Gem::Uninstaller + # TODO: Add sinatures... +end diff --git a/stdlib/rubygems/0/version.rbs b/stdlib/rubygems/0/version.rbs new file mode 100644 index 000000000..1cde02c68 --- /dev/null +++ b/stdlib/rubygems/0/version.rbs @@ -0,0 +1,3 @@ +class Gem::Version + # TODO: Add sinatures... +end diff --git a/test/stdlib/rubygems/Gem_test.rb b/test/stdlib/rubygems/Gem_test.rb new file mode 100644 index 000000000..725a7feed --- /dev/null +++ b/test/stdlib/rubygems/Gem_test.rb @@ -0,0 +1,597 @@ +require_relative "../test_helper" + +class GemSingletonTest < Test::Unit::TestCase + include TypeAssertions + + class HashLike + def initialize(pairs) + @pairs = pairs + end + + def each_pair(&block) + @pairs.each(&block) + end + end + + library "rubygems" + testing "singleton(::Gem)" + + def test_activated_gem_paths + assert_send_type "() -> Integer", + Gem, :activated_gem_paths + end + + def test_add_to_load_path + assert_send_type "(*String) -> Array[String]", + Gem, :add_to_load_path, "foo" + end + + def test_bin_path + assert_send_type "(String, String) -> String", + Gem, :bin_path, "rake", "rake" + assert_send_type "(String, String, Array[Gem::Requirement]) -> String", + Gem, :bin_path, "rake", "rake", [Gem::Requirement.default] + end + + def test_binary_mode + assert_send_type "() -> String", + Gem, :binary_mode + end + + def test_bindir + assert_send_type "() -> String", + Gem, :bindir + assert_send_type "(String) -> String", + Gem, :bindir, "foo" + end + + def test_cache_home + assert_send_type "() -> String", + Gem, :cache_home + end + + def test_clear_default_specs + assert_send_type "() -> void", + Gem, :clear_default_specs + end + + def test_clear_paths + assert_send_type "() -> void", + Gem, :clear_paths + end + + def test_config_file + assert_send_type "() -> String", + Gem, :config_file + end + + def test_config_home + assert_send_type "() -> String", + Gem, :config_home + end + + def test_configuration + assert_send_type "() -> Gem::ConfigFile", + Gem, :configuration + end + + def test_configuration= + assert_send_type "(Gem::ConfigFile) -> Gem::ConfigFile", + Gem, :configuration=, Gem::ConfigFile.new([""]) + end + + def test_data_home + assert_send_type "() -> String", + Gem, :data_home + end + + def test_datadir + assert_send_type "(String) -> nil", + Gem, :datadir, "" + assert_send_type "(String) -> String", + Gem, :datadir, "rake" + end + + def test_default_bindir + assert_send_type "() -> String", + Gem, :default_bindir + end + + def test_default_cert_path + assert_send_type "() -> String", + Gem, :default_cert_path + end + + def test_default_dir + assert_send_type "() -> String", + Gem, :default_dir + end + + def test_default_exec_format + assert_send_type "() -> String", + Gem, :default_exec_format + end + + def test_default_ext_dir_for + assert_send_type "(String) -> String?", + Gem, :default_ext_dir_for, "foo" + end + + def test_default_key_path + assert_send_type "() -> String", + Gem, :default_key_path + end + + def test_default_path + assert_send_type "() -> Array[String]", + Gem, :default_path + end + + def test_default_rubygems_dirs + assert_send_type "() -> Array[String]?", + Gem, :default_rubygems_dirs + end + + def test_default_sources + assert_send_type "() -> Array[String]", + Gem, :default_sources + end + + def test_default_spec_cache_dir + assert_send_type "() -> String", + Gem, :default_spec_cache_dir + end + + def test_default_specifications_dir + assert_send_type "() -> String", + Gem, :default_specifications_dir + end + + def test_deflate + assert_send_type "(String) -> String", + Gem, :deflate, "foo" + end + + def test_dir + assert_send_type "() -> String", + Gem, :dir + end + + def test_disable_system_update_message + assert_send_type "() -> String?", + Gem, :disable_system_update_message + end + + def test_disable_system_update_message= + assert_send_type "(nil) -> nil", + Gem, :disable_system_update_message=, nil + assert_send_type "(String) -> String", + Gem, :disable_system_update_message=, "foo" + end + + def test_done_installing + assert_send_type "() { (Gem::DependencyInstaller, Array[Gem::Specification]) -> [ Gem::DependencyInstaller, Array[Gem::Specification] ] } -> Array[Proc]", + Gem, :done_installing do |installer, spec| [installer, spec] end + end + + def test_done_installing_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :done_installing_hooks + end + + def test_ensure_default_gem_subdirectories + Dir.mktmpdir do |dir| + assert_send_type "() -> Array[String]", + Gem, :ensure_default_gem_subdirectories + assert_send_type "(String) -> Array[String]", + Gem, :ensure_default_gem_subdirectories, dir + assert_send_type "(String, Integer) -> Array[String]", + Gem, :ensure_default_gem_subdirectories, dir, 0600 + assert_send_type "(String, String) -> Array[String]", + Gem, :ensure_default_gem_subdirectories, dir, "u=wrx" + end + end + + def test_ensure_gem_subdirectories + Dir.mktmpdir do |dir| + assert_send_type "() -> Array[String]", + Gem, :ensure_gem_subdirectories + assert_send_type "(String) -> Array[String]", + Gem, :ensure_gem_subdirectories, dir + assert_send_type "(String, Integer) -> Array[String]", + Gem, :ensure_gem_subdirectories, dir, 0600 + assert_send_type "(String, String) -> Array[String]", + Gem, :ensure_gem_subdirectories, dir, "u=wrx" + end + end + + def test_env_requirement + assert_send_type "(String) -> Gem::Requirement", + Gem, :env_requirement, "" + end + + def test_find_config_file + assert_send_type "() -> String", + Gem, :find_config_file + end + + def test_find_files + assert_send_type "(String) -> Array[String]", + Gem, :find_files, "fileutils.rb" + assert_send_type "(String, bool) -> Array[String]", + Gem, :find_files, "fileutils.rb", true + end + + def test_find_latest_files + assert_send_type "(String) -> Array[String]", + Gem, :find_latest_files, "fileutils.rb" + assert_send_type "(String, bool) -> Array[String]", + Gem, :find_latest_files, "fileutils.rb", false + end + + def test_find_unresolved_default_spec + assert_send_type "(String) -> Gem::Specification?", + Gem, :find_unresolved_default_spec, "fileutils.rb" + end + + def test_finish_resolve + assert_send_type "() -> Array[Gem::Specification]", + Gem, :finish_resolve + assert_send_type "(Gem::RequestSet) -> Array[Gem::Specification]", + Gem, :finish_resolve, Gem::RequestSet.new(Gem::Dependency.new("pg")) + end + + def test_gemdeps + assert_send_type "() -> Gem::RequestSet::GemDependencyAPI?", + Gem, :gemdeps + end + + def test_host + assert_send_type "() -> String", + Gem, :host + end + + def test_host= + assert_send_type "(String) -> String", + Gem, :host=, "foo" + end + + def test_install + omit "due to side-effect" + assert_send_type "(String, Gem::Requirement) -> Array[Gem::Specification]", + Gem, :install, "", Gem::Requirement.default + end + + def test_java_platform? + assert_send_type "() -> bool", + Gem, :java_platform? + end + + def test_latest_rubygems_version + assert_send_type "() -> Gem::Version", + Gem, :latest_rubygems_version + end + + def test_latest_spec_for + assert_send_type "(String) -> nil", + Gem, :latest_spec_for, "" + assert_send_type "(String) -> Gem::Specification", + Gem, :latest_spec_for, "fileutils" + end + + def test_latest_version_for + assert_send_type "(String) -> nil", + Gem, :latest_version_for, "" + assert_send_type "(String) -> Gem::Version", + Gem, :latest_version_for, "fileutils" + end + + def test_load_env_plugins + assert_send_type "() -> Array[String]", + Gem, :load_env_plugins + end + + def test_load_path_insert_index + assert_send_type "() -> Integer", + Gem, :load_path_insert_index + end + + def test_load_plugins + assert_send_type "() -> Array[String]", + Gem, :load_plugins + end + + def test_load_yaml + assert_send_type "() -> bool?", + Gem, :load_yaml + end + + def test_loaded_specs + omit "due to Bundler::StubSpecification returns" + assert_send_type "() -> Hash[String, Gem::BasicSpecification]", + Gem, :loaded_specs + end + + def test_location_of_caller + assert_send_type "() -> [ String, Integer ]", + Gem, :location_of_caller + assert_send_type "(Integer) -> [ String, Integer ]", + Gem, :location_of_caller, 0 + end + + def test_marshal_version + assert_send_type "() -> String", + Gem, :marshal_version + end + + def test_needs + assert_send_type "() { (Gem::RequestSet) -> Gem::RequestSet } -> Array[Gem::Specification]", + Gem, :needs do |rs| rs end + end + + def test_operating_system_defaults + assert_send_type "() -> Hash[String, String]", + Gem, :operating_system_defaults + end + + def test_path + assert_send_type "() -> Array[String]", + Gem, :path + end + + def test_path_separator + assert_send_type "() -> String", + Gem, :path_separator + end + + def test_paths + assert_send_type "() -> Gem::PathSupport", + Gem, :paths + end + + def test_paths= + assert_send_type "(GemSingletonTest::HashLike[String, String?]) -> Array[String]", + Gem, :paths=, HashLike.new([["k1", "v1"], ["k2", nil]]) + end + + def test_platform_defaults + assert_send_type "() -> Hash[String, String]", + Gem, :platform_defaults + end + + def test_platforms + assert_send_type "() -> Array[String | Gem::Platform]", + Gem, :platforms + end + + def test_platforms= + assert_send_type "(Array[String | Gem::Platform]) -> Array[String | Gem::Platform]", + Gem, :platforms=, Gem.platforms + end + + def test_plugin_suffix_pattern + assert_send_type "() -> String", + Gem, :plugin_suffix_pattern + end + + def test_plugin_suffix_regexp + assert_send_type "() -> Regexp", + Gem, :plugin_suffix_regexp + end + + def test_plugindir + assert_send_type "() -> String", + Gem, :plugindir + assert_send_type "(String) -> String", + Gem, :plugindir, "foo" + end + + def test_post_build + assert_send_type "() { (Gem::Installer) -> Gem::Installer } -> Array[Proc]", + Gem, :post_build do |installer| installer end + end + + def test_post_build_hooks + assert_send_type "() -> Array[Proc]", + Gem, :post_build_hooks + end + + def test_post_install + assert_send_type "() { (Gem::Installer) -> Gem::Installer } -> Array[Proc]", + Gem, :post_install do |installer| installer end + end + + def test_post_install_hooks + assert_send_type "() -> Array[Proc]", + Gem, :post_install_hooks + end + + def test_post_reset + assert_send_type "() { () -> Integer } -> Array[Proc]", + Gem, :post_reset do 1 end + end + + def test_post_reset_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :post_reset_hooks + end + + def test_post_uninstall + assert_send_type "() { (Gem::Uninstaller) -> Gem::Uninstaller } -> Array[Proc]", + Gem, :post_uninstall do |uninstaller| uninstaller end + end + + def test_post_uninstall_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :post_uninstall_hooks + end + + def test_pre_install + assert_send_type "() { (Gem::Installer) -> Gem::Installer } -> Array[Proc]", + Gem, :pre_install do |installer| installer end + end + + def test_pre_install_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :pre_install_hooks + end + + def test_pre_reset + assert_send_type "() { () -> String } -> Array[Proc]", + Gem, :pre_reset do "" end + end + + def test_pre_reset_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :pre_reset_hooks + end + + def test_pre_uninstall + assert_send_type "() { (Gem::Uninstaller) -> Gem::Uninstaller } -> Array[Proc]", + Gem, :pre_uninstall do |uninstaller| uninstaller end + end + + def test_pre_uninstall_hooks + assert_send_type "() -> Array[Proc?]", + Gem, :pre_uninstall_hooks + end + + def test_prefix + assert_send_type "() -> String?", + Gem, :prefix + end + + def test_read_binary + assert_send_type "(String) -> String", + Gem, :read_binary, __FILE__ + end + + def test_refresh + assert_send_type "() -> Array[Proc]", + Gem, :refresh + end + + def test_register_default_spec + assert_send_type "(Gem::Specification) -> Array[String]", + Gem, :register_default_spec, Gem::Specification.new + end + + def test_ruby + assert_send_type "() -> String", + Gem, :ruby + end + + def test_ruby_api_version + assert_send_type "() -> String", + Gem, :ruby_api_version + end + + def test_ruby_engine + assert_send_type "() -> String", + Gem, :ruby_engine + end + + def test_ruby_version + assert_send_type "() -> Gem::Version", + Gem, :ruby_version + end + + def test_rubygems_version + assert_send_type "() -> Gem::Version", + Gem, :rubygems_version + end + + def test_source_date_epoch + assert_send_type "() -> Time", + Gem, :source_date_epoch + end + + def test_source_date_epoch_string + assert_send_type "() -> String", + Gem, :source_date_epoch_string + end + + def test_sources + assert_send_type "() -> Gem::SourceList", + Gem, :sources + end + + def test_sources= + assert_send_type "(nil) -> nil", + Gem, :sources=, nil + assert_send_type "(Gem::SourceList) -> Gem::SourceList", + Gem, :sources=, Gem::SourceList.new + end + + def test_spec_cache_dir + assert_send_type "() -> String", + Gem, :spec_cache_dir + end + + def test_suffix_pattern + assert_send_type "() -> String", + Gem, :suffix_pattern + end + + def test_suffix_regexp + assert_send_type "() -> Regexp", + Gem, :suffix_regexp + end + + def test_suffixes + assert_send_type "() -> Array[String]", + Gem, :suffixes + end + + def test_time + assert_send_type "(String) { () -> Integer } -> Integer", + Gem, :time, "foo" do 100 end + assert_send_type "(String, Integer, bool) { () -> Regexp } -> Regexp", + Gem, :time, "foo", 5, false do /bar/ end + end + + def test_try_activate + assert_send_type "(String) -> bool", + Gem, :try_activate, "foo" + end + + def test_ui + assert_send_type "() -> Gem::StreamUI", + Gem, :ui + end + + def test_use_gemdeps + assert_send_type "() -> nil", + Gem, :use_gemdeps + assert_send_type "(String) -> Array[Gem::Specification]", + Gem, :use_gemdeps, "-" + end + + def test_use_paths + assert_send_type "(String, String) -> Hash[String, String]", + Gem, :use_paths, "foo", "bar" + end + + def test_user_dir + assert_send_type "() -> String", + Gem, :user_dir + end + + def test_user_home + assert_send_type "() -> String", + Gem, :user_home + end + + def test_win_platform? + assert_send_type "() -> bool", + Gem, :win_platform? + end + + def test_write_binary + Tempfile.open do |file| + assert_send_type "(String, String) -> Integer", + Gem, :write_binary, file.path, "foo" + end + end +end + From f450ec6c261cc6b995347f131b67980650ae9157 Mon Sep 17 00:00:00 2001 From: Masafumi Koba <473530+ybiquitous@users.noreply.github.com> Date: Sat, 20 Feb 2021 04:10:03 +0900 Subject: [PATCH 2/2] Use the latest rubygems via `gem update --system` --- .github/workflows/ruby.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 1b579c0fc..5fda11c92 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -27,10 +27,10 @@ jobs: run: | apt-get update apt-get install -y libdb-dev - - name: Install bundler + - name: Update rubygems & bundler run: | ruby -v - gem install bundler + gem update --system - name: bundle config set with run: | echo "NO_MINITEST=true" >> $GITHUB_ENV