pact_broker-client 1.38.2 → 1.42.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +47 -0
  4. data/Gemfile +4 -0
  5. data/README.md +18 -0
  6. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +61 -140
  7. data/example/scripts/publish-pact.sh +1 -1
  8. data/lib/pact_broker/client/backports.rb +9 -0
  9. data/lib/pact_broker/client/base_client.rb +1 -1
  10. data/lib/pact_broker/client/base_command.rb +95 -0
  11. data/lib/pact_broker/client/can_i_deploy.rb +20 -3
  12. data/lib/pact_broker/client/cli/broker.rb +44 -28
  13. data/lib/pact_broker/client/cli/custom_thor.rb +12 -0
  14. data/lib/pact_broker/client/cli/environment_commands.rb +70 -0
  15. data/lib/pact_broker/client/cli/pacticipant_commands.rb +44 -0
  16. data/lib/pact_broker/client/cli/record_deployment_long_desc.txt +0 -0
  17. data/lib/pact_broker/client/cli/version_selector_options_parser.rb +4 -0
  18. data/lib/pact_broker/client/colorize_notices.rb +31 -0
  19. data/lib/pact_broker/client/environments.rb +3 -0
  20. data/lib/pact_broker/client/environments/create_environment.rb +31 -0
  21. data/lib/pact_broker/client/environments/delete_environment.rb +27 -0
  22. data/lib/pact_broker/client/environments/describe_environment.rb +36 -0
  23. data/lib/pact_broker/client/environments/environment_command.rb +66 -0
  24. data/lib/pact_broker/client/environments/list_environments.rb +30 -0
  25. data/lib/pact_broker/client/environments/text_formatter.rb +30 -0
  26. data/lib/pact_broker/client/environments/update_environment.rb +31 -0
  27. data/lib/pact_broker/client/generate_display_name.rb +27 -0
  28. data/lib/pact_broker/client/hal/entity.rb +26 -3
  29. data/lib/pact_broker/client/hal/http_client.rb +11 -2
  30. data/lib/pact_broker/client/hal/link.rb +20 -0
  31. data/lib/pact_broker/client/hal/links.rb +15 -0
  32. data/lib/pact_broker/client/hal_client_methods.rb +9 -3
  33. data/lib/pact_broker/client/matrix.rb +4 -0
  34. data/lib/pact_broker/client/matrix/abbreviate_version_number.rb +15 -0
  35. data/lib/pact_broker/client/matrix/resource.rb +26 -1
  36. data/lib/pact_broker/client/matrix/text_formatter.rb +28 -17
  37. data/lib/pact_broker/client/pacticipants.rb +6 -0
  38. data/lib/pact_broker/client/pacticipants/create.rb +24 -34
  39. data/lib/pact_broker/client/pacticipants/list.rb +34 -0
  40. data/lib/pact_broker/client/pacticipants/text_formatter.rb +41 -0
  41. data/lib/pact_broker/client/pacts.rb +0 -1
  42. data/lib/pact_broker/client/publish_pacts.rb +94 -128
  43. data/lib/pact_broker/client/publish_pacts_the_old_way.rb +194 -0
  44. data/lib/pact_broker/client/string_refinements.rb +56 -0
  45. data/lib/pact_broker/client/tasks/publication_task.rb +3 -3
  46. data/lib/pact_broker/client/version.rb +1 -1
  47. data/lib/pact_broker/client/versions/record_deployment.rb +6 -6
  48. data/lib/pact_broker/client/versions/record_undeployment.rb +45 -68
  49. data/pact-broker-client.gemspec +2 -0
  50. data/script/approve-all.sh +6 -0
  51. data/script/publish-pact.sh +36 -5
  52. data/script/record-deployment.sh +1 -3
  53. data/script/record-undeployment.sh +4 -0
  54. data/spec/fixtures/approvals/can_i_deploy_ignore.approved.txt +13 -0
  55. data/spec/fixtures/approvals/describe_environment.approved.txt +7 -0
  56. data/spec/fixtures/approvals/list_environments.approved.txt +3 -0
  57. data/spec/fixtures/foo-bar.json +31 -0
  58. data/spec/lib/pact_broker/client/can_i_deploy_spec.rb +47 -5
  59. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +5 -5
  60. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +36 -7
  61. data/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +3 -3
  62. data/spec/lib/pact_broker/client/cli/version_selector_options_parser_spec.rb +21 -0
  63. data/spec/lib/pact_broker/client/environments/delete_environment_spec.rb +120 -0
  64. data/spec/lib/pact_broker/client/environments/describe_environment_spec.rb +89 -0
  65. data/spec/lib/pact_broker/client/environments/update_environment_spec.rb +167 -0
  66. data/spec/lib/pact_broker/client/generate_display_name_spec.rb +39 -0
  67. data/spec/lib/pact_broker/client/hal/entity_spec.rb +2 -2
  68. data/spec/lib/pact_broker/client/pacticipants/create_spec.rb +5 -2
  69. data/spec/lib/pact_broker/client/{publish_pacts_spec.rb → publish_pacts_the_old_way_spec.rb} +10 -9
  70. data/spec/lib/pact_broker/client/tasks/publication_task_spec.rb +18 -12
  71. data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +5 -5
  72. data/spec/pacts/pact_broker_client-pact_broker.json +50 -124
  73. data/spec/service_providers/create_environment_spec.rb +78 -0
  74. data/spec/service_providers/list_environments_spec.rb +77 -0
  75. data/spec/service_providers/pact_broker_client_create_version_spec.rb +4 -4
  76. data/spec/service_providers/pact_broker_client_matrix_ignore_spec.rb +98 -0
  77. data/spec/service_providers/pacticipants_create_spec.rb +5 -4
  78. data/spec/service_providers/publish_pacts_spec.rb +116 -0
  79. data/spec/service_providers/record_deployment_spec.rb +6 -7
  80. data/spec/spec_helper.rb +3 -1
  81. data/spec/support/approvals.rb +26 -0
  82. data/spec/support/shared_context.rb +6 -2
  83. metadata +86 -5
@@ -0,0 +1,15 @@
1
+ module PactBroker
2
+ module Client
3
+ class Matrix
4
+ class AbbreviateVersionNumber
5
+ def self.call version_number
6
+ if version_number
7
+ version_number.gsub(/[A-Za-z0-9]{40}/) do | val |
8
+ val[0...7] + "..."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,9 +2,22 @@ require 'pact_broker/client/base_client'
2
2
 
3
3
  module PactBroker
4
4
  module Client
5
+ class Notice < Hash
6
+ def initialize(hash)
7
+ self.merge!(hash)
8
+ end
9
+
10
+ def text
11
+ self[:text]
12
+ end
13
+
14
+ def type
15
+ self[:type]
16
+ end
17
+ end
5
18
  class Matrix < BaseClient
6
- class Resource < Hash
7
19
 
20
+ class Resource < Hash
8
21
  def initialize hash
9
22
  self.merge!(hash)
10
23
  end
@@ -21,6 +34,10 @@ module PactBroker
21
34
  !!(self[:summary] && Integer === self[:summary][:unknown] )
22
35
  end
23
36
 
37
+ def supports_ignore?
38
+ !!(self[:summary] && Integer === self[:summary][:ignored] )
39
+ end
40
+
24
41
  def unknown_count
25
42
  supports_unknown_count? ? self[:summary][:unknown] : nil
26
43
  end
@@ -32,6 +49,14 @@ module PactBroker
32
49
  def deployable?
33
50
  self[:summary][:deployable]
34
51
  end
52
+
53
+ def notices
54
+ if self[:notices].is_a?(Array)
55
+ self[:notices].collect { | notice_hash | Notice.new(notice_hash) }
56
+ else
57
+ nil
58
+ end
59
+ end
35
60
  end
36
61
  end
37
62
  end
@@ -1,6 +1,7 @@
1
1
  require 'table_print'
2
2
  require 'dig_rb'
3
3
  require 'pact_broker/client/hash_refinements'
4
+ require 'pact_broker/client/matrix/abbreviate_version_number'
4
5
 
5
6
  module PactBroker
6
7
  module Client
@@ -8,38 +9,44 @@ module PactBroker
8
9
  class TextFormatter
9
10
  using PactBroker::Client::HashRefinements
10
11
 
11
- Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref)
12
-
13
- OPTIONS = [
14
- { consumer: {} },
15
- { consumer_version: {display_name: 'C.VERSION'} },
16
- { provider: {} },
17
- { provider_version: {display_name: 'P.VERSION'} },
18
- { success: {display_name: 'SUCCESS?'} },
19
- { ref: { display_name: 'RESULT#' }}
20
- ]
12
+ Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref, :ignored)
21
13
 
22
14
  def self.call(matrix)
23
15
  matrix_rows = matrix[:matrix]
24
16
  return "" if matrix_rows.size == 0
17
+ data = prepare_data(matrix_rows)
18
+ printer = TablePrint::Printer.new(data, tp_options(data))
19
+ printer.table_print + verification_result_urls_text(matrix)
20
+ end
21
+
22
+ def self.prepare_data(matrix_rows)
25
23
  verification_result_number = 0
26
- data = matrix_rows.each_with_index.collect do | line |
24
+ matrix_rows.each_with_index.collect do | line |
27
25
  has_verification_result_url = lookup(line, nil, :verificationResult, :_links, :self, :href)
28
26
  if has_verification_result_url
29
27
  verification_result_number += 1
30
28
  end
31
29
  Line.new(
32
30
  lookup(line, "???", :consumer, :name),
33
- lookup(line, "???", :consumer, :version, :number),
31
+ AbbreviateVersionNumber.call(lookup(line, "???", :consumer, :version, :number)),
34
32
  lookup(line, "???", :provider, :name) ,
35
- lookup(line, "???", :provider, :version, :number),
36
- (lookup(line, "???", :verificationResult, :success)).to_s,
37
- has_verification_result_url ? verification_result_number : ""
33
+ AbbreviateVersionNumber.call(lookup(line, "???", :provider, :version, :number)),
34
+ (lookup(line, "???", :verificationResult, :success)).to_s + ( line[:ignored] ? " [ignored]" : ""),
35
+ has_verification_result_url ? verification_result_number : "",
36
+ lookup(line, nil, :ignored)
38
37
  )
39
38
  end
39
+ end
40
40
 
41
- printer = TablePrint::Printer.new(data, OPTIONS)
42
- printer.table_print + verification_result_urls_text(matrix)
41
+ def self.tp_options(data)
42
+ [
43
+ { consumer: { width: max_width(data, :consumer, 'CONSUMER') } },
44
+ { consumer_version: { display_name: 'C.VERSION', width: max_width(data, :consumer_version, 'C.VERSION') } },
45
+ { provider: { width: max_width(data, :provider, 'PROVIDER') } },
46
+ { provider_version: { display_name: 'P.VERSION', width: max_width(data, :provider_version, 'P.VERSION') } },
47
+ { success: { display_name: 'SUCCESS?' } },
48
+ { ref: { display_name: 'RESULT#' } }
49
+ ]
43
50
  end
44
51
 
45
52
  def self.lookup line, default, *keys
@@ -72,6 +79,10 @@ module PactBroker
72
79
  text
73
80
  end
74
81
  end
82
+
83
+ def self.max_width(data, column, title)
84
+ (data.collect{ |row| row.send(column) } + [title]).compact.collect(&:size).max
85
+ end
75
86
  end
76
87
  end
77
88
  end
@@ -1,3 +1,9 @@
1
+ # New code
2
+ Dir.glob(File.join(__FILE__.gsub(".rb", "/**/*.rb"))).sort.each do | path |
3
+ require path
4
+ end
5
+
6
+ # Old code
1
7
  require 'pact_broker/client/base_client'
2
8
 
3
9
  module PactBroker
@@ -1,55 +1,45 @@
1
- require 'pact_broker/client/hal'
2
- require 'json'
3
- require 'pact_broker/client/command_result'
4
- require 'pact_broker/client/hal_client_methods'
1
+ require 'pact_broker/client/base_command'
5
2
 
6
3
  module PactBroker
7
4
  module Client
8
5
  module Pacticipants2
9
- class Create
6
+ class Create < PactBroker::Client::BaseCommand
10
7
 
11
- include HalClientMethods
8
+ private
12
9
 
13
- def self.call(params, pact_broker_base_url, pact_broker_client_options)
14
- new(params, pact_broker_base_url, pact_broker_client_options).call
15
- end
10
+ attr_reader :action, :response_entity
16
11
 
17
- def initialize(params, pact_broker_base_url, pact_broker_client_options)
18
- @params = params
19
- @index_entry_point = create_index_entry_point(pact_broker_base_url, pact_broker_client_options)
20
- @verbose = pact_broker_client_options[:verbose]
21
- end
12
+ def do_call
13
+ pacticipant_entity = index_resource._link('pb:pacticipant').expand('pacticipant' => params[:name]).get
22
14
 
23
- def call
24
- pacticipant_entity = index_entity._link('pb:pacticipant').expand('pacticipant' => params[:name]).get
25
- message = nil
26
15
  response_entity = if pacticipant_entity.does_not_exist?
27
- message = "Pacticipant \"#{params[:name]}\" created"
28
- index_entity._link!('pb:pacticipants').post(pacticipant_resource_params)
16
+ @action = "created"
17
+ index_resource._link!('pb:pacticipants').post!(pacticipant_resource_params)
18
+ elsif pacticipant_entity.success?
19
+ @action = "updated"
20
+ pacticipant_entity._link!('self').patch!(pacticipant_resource_params)
29
21
  else
30
- message = "Pacticipant \"#{params[:name]}\" updated"
31
- pacticipant_entity._link!('self').patch(pacticipant_resource_params)
22
+ pacticipant_entity.assert_success!
32
23
  end
33
24
 
34
25
  response_entity.assert_success!
35
- PactBroker::Client::CommandResult.new(true, message)
36
- rescue StandardError => e
37
- $stderr.puts("#{e.class} - #{e}\n#{e.backtrace.join("\n")}") if verbose
38
- PactBroker::Client::CommandResult.new(false, "#{e.class} - #{e}")
26
+ PactBroker::Client::CommandResult.new(true, result_message)
39
27
  end
40
28
 
41
- private
42
-
43
- attr_reader :index_entry_point, :params, :verbose
44
-
45
- def index_entity
46
- @index_entity ||= index_entry_point.get!
29
+ def result_message
30
+ if json_output?
31
+ response_entity.response.raw_body
32
+ else
33
+ green(message = "Pacticipant \"#{params[:name]}\" #{action}")
34
+ end
47
35
  end
48
36
 
49
37
  def pacticipant_resource_params
50
- p = { name: params[:name] }
51
- p[:repositoryUrl] = params[:repository_url] if params[:repository_url]
52
- p
38
+ {
39
+ name: params[:name],
40
+ repositoryUrl: params[:repository_url],
41
+ displayName: params[:display_name]
42
+ }.compact
53
43
  end
54
44
  end
55
45
  end
@@ -0,0 +1,34 @@
1
+ require 'pact_broker/client/base_command'
2
+ require 'pact_broker/client/pacticipants/text_formatter'
3
+
4
+ module PactBroker
5
+ module Client
6
+ module Pacticipants2
7
+ class List < PactBroker::Client::BaseCommand
8
+ private
9
+
10
+ attr_reader :environments_resource
11
+
12
+ def do_call
13
+ PactBroker::Client::CommandResult.new(true, result_message)
14
+ end
15
+
16
+ def environments_resource
17
+ @environments_resource = environments_link.get!
18
+ end
19
+
20
+ def environments_link
21
+ index_resource._link!('pb:pacticipants')
22
+ end
23
+
24
+ def result_message
25
+ if json_output?
26
+ environments_resource.response.raw_body
27
+ else
28
+ TextFormatter.call(environments_resource._embedded["pacticipants"])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ require 'table_print'
2
+ require 'ostruct'
3
+
4
+ module PactBroker
5
+ module Client
6
+ module Pacticipants2
7
+ class TextFormatter
8
+ def self.call(pacticipants)
9
+ return "" if pacticipants.size == 0
10
+
11
+ data = pacticipants.collect do | pacticipant |
12
+ # Might add a UUID in at some stage. Backwards compatible supporting code.
13
+ OpenStruct.new({ uuid: "" }.merge(pacticipant).merge(url: pacticipant["_links"]["self"]["href"]))
14
+ end.sort_by{ | pacticipant | pacticipant.name.downcase }
15
+
16
+ TablePrint::Printer.new(data, tp_options(data)).table_print
17
+ end
18
+
19
+ def self.tp_options(data)
20
+ uuid_width = max_width(data, :uuid, "")
21
+ name_width = max_width(data, :name, "NAME")
22
+ display_name_width = max_width(data, :displayName, "DISPLAY NAME")
23
+
24
+ tp_options = [
25
+ { name: { width: name_width} },
26
+ { displayName: { display_name: "Display name", width: display_name_width } },
27
+ ]
28
+
29
+ if uuid_width > 0
30
+ tp_options.unshift({ uuid: { width: uuid_width } })
31
+ end
32
+ tp_options
33
+ end
34
+
35
+ def self.max_width(data, column, title)
36
+ (data.collect{ |row| row.send(column) } + [title]).compact.collect(&:size).max
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -4,7 +4,6 @@ require 'pact_broker/client/pact_hash'
4
4
  module PactBroker
5
5
  module Client
6
6
  class Pacts < BaseClient
7
-
8
7
  def publish options
9
8
  consumer_version = options[:consumer_version]
10
9
  pact_hash = options[:pact_hash]
@@ -1,11 +1,8 @@
1
1
  require 'term/ansicolor'
2
- require 'pact_broker/client'
3
- require 'pact_broker/client/retry'
4
- require 'pact_broker/client/pact_file'
5
- require 'pact_broker/client/pact_hash'
6
- require 'pact_broker/client/merge_pacts'
7
2
  require 'pact_broker/client/hal_client_methods'
8
- require 'pact_broker/client/hash_refinements'
3
+ require 'base64'
4
+ require 'pact_broker/client/publish_pacts_the_old_way'
5
+ require 'pact_broker/client/colorize_notices'
9
6
 
10
7
  module PactBroker
11
8
  module Client
@@ -13,170 +10,135 @@ module PactBroker
13
10
  using PactBroker::Client::HashRefinements
14
11
  include HalClientMethods
15
12
 
16
- def self.call(pact_broker_base_url, pact_file_paths, consumer_version_params, pact_broker_client_options={})
17
- new(pact_broker_base_url, pact_file_paths, consumer_version_params, pact_broker_client_options).call
13
+ def self.call(pact_broker_base_url, pact_file_paths, consumer_version_params, options, pact_broker_client_options={})
14
+ new(pact_broker_base_url, pact_file_paths, consumer_version_params, options, pact_broker_client_options).call
18
15
  end
19
16
 
20
- def initialize pact_broker_base_url, pact_file_paths, consumer_version_params, pact_broker_client_options={}
17
+ def initialize pact_broker_base_url, pact_file_paths, consumer_version_params, options, pact_broker_client_options={}
21
18
  @pact_broker_base_url = pact_broker_base_url
22
19
  @pact_file_paths = pact_file_paths
23
- @consumer_version_number = consumer_version_params[:number].respond_to?(:strip) ? consumer_version_params[:number].strip : consumer_version_params[:number]
24
- @branch = consumer_version_params[:branch]
25
- @build_url = consumer_version_params[:build_url]
26
- @tags = consumer_version_params[:tags] ? consumer_version_params[:tags].collect{ |tag| tag.respond_to?(:strip) ? tag.strip : tag } : []
27
- @version_required = consumer_version_params[:version_required]
20
+ @consumer_version_params = consumer_version_params
21
+ @consumer_version_number = strip(consumer_version_params[:number])
22
+ @branch = strip(consumer_version_params[:branch])
23
+ @build_url = strip(consumer_version_params[:build_url])
24
+ @tags = consumer_version_params[:tags] ? consumer_version_params[:tags].collect{ |tag| strip(tag) } : []
25
+ @options = options
28
26
  @pact_broker_client_options = pact_broker_client_options
29
27
  end
30
28
 
31
29
  def call
32
30
  validate
33
- $stdout.puts("")
34
- result = create_consumer_versions && apply_tags && publish_pacts
35
- $stdout.puts("")
36
- result
31
+ if ENV.fetch("PACT_BROKER_FEATURES", "").include?("publish_contracts") && index_resource.can?("pb:publish-contracts")
32
+ publish_pacts
33
+ PactBroker::Client::CommandResult.new(success?, message)
34
+ else
35
+ PublishPactsTheOldWay.call(pact_broker_base_url, pact_file_paths, consumer_version_params, options, pact_broker_client_options)
36
+ end
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- attr_reader :pact_broker_base_url, :pact_file_paths, :consumer_version_number, :branch, :tags, :build_url, :pact_broker_client_options, :version_required
42
-
43
- def pact_broker_client
44
- @pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options)
45
- end
46
-
47
- def index_entry_point
48
- @index_entry_point ||= create_index_entry_point(pact_broker_base_url, pact_broker_client_options)
49
- end
41
+ attr_reader :pact_broker_base_url, :pact_file_paths, :consumer_version_params, :consumer_version_number, :branch, :tags, :build_url, :options, :pact_broker_client_options, :response_entities
50
42
 
51
- def index_resource
52
- @index_resource ||= Retry.while_error do
53
- index_entry_point.get!
54
- end
55
- end
56
-
57
- def can_create_version_with_branch?
58
- @can_create_version_with_branch ||= index_resource.can?('pb:pacticipant-version')
59
- end
60
-
61
- def merge_on_server?
62
- pact_broker_client_options[:write] == :merge
43
+ def request_body_for(consumer_name)
44
+ {
45
+ pacticipantName: consumer_name,
46
+ pacticipantVersionNumber: consumer_version_number,
47
+ tags: tags,
48
+ branch: branch,
49
+ buildUrl: build_url,
50
+ contracts: contracts_for(consumer_name)
51
+ }.compact
63
52
  end
64
53
 
65
54
  def publish_pacts
66
- pact_files.group_by(&:pact_name).collect do | pact_name, pact_files |
67
- $stdout.puts "Merging #{pact_files.collect(&:path).join(", ")}" if pact_files.size > 1
68
- publish_pact(PactHash[merge_contents(pact_files)])
69
- end.all?
70
- end
71
-
72
- def merge_contents(pact_files)
73
- MergePacts.call(pact_files.collect(&:pact_hash))
74
- end
75
-
76
- def pact_files
77
- @pact_files ||= pact_file_paths.collect{ |pact_file_path| PactFile.new(pact_file_path) }
78
- end
79
-
80
- def consumer_names
81
- pact_files.collect(&:consumer_name).uniq
55
+ @response_entities = consumer_names.collect do | consumer_name |
56
+ index_resource._link("pb:publish-contracts").post(request_body_for(consumer_name))
57
+ end
82
58
  end
83
59
 
84
- def publish_pact pact
85
- begin
86
- $stdout.puts "Publishing #{pact.pact_name} to pact broker at #{pact_broker_base_url}"
87
- publish_pact_contents pact
88
- rescue => e
89
- $stderr.puts "Failed to publish #{pact.pact_name} due to error: #{e.class} - #{e}"
90
- false
91
- end
60
+ def success?
61
+ response_entities.all?(&:success?)
92
62
  end
93
63
 
94
- def create_consumer_versions
95
- if create_versions?
96
- consumer_names.collect do | consumer_name |
97
- create_version(index_resource, consumer_name)
98
- end
99
- true
64
+ def message
65
+ if options[:output] == "json"
66
+ response_entities.collect(&:response).collect(&:body).to_a.to_json
100
67
  else
101
- true
68
+ text_message
102
69
  end
103
70
  end
104
71
 
105
- def create_versions?
106
- if version_required
107
- if can_create_version_with_branch?
108
- true
72
+ def text_message
73
+ response_entities.flat_map do | response_entity |
74
+ if response_entity.success?
75
+ if response_entity.notices
76
+ PactBroker::Client::ColorizeNotices.call(response_entity.notices.collect{ |n| OpenStruct.new(n) } )
77
+ elsif response_entity.logs
78
+ response_entity.logs.collect do | log |
79
+ colorized_message(log)
80
+ end
81
+ else
82
+ "Successfully published pacts"
83
+ end
109
84
  else
110
- raise PactBroker::Client::Error.new("This version of the Pact Broker does not support versions with branches or build URLs. Please upgrade your broker to 2.76.2 or later.")
85
+ ::Term::ANSIColor.red(response_entity.response.body.to_s)
111
86
  end
112
- elsif (branch || build_url) && can_create_version_with_branch?
113
- true
87
+ end.join("\n")
88
+ end
89
+
90
+ def colorized_message(log)
91
+ color = color_for_level(log["level"])
92
+ if color
93
+ ::Term::ANSIColor.send(color, log["message"])
114
94
  else
115
- false
95
+ log["message"]
116
96
  end
117
97
  end
118
98
 
119
- def create_version(index_resource, consumer_name)
120
- Retry.while_error do
121
- version_resource = index_resource._link('pb:pacticipant-version').expand(version: consumer_version_number, pacticipant: consumer_name).put(version_body).assert_success!
122
- message = if version_resource.response.status == 200
123
- "Replaced version #{consumer_version_number} of #{consumer_name}"
124
- else
125
- "Created version #{consumer_version_number} of #{consumer_name}"
126
- end
99
+ def color_for_level(level)
100
+ case level
101
+ when "warn" then :yellow
102
+ when "error" then :red
103
+ when "info" then :green
104
+ else nil
105
+ end
106
+ end
127
107
 
128
- message = message + " (branch #{branch})" if branch
129
- $stdout.puts message
130
- if version_resource.response.status == 200
131
- $stdout.puts ::Term::ANSIColor.yellow("Replacing the version resource is not recommended under normal circumstances and may indicate that you have not configured your Pact pipeline correctly (unless you are just re-running a build for a particular commit). For more information see https://docs.pact.io/versioning")
132
- end
133
- true
108
+ def contracts_for(consumer_name)
109
+ pact_files_for(consumer_name).group_by(&:pact_name).values.collect do | pact_files |
110
+ $stderr.puts "Merging #{pact_files.collect(&:path).join(", ")}" if pact_files.size > 1
111
+ pact_hash = PactHash[merge_contents(pact_files)]
112
+ {
113
+ consumerName: pact_hash.consumer_name,
114
+ providerName: pact_hash.provider_name,
115
+ specification: "pact",
116
+ contentType: "application/json",
117
+ content: Base64.strict_encode64(pact_hash.to_json),
118
+ writeMode: write_mode,
119
+ onConflict: write_mode
120
+ }
134
121
  end
135
122
  end
136
123
 
137
- def version_body
138
- {
139
- branch: branch,
140
- buildUrl: build_url
141
- }.compact
124
+ def merge_contents(pact_files)
125
+ MergePacts.call(pact_files.collect(&:pact_hash))
142
126
  end
143
127
 
144
- def apply_tags
145
- return true if tags.empty?
146
- tags.all? do | tag |
147
- tag_consumer_version tag
148
- end
128
+ def pact_files
129
+ @pact_files ||= pact_file_paths.collect{ |pact_file_path| PactFile.new(pact_file_path) }
149
130
  end
150
131
 
151
- def tag_consumer_version tag
152
- versions = pact_broker_client.pacticipants.versions
153
- Retry.while_error do
154
- consumer_names.collect do | consumer_name |
155
- versions.tag(pacticipant: consumer_name, version: consumer_version_number, tag: tag)
156
- $stdout.puts "Tagged version #{consumer_version_number} of #{consumer_name} as #{tag.inspect}"
157
- true
158
- end
159
- end
160
- rescue => e
161
- $stderr.puts "Failed to tag version due to error: #{e.class} - #{e}"
162
- false
132
+ def pact_files_for(consumer_name)
133
+ pact_files.select{ | pact_file | pact_file.consumer_name == consumer_name }
163
134
  end
164
135
 
165
- def publish_pact_contents(pact)
166
- Retry.while_error do
167
- pacts = pact_broker_client.pacticipants.versions.pacts
168
- if pacts.version_published?(consumer: pact.consumer_name, provider: pact.provider_name, consumer_version: consumer_version_number)
169
- if merge_on_server?
170
- $stdout.puts "A pact for this consumer version is already published. Merging contents."
171
- else
172
- $stdout.puts ::Term::ANSIColor.yellow("A pact for this consumer version is already published. Overwriting. (Note: Overwriting pacts is not recommended as it can lead to race conditions. Best practice is to provide a unique consumer version number for each publication. For more information, see https://docs.pact.io/versioning)")
173
- end
174
- end
136
+ def consumer_names
137
+ pact_files.collect(&:consumer_name).uniq
138
+ end
175
139
 
176
- latest_pact_url = pacts.publish(pact_hash: pact, consumer_version: consumer_version_number)
177
- $stdout.puts "The latest version of this pact can be accessed at the following URL:\n#{latest_pact_url}"
178
- true
179
- end
140
+ def write_mode
141
+ options[:merge] ? "merge" : "overwrite"
180
142
  end
181
143
 
182
144
  def validate
@@ -184,6 +146,10 @@ module PactBroker
184
146
  raise PactBroker::Client::Error.new("Please specify the pact_broker_base_url") unless (pact_broker_base_url && pact_broker_base_url.to_s.strip.size > 0)
185
147
  raise PactBroker::Client::Error.new("No pact files found") unless (pact_file_paths && pact_file_paths.any?)
186
148
  end
149
+
150
+ def strip(maybe_string)
151
+ maybe_string.respond_to?(:strip) ? maybe_string.strip : maybe_string
152
+ end
187
153
  end
188
154
  end
189
155
  end