proto_plugin 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c7fb4f38a0f6f9a22f62228fbd39ac9995319b83b05667f83b510cd3e3407fb
4
- data.tar.gz: d6f39e7a5a77c5f541ee2c52f12d114c8fb6795d8e27617542927008911a23dc
3
+ metadata.gz: d119edf1d041fd9838fe8e63e00be22d1e7592dccc95033e094eb65b282913e3
4
+ data.tar.gz: cf6966a0c8afebfc1c573ee75151e3c494cfd8400d873d374cfecc0d45e1c8bd
5
5
  SHA512:
6
- metadata.gz: a1a877e5ee1ed9e55c882cbe312abaa83c1fc29bacad7ba4c35db5c668f40cefd19182263fadfe974e458e937fa30df30d8c30257afe682a98e5ad1d071f0412
7
- data.tar.gz: 8fc91b1050f5661b616ebd209a116bb8e1edb2e13a2b66b6a20b7be517c78f0fd8b4ee8317af121cc313055e5adc9414855985f70ea754d9494bcc2598a372b8
6
+ metadata.gz: 3dabe171b0c94f545334b1741b3eb7512a3351888f4079b4ccde46a55be9f7ed4123d6c189252f65d41f80ef695523d098870df3aa0b48c6568bca87956e7dd1
7
+ data.tar.gz: 2716675a6bfc4afccbe8eb743b3158338cb74e3177a5d1a053cd5e31473524c8a943508dc57a9a8839fc043f7dbea2763f9005052cf0ff66a0c51b04fecd7075
data/README.md CHANGED
@@ -24,7 +24,7 @@ require "proto_plugin"
24
24
  class MyCoolPlugin < ProtoPlugin::Base
25
25
  def run
26
26
  request.file_to_generate.each do |f|
27
- name = File.basename(f, ".proto")
27
+ name = File.basename(f.name, ".proto")
28
28
 
29
29
  add_file(name: "#{name}.txt", content: <<~TXT)
30
30
  This file was generated from #{name}.proto!
@@ -5,12 +5,12 @@ require "proto_plugin"
5
5
 
6
6
  class Demo < ProtoPlugin::Base
7
7
  def run
8
- request.file_to_generate.each do |f|
9
- name = File.basename(f, ".proto")
8
+ files_to_generate.each do |f|
9
+ name = File.basename(f.name, ".proto")
10
10
  add_file(path: "#{name}.txt", content: <<~TXT)
11
11
  Parameters: #{parameters}
12
12
 
13
- This file was generated from #{name}.proto!
13
+ This file was generated from #{f.name}!
14
14
  TXT
15
15
  end
16
16
  end
@@ -48,6 +48,10 @@ module ProtoPlugin
48
48
  # @return [Google::Protobuf::Compiler::CodeGeneratorRequest]
49
49
  attr_reader :request
50
50
 
51
+ # The context for the current invocation of the plugin.
52
+ # @return [Context]
53
+ attr_reader :context
54
+
51
55
  # The response message to be sent back to `protoc`.
52
56
  # @return [Google::Protobuf::Compiler::CodeGeneratorResponse]
53
57
  attr_reader :response
@@ -56,6 +60,7 @@ module ProtoPlugin
56
60
  # `Google::Protobuf::Compiler::CodeGeneratorRequest`.
57
61
  def initialize(request:)
58
62
  @request = request
63
+ @context = Context.new(request: request)
59
64
  @response = Google::Protobuf::Compiler::CodeGeneratorResponse.new(
60
65
  supported_features: supported_features.reduce(&:|),
61
66
  )
@@ -74,6 +79,30 @@ module ProtoPlugin
74
79
  end
75
80
  end
76
81
 
82
+ # Returns an array of `ProtoPlugin::FileDescriptor` representing the files that
83
+ # were passed to `protoc` to be generated.
84
+ #
85
+ # @example `protoc --myplugin_out=. input_one.proto input_two.proto`
86
+ # [
87
+ # <ProtoPlugin::FileDescriptor: name: "input_one.proto">,
88
+ # <ProtoPlugin::FileDescriptor: name: "input_two.proto">
89
+ # ]
90
+ #
91
+ # @return [Array<FileDescriptor>]
92
+ def files_to_generate
93
+ @files_to_generate ||= request.file_to_generate.filter_map do |filename|
94
+ lookup_file(name: filename)
95
+ end
96
+ end
97
+
98
+ # Finds an imported file descriptor with the given `name` attribute.
99
+ #
100
+ # @return [ProtoPlugin::FileDescriptor]
101
+ # @return [nil] if the file was not found
102
+ def lookup_file(name:)
103
+ context.file_by_filename(name)
104
+ end
105
+
77
106
  # Returns the list of supported `CodeGeneratorResponse::Feature` values by the plugin. The returned
78
107
  # values are bitwise or-ed together and set on `response`.
79
108
  #
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProtoPlugin
4
+ # An object that is responsible for organizing the graph of imported descriptors for
5
+ # a given invocation of a plugin.
6
+ #
7
+ # It provides many helpers for looking up a file, message, or other descriptor.
8
+ class Context
9
+ # Initializes a context from a given `Google::Protobuf::Compiler::CodeGeneratorRequest`.
10
+ def initialize(request:)
11
+ index_files_by_filename(request.proto_file)
12
+ index_types_by_proto_name
13
+ end
14
+
15
+ # Finds an imported file descriptor with the given `name` attribute.
16
+ #
17
+ # @return [ProtoPlugin::FileDescriptor]
18
+ # @return [nil] if the file was not found
19
+ def file_by_filename(name)
20
+ @files_by_filename[name]
21
+ end
22
+
23
+ def type_by_proto_name(name)
24
+ @types_by_proto_name[name]
25
+ end
26
+
27
+ private
28
+
29
+ def index_files_by_filename(files)
30
+ @files_by_filename = files.each_with_object({}) do |fd, hash|
31
+ hash[fd.name] = FileDescriptor.new(self, fd)
32
+ end
33
+ end
34
+
35
+ def index_types_by_proto_name
36
+ @types_by_proto_name = @files_by_filename.values.each_with_object({}) do |fd, hash|
37
+ package = fd.package || ""
38
+ package = ".#{package}" unless package.empty?
39
+ index_enums_by_name(fd.enums, hash, prefix: package)
40
+ index_messages_by_name(fd.messages, hash, prefix: package)
41
+ end
42
+ end
43
+
44
+ def index_enums_by_name(enums, hash, prefix:)
45
+ enums.each do |e|
46
+ hash["#{prefix}.#{e.name}"] = e
47
+ end
48
+ end
49
+
50
+ def index_messages_by_name(msgs, hash, prefix:)
51
+ msgs.each do |m|
52
+ path = "#{prefix}.#{m.name}"
53
+ index_enums_by_name(m.enums, hash, prefix: path)
54
+ index_messages_by_name(m.messages, hash, prefix: path)
55
+ hash[path] = m
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ProtoPlugin
6
+ # A wrapper class around `Google::Protobuf::EnumDescriptorProto`
7
+ # which provides helpers and more idiomatic Ruby access patterns.
8
+ #
9
+ # Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
10
+ #
11
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L336
12
+ class EnumDescriptor < SimpleDelegator
13
+ # @return [Google::Protobuf::EnumDescriptorProto]
14
+ attr_reader :descriptor
15
+
16
+ # The file or message descriptor this enum was defined within.
17
+ #
18
+ # @return [FileDescriptor] if defined as a root enum
19
+ # @return [MessageDescriptor] if defined as a nested enum (inverse of `enum_type`)
20
+ attr_reader :parent
21
+
22
+ # @param descriptor [Google::Protobuf::EnumDescriptorProto]
23
+ # @param parent [FileDescriptorFileDescriptorProto, MessageDescriptor]
24
+ # The file or message descriptor this enum was defined within.
25
+ def initialize(descriptor, parent)
26
+ super(descriptor)
27
+ @descriptor = descriptor
28
+ @parent = parent
29
+ end
30
+
31
+ # The full name of the enum, including parent namespace.
32
+ #
33
+ # @example
34
+ # "My::Ruby::Package::EnumName"
35
+ #
36
+ # @return [String]
37
+ def full_name
38
+ @full_name ||= begin
39
+ prefix = case parent
40
+ when MessageDescriptor
41
+ parent.full_name
42
+ when FileDescriptor
43
+ parent.namespace
44
+ end
45
+ "#{prefix}::#{name}"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ProtoPlugin
6
+ # A wrapper class around `Google::Protobuf::FileDescriptorProto`
7
+ # which provides helpers and more idiomatic Ruby access patterns.
8
+ #
9
+ # Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
10
+ #
11
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L97
12
+ # Google::Protobuf::FileDescriptorProto
13
+ class FileDescriptor < SimpleDelegator
14
+ # @return [Google::Protobuf::FileDescriptorProto]
15
+ attr_reader :descriptor
16
+
17
+ # @param context [Context]
18
+ # @param descriptor [Google::Protobuf::FileDescriptorProto]
19
+ def initialize(context, descriptor)
20
+ super(descriptor)
21
+ @context = context
22
+ @descriptor = descriptor
23
+ end
24
+
25
+ # The enums defined as children of this file.
26
+ #
27
+ # @return [Array<EnumDescriptor>]
28
+ #
29
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L111
30
+ # Google::Protobuf::DescriptorProto#enum_type
31
+ def enums
32
+ @enums ||= @descriptor.enum_type.map do |e|
33
+ EnumDescriptor.new(e, self)
34
+ end
35
+ end
36
+
37
+ # The messages defined as children of this file.
38
+ #
39
+ # @return [Array<MessageDescriptor>]
40
+ #
41
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L110
42
+ # Google::Protobuf::DescriptorProto#message_type
43
+ def messages
44
+ @messages ||= @descriptor.message_type.map do |m|
45
+ MessageDescriptor.new(m, self)
46
+ end
47
+ end
48
+
49
+ # Returns the Ruby namespace (module) for the file.
50
+ #
51
+ # If the `ruby_package` option was specified, then that value
52
+ # is returned directly. Otherwise, the `package` value is
53
+ # transformed to Ruby module notation.
54
+ #
55
+ # @example Using `package my.protobuf.package;`
56
+ # file.namespace #=> "My::Protobuf::Package"
57
+ # @example Using `option ruby_package = "My::Ruby::Package";`
58
+ # file.namespace #=> "My::Ruby::Package"
59
+ #
60
+ # @param split [Boolean] Returns the namespace as an array of module names.
61
+ #
62
+ # @return [String] The namespace for the file.
63
+ # @return [Array<String>] If `split: true`, the namespace as an array of module names.
64
+ def namespace(split: false)
65
+ @namespace ||= begin
66
+ namespace = @descriptor.options&.ruby_package
67
+ if !namespace || namespace.empty?
68
+ namespace = @descriptor.package.split(".")
69
+ .map { |token| Utils.camelize(token) }
70
+ .join("::")
71
+ end
72
+ namespace
73
+ end
74
+ split ? @namespace.split("::") : @namespace
75
+ end
76
+
77
+ # The services defined in this file.
78
+ #
79
+ # @return [Array<ServiceDescriptor>]
80
+ #
81
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L112
82
+ # Google::Protobuf::DescriptorProto#service
83
+ def services
84
+ @services ||= @descriptor.service.map do |s|
85
+ ServiceDescriptor.new(s, self, @context)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ProtoPlugin
6
+ # A wrapper class around `Google::Protobuf::DescriptorProto`
7
+ # which provides helpers and more idiomatic Ruby access patterns.
8
+ #
9
+ # Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
10
+ #
11
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L134
12
+ # Google::Protobuf::DescriptorProto
13
+ class MessageDescriptor < SimpleDelegator
14
+ # @return [Google::Protobuf::DescriptorProto]
15
+ attr_reader :descriptor
16
+
17
+ # The file or message descriptor this message was defined within.
18
+ #
19
+ # @return [FileDescriptor] if defined as a root message
20
+ # @return [MessageDescriptor] if defined as a nested message (inverse of `nested_type`)
21
+ attr_reader :parent
22
+
23
+ # @param descriptor [Google::Protobuf::DescriptorProto]
24
+ # @param parent [FileDescriptorFileDescriptorProto, MessageDescriptor]
25
+ # The file or message descriptor this message was defined within.
26
+ def initialize(descriptor, parent)
27
+ super(descriptor)
28
+ @descriptor = descriptor
29
+ @parent = parent
30
+ end
31
+
32
+ # The enums defined as children of this message.
33
+ #
34
+ # @return [Array<EnumDescriptor>]
35
+ #
36
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L141
37
+ # Google::Protobuf::DescriptorProto#enum_type
38
+ def enums
39
+ @enums ||= @descriptor.enum_type.map do |e|
40
+ EnumDescriptor.new(e, self)
41
+ end
42
+ end
43
+
44
+ # The messages defined as children of this message.
45
+ #
46
+ # @return [Array<MessageDescriptor>]
47
+ #
48
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L140
49
+ # Google::Protobuf::DescriptorProto#nested_type
50
+ def messages
51
+ @nested_messages ||= @descriptor.nested_type.map do |m|
52
+ MessageDescriptor.new(m, self)
53
+ end
54
+ end
55
+
56
+ # The full name of the message, including parent namespace.
57
+ #
58
+ # @example
59
+ # "My::Ruby::Package::MessageName"
60
+ #
61
+ # @return [String]
62
+ def full_name
63
+ @full_name ||= begin
64
+ prefix = case parent
65
+ when MessageDescriptor
66
+ parent.full_name
67
+ when FileDescriptor
68
+ parent.namespace
69
+ end
70
+ "#{prefix}::#{name}"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ProtoPlugin
6
+ # A wrapper class around `Google::Protobuf::MethodDescriptorProto`
7
+ # which provides helpers and more idiomatic Ruby access patterns.
8
+ #
9
+ # Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
10
+ #
11
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L381
12
+ class MethodDescriptor < SimpleDelegator
13
+ # @return [Google::Protobuf::MethodDescriptorProto]
14
+ attr_reader :descriptor
15
+
16
+ # The service this method was defined in.
17
+ #
18
+ # @return [ServiceDescriptor]
19
+ attr_reader :service
20
+
21
+ # @param descriptor [Google::Protobuf::MethodDescriptorProto]
22
+ # @param service [ServiceDescriptor] The service this method was defined in.
23
+ # @param context [Context]
24
+ def initialize(descriptor, service, context)
25
+ super(descriptor)
26
+ @descriptor = descriptor
27
+ @service = service
28
+ @context = context
29
+ end
30
+
31
+ # Returns the `MessageDescriptor` of the method's input type.
32
+ #
33
+ # @return [MessageDescriptor]
34
+ def input
35
+ @context.type_by_proto_name(input_type)
36
+ end
37
+
38
+ # Returns the `MessageDescriptor` of the method's output type.
39
+ #
40
+ # @return [MessageDescriptor]
41
+ def output
42
+ @context.type_by_proto_name(output_type)
43
+ end
44
+
45
+ # Returns true if the client may stream multiple client messages.
46
+ #
47
+ # @return [Boolean]
48
+ def client_streaming?
49
+ descriptor.client_streaming
50
+ end
51
+
52
+ # Returns true if the server may stream multiple server messages.
53
+ #
54
+ # @return [Boolean]
55
+ def server_streaming?
56
+ descriptor.server_streaming
57
+ end
58
+
59
+ # Returns true if both the client and server only may send single messages.
60
+ #
61
+ # @return [Boolean]
62
+ def unary?
63
+ !client_streaming? && !server_streaming?
64
+ end
65
+
66
+ # Returns true if both the client and server may send multiple streamed messages.
67
+ #
68
+ # @return [Boolean]
69
+ def bidirectional_streaming?
70
+ client_streaming? && server_streaming?
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ProtoPlugin
6
+ # A wrapper class around `Google::Protobuf::ServiceDescriptorProto`
7
+ # which provides helpers and more idiomatic Ruby access patterns.
8
+ #
9
+ # Any method not defined directly is delegated to the descriptor the wrapper was initialized with.
10
+ #
11
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L373
12
+ class ServiceDescriptor < SimpleDelegator
13
+ # @return [Google::Protobuf::ServiceDescriptorProto]
14
+ attr_reader :descriptor
15
+
16
+ # The file this service was defined within.
17
+ #
18
+ # @return [FileDescriptor]
19
+ attr_reader :parent
20
+
21
+ # @param descriptor [Google::Protobuf::ServiceDescriptorProto]
22
+ # @param parent [FileDescriptor] The file this service was defined within.
23
+ # @param context [Context]
24
+ def initialize(descriptor, parent, context)
25
+ super(descriptor)
26
+ @descriptor = descriptor
27
+ @parent = parent
28
+ @context = context
29
+ end
30
+
31
+ # The full name of the service, including parent namespace.
32
+ #
33
+ # @example
34
+ # "My::Ruby::Package::ServiceName"
35
+ #
36
+ # @return [String]
37
+ def full_name
38
+ @full_name ||= "#{parent.namespace}::#{name}"
39
+ end
40
+
41
+ # The methods defined for the service.
42
+ #
43
+ # @note This method is named `rpc_methods` to avoid conflicting with Object#methods.
44
+ #
45
+ # @return [Array<MethodDescriptor>]
46
+ #
47
+ # @see https://github.com/protocolbuffers/protobuf/blob/v28.2/src/google/protobuf/descriptor.proto#L375
48
+ # Google::Protobuf::ServiceDescriptorProto#method
49
+ def rpc_methods
50
+ @rpc_methods ||= @descriptor["method"].map do |m|
51
+ MethodDescriptor.new(m, self, @context)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProtoPlugin
4
+ # A set of utility functions used by the library.
5
+ module Utils
6
+ class << self
7
+ # Converts string to UpperCamelCase.
8
+ #
9
+ # @param value [String]
10
+ #
11
+ # @return [String]
12
+ def camelize(value)
13
+ string = value.to_s
14
+
15
+ if string.match?(/\A[a-z\d]*\z/)
16
+ return string.capitalize
17
+ else
18
+ string = string.sub(/^[a-z\d]*/) do |match|
19
+ match.capitalize! || match
20
+ end
21
+ end
22
+
23
+ string.gsub!(%r{(?:_|(/))([a-z\d]*)}i) do
24
+ word = ::Regexp.last_match(2)
25
+ substituted = word.capitalize! || word
26
+ ::Regexp.last_match(1) ? "::#{substituted}" : substituted
27
+ end
28
+
29
+ string
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProtoPlugin
4
- VERSION = "0.2.0"
4
+ # The version of the ProtoPlugin gem.
5
+ # @return [String]
6
+ VERSION = "0.3.0"
5
7
  end
data/lib/proto_plugin.rb CHANGED
@@ -1,7 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Easily build protobuf compiler plugins in Ruby.
3
4
  module ProtoPlugin
4
5
  end
5
6
 
6
- require_relative "proto_plugin/version"
7
+ require_relative "proto_plugin/utils"
8
+ require_relative "proto_plugin/context"
9
+ require_relative "proto_plugin/file_descriptor"
10
+ require_relative "proto_plugin/enum_descriptor"
11
+ require_relative "proto_plugin/message_descriptor"
12
+ require_relative "proto_plugin/service_descriptor"
13
+ require_relative "proto_plugin/method_descriptor"
7
14
  require_relative "proto_plugin/base"
15
+ require_relative "proto_plugin/version"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proto_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Baker
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-09-25 00:00:00.000000000 Z
10
+ date: 2025-02-27 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: google-protobuf
@@ -24,7 +23,6 @@ dependencies:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
25
  version: '4.28'
27
- description:
28
26
  email:
29
27
  - jonathan@jmb.dev
30
28
  executables:
@@ -37,6 +35,13 @@ files:
37
35
  - exe/protoc-gen-proto-plugin-demo
38
36
  - lib/proto_plugin.rb
39
37
  - lib/proto_plugin/base.rb
38
+ - lib/proto_plugin/context.rb
39
+ - lib/proto_plugin/enum_descriptor.rb
40
+ - lib/proto_plugin/file_descriptor.rb
41
+ - lib/proto_plugin/message_descriptor.rb
42
+ - lib/proto_plugin/method_descriptor.rb
43
+ - lib/proto_plugin/service_descriptor.rb
44
+ - lib/proto_plugin/utils.rb
40
45
  - lib/proto_plugin/version.rb
41
46
  homepage: https://github.com/cocoahero/proto_plugin
42
47
  licenses:
@@ -47,7 +52,6 @@ metadata:
47
52
  documentation_uri: https://cocoahero.github.io/proto_plugin
48
53
  allowed_push_host: https://rubygems.org
49
54
  funding_uri: https://github.com/sponsors/cocoahero
50
- post_install_message:
51
55
  rdoc_options: []
52
56
  require_paths:
53
57
  - lib
@@ -55,15 +59,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
55
59
  requirements:
56
60
  - - "~>"
57
61
  - !ruby/object:Gem::Version
58
- version: '3.0'
62
+ version: '3.1'
59
63
  required_rubygems_version: !ruby/object:Gem::Requirement
60
64
  requirements:
61
65
  - - ">="
62
66
  - !ruby/object:Gem::Version
63
67
  version: '0'
64
68
  requirements: []
65
- rubygems_version: 3.5.11
66
- signing_key:
69
+ rubygems_version: 3.6.2
67
70
  specification_version: 4
68
71
  summary: Easily build protobuf compiler plugins in Ruby.
69
72
  test_files: []