Skip to content

Commit

Permalink
Merge pull request #307 from armilam/switch-to-faraday
Browse files Browse the repository at this point in the history
Allow use of either rest-client or faraday
  • Loading branch information
hoppergee authored May 30, 2022
2 parents b68881d + 3461d93 commit 9312d24
Show file tree
Hide file tree
Showing 17 changed files with 282 additions and 53 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ jobs:
- '6.0'
- '6.1'
- '7.0'
http_client_gem:
- 'rest-client'
- 'faraday'
exclude:
- ruby: '2.5'
active_model: '7.0'
Expand All @@ -48,6 +51,7 @@ jobs:

env:
ACTIVE_MODEL_VERSION: "~> ${{ matrix.active_model }}.0"
HTTP_CLIENT_GEM: "${{ matrix.http_client_gem }}"

steps:
- uses: actions/checkout@v2
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ group :development, :spec do
gem 'vcr'
gem 'dotenv'

if RUBY_VERSION < '2.6.0'
gem 'faraday', '~> 1.0'
else
gem 'faraday', '~> 2.0'
end

if RUBY_ENGINE == 'jruby'
gem 'jruby-openssl', platforms: :jruby
gem 'pry-nav', platforms: :jruby
Expand Down
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,19 @@ end

All the calls this library makes to Trello require authentication using these keys. Be sure to protect them.

#### Usage
#### HTTP Client

By default, ruby-trello uses [rest-client](https://rubygems.org/gems/rest-client) for network calls. You can configure ruby-trello to use either rest-client or [faraday](https://rubygems.org/gems/faraday), depending on your project's needs. In the next major version, ruby-trello will not require either gem in the gemspec and will default to faraday if both are present.

```ruby
Trello.configure do |config|
config.http_client = 'rest-client'
# OR
config.http_client = 'faraday'
end
```

## Usage

So let's say you want to get information about the user *bobtester*. We can do something like this:

Expand All @@ -103,7 +115,7 @@ puts bob.bio # A wonderfully delightful test user
# How about a list of his boards?
bob.boards

# And then to read the lists of the first board do :
# And then to read the lists of the first board do :
bob.boards.first.lists
```

Expand All @@ -130,10 +142,10 @@ pp Trello::Card.find( card_id ).checklists

##### Changing a checkbox state
```ruby
# First get your checklist id
# First get your checklist id
checklist = Trello::Checklist.find( checklist_id )

# At this point, there is no more ids. To get your checklist item,
# At this point, there is no more ids. To get your checklist item,
# you have to know it's position (same as in the trello interface).
# Let's take the first
checklist_item = checklist.items.first
Expand Down
49 changes: 49 additions & 0 deletions lib/trello.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,22 @@ module Trello
autoload :Organization, 'trello/organization'
autoload :PluginDatum, 'trello/plugin_datum'
autoload :Request, 'trello/net'
autoload :Response, 'trello/net'
autoload :TInternet, 'trello/net'
autoload :Token, 'trello/token'
autoload :Webhook, 'trello/webhook'
autoload :JsonUtils, 'trello/json_utils'
autoload :AssociationInferTool, 'trello/association_infer_tool'
autoload :Schema, 'trello/schema'

module TFaraday
autoload :TInternet, 'trello/net/faraday'
end

module TRestClient
autoload :TInternet, 'trello/net/rest_client'
end

module Authorization
autoload :AuthPolicy, 'trello/authorization'
autoload :BasicAuthPolicy, 'trello/authorization'
Expand Down Expand Up @@ -112,6 +121,45 @@ def self.logger=(logger)
@logger = logger
end

# The order in which we will try the http clients
HTTP_CLIENT_PRIORITY = %w(rest-client faraday)
HTTP_CLIENTS = {
'faraday' => Trello::TFaraday::TInternet,
'rest-client' => Trello::TRestClient::TInternet
}

def self.http_client
@http_client ||= begin
# No client has been set explicitly. Try to load each supported client.
# The first one that loads successfully will be used.
client = HTTP_CLIENT_PRIORITY.each do |key|
begin
require key
break HTTP_CLIENTS[key]
rescue LoadError
next
end
end

raise ConfigurationError, 'Trello requires either rest-client or faraday installed' unless client

client
end
end

def self.http_client=(http_client)
if HTTP_CLIENTS.include?(http_client)
begin
require http_client
@http_client = HTTP_CLIENTS[http_client]
rescue LoadError
raise ConfigurationError, "Trello tried to use #{http_client}, but that gem is not installed"
end
else
raise ArgumentError, "Unsupported HTTP client: #{http_client}"
end
end

def self.client
@client ||= Client.new
end
Expand All @@ -123,6 +171,7 @@ def self.configure(&block)

def self.reset!
@client = nil
@http_client = nil
end

def self.auth_policy; client.auth_policy; end
Expand Down
2 changes: 1 addition & 1 deletion lib/trello/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def invoke_verb(name, uri, body = nil)
raise Error.new(response.body, response.code)
end

response.body
response
end

def auth_policy_class
Expand Down
8 changes: 8 additions & 0 deletions lib/trello/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ def basic?
developer_public_key && member_token
end

def http_client=(http_client)
Trello.http_client = http_client.to_s
end

def http_client
Trello::HTTP_CLIENTS.find { |k, v| v == Trello.http_client }[0]
end

private

def oauth_credentials
Expand Down
14 changes: 10 additions & 4 deletions lib/trello/json_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ module ClassMethods
# thing.a == 42
# thing.b == "foo"
#
def from_response(data, encoding = 'UTF-8')
from_json(parse_json(data, encoding))
def from_response(response, encoding = 'UTF-8')
from_json(parse_json(response, encoding))
end

def from_json(json)
Expand All @@ -47,8 +47,14 @@ def from_json(json)
end
end

def parse_json(string, encoding = 'UTF-8')
JSON.parse(string.force_encoding(encoding))
def parse_json(data, encoding = 'UTF-8')
# Trello.http_client.parse_json(data, encoding)
case data
when Trello::Response
JSON.parse(data.body.force_encoding(encoding))
else
JSON.parse(data.force_encoding(encoding))
end
rescue JSON::ParserError => json_error
if json_error.message =~ /model not found/
Trello.logger.error "Could not find that record."
Expand Down
29 changes: 1 addition & 28 deletions lib/trello/net.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,8 @@ module Trello

class TInternet
class << self
require "rest_client"

def execute(request)
try_execute request
end

private

def try_execute(request)
begin
if request
result = execute_core request
Response.new(200, {}, result)
end
rescue RestClient::Exception => e
raise if !e.respond_to?(:http_code) || e.http_code.nil?
Response.new(e.http_code, {}, e.http_body)
end
end

def execute_core(request)
RestClient.proxy = ENV['HTTP_PROXY'] if ENV['HTTP_PROXY']
RestClient::Request.execute(
method: request.verb,
url: request.uri.to_s,
headers: request.headers,
payload: request.body,
timeout: 10
)
Trello.http_client.execute(request)
end
end
end
Expand Down
46 changes: 46 additions & 0 deletions lib/trello/net/faraday.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module Trello
module TFaraday
class TInternet
class << self
begin
require 'faraday'
rescue LoadError
end

def execute(request)
try_execute request
end

private

def try_execute(request)
begin
if request
result = execute_core request
Response.new(200, {}, result.body)
end
rescue Faraday::Error => e
raise if !e.respond_to?(:response) || e.response.nil? || e.response[:status].nil?
Response.new(e.response[:status], {}, e.response[:body])
end
end

def execute_core(request)
conn = Faraday.new(
request.uri.to_s,
headers: request.headers,
proxy: ENV['HTTP_PROXY'],
request: { timeout: 10 }
) do |faraday|
faraday.response :raise_error
faraday.request :json
end

conn.send(request.verb) do |req|
req.body = request.body
end
end
end
end
end
end
41 changes: 41 additions & 0 deletions lib/trello/net/rest_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module Trello
module TRestClient
class TInternet
class << self
begin
require 'rest-client'
rescue LoadError
end

def execute(request)
try_execute request
end

private

def try_execute(request)
begin
if request
result = execute_core request
Response.new(200, {}, result.body)
end
rescue RestClient::Exception => e
raise if !e.respond_to?(:http_code) || e.http_code.nil?
Response.new(e.http_code, {}, e.http_body)
end
end

def execute_core(request)
RestClient.proxy = ENV['HTTP_PROXY'] if ENV['HTTP_PROXY']
RestClient::Request.execute(
method: request.verb,
url: request.uri.to_s,
headers: request.headers,
payload: request.body,
timeout: 10
)
end
end
end
end
end
21 changes: 15 additions & 6 deletions matrixeval.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,30 @@ matrix:
active_model:
variants:
- key: 4.2
env:
env:
ACTIVE_MODEL_VERSION: "~> 4.2.0"
- key: 5.2
env:
env:
ACTIVE_MODEL_VERSION: "~> 5.2.0"
- key: 6.0
env:
env:
ACTIVE_MODEL_VERSION: "~> 6.0.0"
- key: 6.1
env:
env:
ACTIVE_MODEL_VERSION: "~> 6.1.0"
default: true
- key: 7.0
env:
env:
ACTIVE_MODEL_VERSION: "~> 7.0.0"
http_client_gem:
variants:
- key: faraday
env:
HTTP_CLIENT_GEM: "faraday"
default: true
- key: rest-client
env:
HTTP_CLIENT_GEM: "rest-client"
exclude:
- ruby: 2.5
active_model: 7.0
Expand All @@ -68,4 +77,4 @@ exclude:
- ruby: 3.1
active_model: 5.2
- ruby: jruby-9.3
active_model: 7.0
active_model: 7.0
Loading

0 comments on commit 9312d24

Please sign in to comment.