From 26667d9a1cfe0a4fca454f8bc08db119aa13c616 Mon Sep 17 00:00:00 2001 From: ksss Date: Tue, 5 Dec 2023 13:57:53 +0900 Subject: [PATCH] Add rdoc to RBS and generation task --- .gitignore | 1 + gems/aws-sdk-core/sig/aws-sdk-core.rbs | 301 ++++++++++++++++++++++++- gems/aws-sdk-core/sig/seahorse.rbs | 56 +++++ tasks/rbs.rake | 9 + 4 files changed, 363 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 936405f291c..8a84a44b454 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ coverage *.DS_Store .idea .ruby-version +/tmp diff --git a/gems/aws-sdk-core/sig/aws-sdk-core.rbs b/gems/aws-sdk-core/sig/aws-sdk-core.rbs index dff7fd18850..44f73e153d6 100644 --- a/gems/aws-sdk-core/sig/aws-sdk-core.rbs +++ b/gems/aws-sdk-core/sig/aws-sdk-core.rbs @@ -1,39 +1,321 @@ module Aws + # + # @return [Hash] Returns a hash of default configuration options shared + # by all constructed clients. + # attr_reader self.config: Hash[Symbol, untyped] + + # + # The SDK ships with a ca certificate bundle to use when verifying SSL peer + # certificates. By default, this cert bundle is **NOT** used. The SDK will rely + # on the default cert available to OpenSSL. This ensures the cert provided by + # your OS is used. + # + # For cases where the default cert is unavailable, e.g. Windows, you can call + # this method. + # + # Aws.use_bundled_cert! + # + # @return [String] Returns the path to the bundled cert. + # def self.use_bundled_cert!: () -> String + # + # This module provides the ability to specify the data and/or errors to return + # when a client is using stubbed responses. Pass `:stub_responses => true` to a + # client constructor to enable this behavior. + # + # Also allows you to see the requests made by the client by reading the + # api_requests instance variable + # module ClientStubs + # + # Configures what data / errors should be returned from the named operation when + # response stubbing is enabled. + # + # ## Basic usage + # + # When you enable response stubbing, the client will generate fake responses and + # will not make any HTTP requests. + # + # client = Aws::S3::Client.new(stub_responses: true) + # client.list_buckets + # #=> # + # + # You can provide stub data that will be returned by the client. + # + # # stub data in the constructor + # client = Aws::S3::Client.new(stub_responses: { + # list_buckets: { buckets: [{name: 'my-bucket' }] }, + # get_object: { body: 'data' }, + # }) + # + # client.list_buckets.buckets.map(&:name) #=> ['my-bucket'] + # client.get_object(bucket:'name', key:'key').body.read #=> 'data' + # + # You can also specify the stub data using {#stub_responses} + # + # client = Aws::S3::Client.new(stub_responses: true) + # client.stub_responses(:list_buckets, { + # buckets: [{ name: 'my-bucket' }] + # }) + # + # client.list_buckets.buckets.map(&:name) + # #=> ['my-bucket'] + # + # With a Resource class {#stub_responses} on the corresponding client: + # + # s3 = Aws::S3::Resource.new(stub_responses: true) + # s3.client.stub_responses(:list_buckets, { + # buckets: [{ name: 'my-bucket' }] + # }) + # + # s3.buckets.map(&:name) + # #=> ['my-bucket'] + # + # Lastly, default stubs can be configured via `Aws.config`: + # + # Aws.config[:s3] = { + # stub_responses: { + # list_buckets: { buckets: [{name: 'my-bucket' }] } + # } + # } + # + # Aws::S3::Client.new.list_buckets.buckets.map(&:name) + # #=> ['my-bucket'] + # + # Aws::S3::Resource.new.buckets.map(&:name) + # #=> ['my-bucket'] + # + # ## Dynamic Stubbing + # + # In addition to creating static stubs, it's also possible to generate stubs + # dynamically based on the parameters with which operations were called, by + # passing a `Proc` object: + # + # s3 = Aws::S3::Resource.new(stub_responses: true) + # s3.client.stub_responses(:put_object, -> (context) { + # s3.client.stub_responses(:get_object, content_type: context.params[:content_type]) + # }) + # + # The yielded object is an instance of {Seahorse::Client::RequestContext}. + # + # ## Stubbing Errors + # + # When stubbing is enabled, the SDK will default to generate fake responses with + # placeholder values. You can override the data returned. You can also specify + # errors it should raise. + # + # # simulate service errors, give the error code + # client.stub_responses(:get_object, 'NotFound') + # client.get_object(bucket:'aws-sdk', key:'foo') + # #=> raises Aws::S3::Errors::NotFound + # + # # to simulate other errors, give the error class, you must + # # be able to construct an instance with `.new` + # client.stub_responses(:get_object, Timeout::Error) + # client.get_object(bucket:'aws-sdk', key:'foo') + # #=> raises new Timeout::Error + # + # # or you can give an instance of an error class + # client.stub_responses(:get_object, RuntimeError.new('custom message')) + # client.get_object(bucket:'aws-sdk', key:'foo') + # #=> raises the given runtime error object + # + # ## Stubbing HTTP Responses + # + # As an alternative to providing the response data, you can provide an HTTP + # response. + # + # client.stub_responses(:get_object, { + # status_code: 200, + # headers: { 'header-name' => 'header-value' }, + # body: "...", + # }) + # + # To stub a HTTP response, pass a Hash with all three of the following keys set: + # + # * **`:status_code`** - - The HTTP status code + # * **`:headers`** - Hash - A hash of HTTP header keys and + # values + # * **`:body`** - - The HTTP response body. + # + # + # ## Stubbing Multiple Responses + # + # Calling an operation multiple times will return similar responses. You can + # configure multiple stubs and they will be returned in sequence. + # + # client.stub_responses(:head_object, [ + # 'NotFound', + # { content_length: 150 }, + # ]) + # + # client.head_object(bucket:'aws-sdk', key:'foo') + # #=> raises Aws::S3::Errors::NotFound + # + # resp = client.head_object(bucket:'aws-sdk', key:'foo') + # resp.content_length #=> 150 + # + # @param [Symbol] operation_name + # + # @param [Mixed] stubs One or more responses to return from the named + # operation. + # + # @return [void] + # + # @raise [RuntimeError] Raises a runtime error when called + # on a client that has not enabled response stubbing via + # `:stub_responses => true`. + # def stub_responses: (Symbol operation_name, *untyped stubs) -> void + + # + # Allows you to access all of the requests that the stubbed client has made. + # + # @param [Hash] options The options for the api requests. @option options + # [Boolean] :exclude_presign (false) Set to true to filter + # out unsent requests from generated presigned urls. + # + # @return [Array] Returns an array of the api requests made. Each request + # object contains the :operation_name, :params, and :context. + # + # @raise [NotImplementedError] Raises `NotImplementedError` when the client + # is not stubbed. + # def api_requests: () -> Array[{ operation_name: Symbol, params: untyped, context: untyped }] + + # + # Generates and returns stubbed response data from the named operation. + # + # s3 = Aws::S3::Client.new + # s3.stub_data(:list_buckets) + # #=> #> + # + # In addition to generating default stubs, you can provide data to apply to the + # response stub. + # + # s3.stub_data(:list_buckets, buckets:[{name:'aws-sdk'}]) + # #=> #], + # owner=#> + # + # @param [Symbol] operation_name @param [Hash] data @return [Structure] Returns + # a stubbed response data structure. The + # actual class returned will depend on the given `operation_name`. + # def stub_data: (Symbol operation_name, untyped data) -> untyped end module Errors - # The base class for all errors returned by an Amazon Web Service. - # All ~400 level client errors and ~500 level server errors are raised - # as service errors. This indicates it was an error returned from the - # service and not one generated by the client. + # + # The base class for all errors returned by an Amazon Web Service. All ~400 + # level client errors and ~500 level server errors are raised as service errors. + # This indicates it was an error returned from the service and not one + # generated by the client. + # class ServiceError < RuntimeError + # + # @return [String] + # attr_reader code: String + + # + # @return [Seahorse::Client::RequestContext] The context of the request + # that triggered the remote service to return this error. + # attr_reader context: untyped + + # + # @return [Aws::Structure] + # attr_reader data: untyped + + # + # @return [String] + # attr_accessor self.code: String end end + # + # @api private + # class EmptyStructure end module Resources class Collection[T] include Enumerable[T] + + # + # @param [Enumerator] batches @option options [Integer] :limit @option + # options [Integer] :size @api private + # def initialize: (Enumerable[Enumerable[T]] batches, ?size: Integer, ?limit: Integer) -> void + + # + # @return [Enumerator] + # def each: () -> Enumerator[T, untyped] | () { (T) -> untyped } -> Enumerator[T, untyped] + + # + # @return [Integer,nil] + # Returns the size of this collection if known, returns `nil` when + # an API call is necessary to enumerate items in this collection. + # def size: () -> Integer? + + # + # alias length size + + # + # @param [Integer] count @return [Resource, Collection] + # def first: () -> T? | (Integer) -> self + + # + # Returns a new collection that will enumerate a limited number of items. + # + # collection.limit(10).each do |band| + # # yields at most 10 times + # end + # + # @return [Collection] @param [Integer] limit + # def limit: (Integer) -> self end end @@ -42,14 +324,25 @@ module Aws type waiter_options = { max_attempts: Integer?, delay: Numeric?, before_attempt: (^(Integer attempts) -> void)?, before_wait: (^(Integer attempts, untyped response) -> void)? } module Errors + # + # Raised when a waiter detects a condition where the waiter can never succeed. + # class WaiterFailed < StandardError end + class FailureStateError < WaiterFailed end + class TooManyAttemptsError < WaiterFailed end + class UnexpectedError < WaiterFailed end + + # + # Raised when attempting to get a waiter by name and the waiter has not been + # defined. + # class NoSuchWaiterError < ArgumentError end end diff --git a/gems/aws-sdk-core/sig/seahorse.rbs b/gems/aws-sdk-core/sig/seahorse.rbs index 74f08a46d55..b03ee34c31d 100644 --- a/gems/aws-sdk-core/sig/seahorse.rbs +++ b/gems/aws-sdk-core/sig/seahorse.rbs @@ -3,6 +3,12 @@ module Seahorse class Base include HandlerBuilder + # + # @api private + # def self.new: (?untyped options) -> instance def self.add_plugin: (untyped plugin) -> untyped def self.remove_plugin: (untyped plugin) -> untyped @@ -13,18 +19,68 @@ module Seahorse def self.set_api: (untyped api) -> untyped def self.define: (?untyped options) -> untyped + # # @return [Configuration] + # attr_reader config: untyped + + # # @return [HandlerList] + # attr_reader handlers: untyped + + # + # Builds and returns a {Request} for the named operation. The request will not + # have been sent. @param [Symbol, String] operation_name @return [Request] + # def build_request: (_ToS operation_name, ?untyped params) -> untyped + + # + # @return [Array] Returns a list of valid request operation + # names. These are valid arguments to {#build_request} and are also + # valid methods. + # def operation_names: () -> Array[Symbol] end + # + # This module provides the ability to add handlers to a class or module. The + # including class or extending module must respond to `#handlers`, returning a + # {HandlerList}. + # module HandlerBuilder + # + # def handle_request: (*untyped) { (untyped context) -> void } -> untyped + + # + # def handle_response: (*untyped) { (untyped resp) -> void } -> untyped + + # + # def handle: (*untyped) ?{ (untyped context) -> void } -> untyped + + # + # alias handler handle end end diff --git a/tasks/rbs.rake b/tasks/rbs.rake index 4eb59b21489..90d6c5d6560 100644 --- a/tasks/rbs.rake +++ b/tasks/rbs.rake @@ -19,4 +19,13 @@ namespace :rbs do end abort('one or more rbs validate failed: %s' % [sigs.join(', ')]) unless sigs.empty? end + + task :doc do + all_gems = Dir.glob("gems/*").map { File.basename(_1) }.to_set + sig_dirs = Dir.glob('gems/*/sig') + gem_dirs = sig_dirs.map { |sig_dir| File.dirname(sig_dir) } + sh("rm -rf tmp") + sh("bundle exec rdoc --ri --output tmp #{gem_dirs.map {|gem_dir| "#{gem_dir}/lib" }.join(' ')}") + sh("bundle exec rbs annotate --dir tmp #{sig_dirs.join(' ')}") + end end