Skip to content

Commit

Permalink
Merge pull request #2 from franzliedke/fl/modernize
Browse files Browse the repository at this point in the history
Update CI, test dependencies and code style
  • Loading branch information
jgraichen authored Nov 17, 2021
2 parents 92d0c02 + d48d552 commit fae3f5f
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 93 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
19 changes: 19 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Lint
on: push
jobs:
rubocop:
name: rubocop
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@master
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
bundler-cache: true
env:
BUNDLE_JOBS: 4
BUNDLE_RETRY: 3

- name: Run rubocop
run: bundle exec rubocop --parallel --color
28 changes: 28 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: test
on: push
jobs:
rspec:
name: "${{ matrix.ruby }} / ${{ matrix.adapter }}"
runs-on: ubuntu-20.04

strategy:
fail-fast: false
matrix:
ruby:
- "3.0"
- "2.7"
- "2.6"
- "2.5"

steps:
- uses: actions/checkout@master
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
env:
BUNDLE_JOBS: 4
BUNDLE_RETRY: 3

- run: bundle exec rspec --color
14 changes: 14 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
inherit_gem:
my-rubocop: default.yml

AllCops:
TargetRubyVersion: 2.5
Exclude:
- vendor/**/*

Layout/LineLength:
Exclude:
- spec/**/*

RSpec/MessageSpies:
EnforcedStyle: receive
6 changes: 0 additions & 6 deletions .travis.yml

This file was deleted.

17 changes: 11 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in rack-remote.gemspec
gemspec

# Development gems
#
gem 'rake'
gem 'rspec'
gem 'coveralls'
gem 'webmock', '~> 1.7'
gem 'rack-test'
gem 'rake'
gem 'rspec'
gem 'webmock', '~> 3.0'

# Specify your gem's dependencies in gemspec
gemroot = File.dirname File.absolute_path __FILE__
gemspec path: gemroot
group :test do
gem 'my-rubocop', github: 'jgraichen/my-rubocop'
end
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ Or install it yourself as:
Register available remote calls:

```ruby
Rack::Remote.register :factory_girl do |params, env, request|
FactoryGirl.create params[:factory]
Rack::Remote.register :factory_bot do |params, env, request|
FactoryBot.create params[:factory]
end
```

Expand All @@ -36,8 +36,8 @@ Return value can be a Rack response array or any object that will be converted t

```ruby
Rack::Remote.add :srv1, url: 'http://serv.domain.tld/proxyed/path'
Rack::Remote.invoke :srv1, :factory_girl, factory: 'user'
Rack::Remote.invoke 'http://serv.domain.tld/proxyed/path', :factory_girl, factory: 'user'
Rack::Remote.invoke :srv1, :factory_bot, factory: 'user'
Rack::Remote.invoke 'http://serv.domain.tld/proxyed/path', :factory_bot, factory: 'user'
```

## Contributing
Expand Down
10 changes: 6 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# frozen_string_literal: true

require 'bundler/gem_tasks'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)
task :default => :spec
task default: :spec

begin
require 'yard'
require 'yard/rake/yardoc_task'

YARD::Rake::YardocTask.new do |t|
t.files = %w(lib/**/*.rb)
t.options = %w(--output-dir doc/)
t.files = %w[lib/**/*.rb]
t.options = %w[--output-dir doc/]
end
rescue LoadError
rescue LoadError # rubocop:disable Lint/SuppressedException
end
86 changes: 59 additions & 27 deletions lib/rack/remote.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'rack/remote/version'
require 'rack/request'
require 'multi_json'
Expand All @@ -18,15 +20,15 @@ def initialize(*attrs)
@cause = attrs.last.delete(:cause)
attrs.pop if attrs.last.empty?
end
super *attrs
super
end

def set_backtrace(trace)
def set_backtrace(trace) # rubocop:disable Naming/AccessorMethodName
trace.is_a?(Array) ? trace.map!(&:to_s) : trace = trace.to_s.split("\n")
trace.map! { |line| " #{line}" }
trace.map! {|line| " #{line}" }
if cause
trace << "/:0 caused by #{cause.class.name}: #{cause.message}"
trace += cause.backtrace.map! { |line| " #{line}" }
trace += cause.backtrace.map! {|line| " #{line}" }
end
super trace
end
Expand Down Expand Up @@ -62,15 +64,32 @@ def call(env)

response = cb.call(json, env, request)
if response.is_a?(Array) && response.size == 3
return response
response
else
[200, {'Content-Type' => 'application/json'}, StringIO.new(MultiJson.dump response) ]
[
200, {'Content-Type' => 'application/json'},
StringIO.new(MultiJson.dump(response))
]
end
rescue => err
[500, {'Content-Type' => 'application/json'}, StringIO.new(MultiJson.dump error: err.message, backtrace: err.backtrace, class: err.class.name) ]
rescue StandardError => e
[
500, {'Content-Type' => 'application/json'}, StringIO.new(
MultiJson.dump(
error: e.message, backtrace: e.backtrace, class: e.class.name
)
)
]
end
else
[404, {'Content-Type' => 'application/json'}, StringIO.new(MultiJson.dump error: 'remote call not defined', calls: call, list: self.class.calls.keys) ]
[
404, {'Content-Type' => 'application/json'}, StringIO.new(
MultiJson.dump(
error: 'remote call not defined',
calls: call,
list: self.class.calls.keys
)
)
]
end
end

Expand Down Expand Up @@ -105,6 +124,7 @@ def clear
#
def add(name, options = {})
raise ArgumentError unless options[:url]

remotes[name.to_sym] = options
end

Expand All @@ -114,38 +134,36 @@ def remotes

# Invoke remote call.
#
# @param remote [Symbol, String, #to_s] Symbolic remote name or remote URL.
# @param call [String, #to_s] Remote call to invoke.
# @param params [Hash] Key-Value pairs that will be converted to json and sent to remote call.
# @param headers [Hash] Header added to request.
# @param remote [Symbol, String, #to_s] Symbolic remote name or remote URL
# @param call [String, #to_s] Remote call to invoke
# @param params [Hash] Key-Value pairs that will be converted to json and
# sent to remote call
# @param headers [Hash] Header added to request
#
def invoke(remote, call, params = {}, headers = {})
remote = remotes[remote][:url] if remote.is_a? Symbol
uri = URI.parse remote.to_s
uri.path = '/' if uri.path.empty?

Net::HTTP.start uri.host, uri.port do |http|
request = Net::HTTP::Post.new uri.path
headers.each do |key, value|
request[key] = value.to_s
end
response = http.request request(uri, call, params, headers)

request['X-Rack-Remote-Call'] = call.to_s
request['Content-Type'] = 'application/json'
request.body = MultiJson.dump(params)

response = http.request request
if response.code.to_i == 500 and response['Content-Type'] == 'application/json'
if response.code.to_i == 500 &&
response['Content-Type'] == 'application/json'
json = MultiJson.load(response.body)

if json['error'] && json['backtrace'] && json['class']
remote_error = RemoteError.new class: json['class'], error: json['error'], backtrace: json['backtrace']
raise remote_error
#raise Rack::Remote::RemoteCallFailed.new("Remote call returned error code #{response.code}", cause: remote_error)
raise RemoteError.new \
class: json['class'],
error: json['error'],
backtrace: json['backtrace']
end
end

raise StandardError, "Rack Remote Error Response: #{response.code}: #{response.body}" if response.code.to_i != 200
if response.code.to_i != 200
raise StandardError.new \
"Rack Remote Error Response: #{response.code}: #{response.body}"
end

if response['Content-Type'] == 'application/json'
response.body.empty? ? {} : MultiJson.load(response.body)
Expand All @@ -154,6 +172,20 @@ def invoke(remote, call, params = {}, headers = {})
end
end
end

private

def request(uri, call, params, headers)
Net::HTTP::Post.new(uri.path).tap do |request|
headers.each do |key, value|
request[key] = value.to_s
end

request['X-Rack-Remote-Call'] = call.to_s
request['Content-Type'] = 'application/json'
request.body = MultiJson.dump(params)
end
end
end
end
end
2 changes: 2 additions & 0 deletions lib/rack/remote/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

class Rack::Remote
class Railtie < ::Rails::Railtie
initializer 'rack-remote.middleware' do |app|
Expand Down
2 changes: 2 additions & 0 deletions lib/rack/remote/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Rack
class Remote
VERSION = '1.1.0'
Expand Down
22 changes: 13 additions & 9 deletions rack-remote.gemspec
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
# frozen_string_literal: true

lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)

require 'rack/remote/version'

Gem::Specification.new do |spec|
spec.name = 'rack-remote'
spec.version = Rack::Remote::VERSION
spec.authors = ['Jan Graichen']
spec.email = %w([email protected])
spec.summary = %q{Small request intercepting rack middleware to invoke remote calls over HTTP.}
spec.description = %q{Small request intercepting rack middleware to invoke remote calls over HTTP.}
spec.email = %w[[email protected]]
spec.summary = 'Small request intercepting rack middleware to ' \
'invoke remote calls over HTTP.'
spec.description = 'Small request intercepting rack middleware to ' \
'invoke remote calls over HTTP.'
spec.homepage = 'https://github.com/jgraichen/rack-remote'
spec.license = 'MIT'

spec.files = `git ls-files`.split($/)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = %w(lib)
spec.require_paths = %w[lib]

spec.add_dependency 'rack'
spec.add_dependency 'multi_json'
spec.add_dependency 'rack'

spec.add_development_dependency 'bundler'
end
Loading

0 comments on commit fae3f5f

Please sign in to comment.