|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
3 | | -# rubocop:disable Metrics/BlockLength, Lint/MissingCopEnableDirective, Style/DocumentationMethod |
| 3 | +# rubocop:disable Lint/MissingCopEnableDirective, Style/DocumentationMethod |
4 | 4 |
|
5 | 5 | require 'bundler/gem_tasks' |
6 | 6 | require 'rb_sys/cargo/metadata' |
@@ -55,310 +55,25 @@ module CustomizeYardWarnings # rubocop:disable Style/Documentation |
55 | 55 | super |
56 | 56 | rescue YARD::Parser::UndocumentableError |
57 | 57 | # We ignore if it's an API warning |
58 | | - raise unless statement.last.file.start_with?('lib/temporalio/api/') || |
59 | | - statement.last.file.start_with?('lib/temporalio/internal/bridge/api/') |
| 58 | + last_file = statement.last.file |
| 59 | + raise unless (last_file.start_with?('lib/temporalio/api/') && last_file.count('/') > 3) || |
| 60 | + last_file.start_with?('lib/temporalio/internal/bridge/api/') |
60 | 61 | end |
61 | 62 | end |
62 | 63 |
|
63 | 64 | YARD::Handlers::Ruby::ConstantHandler.prepend(CustomizeYardWarnings) |
64 | 65 |
|
65 | 66 | YARD::Rake::YardocTask.new { |t| t.options = ['--fail-on-warning'] } |
66 | 67 |
|
67 | | -require 'fileutils' |
68 | | -require 'google/protobuf' |
| 68 | +Rake::Task[:yard].enhance([:copy_parent_files]) do |
| 69 | + rm ['LICENSE', 'README.md'] |
| 70 | +end |
69 | 71 |
|
70 | 72 | namespace :proto do |
71 | 73 | desc 'Generate API and Core protobufs' |
72 | 74 | task :generate do |
73 | | - # Remove all existing |
74 | | - FileUtils.rm_rf('lib/temporalio/api') |
75 | | - |
76 | | - def generate_protos(api_protos) |
77 | | - # Generate API to temp dir and move |
78 | | - FileUtils.rm_rf('tmp-proto') |
79 | | - FileUtils.mkdir_p('tmp-proto') |
80 | | - sh 'bundle exec grpc_tools_ruby_protoc ' \ |
81 | | - '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_upstream ' \ |
82 | | - '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_cloud_upstream ' \ |
83 | | - '--proto_path=ext/additional_protos ' \ |
84 | | - '--ruby_out=tmp-proto ' \ |
85 | | - "#{api_protos.join(' ')}" |
86 | | - |
87 | | - # Walk all generated Ruby files and cleanup content and filename |
88 | | - Dir.glob('tmp-proto/temporal/api/**/*.rb') do |path| |
89 | | - # Fix up the import |
90 | | - content = File.read(path) |
91 | | - content.gsub!(%r{^require 'temporal/(.*)_pb'$}, "require 'temporalio/\\1'") |
92 | | - File.write(path, content) |
93 | | - |
94 | | - # Remove _pb from the filename |
95 | | - FileUtils.mv(path, path.sub('_pb', '')) |
96 | | - end |
97 | | - |
98 | | - # Move from temp dir and remove temp dir |
99 | | - FileUtils.cp_r('tmp-proto/temporal/api', 'lib/temporalio') |
100 | | - FileUtils.rm_rf('tmp-proto') |
101 | | - end |
102 | | - |
103 | | - # Generate from API with Google ones removed |
104 | | - generate_protos(Dir.glob('ext/sdk-core/sdk-core-protos/protos/api_upstream/**/*.proto').reject do |proto| |
105 | | - proto.include?('google') |
106 | | - end) |
107 | | - |
108 | | - # Generate from Cloud API |
109 | | - generate_protos(Dir.glob('ext/sdk-core/sdk-core-protos/protos/api_cloud_upstream/**/*.proto')) |
110 | | - |
111 | | - # Generate additional protos |
112 | | - generate_protos(Dir.glob('ext/additional_protos/**/*.proto')) |
113 | | - |
114 | | - # Write files that will help with imports. We are requiring the |
115 | | - # request_response and not the service because the service depends on Google |
116 | | - # API annotations we don't want to have to depend on. |
117 | | - File.write( |
118 | | - 'lib/temporalio/api/cloud/cloudservice.rb', |
119 | | - <<~TEXT |
120 | | - # frozen_string_literal: true |
121 | | -
|
122 | | - require 'temporalio/api/cloud/cloudservice/v1/request_response' |
123 | | - TEXT |
124 | | - ) |
125 | | - File.write( |
126 | | - 'lib/temporalio/api/workflowservice.rb', |
127 | | - <<~TEXT |
128 | | - # frozen_string_literal: true |
129 | | -
|
130 | | - require 'temporalio/api/workflowservice/v1/request_response' |
131 | | - TEXT |
132 | | - ) |
133 | | - File.write( |
134 | | - 'lib/temporalio/api/operatorservice.rb', |
135 | | - <<~TEXT |
136 | | - # frozen_string_literal: true |
137 | | -
|
138 | | - require 'temporalio/api/operatorservice/v1/request_response' |
139 | | - TEXT |
140 | | - ) |
141 | | - File.write( |
142 | | - 'lib/temporalio/api.rb', |
143 | | - <<~TEXT |
144 | | - # frozen_string_literal: true |
145 | | -
|
146 | | - require 'temporalio/api/cloud/cloudservice' |
147 | | - require 'temporalio/api/common/v1/grpc_status' |
148 | | - require 'temporalio/api/errordetails/v1/message' |
149 | | - require 'temporalio/api/operatorservice' |
150 | | - require 'temporalio/api/workflowservice' |
151 | | -
|
152 | | - module Temporalio |
153 | | - # Raw protocol buffer models. |
154 | | - module Api |
155 | | - end |
156 | | - end |
157 | | - TEXT |
158 | | - ) |
159 | | - |
160 | | - # Write the service classes that have the RPC calls |
161 | | - def write_service_file(qualified_service_name:, file_name:, class_name:, service_enum:) |
162 | | - # Do service lookup |
163 | | - desc = Google::Protobuf::DescriptorPool.generated_pool.lookup(qualified_service_name) |
164 | | - raise 'Failed finding service descriptor' unless desc |
165 | | - |
166 | | - # Open file to generate Ruby code |
167 | | - File.open("lib/temporalio/client/connection/#{file_name}.rb", 'w') do |file| |
168 | | - file.puts <<~TEXT |
169 | | - # frozen_string_literal: true |
170 | | -
|
171 | | - # Generated code. DO NOT EDIT! |
172 | | -
|
173 | | - require 'temporalio/api' |
174 | | - require 'temporalio/client/connection/service' |
175 | | - require 'temporalio/internal/bridge/client' |
176 | | -
|
177 | | - module Temporalio |
178 | | - class Client |
179 | | - class Connection |
180 | | - # #{class_name} API. |
181 | | - class #{class_name} < Service |
182 | | - # @!visibility private |
183 | | - def initialize(connection) |
184 | | - super(connection, Internal::Bridge::Client::#{service_enum}) |
185 | | - end |
186 | | - TEXT |
187 | | - |
188 | | - desc.each do |method| |
189 | | - # Camel case to snake case |
190 | | - rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_') |
191 | | - file.puts <<-TEXT |
192 | | -
|
193 | | - # Calls #{class_name}.#{method.name} API call. |
194 | | - # |
195 | | - # @param request [#{method.input_type.msgclass}] API request. |
196 | | - # @param rpc_options [RPCOptions, nil] Advanced RPC options. |
197 | | - # @return [#{method.output_type.msgclass}] API response. |
198 | | - def #{rpc}(request, rpc_options: nil) |
199 | | - invoke_rpc( |
200 | | - rpc: '#{rpc}', |
201 | | - request_class: #{method.input_type.msgclass}, |
202 | | - response_class: #{method.output_type.msgclass}, |
203 | | - request:, |
204 | | - rpc_options: |
205 | | - ) |
206 | | - end |
207 | | - TEXT |
208 | | - end |
209 | | - |
210 | | - file.puts <<~TEXT |
211 | | - end |
212 | | - end |
213 | | - end |
214 | | - end |
215 | | - TEXT |
216 | | - end |
217 | | - |
218 | | - # Open file to generate RBS code |
219 | | - # TODO(cretz): Improve this when RBS proto is supported |
220 | | - File.open("sig/temporalio/client/connection/#{file_name}.rbs", 'w') do |file| |
221 | | - file.puts <<~TEXT |
222 | | - # Generated code. DO NOT EDIT! |
223 | | -
|
224 | | - module Temporalio |
225 | | - class Client |
226 | | - class Connection |
227 | | - class #{class_name} < Service |
228 | | - def initialize: (Connection) -> void |
229 | | - TEXT |
230 | | - |
231 | | - desc.each do |method| |
232 | | - # Camel case to snake case |
233 | | - rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_') |
234 | | - file.puts <<-TEXT |
235 | | - def #{rpc}: ( |
236 | | - untyped request, |
237 | | - ?rpc_options: RPCOptions? |
238 | | - ) -> untyped |
239 | | - TEXT |
240 | | - end |
241 | | - |
242 | | - file.puts <<~TEXT |
243 | | - end |
244 | | - end |
245 | | - end |
246 | | - end |
247 | | - TEXT |
248 | | - end |
249 | | - end |
250 | | - |
251 | | - require './lib/temporalio/api/workflowservice/v1/service' |
252 | | - write_service_file( |
253 | | - qualified_service_name: 'temporal.api.workflowservice.v1.WorkflowService', |
254 | | - file_name: 'workflow_service', |
255 | | - class_name: 'WorkflowService', |
256 | | - service_enum: 'SERVICE_WORKFLOW' |
257 | | - ) |
258 | | - require './lib/temporalio/api/operatorservice/v1/service' |
259 | | - write_service_file( |
260 | | - qualified_service_name: 'temporal.api.operatorservice.v1.OperatorService', |
261 | | - file_name: 'operator_service', |
262 | | - class_name: 'OperatorService', |
263 | | - service_enum: 'SERVICE_OPERATOR' |
264 | | - ) |
265 | | - require './lib/temporalio/api/cloud/cloudservice/v1/service' |
266 | | - write_service_file( |
267 | | - qualified_service_name: 'temporal.api.cloud.cloudservice.v1.CloudService', |
268 | | - file_name: 'cloud_service', |
269 | | - class_name: 'CloudService', |
270 | | - service_enum: 'SERVICE_CLOUD' |
271 | | - ) |
272 | | - |
273 | | - # Generate Rust code |
274 | | - def generate_rust_match_arm(file:, qualified_service_name:, service_enum:, trait:) |
275 | | - # Do service lookup |
276 | | - desc = Google::Protobuf::DescriptorPool.generated_pool.lookup(qualified_service_name) |
277 | | - file.puts <<~TEXT |
278 | | - #{service_enum} => match call.rpc.as_str() { |
279 | | - TEXT |
280 | | - |
281 | | - desc.to_a.sort_by(&:name).each do |method| |
282 | | - # Camel case to snake case |
283 | | - rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_') |
284 | | - file.puts <<~TEXT |
285 | | - "#{rpc}" => rpc_call!(self, callback, call, #{trait}, #{rpc}), |
286 | | - TEXT |
287 | | - end |
288 | | - file.puts <<~TEXT |
289 | | - _ => Err(error!("Unknown RPC call {}", call.rpc)), |
290 | | - }, |
291 | | - TEXT |
292 | | - end |
293 | | - File.open('ext/src/client_rpc_generated.rs', 'w') do |file| |
294 | | - file.puts <<~TEXT |
295 | | - // Generated code. DO NOT EDIT! |
296 | | -
|
297 | | - use magnus::{Error, Ruby}; |
298 | | - use temporal_client::{CloudService, OperatorService, WorkflowService}; |
299 | | -
|
300 | | - use super::{error, rpc_call}; |
301 | | - use crate::{ |
302 | | - client::{Client, RpcCall, SERVICE_CLOUD, SERVICE_OPERATOR, SERVICE_WORKFLOW}, |
303 | | - util::AsyncCallback, |
304 | | - }; |
305 | | -
|
306 | | - impl Client { |
307 | | - pub fn invoke_rpc(&self, service: u8, callback: AsyncCallback, call: RpcCall) -> Result<(), Error> { |
308 | | - match service { |
309 | | - TEXT |
310 | | - generate_rust_match_arm( |
311 | | - file:, |
312 | | - qualified_service_name: 'temporal.api.workflowservice.v1.WorkflowService', |
313 | | - service_enum: 'SERVICE_WORKFLOW', |
314 | | - trait: 'WorkflowService' |
315 | | - ) |
316 | | - generate_rust_match_arm( |
317 | | - file:, |
318 | | - qualified_service_name: 'temporal.api.operatorservice.v1.OperatorService', |
319 | | - service_enum: 'SERVICE_OPERATOR', |
320 | | - trait: 'OperatorService' |
321 | | - ) |
322 | | - generate_rust_match_arm( |
323 | | - file:, |
324 | | - qualified_service_name: 'temporal.api.cloud.cloudservice.v1.CloudService', |
325 | | - service_enum: 'SERVICE_CLOUD', |
326 | | - trait: 'CloudService' |
327 | | - ) |
328 | | - file.puts <<~TEXT |
329 | | - _ => Err(error!("Unknown service")), |
330 | | - } |
331 | | - } |
332 | | - } |
333 | | - TEXT |
334 | | - end |
335 | | - sh 'cargo', 'fmt', '--', 'ext/src/client_rpc_generated.rs' |
336 | | - |
337 | | - # Generate core protos |
338 | | - FileUtils.rm_rf('lib/temporalio/internal/bridge/api') |
339 | | - # Generate API to temp dir |
340 | | - FileUtils.rm_rf('tmp-proto') |
341 | | - FileUtils.mkdir_p('tmp-proto') |
342 | | - sh 'bundle exec grpc_tools_ruby_protoc ' \ |
343 | | - '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_upstream ' \ |
344 | | - '--proto_path=ext/sdk-core/sdk-core-protos/protos/local ' \ |
345 | | - '--ruby_out=tmp-proto ' \ |
346 | | - "#{Dir.glob('ext/sdk-core/sdk-core-protos/protos/local/**/*.proto').join(' ')}" |
347 | | - # Walk all generated Ruby files and cleanup content and filename |
348 | | - Dir.glob('tmp-proto/temporal/sdk/**/*.rb') do |path| |
349 | | - # Fix up the imports |
350 | | - content = File.read(path) |
351 | | - content.gsub!(%r{^require 'temporal/(.*)_pb'$}, "require 'temporalio/\\1'") |
352 | | - content.gsub!(%r{^require 'temporalio/sdk/core/(.*)'$}, "require 'temporalio/internal/bridge/api/\\1'") |
353 | | - File.write(path, content) |
354 | | - |
355 | | - # Remove _pb from the filename |
356 | | - FileUtils.mv(path, path.sub('_pb', '')) |
357 | | - end |
358 | | - # Move from temp dir and remove temp dir |
359 | | - FileUtils.mkdir_p('lib/temporalio/internal/bridge/api') |
360 | | - FileUtils.cp_r(Dir.glob('tmp-proto/temporal/sdk/core/*'), 'lib/temporalio/internal/bridge/api') |
361 | | - FileUtils.rm_rf('tmp-proto') |
| 75 | + require_relative 'extra/proto_gen' |
| 76 | + ProtoGen.new.run |
362 | 77 | end |
363 | 78 | end |
364 | 79 |
|
|
0 commit comments