class TwirpGenerator

Constants

PROTO_RPC_REGEXP

Public Instance Methods

check_requirements() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 34
def check_requirements
  in_root do
    abort "#{proto_file_name} not found" unless File.exist?(proto_file_name)
  end

  protoc.check_requirements(check_swagger: gen_swagger?) do |msg|
    abort msg
  end
end
create_module_files() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 87
  def create_module_files
    return if regular_class_path.empty?

    class_path.length.times do |i|
      current_path = class_path[0..i]

      create_file File.join('app/rpc', "#{current_path.join('/')}.rb"), <<~RUBY
        # :nocov:
        #{module_hier(current_path.map(&:camelize))}# :nocov:
      RUBY
    end
  end
generate_handler() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 102
  def generate_handler
    methods = proto_content.scan(PROTO_RPC_REGEXP).map do |method, _arg_type, _result_type|
      optimize_indentation <<~RUBY, 2
        def #{method.underscore}(req, _env)
        end
      RUBY
    end.join("\n")

    # Let us assume that the service name is the same file name
    create_file "app/rpc/#{file_path}_handler.rb", <<~RUBY
      class #{class_name}Handler
      #{methods}end
    RUBY
  end
generate_route() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 117
def generate_route
  route "mount_twirp '#{file_path}'"
end
generate_rspec_files() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 121
  def generate_rspec_files
    in_root do
      return unless File.exist?('spec')

      methods = proto_content.scan(PROTO_RPC_REGEXP).map do |method, _arg_type, result_type|
        result_type = proto_type_to_ruby(result_type)
        optimize_indentation <<~RUBY, 2
          context '##{method.underscore}' do
            rpc { [:#{method.underscore}, 'arg'] }

            it do
              expect { #{result_type}.new(subject) }.to_not raise_exception
              should match({})
            end
          end
        RUBY
      end.join("\n")

      create_file "spec/rpc/#{file_path}_handler_spec.rb", <<~RUBY
        require 'rails_helper'

        describe #{class_name}Handler do

        #{methods}end
      RUBY
    end
  end
generate_twirp_files() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 57
def generate_twirp_files
  in_root do
    FileUtils.mkdir_p dst_path

    protos_mask = File.join src_path, '**/*.proto'
    proto_files = Dir.glob protos_mask

    protoc_files_count = 0
    swagger_files_count = 0

    proto_files.each do |file|
      gen_swagger = gen_swagger? && file =~ %r{/#{file_name}\.proto$}

      FileUtils.mkdir_p cfg.swagger_output_path if gen_swagger

      cmd = protoc.cmd(file, gen_swagger)

      protoc_files_count += 1
      swagger_files_count += gen_swagger ? 1 : 0

      `#{cmd}`

      abort "protoc failure: #{cmd}" unless $?.success?
    end

    msg = "#{protoc_files_count} proto files processed, #{swagger_files_count} with swagger"
    say_status :protoc, msg, :green
  end
end
rm_old_twirp_files() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 44
def rm_old_twirp_files
  return unless cfg.purge_old_twirp_code

  in_root do
    removed_files = protoc.rm_old_twirp_files

    if removed_files
      msg = "#{removed_files.size} twirp and pb files purged from #{dst_path}"
      say_status :protoc, msg, :green
    end
  end
end
smart_detect_proto_file_name() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 9
def smart_detect_proto_file_name
  return if File.exist?(proto_file_name) # dont detect when file exists
  return if class_path.any? # dont detect when file with path

  in_root do
    [file_name, "#{file_name}_api"].each do |file|
      mask = File.join src_path, "**/#{file}.proto"
      matched_files = Dir.glob(mask)

      next if matched_files.empty?

      abort "many proto files matched the #{file_name}: #{matched_files.join(' ')}" if matched_files.size > 1

      matched_file = Pathname.new(matched_files.first).relative_path_from Pathname.new(src_path)
      matched_file = matched_file.to_s[0..-(matched_file.extname.length + 1)] # remove extension

      @file_path = nil # reset cache

      say_status :detect, "Smart detect #{file_name} as #{matched_file}", :yellow
      assign_names!(matched_file)
      break
    end
  end
end

Private Instance Methods

abort(msg) click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 194
def abort(msg)
  raise Thor::InvocationError, msg
end
cfg() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 186
def cfg
  TwirpRails.configuration
end
dst_path() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 169
def dst_path
  cfg.services_twirp_code_path
end
gen_swagger?() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 190
def gen_swagger?
  options[:gen_swagger] && cfg.swagger_output_path.present?
end
module_hier(modules, indent = 0) click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 151
  def module_hier(modules, indent = 0)
    return '' if modules.size.zero?

    cur, *tail = modules
    optimize_indentation <<~RUBY, indent
      module #{cur}
      #{module_hier(tail, 2)}end
    RUBY
  end
proto_content() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 173
def proto_content
  unless @proto_content
    in_root do
      @proto_content = File.read proto_file_name
    end
  end
  @proto_content
end
proto_file_name() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 182
def proto_file_name
  File.join src_path, "#{file_path}.proto"
end
proto_type_to_ruby(result_type) click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 161
def proto_type_to_ruby(result_type)
  result_type.split('.').map(&:camelize).join('::')
end
protoc() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 198
def protoc
  @protoc ||= ProtocAdapter.new(src_path, dst_path, cfg.swagger_output_path)
end
src_path() click to toggle source
# File lib/twirp_rails/generators/twirp/twirp_generator.rb, line 165
def src_path
  cfg.services_proto_path
end