twirp_rails 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dd3357733d9ed117fd486b9ef3dd7c4ca5bd9ffcb73a891e2959fb93aed2ec9
4
- data.tar.gz: 1c5eee503666ad7810a9e02b0d3815d1716b8e9103799c9b1397a02bb95d78bb
3
+ metadata.gz: f7fbba3b1fe02ffed0c06b8a421f52577aab8634e0c3628c079721415c22df56
4
+ data.tar.gz: 25ab97b4b24fd79ea5c338bbef35f124e082c3ce34a9588b0d66658858936f77
5
5
  SHA512:
6
- metadata.gz: ffc1c1b275fc2a92aab71d3c09371168abe9396123f31442e6f1352668523a8b8d4ca3cae3f224df0ac67942286ecc5ac0072524454f776f12a70704d1204a75
7
- data.tar.gz: b54953adfc17d1b2d8fdce6af8e2e1d3f9be524b0f3917ddb80ed6e86f09cb4dc2235518aa03907c9a93fde188e35cf0bad7d7b47fab111d828ff63361069469
6
+ metadata.gz: 11e6b0f20cfc055c2b0d89b06e7a79011b3ca28b5d0f4456d8872b62c67e6c22e8ca50728f6d1c3700fbf8c6bc04b5bcef0245c37392eb3f687b1329603446d2
7
+ data.tar.gz: 2ee3fb02db058cea267475e4e872cc5049f732a3877a4454677ff9b4cbf9445f2c83b00fc654fae274f8994d822cdefdabb2656c178c886070ccd9ef02fd29fb
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## 0.4.1 - 2020-03-30
8
+
9
+ ### Added
10
+
11
+ - smart service detection - you can use `rails g twirp svc` if you `Svc` or
12
+ `SvcAPI` service described at `company/service/subservice/version/etc/svc_api.proto`
13
+ - Add `# :nocov:` comment to generated modules to avoid decrease coverage
14
+ - Improve generator console output and error handling
15
+ - `add_api_acronym` configuration option
16
+
17
+ ### Fixed
18
+
19
+ - `protoc` path was cached on start and didn't reload with spring
20
+
7
21
  ## 0.4.0 - 2020-03-24
8
22
 
9
23
  ### Breaking changes
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- twirp_rails (0.4.0)
4
+ twirp_rails (0.4.1)
5
5
  railties (~> 6.0)
6
6
  twirp (~> 1)
7
7
 
data/README.md CHANGED
@@ -25,7 +25,7 @@ to install required protoc and twirp-ruby plugin.
25
25
 
26
26
  ### Generator
27
27
 
28
- Create a proto file ```app/protos/people.proto```:
28
+ Create a proto file ```rpc/people.proto```:
29
29
  ```proto
30
30
  syntax = "proto3";
31
31
 
@@ -110,18 +110,14 @@ or run ```rails g twirp:rspec``` to do it automatically.
110
110
 
111
111
  ## Log twirp calls
112
112
 
113
- By default, Rails logs only start of POST request. To get a more detailed log of twirp calls, add this code to the initializer.
113
+ By default, Rails logs only start of POST request. To get a more detailed log of twirp calls
114
+ use `config.log_twirp_calls` configuration option (default `true`).
114
115
 
115
- ```ruby
116
- # config/initializers/twirp_rails.rb
117
- TwirpRails.log_twirp_calls!
118
- ```
119
-
120
- You can customize log output by pass a block argument
116
+ You can customize log output by pass a proc.
121
117
 
122
118
  ```ruby
123
119
  # config/initializers/twirp_rails.rb
124
- TwirpRails.log_twirp_calls! do |event|
120
+ config.log_twirp_calls = -> (event) do
125
121
  twirp_call_info = {
126
122
  duration: event.duration,
127
123
  method: event.payload[:env][:rpc_method],
@@ -136,6 +132,42 @@ TwirpRails.log_twirp_calls! do |event|
136
132
  end
137
133
  ```
138
134
 
135
+ ## Generate clients
136
+
137
+ Clients generator calls `protoc` to generate code from all proto files from
138
+ `rpc_clients` directory to `lib/twirp_clients` (all files auto required on application startup).
139
+
140
+ Generator runs without options by executing
141
+
142
+ ```
143
+ $ rails g twirp:clients
144
+ ```
145
+
146
+ ## Configuration
147
+
148
+ All configuration options (e.g. paths) can be customized via initializer file
149
+ generated by
150
+ ```
151
+ $ rails g twirp:init
152
+ ```
153
+
154
+ ## API acronym
155
+
156
+ Gem adds inflector acronym `API` to correct using services with suffix `API`.
157
+ `API` suffix required by `prototool` linter with `uber2` rules. You can disable this
158
+ inflection by set to false `add_api_acronym` configuration option.
159
+
160
+ ## Swagger generation
161
+
162
+ Service generator `rails g twirp service` generates swagger file in `public/swagger`
163
+ by default. You can turn it off or customize path in configuration.
164
+
165
+ ## Smart service detection
166
+
167
+ You can use `rails g twirp svc` if your `Svc` or
168
+ `SvcAPI` service described at `company/service/subservice/version/etc/svc_api.proto`
169
+ and you have no other files `svc_api.proto`.
170
+
139
171
  ## Development
140
172
 
141
173
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -29,8 +29,10 @@ module TwirpRails
29
29
  end
30
30
 
31
31
  initializer 'twirp_rails.add_api_acronym' do
32
- ActiveSupport::Inflector.inflections(:en) do |inflect|
33
- inflect.acronym 'API'
32
+ if TwirpRails.configuration.add_api_acronym
33
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
34
+ inflect.acronym 'API'
35
+ end
34
36
  end
35
37
  end
36
38
  end
@@ -0,0 +1,5 @@
1
+ require 'twirp_rails/generators/twirp/protoc_adapter'
2
+ require 'twirp_rails/generators/twirp/init/init_generator'
3
+ require 'twirp_rails/generators/twirp/clients/clients_generator'
4
+ require 'twirp_rails/generators/twirp/twirp_generator'
5
+ require 'twirp_rails/generators/twirp/twirp_rspec_generator'
@@ -5,30 +5,37 @@ module Twirp
5
5
  desc 'This generator run protoc generation on each file in the twirp_clients dir'
6
6
 
7
7
  def check_requirements
8
- raise 'protoc not found - install protobuf (brew/apt/yum install protobuf)' unless File.exist?(TwirpGenerator::PROTOC_PATH)
9
-
10
- unless File.exist?(TwirpGenerator::TWIRP_PLUGIN_PATH)
11
- raise <<~TEXT
12
- protoc-gen-twirp_ruby not found - install go (brew install go)
13
- and run "go get github.com/twitchtv/twirp-ruby/protoc-gen-twirp_ruby
14
- or set TWIRP_PLUGIN_PATH environment variable to right location.
15
- TEXT
8
+ protoc.check_requirements do |msg|
9
+ abort msg
10
+ end
11
+ end
12
+
13
+ def rm_old_twirp_files
14
+ return unless cfg.purge_old_twirp_code
15
+
16
+ in_root do
17
+ removed_files = protoc.rm_old_twirp_files
18
+
19
+ if removed_files
20
+ msg = "#{removed_files.size} twirp and pb files purged from #{dst_path}"
21
+ say_status :protoc, msg, :green
22
+ end
16
23
  end
17
24
  end
18
25
 
19
26
  def generate_twirp_files
20
27
  in_root do
21
- FileUtils.mkdir_p cfg.clients_twirp_code_path
28
+ FileUtils.mkdir_p dst_path
22
29
 
23
- protos_mask = File.join cfg.clients_proto_path, '**/*.proto'
30
+ protos_mask = File.join src_path, '**/*.proto'
24
31
  proto_files = Dir.glob protos_mask
25
32
 
26
33
  proto_files.each do |file|
27
- cmd = protoc_cmd(file)
34
+ cmd = protoc.cmd(file)
28
35
 
29
36
  `#{cmd}`
30
37
 
31
- raise "protoc failure: #{cmd}" unless $?.success?
38
+ abort "protoc failure: #{cmd}" unless $?.success?
32
39
  end
33
40
  end
34
41
  end
@@ -39,13 +46,20 @@ module Twirp
39
46
  TwirpRails.configuration
40
47
  end
41
48
 
42
- def protoc_cmd(files)
43
- flags = "--proto_path=#{cfg.clients_proto_path} " \
44
- "--ruby_out=#{cfg.clients_twirp_code_path} --twirp_ruby_out=#{cfg.clients_twirp_code_path} " \
45
- "--plugin=#{TwirpGenerator::TWIRP_PLUGIN_PATH}"
49
+ def abort(msg)
50
+ raise Thor::InvocationError, msg
51
+ end
46
52
 
47
- "#{TwirpGenerator::PROTOC_PATH} #{flags} #{files}"
53
+ def protoc
54
+ @protoc ||= ProtocAdapter.new(src_path, dst_path)
48
55
  end
49
56
 
57
+ def src_path
58
+ cfg.clients_proto_path
59
+ end
60
+
61
+ def dst_path
62
+ cfg.clients_twirp_code_path
63
+ end
50
64
  end
51
65
  end
@@ -18,4 +18,11 @@ TwirpRails.configure do |config|
18
18
  # set to proc to customize log output
19
19
  # set to false to disable feature
20
20
  # config.log_twirp_calls = true
21
+ #
22
+ # Delete all files from x_twirp_code_path
23
+ # before run protoc on proto files
24
+ # config.purge_old_twirp_code = true
25
+ #
26
+ # Add API acronym to inflector
27
+ # config.add_api_acronym = true
21
28
  end
@@ -0,0 +1,65 @@
1
+ class ProtocAdapter
2
+ attr_reader :src_path, :dst_path, :swagger_out_path
3
+
4
+ attr_reader :twirp_plugin_path, :swagger_plugin_path, :protoc_path
5
+
6
+ def initialize(src_path, dst_path, swagger_out_path: nil)
7
+ @src_path = src_path
8
+ @dst_path = dst_path
9
+ @swagger_out_path = swagger_out_path
10
+
11
+ go_path = ENV.fetch('GOPATH') { File.expand_path('~/go') }
12
+ go_bin_path = File.join(go_path, 'bin')
13
+ @twirp_plugin_path = ENV.fetch('TWIRP_PLUGIN_PATH') { File.join(go_bin_path, 'protoc-gen-twirp_ruby') }
14
+ @swagger_plugin_path = ENV.fetch('SWAGGER_PLUGIN_PATH') { File.join(go_bin_path, 'protoc-gen-twirp_swagger') }
15
+ @protoc_path = `which protoc`.chomp
16
+ end
17
+
18
+ def rm_old_twirp_files
19
+ return unless File.exists? dst_path
20
+
21
+ remove_mask = File.join dst_path, '**/*_{twirp,pb}.rb'
22
+ files_to_remove = Dir.glob remove_mask
23
+
24
+ return if files_to_remove.empty?
25
+
26
+ files_to_remove.each do |file|
27
+ File.unlink file
28
+ end
29
+ end
30
+
31
+ def cmd(files, gen_swagger: false)
32
+ flags = "--proto_path=#{src_path} " \
33
+ "--ruby_out=#{dst_path} --twirp_ruby_out=#{dst_path} " \
34
+ "--plugin=#{twirp_plugin_path}"
35
+
36
+ if gen_swagger
37
+ flags += " --plugin=#{swagger_plugin_path}" \
38
+ " --twirp_swagger_out=#{swagger_out_path}"
39
+ end
40
+
41
+ "#{protoc_path} #{flags} #{files}"
42
+ end
43
+
44
+ def check_requirements(check_swagger: false)
45
+ unless File.exist?(protoc_path)
46
+ yield 'protoc not found - install protobuf (brew/apt/yum install protobuf)'
47
+ end
48
+
49
+ unless File.exist?(twirp_plugin_path)
50
+ yield <<~TEXT
51
+ protoc-gen-twirp_ruby not found - install go (brew install go)
52
+ and run "go get github.com/twitchtv/twirp-ruby/protoc-gen-twirp_ruby
53
+ or set TWIRP_PLUGIN_PATH environment variable to right location.
54
+ TEXT
55
+ end
56
+
57
+ if check_swagger && !File.exist?(swagger_plugin_path)
58
+ yield <<~TEXT
59
+ protoc-gen-twirp_swagger not found - install go (brew install go)
60
+ and run "go get github.com/elliots/protoc-gen-twirp_swagger
61
+ or set SWAGGER_PLUGIN_PATH environment variable to right location.
62
+ TEXT
63
+ end
64
+ end
65
+ end
@@ -6,71 +6,99 @@ class TwirpGenerator < Rails::Generators::NamedBase
6
6
  class_option :skip_swagger, type: :boolean, default: false
7
7
  class_option :swagger_out, type: :string, default: nil
8
8
 
9
- GOPATH = ENV.fetch('GOPATH') { File.expand_path('~/go') }
10
- GO_BIN_PATH = File.join(GOPATH, 'bin')
11
- TWIRP_PLUGIN_PATH = ENV.fetch('TWIRP_PLUGIN_PATH') { File.join(GO_BIN_PATH, 'protoc-gen-twirp_ruby') }
12
- SWAGGER_PLUGIN_PATH = ENV.fetch('SWAGGER_PLUGIN_PATH') { File.join(GO_BIN_PATH, 'protoc-gen-twirp_swagger') }
13
- PROTOC_PATH = `which protoc`.chomp
9
+ def smart_detect_proto_file_name
10
+ return if File.exist?(proto_file_name) # dont detect when file exists
11
+ return if class_path.any? # dont detect when file with path
14
12
 
15
- def check_requirements
16
13
  in_root do
17
- raise "#{proto_file_name} not found" unless File.exist?(proto_file_name)
14
+ [file_name, "#{file_name}_api"].each do |file|
15
+ mask = File.join src_path, "**/#{file}.proto"
16
+ matched_files = Dir.glob(mask)
17
+
18
+ next if matched_files.empty?
19
+
20
+ abort "many proto files matched the #{file_name}: #{matched_files.join(' ')}" if matched_files.size > 1
21
+
22
+ matched_file = Pathname.new(matched_files.first).relative_path_from Pathname.new(src_path)
23
+ matched_file = matched_file.to_s[0..-(matched_file.extname.length + 1)] # remove extension
24
+
25
+ @file_path = nil # reset cache
26
+
27
+ say_status :detect, "Smart detect #{file_name} as #{matched_file}", :yellow
28
+ assign_names!(matched_file)
29
+ break
30
+ end
18
31
  end
32
+ end
19
33
 
20
- unless File.exist?(PROTOC_PATH)
21
- raise 'protoc not found - install protobuf (brew/apt/yum install protobuf)'
34
+ def check_requirements
35
+ in_root do
36
+ abort "#{proto_file_name} not found" unless File.exist?(proto_file_name)
22
37
  end
23
38
 
24
- unless File.exist?(TWIRP_PLUGIN_PATH)
25
- raise <<~TEXT
26
- protoc-gen-twirp_ruby not found - install go (brew install go)
27
- and run "go get github.com/twitchtv/twirp-ruby/protoc-gen-twirp_ruby
28
- or set TWIRP_PLUGIN_PATH environment variable to right location.
29
- TEXT
39
+ protoc.check_requirements(check_swagger: gen_swagger?) do |msg|
40
+ abort msg
30
41
  end
42
+ end
43
+
44
+ def rm_old_twirp_files
45
+ return unless cfg.purge_old_twirp_code
31
46
 
32
- if gen_swagger? && !File.exist?(SWAGGER_PLUGIN_PATH)
33
- raise <<~TEXT
34
- protoc-gen-twirp_swagger not found - install go (brew install go)
35
- and run "go get github.com/elliots/protoc-gen-twirp_swagger
36
- or set SWAGGER_PLUGIN_PATH environment variable to right location.
37
- TEXT
47
+ in_root do
48
+ removed_files = protoc.rm_old_twirp_files
49
+
50
+ if removed_files
51
+ msg = "#{removed_files.size} twirp and pb files purged from #{dst_path}"
52
+ say_status :protoc, msg, :green
53
+ end
38
54
  end
39
55
  end
40
56
 
41
57
  def generate_twirp_files
42
58
  in_root do
43
- FileUtils.mkdir_p cfg.services_twirp_code_path
59
+ FileUtils.mkdir_p dst_path
44
60
 
45
- protos_mask = File.join cfg.services_proto_path, '**/*.proto'
61
+ protos_mask = File.join src_path, '**/*.proto'
46
62
  proto_files = Dir.glob protos_mask
47
63
 
64
+ protoc_files_count = 0
65
+ swagger_files_count = 0
66
+
48
67
  proto_files.each do |file|
49
68
  gen_swagger = gen_swagger? && file =~ %r{/#{file_name}\.proto$}
50
69
 
51
70
  FileUtils.mkdir_p swagger_out_path if gen_swagger
52
71
 
53
- cmd = protoc_cmd(file, gen_swagger: gen_swagger)
72
+ cmd = protoc.cmd(file, gen_swagger: gen_swagger)
73
+
74
+ protoc_files_count += 1
75
+ swagger_files_count += gen_swagger ? 1 : 0
54
76
 
55
77
  `#{cmd}`
56
78
 
57
- raise "protoc failure: #{cmd}" unless $?.success?
79
+ abort "protoc failure: #{cmd}" unless $?.success?
58
80
  end
81
+
82
+ msg = "#{protoc_files_count} proto files processed, #{swagger_files_count} with swagger"
83
+ say_status :protoc, msg, :green
59
84
  end
60
85
  end
61
86
 
62
- PROTO_RPC_REGEXP = /\brpc\s+(\S+)\s*\(\s*(\S+)\s*\)\s*returns\s*\(\s*(\S+)\s*\)/m.freeze
63
-
64
87
  def create_module_files
65
88
  return if regular_class_path.empty?
66
89
 
67
90
  class_path.length.times do |i|
68
91
  current_path = class_path[0..i]
69
- create_file File.join('app/rpc', "#{current_path.join('/')}.rb"),
70
- module_hier(current_path.map(&:camelize))
92
+
93
+ create_file File.join('app/rpc', "#{current_path.join('/')}.rb"), <<~RUBY
94
+ # :nocov:
95
+ #{module_hier(current_path.map(&:camelize))}# :nocov:
96
+ RUBY
71
97
  end
72
98
  end
73
99
 
100
+ PROTO_RPC_REGEXP = /\brpc\s+(\S+)\s*\(\s*(\S+)\s*\)\s*returns\s*\(\s*(\S+)\s*\)/m.freeze
101
+
74
102
  def generate_handler
75
103
  methods = proto_content.scan(PROTO_RPC_REGEXP).map do |method, _arg_type, _result_type|
76
104
  optimize_indentation <<~RUBY, 2
@@ -134,17 +162,12 @@ class TwirpGenerator < Rails::Generators::NamedBase
134
162
  result_type.split('.').map(&:camelize).join('::')
135
163
  end
136
164
 
137
- def protoc_cmd(files, gen_swagger: gen_swagger?)
138
- flags = "--proto_path=#{cfg.services_proto_path} " \
139
- "--ruby_out=#{cfg.services_twirp_code_path} --twirp_ruby_out=#{cfg.services_twirp_code_path} " \
140
- "--plugin=#{TWIRP_PLUGIN_PATH}"
141
-
142
- if gen_swagger
143
- flags += " --plugin=#{SWAGGER_PLUGIN_PATH}" \
144
- " --twirp_swagger_out=#{swagger_out_path}"
145
- end
165
+ def src_path
166
+ cfg.services_proto_path
167
+ end
146
168
 
147
- "#{PROTOC_PATH} #{flags} #{files}"
169
+ def dst_path
170
+ cfg.services_twirp_code_path
148
171
  end
149
172
 
150
173
  def proto_content
@@ -157,7 +180,7 @@ class TwirpGenerator < Rails::Generators::NamedBase
157
180
  end
158
181
 
159
182
  def proto_file_name
160
- File.join cfg.services_proto_path, "#{file_path}.proto"
183
+ File.join src_path, "#{file_path}.proto"
161
184
  end
162
185
 
163
186
  def cfg
@@ -171,4 +194,12 @@ class TwirpGenerator < Rails::Generators::NamedBase
171
194
  def swagger_out_path
172
195
  options[:swagger_out] || cfg.swagger_output_path
173
196
  end
197
+
198
+ def abort(msg)
199
+ raise Thor::InvocationError, msg
200
+ end
201
+
202
+ def protoc
203
+ @protoc ||= ProtocAdapter.new(src_path, dst_path, swagger_out_path: swagger_out_path)
204
+ end
174
205
  end
@@ -1,3 +1,3 @@
1
1
  module TwirpRails
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.4.1'.freeze
3
3
  end
data/lib/twirp_rails.rb CHANGED
@@ -2,10 +2,7 @@
2
2
 
3
3
  require 'twirp_rails/version'
4
4
  require 'twirp_rails/engine'
5
- require 'twirp_rails/generators/twirp/init/init_generator'
6
- require 'twirp_rails/generators/twirp/clients/clients_generator'
7
- require 'twirp_rails/generators/twirp/twirp_generator'
8
- require 'twirp_rails/generators/twirp/twirp_rspec_generator'
5
+ require 'twirp_rails/generators/generators'
9
6
  require 'twirp_rails/active_record_extension'
10
7
  require 'twirp_rails/log_subscriber'
11
8
 
@@ -60,6 +57,10 @@ module TwirpRails
60
57
  config_param :swagger_output_path, 'public/swagger'
61
58
 
62
59
  config_param :log_twirp_calls, true
60
+
61
+ config_param :purge_old_twirp_code, true
62
+
63
+ config_param :add_api_acronym, true
63
64
  end
64
65
 
65
66
  def self.configuration
@@ -100,4 +101,22 @@ module TwirpRails
100
101
  yield
101
102
  end
102
103
  end
104
+
105
+ # Convert google.protobuf.Timestamp or Google::Protobuf::Timestampp hash
106
+ # to [Time]
107
+ # @param [Hash|Google::Protobuf::Timestamp] proto_timestamp
108
+ def self.timestamp_to_time(proto_timestamp)
109
+ return nil unless proto_timestamp
110
+
111
+ proto_timestamp = proto_timestamp.to_h unless proto_timestamp.is_a?(Hash)
112
+
113
+ seconds = proto_timestamp[:seconds]
114
+ raise "invalid timestamp #{proto_timestamp.inspect}" unless seconds
115
+
116
+ nanos = proto_timestamp[:nanos]
117
+
118
+ seconds += nanos * 1e-9 unless nanos.nil? || nanos.zero?
119
+
120
+ Time.zone.at seconds
121
+ end
103
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twirp_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandr Zimin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-24 00:00:00.000000000 Z
11
+ date: 2020-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: twirp
@@ -142,12 +142,14 @@ files:
142
142
  - lib/twirp_rails.rb
143
143
  - lib/twirp_rails/active_record_extension.rb
144
144
  - lib/twirp_rails/engine.rb
145
+ - lib/twirp_rails/generators/generators.rb
145
146
  - lib/twirp_rails/generators/twirp/USAGE
146
147
  - lib/twirp_rails/generators/twirp/clients/USAGE
147
148
  - lib/twirp_rails/generators/twirp/clients/clients_generator.rb
148
149
  - lib/twirp_rails/generators/twirp/init/USAGE
149
150
  - lib/twirp_rails/generators/twirp/init/init_generator.rb
150
151
  - lib/twirp_rails/generators/twirp/init/templates/twirp_rails.rb
152
+ - lib/twirp_rails/generators/twirp/protoc_adapter.rb
151
153
  - lib/twirp_rails/generators/twirp/twirp_generator.rb
152
154
  - lib/twirp_rails/generators/twirp/twirp_rspec_generator.rb
153
155
  - lib/twirp_rails/log_subscriber.rb