Skip to content

Commit

Permalink
feat: add 'pact-broker can-i-deploy' executable
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Oct 10, 2017
1 parent cc1e28b commit ca68c54
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 7 deletions.
4 changes: 4 additions & 0 deletions bin/pact-broker
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
require 'pact_broker/client/cli/broker'

PactBroker::Client::CLI::Broker.start
11 changes: 10 additions & 1 deletion lib/pact_broker/client/base_client.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
require 'erb'
require 'httparty'
require 'pact_broker/client/error'

module PactBroker
module Client

class Error < StandardError; end

module UrlHelpers
def encode_param param
ERB::Util.url_encode param
Expand Down Expand Up @@ -57,7 +60,13 @@ def handle_response response
elsif response.code == 404
nil
else
raise response.body
error_message = nil
begin
error_message = JSON.parse(response.body)['errors'].join("\n")
rescue
raise Error.new(response.body)
end
raise Error.new(error_message)
end
end

Expand Down
49 changes: 49 additions & 0 deletions lib/pact_broker/client/can_i_deploy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'pact_broker/client/error'
require 'pact_broker/client/pact_broker_client'

module PactBroker
module Client
class CanIDeploy

class Result
attr_reader :success, :message

def initialize success, message = nil
@success = success
@message = message
end
end

def self.call(pact_broker_base_url, version_selectors, pact_broker_client_options={})
new(pact_broker_base_url, version_selectors, pact_broker_client_options).call
end

def initialize(pact_broker_base_url, version_selectors, pact_broker_client_options)
@pact_broker_base_url = pact_broker_base_url
@version_selectors = version_selectors
@pact_broker_client_options = pact_broker_client_options
end

def call
matrix = pact_broker_client.matrix.get(version_selectors)
if matrix[:matrix].any?
Result.new(true, 'Computer says yes \o/')

This comment has been minimized.

Copy link
@froblesmartin

froblesmartin May 22, 2023

@bethesque I came all the way just to say thanks for the nice text "emojis" in both yes and no messages 😄

else
Result.new(false, 'Computer says no ¯\_(ツ)_/¯')
end
rescue PactBroker::Client::Error => e
Result.new(false, e.message)
rescue StandardError => e
Result.new(false, "Error retrieving matrix #{e.class} - #{e.message}\n#{e.backtrace.join("\n")}")
end

private

attr_reader :pact_broker_base_url, :version_selectors, :pact_broker_client_options

def pact_broker_client
@pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options)
end
end
end
end
46 changes: 46 additions & 0 deletions lib/pact_broker/client/cli/broker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
require 'pact_broker/client/can_i_deploy'
require 'pact_broker/client/version'
require 'thor'

module PactBroker
module Client
module CLI
class Broker < Thor
desc 'can-i-deploy VERSION_SELECTOR_ONE VERSION_SELECTOR_TWO ...', "Returns exit code 0 or 1, indicating whether or not the specified application versions are compatible.\n\nThe VERSION_SELECTOR format is <pacticipant_name>/version/<version_number>."

method_option :broker_base_url, required: true, aliases: "-b", desc: "The base URL of the Pact Broker"
method_option :broker_username, aliases: "-n", desc: "Pact Broker basic auth username"
method_option :broker_password, aliases: "-p", desc: "Pact Broker basic auth password"
method_option :verbose, aliases: "-v", desc: "Verbose output", :required => false

def can_i_deploy(*selectors)
result = CanIDeploy.call(options.broker_base_url, selectors, pact_broker_client_options)
if result.success
$stdout.puts result.message
else
$stdout.puts result.message
exit(1)
end
end

desc 'version', "Show the pact_broker-client gem version"
def version
$stdout.puts PactBroker::Client::VERSION
end

no_commands do
def pact_broker_client_options
if options[:username]
{
username: options[:username],
password: options[:password]
}
else
{}
end
end
end
end
end
end
end
16 changes: 16 additions & 0 deletions lib/pact_broker/client/matrix.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require_relative 'base_client'

module PactBroker
module Client
class Matrix < BaseClient
def get selectors
query = {selectors: selectors}
response = self.class.get("/matrix", query: query, headers: default_get_headers)

handle_response(response) do
JSON.parse(response.body, symbolize_names: true)
end
end
end
end
end
10 changes: 5 additions & 5 deletions lib/pact_broker/client/pact_broker_client.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
require 'pact_broker/client/pacticipants'
require 'pact_broker/client/versions'
require 'pact_broker/client/pacts'

require 'pact_broker/client/matrix'

module PactBroker


module Client

DEFAULT_PACT_BROKER_BASE_URL = 'http://pact-broker'
Expand All @@ -30,7 +28,9 @@ def pacts
PactBroker::Client::Pacts.new base_url: base_url, client_options: client_options
end

def matrix
PactBroker::Client::Matrix.new base_url: base_url, client_options: client_options
end
end
end

end
end
2 changes: 1 addition & 1 deletion pact-broker-client.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency 'json'
gem.add_runtime_dependency 'term-ansicolor'

gem.add_development_dependency 'pry'
gem.add_development_dependency 'pry-byebug'
gem.add_development_dependency 'fakefs', '~> 0.4'
gem.add_development_dependency 'rspec-fire'
gem.add_development_dependency 'appraisal'
Expand Down
61 changes: 61 additions & 0 deletions spec/pacts/pact_broker_client-pact_broker.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,67 @@
}
}
},
{
"description": "a request for the compatibility matrix for Foo version 1.2.3 and Bar version 4.5.6",
"providerState": "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6",
"request": {
"method": "get",
"path": "/matrix",
"query": "selectors[]=Foo%2Fversion%2F1.2.3&selectors[]=Bar%2Fversion%2F4.5.6"
},
"response": {
"status": 200,
"headers": {
},
"body": {
"matrix": [
{
}
]
}
}
},
{
"description": "a request for the compatibility matrix where one or more versions does not exist",
"providerState": "the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6",
"request": {
"method": "get",
"path": "/matrix",
"query": "selectors[]=Foo%2Fversion%2F1.2.3&selectors[]=Bar%2Fversion%2F9.9.9"
},
"response": {
"status": 400,
"headers": {
},
"body": {
"errors": {
"json_class": "Pact::ArrayLike",
"contents": "an error message",
"min": 1
}
}
}
},
{
"description": "a request for the compatibility matrix for a pacticipant that does not exist",
"request": {
"method": "get",
"path": "/matrix",
"query": "selectors[]=Foo%2Fversion%2F1.2.3&selectors[]=Bar%2Fversion%2F9.9.9"
},
"response": {
"status": 400,
"headers": {
},
"body": {
"errors": {
"json_class": "Pact::ArrayLike",
"contents": "an error message",
"min": 1
}
}
}
},
{
"description": "a request to publish a pact",
"providerState": "the 'Pricing Service' already exists in the pact-broker",
Expand Down
117 changes: 117 additions & 0 deletions spec/service_providers/pact_broker_client_matrix_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
require_relative 'pact_helper'
require 'pact_broker/client'

module PactBroker::Client
describe Matrix, :pact => true do

include_context "pact broker"

describe "retriving the compatibility matrix" do
let(:matrix_response_body) do
{
matrix: [{}]
}
end

context "when results are found" do
before do
pact_broker.
given("the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6").
upon_receiving("a request for the compatibility matrix for Foo version 1.2.3 and Bar version 4.5.6").
with(
method: :get,
path: "/matrix",
query: {
'selectors[]' => ['Foo/version/1.2.3', 'Bar/version/4.5.6']
}
).
will_respond_with(
status: 200,
headers: pact_broker_response_headers,
body: matrix_response_body
)
end

it 'a matrix of compatible versions' do
matrix = pact_broker_client.matrix.get(['Foo/version/1.2.3', 'Bar/version/4.5.6'])
expect(matrix[:matrix].size).to eq 1
end
end

context "with only one version selector" do
before do
pact_broker.
given("the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6").
upon_receiving("a request for the compatibility matrix where only the version of Foo is specified").
with(
method: :get,
path: "/matrix",
query: {
'selectors[]' => ['Foo/version/1.2.3']
}
).
will_respond_with(
status: 200,
headers: pact_broker_response_headers,
body: matrix_response_body
)
end
end

context "when one or more of the versions does not exist" do
before do
pact_broker.
given("the pact for Foo version 1.2.3 has been verified by Bar version 4.5.6").
upon_receiving("a request for the compatibility matrix where one or more versions does not exist").
with(
method: :get,
path: "/matrix",
query: {
'selectors[]' => ['Foo/version/1.2.3', 'Bar/version/9.9.9']
}
).
will_respond_with(
status: 400,
headers: pact_broker_response_headers,
body: {
errors: Pact.each_like("an error message")
}
)
end

it 'returns a list of errors' do
expect {
pact_broker_client.matrix.get(['Foo/version/1.2.3', 'Bar/version/9.9.9'])
}.to raise_error PactBroker::Client::Error, "an error message"
end
end

context "when results are not found" do
before do
pact_broker.
upon_receiving("a request for the compatibility matrix for a pacticipant that does not exist").
with(
method: :get,
path: "/matrix",
query: {
'selectors[]' => ['Foo/version/1.2.3', 'Bar/version/9.9.9']
}
).
will_respond_with(
status: 400,
headers: pact_broker_response_headers,
body: {
errors: Pact.each_like("an error message")
}
)
end

it 'returns a list of errors' do
expect {
pact_broker_client.matrix.get(['Foo/version/1.2.3', 'Bar/version/9.9.9'])
}.to raise_error PactBroker::Client::Error, "an error message"
end
end
end
end
end

0 comments on commit ca68c54

Please sign in to comment.