pact_broker-client 1.41.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/lib/pact_broker/client/backports.rb +9 -0
  4. data/lib/pact_broker/client/base_command.rb +95 -0
  5. data/lib/pact_broker/client/cli/broker.rb +11 -19
  6. data/lib/pact_broker/client/cli/custom_thor.rb +12 -0
  7. data/lib/pact_broker/client/cli/environment_commands.rb +70 -0
  8. data/lib/pact_broker/client/cli/pacticipant_commands.rb +44 -0
  9. data/lib/pact_broker/client/environments.rb +3 -0
  10. data/lib/pact_broker/client/environments/create_environment.rb +31 -0
  11. data/lib/pact_broker/client/environments/delete_environment.rb +27 -0
  12. data/lib/pact_broker/client/environments/describe_environment.rb +36 -0
  13. data/lib/pact_broker/client/environments/environment_command.rb +66 -0
  14. data/lib/pact_broker/client/environments/list_environments.rb +30 -0
  15. data/lib/pact_broker/client/environments/text_formatter.rb +30 -0
  16. data/lib/pact_broker/client/environments/update_environment.rb +31 -0
  17. data/lib/pact_broker/client/generate_display_name.rb +27 -0
  18. data/lib/pact_broker/client/hal/entity.rb +10 -3
  19. data/lib/pact_broker/client/hal/http_client.rb +5 -0
  20. data/lib/pact_broker/client/hal/link.rb +8 -0
  21. data/lib/pact_broker/client/hal_client_methods.rb +1 -3
  22. data/lib/pact_broker/client/matrix/text_formatter.rb +21 -13
  23. data/lib/pact_broker/client/pacticipants.rb +6 -0
  24. data/lib/pact_broker/client/pacticipants/create.rb +24 -34
  25. data/lib/pact_broker/client/pacticipants/list.rb +34 -0
  26. data/lib/pact_broker/client/pacticipants/text_formatter.rb +41 -0
  27. data/lib/pact_broker/client/string_refinements.rb +56 -0
  28. data/lib/pact_broker/client/version.rb +1 -1
  29. data/pact-broker-client.gemspec +1 -0
  30. data/spec/fixtures/approvals/describe_environment.approved.txt +7 -0
  31. data/spec/fixtures/approvals/list_environments.approved.txt +3 -0
  32. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +3 -3
  33. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +1 -1
  34. data/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +3 -3
  35. data/spec/lib/pact_broker/client/environments/delete_environment_spec.rb +120 -0
  36. data/spec/lib/pact_broker/client/environments/describe_environment_spec.rb +89 -0
  37. data/spec/lib/pact_broker/client/environments/update_environment_spec.rb +167 -0
  38. data/spec/lib/pact_broker/client/generate_display_name_spec.rb +39 -0
  39. data/spec/lib/pact_broker/client/hal/entity_spec.rb +2 -2
  40. data/spec/lib/pact_broker/client/pacticipants/create_spec.rb +2 -2
  41. data/spec/service_providers/create_environment_spec.rb +78 -0
  42. data/spec/service_providers/list_environments_spec.rb +77 -0
  43. data/spec/service_providers/pacticipants_create_spec.rb +5 -4
  44. data/spec/spec_helper.rb +1 -0
  45. data/spec/support/approvals.rb +1 -1
  46. metadata +48 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b929ba48b8f21f7cafeb339e925fac9ecf7a4a83cd3392f5170c769c725998c3
4
- data.tar.gz: 1b50eef690671dfdf9a78f1bb8da0f2f1e58cf380b199a554b5a9e770d40a825
3
+ metadata.gz: 1da6a5e8cef3f91ae1cd441eb92dd2d788ad67ccac947c476090787b27b134ea
4
+ data.tar.gz: 0df7d512c7c45a8b7ea4d049560be927d1d7c3273c0ec157c22cb81651caa16e
5
5
  SHA512:
6
- metadata.gz: e527702e1d7d9cc3644f3c4db48c7e02060435699b0104f9048ab6142228475405fac9abea025c713bbf8a3a15b71660a56973515b72464814ff8dee62518289
7
- data.tar.gz: 0b81d80a4ab02de7f7d71a7e5c991a6e322731c1803c7c85fd0b53379d92f4739e3296c0acd76cf528567b14147fb3743c352322104da46e4064116bc531514b
6
+ metadata.gz: 27dc97ff230f86c530b8aed93cf5e86334dd51982017627a7c99de57a2cf8f65af6706c5a73c5d1999df0b145b60b88a649b716fc7f859cbc289193f9dbca437
7
+ data.tar.gz: 1f970d5b863efc1bc27c55515b95afe8c4a3e166e3da62819ac92e1d4f6205fccb7f8979925266dc37342c1be496310c59a150408398e000b5e8e8b2079ab609
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ <a name="v1.42.0"></a>
2
+ ### v1.42.0 (2021-05-31)
3
+
4
+ #### Features
5
+
6
+ * add list-pacticipants ([fc8ce3b](/../../commit/fc8ce3b))
7
+ * add --display-name to create-or-update-pacticipant ([76f323b](/../../commit/76f323b))
8
+ * add backtrace to error output when verbose is true ([abf1ef0](/../../commit/abf1ef0))
9
+ * add list-environments and describe-environment ([4472d48](/../../commit/4472d48))
10
+ * add delete-environment ([361eed1](/../../commit/361eed1))
11
+ * add update-environment command ([95276cd](/../../commit/95276cd))
12
+ * add create-environment command ([a9fab50](/../../commit/a9fab50))
13
+
14
+ #### Bug Fixes
15
+
16
+ * stop long values in columns from being truncated ([18063fd](/../../commit/18063fd))
17
+
1
18
  <a name="v1.41.0"></a>
2
19
  ### v1.41.0 (2021-05-25)
3
20
 
@@ -10,4 +10,13 @@ class Hash
10
10
  def compact!
11
11
  reject! {|_key, value| value == nil}
12
12
  end unless method_defined? :compact!
13
+
14
+ def except(*keys)
15
+ if keys.size > 4 && size > 4 # index if O(m*n) is big
16
+ h = {}
17
+ keys.each { |key| h[key] = true }
18
+ keys = h
19
+ end
20
+ reject { |key, _value| keys.include? key}
21
+ end unless method_defined? :except
13
22
  end
@@ -0,0 +1,95 @@
1
+ require 'pact_broker/client/hal_client_methods'
2
+ require 'pact_broker/client/error'
3
+ require 'pact_broker/client/command_result'
4
+ require 'term/ansicolor'
5
+ require 'pact_broker/client/backports'
6
+
7
+ module PactBroker
8
+ module Client
9
+ class BaseCommand
10
+ include PactBroker::Client::HalClientMethods
11
+
12
+ def self.call(params, options, pact_broker_client_options)
13
+ new(params, options, pact_broker_client_options).call
14
+ end
15
+
16
+ def initialize(params, options, pact_broker_client_options)
17
+ @params = params
18
+ @options = options
19
+ @pact_broker_base_url = pact_broker_client_options.fetch(:pact_broker_base_url)
20
+ @pact_broker_client_options = pact_broker_client_options
21
+ end
22
+
23
+ def call
24
+ check_if_command_supported
25
+ do_call
26
+ rescue PactBroker::Client::Hal::ErrorResponseReturned => e
27
+ handle_http_error(e)
28
+ rescue PactBroker::Client::Error => e
29
+ handle_ruby_error(e)
30
+ rescue StandardError => e
31
+ handle_ruby_error(e, verbose?)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :params, :options
37
+ attr_reader :pact_broker_base_url, :pact_broker_client_options
38
+
39
+ def handle_http_error(e)
40
+ message = if json_output?
41
+ body = e.entity.response.raw_body
42
+ (body.nil? || body == "") ? "{}" : body
43
+ else
44
+ red(e.message)
45
+ end
46
+ PactBroker::Client::CommandResult.new(false, message)
47
+ end
48
+
49
+ def handle_ruby_error(e, include_backtrace = false)
50
+ PactBroker::Client::CommandResult.new(false, error_message(e, include_backtrace))
51
+ end
52
+
53
+ def error_message(e, include_backtrace)
54
+ if json_output?
55
+ json_error_message(e, include_backtrace)
56
+ else
57
+ text_error_message(e, include_backtrace)
58
+ end
59
+ end
60
+
61
+ def json_error_message(e, include_backtrace)
62
+ error_hash = { message: e.message }
63
+ error_hash[:class] = e.class.name unless e.is_a?(PactBroker::Client::Error)
64
+ error_hash[:backtrace] = e.backtrace if include_backtrace
65
+ { error: error_hash }.to_json
66
+ end
67
+
68
+
69
+ def text_error_message(e, include_backtrace)
70
+ maybe_backtrace = (include_backtrace ? "\n" + e.backtrace.join("\n") : "")
71
+ exception_message = e.is_a?(PactBroker::Client::Error) ? e.message : "#{e.class} - #{e.message}"
72
+ red(exception_message) + maybe_backtrace
73
+ end
74
+
75
+ def check_if_command_supported
76
+ end
77
+
78
+ def json_output?
79
+ options[:output] == "json"
80
+ end
81
+
82
+ def verbose?
83
+ options[:verbose]
84
+ end
85
+
86
+ def green(text)
87
+ ::Term::ANSIColor.green(text)
88
+ end
89
+
90
+ def red(text)
91
+ ::Term::ANSIColor.red(text)
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,6 +1,8 @@
1
1
  require 'pact_broker/client/cli/custom_thor'
2
2
  require 'pact_broker/client/hash_refinements'
3
3
  require 'thor/error'
4
+ require 'pact_broker/client/cli/environment_commands'
5
+ require 'pact_broker/client/cli/pacticipant_commands'
4
6
 
5
7
  module PactBroker
6
8
  module Client
@@ -13,6 +15,10 @@ module PactBroker
13
15
 
14
16
  class Broker < CustomThor
15
17
  using PactBroker::Client::HashRefinements
18
+ if ENV.fetch("PACT_BROKER_FEATURES", "").include?("deployments")
19
+ include PactBroker::Client::CLI::EnvironmentCommands
20
+ end
21
+ include PactBroker::Client::CLI::PacticipantCommands
16
22
 
17
23
  desc 'can-i-deploy', ''
18
24
  long_desc File.read(File.join(__dir__, 'can_i_deploy_long_desc.txt'))
@@ -60,7 +66,7 @@ module PactBroker
60
66
  method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Default: false"
61
67
  method_option :build_url, desc: "The build URL that created the pact"
62
68
  method_option :merge, type: :boolean, default: false, require: false, desc: "If a pact already exists for this consumer version and provider, merge the contents. Useful when running Pact tests concurrently on different build nodes."
63
- method_option :output, aliases: "-o", desc: "json or text", default: 'text'
69
+ output_option_json_or_text
64
70
  shared_authentication_options
65
71
 
66
72
  def publish(*pact_files)
@@ -157,22 +163,9 @@ module PactBroker
157
163
  puts SecureRandom.uuid
158
164
  end
159
165
 
160
- desc 'create-or-update-pacticipant', 'Create or update pacticipant by name'
161
- method_option :name, type: :string, required: true, desc: "Pacticipant name"
162
- method_option :repository_url, type: :string, required: false, desc: "The repository URL of the pacticipant"
163
- shared_authentication_options
164
- verbose_option
165
- def create_or_update_pacticipant(*required_but_ignored)
166
- raise ::Thor::RequiredArgumentMissingError, "Pacticipant name cannot be blank" if options.name.strip.size == 0
167
- require 'pact_broker/client/pacticipants/create'
168
- result = PactBroker::Client::Pacticipants2::Create.call({ name: options.name, repository_url: options.repository_url }, options.broker_base_url, pact_broker_client_options)
169
- $stdout.puts result.message
170
- exit(1) unless result.success
171
- end
172
-
173
166
  desc 'list-latest-pact-versions', 'List the latest pact for each integration'
174
167
  shared_authentication_options
175
- method_option :output, aliases: "-o", desc: "json or table", default: 'table'
168
+ output_option_json_or_table
176
169
  def list_latest_pact_versions(*required_but_ignored)
177
170
  require 'pact_broker/client/pacts/list_latest_versions'
178
171
  result = PactBroker::Client::Pacts::ListLatestVersions.call(options.broker_base_url, options.output, pact_broker_client_options)
@@ -181,14 +174,13 @@ module PactBroker
181
174
  end
182
175
 
183
176
  if ENV.fetch("PACT_BROKER_FEATURES", "").include?("deployments")
184
-
185
177
  ignored_and_hidden_potential_options_from_environment_variables
186
178
  desc "record-deployment", "Record deployment of a pacticipant version to an environment. See https://docs.pact.io/go/record_deployment for more information."
187
179
  method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that was deployed."
188
180
  method_option :version, required: true, aliases: "-e", desc: "The pacticipant version number that was deployed."
189
181
  method_option :environment, required: true, desc: "The name of the environment that the pacticipant version was deployed to."
190
182
  method_option :target, default: nil, required: false, desc: "Optional. The target of the deployment - a logical identifer required to differentiate deployments when there are multiple instances of the same application in an environment."
191
- method_option :output, aliases: "-o", desc: "json or text", default: 'text'
183
+ output_option_json_or_text
192
184
  shared_authentication_options
193
185
 
194
186
  def record_deployment
@@ -214,7 +206,7 @@ module PactBroker
214
206
  method_option :pacticipant, required: true, aliases: "-a", desc: "The name of the pacticipant that was deployed."
215
207
  method_option :version, required: true, aliases: "-e", desc: "The pacticipant version number that was deployed."
216
208
  method_option :environment, required: true, desc: "The name of the environment that the pacticipant version was deployed to."
217
- method_option :output, aliases: "-o", desc: "json or text", default: 'text'
209
+ output_option_json_or_text
218
210
  shared_authentication_options
219
211
 
220
212
  def record_undeployment
@@ -347,7 +339,7 @@ module PactBroker
347
339
  end
348
340
 
349
341
  def pact_broker_client_options
350
- client_options = { verbose: options.verbose }
342
+ client_options = { verbose: options.verbose, pact_broker_base_url: options.broker_base_url }
351
343
  client_options[:token] = options.broker_token || ENV['PACT_BROKER_TOKEN']
352
344
  if options.broker_username || ENV['PACT_BROKER_USERNAME']
353
345
  client_options[:basic_auth] = {
@@ -110,6 +110,18 @@ module PactBroker
110
110
  def self.verbose_option
111
111
  method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
112
112
  end
113
+
114
+ def self.output_option_json_or_text
115
+ method_option :output, aliases: "-o", desc: "json or text", default: 'text'
116
+ end
117
+
118
+ def self.output_option_json_or_table
119
+ method_option :output, aliases: "-o", desc: "json or table", default: 'table'
120
+ end
121
+
122
+ def params_from_options(keys)
123
+ keys.each_with_object({}) { | key, p | p[key] = options[key] }
124
+ end
113
125
  end
114
126
  end
115
127
  end
@@ -0,0 +1,70 @@
1
+ module PactBroker
2
+ module Client
3
+ module CLI
4
+ module EnvironmentCommands
5
+ ENVIRONMENT_PARAM_NAMES = [:name, :display_name, :production, :contact_name, :contact_email_address]
6
+
7
+ def self.included(thor)
8
+ thor.class_eval do
9
+ def self.shared_environment_options(name_required: false)
10
+ method_option :name, required: name_required, desc: "The uniquely identifying name of the environment as used in deployment code"
11
+ method_option :display_name, desc: "The display name of the environment"
12
+ method_option :production, type: :boolean, default: false, desc: "Whether or not this environment is a production environment. Default: false"
13
+ method_option :contact_name, required: false, desc: "The name of the team/person responsible for this environment"
14
+ method_option :contact_email_address, required: false, desc: "The email address of the team/person responsible for this environment"
15
+ output_option_json_or_text
16
+ end
17
+
18
+ desc "create-environment", "Create an environment resource in the Pact Broker to represent a real world deployment or release environment."
19
+ shared_environment_options(name_required: true)
20
+ shared_authentication_options
21
+ def create_environment
22
+ execute_environment_command(params_from_options(ENVIRONMENT_PARAM_NAMES), "CreateEnvironment")
23
+ end
24
+
25
+ desc "update-environment", "Update an environment resource in the Pact Broker."
26
+ method_option :uuid, required: true, desc: "The UUID of the environment to update"
27
+ shared_environment_options(name_required: false)
28
+ shared_authentication_options
29
+ def update_environment
30
+ execute_environment_command(params_from_options(ENVIRONMENT_PARAM_NAMES + [:uuid]), "UpdateEnvironment")
31
+ end
32
+
33
+ desc "describe-environment", "Describe an environment"
34
+ method_option :uuid, required: true, desc: "The UUID of the environment to describe"
35
+ method_option :output, aliases: "-o", desc: "json or text", default: 'text'
36
+ shared_authentication_options
37
+ def describe_environment
38
+ execute_environment_command(params_from_options([:uuid]), "DescribeEnvironment")
39
+ end
40
+
41
+ desc "list-environments", "List environment"
42
+ method_option :output, aliases: "-o", desc: "json or text", default: 'text'
43
+ shared_authentication_options
44
+ def list_environments
45
+ execute_environment_command({}, "ListEnvironments")
46
+ end
47
+
48
+ desc "delete-environment", "Delete an environment"
49
+ method_option :uuid, required: true, desc: "The UUID of the environment to delete"
50
+ method_option :output, aliases: "-o", desc: "json or text", default: 'text'
51
+ shared_authentication_options
52
+ def delete_environment
53
+ execute_environment_command(params_from_options([:uuid]), "DeleteEnvironment")
54
+ end
55
+
56
+ no_commands do
57
+ def execute_environment_command(params, command_class_name)
58
+ require 'pact_broker/client/environments'
59
+ command_options = { verbose: options.verbose, output: options.output }
60
+ result = PactBroker::Client::Environments.const_get(command_class_name).call(params, command_options, pact_broker_client_options)
61
+ $stdout.puts result.message
62
+ exit(1) unless result.success
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,44 @@
1
+ module PactBroker
2
+ module Client
3
+ module CLI
4
+ module PacticipantCommands
5
+ PACTICIPANT_PARAM_NAMES = [:name, :display_name, :repository_url]
6
+
7
+ def self.included(thor)
8
+ thor.class_eval do
9
+ desc 'create-or-update-pacticipant', 'Create or update pacticipant by name'
10
+ method_option :name, type: :string, required: true, desc: "Pacticipant name"
11
+ method_option :display_name, type: :string, desc: "Display name"
12
+ method_option :repository_url, type: :string, required: false, desc: "The repository URL of the pacticipant"
13
+ output_option_json_or_text
14
+ shared_authentication_options
15
+ verbose_option
16
+
17
+ def create_or_update_pacticipant(*required_but_ignored)
18
+ raise ::Thor::RequiredArgumentMissingError, "Pacticipant name cannot be blank" if options.name.strip.size == 0
19
+ execute_pacticipant_command(params_from_options(PACTICIPANT_PARAM_NAMES), 'Create')
20
+ end
21
+
22
+ desc 'list-pacticipants', 'List pacticipants'
23
+ output_option_json_or_text
24
+ shared_authentication_options
25
+ verbose_option
26
+ def list_pacticipants
27
+ execute_pacticipant_command(params_from_options(PACTICIPANT_PARAM_NAMES), 'List')
28
+ end
29
+
30
+ no_commands do
31
+ def execute_pacticipant_command(params, command_class_name)
32
+ require 'pact_broker/client/pacticipants'
33
+ command_options = { verbose: options.verbose, output: options.output }
34
+ result = PactBroker::Client::Pacticipants2.const_get(command_class_name).call(params, command_options, pact_broker_client_options)
35
+ $stdout.puts result.message
36
+ exit(1) unless result.success
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(__FILE__.gsub(".rb", "/**/*.rb"))).sort.each do | path |
2
+ require path
3
+ end
@@ -0,0 +1,31 @@
1
+ require 'pact_broker/client/environments/environment_command'
2
+
3
+ module PactBroker
4
+ module Client
5
+ module Environments
6
+ class CreateEnvironment < PactBroker::Client::Environments::EnvironmentCommand
7
+
8
+ private
9
+
10
+ attr_reader :created_environment_resource
11
+
12
+ def do_call
13
+ @created_environment_resource = environments_link.post!(new_environment_body)
14
+ PactBroker::Client::CommandResult.new(created_environment_resource.success?, result_message)
15
+ end
16
+
17
+ def result_message
18
+ if json_output?
19
+ created_environment_resource.response.raw_body
20
+ else
21
+ ::Term::ANSIColor.green("Created #{params[:name]} environment in #{pact_broker_name} with UUID #{uuid}")
22
+ end
23
+ end
24
+
25
+ def uuid
26
+ created_environment_resource.uuid
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ require 'pact_broker/client/environments/environment_command'
2
+
3
+ module PactBroker
4
+ module Client
5
+ module Environments
6
+ class DeleteEnvironment < PactBroker::Client::Environments::EnvironmentCommand
7
+ private
8
+
9
+ attr_reader :deletion_request_resource
10
+
11
+ def do_call
12
+ existing_environment_resource!
13
+ @deletion_request_resource = existing_environment_link.delete!
14
+ PactBroker::Client::CommandResult.new(deletion_request_resource.success?, result_message)
15
+ end
16
+
17
+ def result_message
18
+ if json_output?
19
+ deletion_request_resource.response.raw_body
20
+ else
21
+ ::Term::ANSIColor.green("Deleted environment #{existing_environment_resource.name} from #{pact_broker_name}")
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ require 'pact_broker/client/environments/environment_command'
2
+ require 'pact_broker/client/generate_display_name'
3
+ require 'yaml'
4
+
5
+ module PactBroker
6
+ module Client
7
+ module Environments
8
+ class DescribeEnvironment < PactBroker::Client::Environments::EnvironmentCommand
9
+ include PactBroker::Client::GenerateDisplayName
10
+ private
11
+
12
+ def do_call
13
+ existing_environment_resource!
14
+ PactBroker::Client::CommandResult.new(true, result_message)
15
+ end
16
+
17
+ def result_message
18
+ if json_output?
19
+ existing_environment_resource.response.raw_body
20
+ else
21
+ YAML.dump(displayify_keys(existing_environment_resource.response.body.except("_links"))).gsub("---\n", "")
22
+ end
23
+ end
24
+
25
+ def displayify_keys(thing)
26
+ case thing
27
+ when Hash then thing.each_with_object({}) { | (key, value), new_hash | new_hash[generate_display_name(key)] = displayify_keys(value) }
28
+ when Array then thing.collect{ | value | displayify_keys(value) }
29
+ else
30
+ thing
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end