uffizzi-cli 0.6.0 → 0.8.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +20 -7
  3. data/exe/uffizzi +1 -1
  4. data/lib/uffizzi/auth_helper.rb +0 -4
  5. data/lib/uffizzi/cli/common.rb +2 -2
  6. data/lib/uffizzi/cli/config.rb +5 -11
  7. data/lib/uffizzi/cli/connect.rb +74 -27
  8. data/lib/uffizzi/cli/disconnect.rb +1 -1
  9. data/lib/uffizzi/cli/login.rb +2 -2
  10. data/lib/uffizzi/cli/logout.rb +1 -1
  11. data/lib/uffizzi/cli/preview/service.rb +8 -7
  12. data/lib/uffizzi/cli/preview.rb +90 -123
  13. data/lib/uffizzi/cli/project/compose.rb +14 -16
  14. data/lib/uffizzi/cli/project/secret.rb +19 -8
  15. data/lib/uffizzi/cli/project.rb +31 -7
  16. data/lib/uffizzi/cli.rb +15 -23
  17. data/lib/uffizzi/clients/api/api_client.rb +67 -22
  18. data/lib/uffizzi/clients/api/api_routes.rb +8 -0
  19. data/lib/uffizzi/clients/api/http_client.rb +47 -45
  20. data/lib/uffizzi/config_file.rb +9 -5
  21. data/lib/uffizzi/date_helper.rb +45 -0
  22. data/lib/uffizzi/response_helper.rb +11 -7
  23. data/lib/uffizzi/services/command_service.rb +9 -0
  24. data/lib/uffizzi/services/compose_file_service.rb +3 -0
  25. data/lib/uffizzi/services/preview_service.rb +97 -0
  26. data/lib/uffizzi/version.rb +1 -1
  27. data/man/uffizzi-connect +37 -0
  28. data/man/uffizzi-connect-acr +35 -0
  29. data/man/uffizzi-connect-acr.ronn +28 -0
  30. data/man/uffizzi-connect-docker-hub +34 -0
  31. data/man/uffizzi-connect-docker-hub.ronn +27 -0
  32. data/man/uffizzi-connect-ecr +35 -0
  33. data/man/uffizzi-connect-ecr.ronn +28 -0
  34. data/man/uffizzi-connect-gcr +40 -0
  35. data/man/uffizzi-connect-gcr.ronn +32 -0
  36. data/man/uffizzi-connect-ghcr +35 -0
  37. data/man/uffizzi-connect-ghcr.ronn +28 -0
  38. data/man/uffizzi-connect.ronn +31 -0
  39. data/man/uffizzi-disconnect +37 -0
  40. data/man/uffizzi-disconnect.ronn +31 -0
  41. data/man/uffizzi-login +1 -1
  42. data/man/uffizzi-login.ronn +1 -1
  43. data/man/uffizzi-preview-update +34 -0
  44. data/man/uffizzi-preview-update.ronn +33 -0
  45. data/man/uffizzi-project-set-default +34 -0
  46. data/man/uffizzi-project-set-default.html +111 -0
  47. data/man/uffizzi-project-set-default.ronn +26 -0
  48. metadata +23 -2
@@ -8,153 +8,197 @@ module ApiClient
8
8
 
9
9
  def create_session(server, params = {})
10
10
  uri = session_uri(server)
11
- response = Uffizzi::HttpClient.make_post_request(uri, params, false)
11
+ response = http_client.make_post_request(uri, params)
12
12
 
13
13
  build_response(response)
14
14
  end
15
15
 
16
16
  def destroy_session(server)
17
17
  uri = session_uri(server)
18
- response = Uffizzi::HttpClient.make_delete_request(uri)
18
+ response = http_client.make_delete_request(uri)
19
19
 
20
20
  build_response(response)
21
21
  end
22
22
 
23
23
  def fetch_projects(server)
24
24
  uri = projects_uri(server)
25
- response = Uffizzi::HttpClient.make_get_request(uri)
25
+ response = http_client.make_get_request(uri)
26
+
27
+ build_response(response)
28
+ end
29
+
30
+ def fetch_credentials(server)
31
+ uri = credentials_uri(server)
32
+
33
+ response = http_client.make_get_request(uri)
34
+
35
+ build_response(response)
36
+ end
37
+
38
+ def check_credential(server, type)
39
+ uri = check_credential_uri(server, type)
40
+ response = http_client.make_get_request(uri)
41
+
42
+ build_response(response)
43
+ end
44
+
45
+ def describe_project(server, project_slug)
46
+ uri = project_uri(server, project_slug)
47
+ response = http_client.make_get_request(uri)
26
48
 
27
49
  build_response(response)
28
50
  end
29
51
 
30
52
  def create_credential(server, params)
31
53
  uri = credentials_uri(server)
32
- response = Uffizzi::HttpClient.make_post_request(uri, params)
54
+ response = http_client.make_post_request(uri, params)
33
55
 
34
56
  build_response(response)
35
57
  end
36
58
 
37
59
  def fetch_deployment_services(server, project_slug, deployment_id)
38
60
  uri = preview_services_uri(server, project_slug, deployment_id)
39
- response = Uffizzi::HttpClient.make_get_request(uri)
61
+ response = http_client.make_get_request(uri)
40
62
 
41
63
  build_response(response)
42
64
  end
43
65
 
44
66
  def delete_credential(server, credential_type)
45
67
  uri = delete_credential_uri(server, credential_type)
46
- response = Uffizzi::HttpClient.make_delete_request(uri)
68
+ response = http_client.make_delete_request(uri)
47
69
 
48
70
  build_response(response)
49
71
  end
50
72
 
51
73
  def fetch_deployment_service_logs(server, project_slug, deployment_id, container_name)
52
74
  uri = preview_service_logs_uri(server, project_slug, deployment_id, container_name)
53
- response = Uffizzi::HttpClient.make_get_request(uri)
75
+ response = http_client.make_get_request(uri)
54
76
 
55
77
  build_response(response)
56
78
  end
57
79
 
58
80
  def set_compose_file(server, params, project_slug)
59
81
  uri = compose_file_uri(server, project_slug)
60
- response = Uffizzi::HttpClient.make_post_request(uri, params)
82
+ response = http_client.make_post_request(uri, params)
61
83
 
62
84
  build_response(response)
63
85
  end
64
86
 
65
87
  def unset_compose_file(server, project_slug)
66
88
  uri = compose_file_uri(server, project_slug)
67
- response = Uffizzi::HttpClient.make_delete_request(uri)
89
+ response = http_client.make_delete_request(uri)
68
90
 
69
91
  build_response(response)
70
92
  end
71
93
 
72
94
  def fetch_secrets(server, project_slug)
73
95
  uri = secrets_uri(server, project_slug)
74
- response = Uffizzi::HttpClient.make_get_request(uri)
96
+ response = http_client.make_get_request(uri)
75
97
 
76
98
  build_response(response)
77
99
  end
78
100
 
79
101
  def bulk_create_secrets(server, project_slug, params)
80
102
  uri = "#{secrets_uri(server, project_slug)}/bulk_create"
81
- response = Uffizzi::HttpClient.make_post_request(uri, params)
103
+ response = http_client.make_post_request(uri, params)
82
104
 
83
105
  build_response(response)
84
106
  end
85
107
 
86
108
  def delete_secret(server, project_slug, id)
87
109
  uri = secret_uri(server, project_slug, id)
88
- response = Uffizzi::HttpClient.make_delete_request(uri)
110
+ response = http_client.make_delete_request(uri)
89
111
 
90
112
  build_response(response)
91
113
  end
92
114
 
93
115
  def describe_compose_file(server, project_slug)
94
116
  uri = compose_file_uri(server, project_slug)
95
- response = Uffizzi::HttpClient.make_get_request(uri)
117
+ response = http_client.make_get_request(uri)
96
118
 
97
119
  build_response(response)
98
120
  end
99
121
 
100
122
  def validate_compose_file(server, project_slug)
101
123
  uri = validate_compose_file_uri(server, project_slug)
102
- response = Uffizzi::HttpClient.make_get_request(uri)
124
+ response = http_client.make_get_request(uri)
103
125
 
104
126
  build_response(response)
105
127
  end
106
128
 
107
129
  def fetch_deployments(server, project_slug)
108
130
  uri = deployments_uri(server, project_slug)
109
- response = Uffizzi::HttpClient.make_get_request(uri)
131
+ response = http_client.make_get_request(uri)
110
132
 
111
133
  build_response(response)
112
134
  end
113
135
 
114
136
  def create_deployment(server, project_slug, params)
115
137
  uri = deployments_uri(server, project_slug)
116
- response = Uffizzi::HttpClient.make_post_request(uri, params)
138
+ response = http_client.make_post_request(uri, params)
139
+
140
+ build_response(response)
141
+ end
142
+
143
+ def update_deployment(server, project_slug, deployment_id, params)
144
+ uri = deployment_uri(server, project_slug, deployment_id)
145
+ response = http_client.make_put_request(uri, params)
117
146
 
118
147
  build_response(response)
119
148
  end
120
149
 
121
150
  def delete_deployment(server, project_slug, deployment_id)
122
151
  uri = deployment_uri(server, project_slug, deployment_id)
123
- response = Uffizzi::HttpClient.make_delete_request(uri)
152
+ response = http_client.make_delete_request(uri)
124
153
 
125
154
  build_response(response)
126
155
  end
127
156
 
128
157
  def describe_deployment(server, project_slug, deployment_id)
129
158
  uri = deployment_uri(server, project_slug, deployment_id)
130
- response = Uffizzi::HttpClient.make_get_request(uri)
159
+ response = http_client.make_get_request(uri)
131
160
 
132
161
  build_response(response)
133
162
  end
134
163
 
135
164
  def fetch_events(server, project_slug, deployment_id)
136
165
  uri = events_uri(server, project_slug, deployment_id)
137
- response = Uffizzi::HttpClient.make_get_request(uri)
166
+ response = http_client.make_get_request(uri)
138
167
 
139
168
  build_response(response)
140
169
  end
141
170
 
142
171
  def get_activity_items(server, project_slug, deployment_id)
143
172
  uri = activity_items_uri(server, project_slug, deployment_id)
144
- response = Uffizzi::HttpClient.make_get_request(uri)
173
+ response = http_client.make_get_request(uri)
145
174
 
146
175
  build_response(response)
147
176
  end
148
177
 
149
178
  def deploy_containers(server, project_slug, deployment_id, params)
150
179
  uri = deploy_containers_uri(server, project_slug, deployment_id)
151
- response = Uffizzi::HttpClient.make_post_request(uri, params)
180
+ response = http_client.make_post_request(uri, params)
152
181
 
153
182
  build_response(response)
154
183
  end
155
184
 
156
185
  private
157
186
 
187
+ def http_client
188
+ if @http_client.nil?
189
+ params = {}
190
+ if Uffizzi::ConfigFile.exists?
191
+ params[:cookie] = Uffizzi::ConfigFile.read_option(:cookie)
192
+ params[:basic_auth_user] = Uffizzi::ConfigFile.read_option(:basic_auth_user)
193
+ params[:basic_auth_password] = Uffizzi::ConfigFile.read_option(:basic_auth_password)
194
+ end
195
+
196
+ @http_client = Uffizzi::HttpClient.new(params[:cookie], params[:basic_auth_user], params[:basic_auth_password])
197
+ end
198
+
199
+ @http_client
200
+ end
201
+
158
202
  def build_response(response)
159
203
  {
160
204
  body: response_body(response),
@@ -164,7 +208,7 @@ module ApiClient
164
208
  end
165
209
 
166
210
  def response_body(response)
167
- return nil if response.body.nil?
211
+ return nil if response.body.nil? || response.body.empty?
168
212
 
169
213
  JSON.parse(response.body, symbolize_names: true)
170
214
  rescue JSON::ParserError
@@ -178,6 +222,7 @@ module ApiClient
178
222
  cookie_content = cookies.first
179
223
  cookie = cookie_content.split(';').first
180
224
  Uffizzi::ConfigFile.rewrite_cookie(cookie) if Uffizzi::ConfigFile.exists?
225
+ http_client.auth_cookie = cookie
181
226
 
182
227
  cookie
183
228
  end
@@ -7,6 +7,10 @@ module ApiRoutes
7
7
  "#{server}/api/cli/v1/projects/#{project_slug}/compose_file"
8
8
  end
9
9
 
10
+ def project_uri(server, project_slug)
11
+ "#{server}/api/cli/v1/projects/#{project_slug}"
12
+ end
13
+
10
14
  def projects_uri(server)
11
15
  "#{server}/api/cli/v1/projects"
12
16
  end
@@ -48,6 +52,10 @@ module ApiRoutes
48
52
  "#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/events"
49
53
  end
50
54
 
55
+ def check_credential_uri(server, type)
56
+ "#{server}/api/cli/v1/account/credentials/#{type}/check_credential"
57
+ end
58
+
51
59
  def credentials_uri(server)
52
60
  "#{server}/api/cli/v1/account/credentials"
53
61
  end
@@ -2,67 +2,69 @@
2
2
 
3
3
  require 'net/http'
4
4
  require 'json'
5
- require 'uffizzi/config_file'
6
- require 'uffizzi/response_helper'
7
5
 
8
6
  module Uffizzi
9
7
  class HttpClient
10
- class << self
11
- def make_get_request(request_uri, cookies_required = true)
12
- make_request(:get, request_uri, cookies_required)
13
- end
8
+ attr_accessor :auth_cookie, :basic_auth_user, :basic_auth_password
14
9
 
15
- def make_post_request(request_uri, params = {}, cookies_required = true)
16
- make_request(:post, request_uri, cookies_required, params)
17
- end
10
+ def initialize(auth_cookie, basic_auth_user, basic_auth_password)
11
+ @auth_cookie = auth_cookie
12
+ @basic_auth_user = basic_auth_user
13
+ @basic_auth_password = basic_auth_password
14
+ end
18
15
 
19
- def make_put_request(request_uri, cookies_required = true)
20
- make_request(:put, request_uri, cookies_required)
21
- end
16
+ def make_get_request(request_uri)
17
+ make_request(:get, request_uri)
18
+ end
22
19
 
23
- def make_delete_request(request_uri, cookies_required = true)
24
- make_request(:delete, request_uri, cookies_required)
25
- end
20
+ def make_post_request(request_uri, params = {})
21
+ make_request(:post, request_uri, params)
22
+ end
26
23
 
27
- private
24
+ def make_put_request(request_uri, params = {})
25
+ make_request(:put, request_uri, params)
26
+ end
28
27
 
29
- def make_request(method, request_uri, require_cookies, params = {})
30
- uri = URI(request_uri)
31
- use_ssl = request_uri.start_with?('https')
28
+ def make_delete_request(request_uri)
29
+ make_request(:delete, request_uri)
30
+ end
32
31
 
33
- response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
34
- request = build_request(uri, params, method, require_cookies)
32
+ private
35
33
 
36
- http.request(request)
37
- end
34
+ def make_request(method, request_uri, params = {})
35
+ uri = URI(request_uri)
36
+ use_ssl = request_uri.start_with?('https')
38
37
 
39
- raise Uffizzi::Error.new('Not authorized') if response.is_a?(Net::HTTPUnauthorized)
38
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
39
+ request = build_request(uri, params, method)
40
40
 
41
- response
41
+ http.request(request)
42
42
  end
43
43
 
44
- def build_request(uri, params, method, require_cookies)
45
- headers = { 'Content-Type' => 'application/json' }
46
- request = case method
47
- when :get
48
- Net::HTTP::Get.new(uri.path, headers)
49
- when :post
50
- Net::HTTP::Post.new(uri.path, headers)
51
- when :delete
52
- Net::HTTP::Delete.new(uri.path, headers)
53
- when :put
54
- Net::HTTP::Put.new(uri.path, headers)
55
- end
56
- if request.instance_of?(Net::HTTP::Post)
57
- request.body = params.to_json
58
- end
59
- request['Cookie'] = ConfigFile.read_option(:cookie) if require_cookies
60
- if ConfigFile.exists? && ConfigFile.option_has_value?(:basic_auth_user) && ConfigFile.option_has_value?(:basic_auth_password)
61
- request.basic_auth(ConfigFile.read_option(:basic_auth_user), ConfigFile.read_option(:basic_auth_password))
62
- end
44
+ raise Uffizzi::Error.new('Not authorized') if response.is_a?(Net::HTTPUnauthorized)
45
+
46
+ response
47
+ end
63
48
 
64
- request
49
+ def build_request(uri, params, method)
50
+ headers = { 'Content-Type' => 'application/json' }
51
+ request = case method
52
+ when :get
53
+ Net::HTTP::Get.new(uri.path, headers)
54
+ when :post
55
+ Net::HTTP::Post.new(uri.path, headers)
56
+ when :delete
57
+ Net::HTTP::Delete.new(uri.path, headers)
58
+ when :put
59
+ Net::HTTP::Put.new(uri.path, headers)
60
+ end
61
+ if request.instance_of?(Net::HTTP::Post) || request.instance_of?(Net::HTTP::Put)
62
+ request.body = params.to_json
65
63
  end
64
+ request['Cookie'] = @auth_cookie
65
+ request.basic_auth(@basic_auth_user, @basic_auth_password)
66
+
67
+ request
66
68
  end
67
69
  end
68
70
  end
@@ -8,17 +8,21 @@ module Uffizzi
8
8
  CONFIG_PATH = "#{Dir.home}/.config/uffizzi/config_default.json"
9
9
 
10
10
  class << self
11
+ def config_path
12
+ CONFIG_PATH
13
+ end
14
+
11
15
  def create(account_id, cookie, server)
12
16
  data = prepare_config_data(account_id, cookie, server)
13
17
  data.each_pair { |key, value| write_option(key, value) }
14
18
  end
15
19
 
16
20
  def delete
17
- File.delete(CONFIG_PATH) if exists?
21
+ File.delete(config_path) if exists?
18
22
  end
19
23
 
20
24
  def exists?
21
- File.exist?(CONFIG_PATH)
25
+ File.exist?(config_path)
22
26
  end
23
27
 
24
28
  def read_option(option)
@@ -79,7 +83,7 @@ module Uffizzi
79
83
  end
80
84
 
81
85
  def read
82
- data = File.read(CONFIG_PATH)
86
+ data = File.read(config_path)
83
87
  options = data.split("\n")
84
88
  options.reduce({}) do |acc, option|
85
89
  key, value = option.split('=', 2)
@@ -112,11 +116,11 @@ module Uffizzi
112
116
  end
113
117
 
114
118
  def create_file
115
- dir = File.dirname(CONFIG_PATH)
119
+ dir = File.dirname(config_path)
116
120
 
117
121
  FileUtils.mkdir_p(dir) unless File.directory?(dir)
118
122
 
119
- File.new(CONFIG_PATH, 'w')
123
+ File.new(config_path, 'w')
120
124
  end
121
125
  end
122
126
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Uffizzi
6
+ module DateHelper
7
+ TWO_MINUTES = 120
8
+ TWO_HOURS = 120
9
+ TWO_DAYS = 48
10
+ TWO_WEEKS = 14
11
+ TWO_MONTHS = (365 / 12 * 2)
12
+ TWO_YEARS = 730
13
+
14
+ class << self
15
+ def count_distanse(now, previous_date)
16
+ seconds = (now - previous_date).round
17
+ return convert_to_words(seconds, 'seconds') if seconds < TWO_MINUTES
18
+
19
+ minutes = seconds / 60
20
+ return convert_to_words(minutes, 'minutes') if minutes < TWO_HOURS
21
+
22
+ hours = minutes / 60
23
+ return convert_to_words(hours, 'hours') if hours < TWO_DAYS
24
+
25
+ days = hours / 24
26
+ return convert_to_words(days, 'days') if days < TWO_WEEKS
27
+
28
+ weeks = days / 7
29
+ return convert_to_words(weeks, 'weeks') if days < TWO_MONTHS
30
+
31
+ months = (days / (365 / 12)).round
32
+ return convert_to_words(months, 'months') if days < TWO_YEARS
33
+
34
+ years = days / 365
35
+ convert_to_words(years, 'years')
36
+ end
37
+
38
+ private
39
+
40
+ def convert_to_words(value, unit)
41
+ "#{value} #{unit} ago"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -28,22 +28,26 @@ module Uffizzi
28
28
  end
29
29
 
30
30
  def handle_failed_response(response)
31
- print_errors(response[:body][:errors])
31
+ prepared_errors = prepare_errors(response[:body][:errors])
32
+ raise Uffizzi::Error.new(prepared_errors)
32
33
  end
33
34
 
34
35
  def handle_invalid_compose_response(response)
35
- print_errors(response[:body][:compose_file][:payload][:errors])
36
+ prepared_errors = prepare_errors(response[:body][:compose_file][:payload][:errors])
37
+ raise Uffizzi::Error.new(prepared_errors)
36
38
  end
37
39
 
38
40
  private
39
41
 
40
- def print_errors(errors)
41
- errors.each_key do |key|
42
- if errors[key].is_a?(Array)
43
- errors[key].each { |error_message| Uffizzi.ui.say(error_message) }
42
+ def prepare_errors(errors)
43
+ errors.values.reduce('') do |acc, error_messages|
44
+ if error_messages.is_a?(Array)
45
+ error_messages.each { |error_message| acc = "#{acc}#{error_message}\n" }
44
46
  else
45
- Uffizzi.ui.say(errors[key])
47
+ acc = "#{acc}#{error_messages}\n"
46
48
  end
49
+
50
+ acc
47
51
  end
48
52
  end
49
53
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CommandService
4
+ class << self
5
+ def project_set?(options)
6
+ !options[:project].nil? || (Uffizzi::ConfigFile.exists? && Uffizzi::ConfigFile.option_has_value?(:project))
7
+ end
8
+ end
9
+ end
@@ -29,6 +29,9 @@ class ComposeFileService
29
29
  content: Base64.encode64(dependency_file_data),
30
30
  }
31
31
  end
32
+ rescue Errno::ENOENT => e
33
+ dependency_path = e.message.split('- ').last
34
+ raise Uffizzi::Error.new("The config file #{dependency_path} does not exist")
32
35
  end
33
36
 
34
37
  def fetch_configs(configs_data)
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uffizzi/clients/api/api_client'
4
+
3
5
  class PreviewService
4
6
  class << self
7
+ include ApiClient
8
+
5
9
  def read_deployment_id(deployment_name)
6
10
  return nil unless deployment_name.start_with?('deployment-')
7
11
  return nil unless deployment_name.split('-').size == 2
@@ -11,5 +15,98 @@ class PreviewService
11
15
 
12
16
  deployment_id
13
17
  end
18
+
19
+ def run_containers_deploy(project_slug, deployment)
20
+ deployment_id = deployment[:id]
21
+ params = { id: deployment_id }
22
+
23
+ response = deploy_containers(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment_id, params)
24
+
25
+ if !Uffizzi::ResponseHelper.no_content?(response)
26
+ Uffizzi::ResponseHelper.handle_failed_response(response)
27
+ end
28
+
29
+ activity_items = wait_containers_creation(deployment, project_slug)
30
+ wait_containers_deploy(deployment, project_slug, activity_items)
31
+ end
32
+
33
+ private
34
+
35
+ def wait_containers_creation(deployment, project_slug)
36
+ spinner = TTY::Spinner.new('[:spinner] Creating containers...', format: :dots)
37
+ spinner.auto_spin
38
+
39
+ activity_items = []
40
+ loop do
41
+ response = get_activity_items(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment[:id])
42
+ handle_activity_items_response(response, spinner)
43
+ activity_items = response[:body][:activity_items]
44
+ break if activity_items.count == deployment[:containers].count
45
+
46
+ sleep(5)
47
+ end
48
+
49
+ spinner.success
50
+
51
+ Uffizzi.ui.say('Done')
52
+
53
+ activity_items
54
+ end
55
+
56
+ def wait_containers_deploy(deployment, project_slug, activity_items)
57
+ spinner = TTY::Spinner::Multi.new('[:spinner] Deploying preview...', format: :dots, style: {
58
+ middle: ' ',
59
+ bottom: ' ',
60
+ })
61
+
62
+ containers_spinners = create_containers_spinners(activity_items, spinner)
63
+
64
+ loop do
65
+ response = get_activity_items(Uffizzi::ConfigFile.read_option(:server), project_slug, deployment[:id])
66
+ handle_activity_items_response(response, spinner)
67
+ activity_items = response[:body][:activity_items]
68
+ update_containers_spinners!(activity_items, containers_spinners)
69
+ break if activity_items.all? { |activity_item| activity_item[:state] == 'deployed' || activity_item[:state] == 'failed' }
70
+
71
+ sleep(5)
72
+ end
73
+
74
+ spinner.success?
75
+ end
76
+
77
+ def create_containers_spinners(activity_items, spinner)
78
+ activity_items.map do |activity_item|
79
+ container_spinner = spinner.register("[:spinner] #{activity_item[:name]}")
80
+ container_spinner.auto_spin
81
+ {
82
+ name: activity_item[:name],
83
+ spinner: container_spinner,
84
+ }
85
+ end
86
+ end
87
+
88
+ def update_containers_spinners!(activity_items, containers_spinners)
89
+ finished_activity_items = activity_items.filter do |activity_item|
90
+ activity_item[:state] == 'deployed' || activity_item[:state] == 'failed'
91
+ end
92
+
93
+ finished_activity_items.each do |activity_item|
94
+ container_spinner = containers_spinners.detect { |spinner| spinner[:name] == activity_item[:name] }
95
+ spinner = container_spinner[:spinner]
96
+ case activity_item[:state]
97
+ when 'deployed'
98
+ spinner.success
99
+ when 'failed'
100
+ spinner.error
101
+ end
102
+ end
103
+ end
104
+
105
+ def handle_activity_items_response(response, spinner)
106
+ unless Uffizzi::ResponseHelper.ok?(response)
107
+ spinner.error
108
+ Uffizzi::ResponseHelper.handle_failed_response(response)
109
+ end
110
+ end
14
111
  end
15
112
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '0.6.0'
4
+ VERSION = '0.8.0'
5
5
  end
@@ -0,0 +1,37 @@
1
+ .\" generated with Ronn-NG/v0.9.1
2
+ .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
+ .TH "UFFIZZI\-CONNECT" "" "April 2022" ""
4
+ .SH "NAME"
5
+ \fBuffizzi\-connect\fR \- grant a Uffizzi user account access to external services
6
+ .SH "SYNOPSIS"
7
+ .nf
8
+ uffizzi connect COMMAND
9
+ .fi
10
+ .SH "DESCRIPTION"
11
+ .nf
12
+ Grants a Uffizzi user account access to external services
13
+
14
+ For more information on connecting to external services, see:
15
+ https://docs\.uffizzi\.com/cli
16
+ .fi
17
+ .SH "COMMANDS"
18
+ .nf
19
+ COMMAND is one of the following:
20
+
21
+ acr
22
+ Connect to Azure Container Registry (azurecr\.io)\.
23
+
24
+ docker\-hub
25
+ Connect to Docker Hub (hub\.docker\.com)\.
26
+
27
+ ecr
28
+ Connect to Amazon Elastic Container Registry (amazonaws\.com)\.
29
+
30
+ gcr
31
+ Connect to Google Container Registry (gcr\.io)\.
32
+
33
+ gchr
34
+ Connect to GitHub Container Registry (ghcr\.io)\.
35
+ .fi
36
+ .P
37
+ Run \'uffizzi connect COMMAND \-\-help\' for more information on a command\.