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
@@ -3,39 +3,43 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/services/preview_service'
6
+ require 'uffizzi/services/command_service'
6
7
 
7
8
  module Uffizzi
8
- class CLI::Preview < Thor
9
+ class Cli::Preview < Thor
9
10
  include ApiClient
10
11
 
11
- @spinner
12
-
13
- desc 'service', 'service'
12
+ desc 'service', 'Show the preview services info'
14
13
  require_relative 'preview/service'
15
- subcommand 'service', Uffizzi::CLI::Preview::Service
16
-
17
- desc 'list', 'list'
14
+ subcommand 'service', Uffizzi::Cli::Preview::Service
15
+ desc 'list', 'List all previews'
18
16
  def list
19
17
  run('list')
20
18
  end
21
19
 
22
- desc 'create [COMPOSE_FILE]', 'create'
20
+ desc 'create [COMPOSE_FILE]', 'Create a preview'
23
21
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
24
22
  def create(file_path = nil)
25
23
  run('create', file_path: file_path)
26
24
  end
27
25
 
28
- desc 'delete [DEPLOYMENT_ID]', 'delete'
26
+ desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a preview'
27
+ method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
28
+ def update(deployment_name, file_path)
29
+ run('update', deployment_name: deployment_name, file_path: file_path)
30
+ end
31
+
32
+ desc 'delete [DEPLOYMENT_ID]', 'Delete a preview'
29
33
  def delete(deployment_name)
30
34
  run('delete', deployment_name: deployment_name)
31
35
  end
32
36
 
33
- desc 'describe [DEPLOYMENT_ID]', 'describe'
37
+ desc 'describe [DEPLOYMENT_ID]', 'Display details of a preview'
34
38
  def describe(deployment_name)
35
39
  run('describe', deployment_name: deployment_name)
36
40
  end
37
41
 
38
- desc 'events [DEPLOYMENT_ID]', 'events'
42
+ desc 'events [DEPLOYMENT_ID]', 'Show the deployment event logs for a preview'
39
43
  def events(deployment_name)
40
44
  run('events', deployment_name: deployment_name)
41
45
  end
@@ -48,7 +52,7 @@ module Uffizzi
48
52
  Uffizzi.ui.disable_stdout
49
53
  end
50
54
  raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
51
- raise Uffizzi::Error.new('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?(options)
55
+ raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
52
56
 
53
57
  project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
54
58
 
@@ -57,6 +61,8 @@ module Uffizzi
57
61
  handle_list_command(project_slug)
58
62
  when 'create'
59
63
  handle_create_command(file_path, project_slug)
64
+ when 'update'
65
+ handle_update_command(deployment_name, file_path, project_slug)
60
66
  when 'delete'
61
67
  handle_delete_command(deployment_name, project_slug)
62
68
  when 'describe'
@@ -80,133 +86,63 @@ module Uffizzi
80
86
  params = file_path.nil? ? {} : prepare_params(file_path)
81
87
  response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
82
88
 
83
- if ResponseHelper.created?(response)
84
- handle_succeed_create_response(project_slug, response)
85
- else
86
- ResponseHelper.handle_failed_response(response)
87
- end
88
- end
89
-
90
- def handle_events_command(deployment_name, project_slug)
91
- deployment_id = PreviewService.read_deployment_id(deployment_name)
92
-
93
- return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
94
-
95
- response = fetch_events(ConfigFile.read_option(:server), project_slug, deployment_id)
96
-
97
- if ResponseHelper.ok?(response)
98
- handle_succeed_events_response(response)
99
- else
89
+ if !ResponseHelper.created?(response)
100
90
  ResponseHelper.handle_failed_response(response)
101
91
  end
102
- end
103
-
104
- def handle_succeed_events_response(response)
105
- Uffizzi.ui.pretty_say(response[:body][:events])
106
- end
107
92
 
108
- def handle_succeed_create_response(project_slug, response)
109
93
  deployment = response[:body][:deployment]
110
- deployment_id = deployment[:id]
111
- params = { id: deployment_id }
94
+ Uffizzi.ui.say("Preview created with name deployment-#{deployment[:id]}")
112
95
 
113
- response = deploy_containers(ConfigFile.read_option(:server), project_slug, deployment_id, params)
96
+ success = PreviewService.run_containers_deploy(project_slug, deployment)
114
97
 
115
- if ResponseHelper.no_content?(response)
116
- Uffizzi.ui.say("Preview created with name deployment-#{deployment_id}")
117
- print_deployment_progress(deployment, project_slug)
118
- else
119
- ResponseHelper.handle_failed_response(response)
120
- end
98
+ display_deployment_data(deployment, success)
99
+ rescue SystemExit, Interrupt, SocketError
100
+ deployment_id = response[:body][:deployment][:id]
101
+ handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
121
102
  end
122
103
 
123
- def print_deployment_progress(deployment, project_slug)
124
- deployment_id = deployment[:id]
125
-
126
- @spinner = TTY::Spinner.new('[:spinner] Creating containers...', format: :dots)
127
- @spinner.auto_spin
128
-
129
- activity_items = []
104
+ def handle_update_command(deployment_name, file_path, project_slug)
105
+ deployment_id = PreviewService.read_deployment_id(deployment_name)
130
106
 
131
- loop do
132
- response = get_activity_items(ConfigFile.read_option(:server), project_slug, deployment_id)
133
- handle_activity_items_response(response)
134
- return unless @spinner.spinning?
107
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
135
108
 
136
- activity_items = response[:body][:activity_items]
137
- break if !activity_items.empty? && activity_items.count == deployment[:containers].count
109
+ params = prepare_params(file_path)
110
+ response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
138
111
 
139
- sleep(5)
112
+ if !ResponseHelper.ok?(response)
113
+ ResponseHelper.handle_failed_response(response)
140
114
  end
141
115
 
142
- @spinner.success
143
-
144
- Uffizzi.ui.say('Done')
145
-
146
- @spinner = TTY::Spinner::Multi.new('[:spinner] Deploying preview...', format: :dots, style: {
147
- middle: ' ',
148
- bottom: ' ',
149
- })
150
-
151
- containers_spinners = create_containers_spinners(activity_items)
116
+ deployment = response[:body][:deployment]
117
+ Uffizzi.ui.say("Preview with ID deployment-#{deployment_id} was successfully updated.")
152
118
 
153
- wait_containers_deploying(project_slug, deployment_id, containers_spinners)
119
+ success = PreviewService.run_containers_deploy(project_slug, deployment)
154
120
 
155
- if options[:output].nil?
156
- Uffizzi.ui.say('Done')
157
- preview_url = "https://#{deployment[:preview_url]}"
158
- Uffizzi.ui.say(preview_url) if @spinner.success?
159
- else
160
- output_data = build_output_data(deployment)
161
- Uffizzi.ui.output(output_data)
162
- end
121
+ display_deployment_data(deployment, success)
163
122
  end
164
123
 
165
- def wait_containers_deploying(project_slug, deployment_id, containers_spinners)
166
- loop do
167
- response = get_activity_items(ConfigFile.read_option(:server), project_slug, deployment_id)
168
- handle_activity_items_response(response)
169
- return if @spinner.done?
124
+ def handle_events_command(deployment_name, project_slug)
125
+ deployment_id = PreviewService.read_deployment_id(deployment_name)
170
126
 
171
- activity_items = response[:body][:activity_items]
172
- check_activity_items_state(activity_items, containers_spinners)
173
- break if activity_items.all? { |activity_item| activity_item[:state] == 'deployed' || activity_item[:state] == 'failed' }
127
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
174
128
 
175
- sleep(5)
176
- end
177
- end
129
+ response = fetch_events(ConfigFile.read_option(:server), project_slug, deployment_id)
178
130
 
179
- def create_containers_spinners(activity_items)
180
- activity_items.map do |activity_item|
181
- container_spinner = @spinner.register("[:spinner] #{activity_item[:name]}")
182
- container_spinner.auto_spin
183
- {
184
- name: activity_item[:name],
185
- spinner: container_spinner,
186
- }
131
+ if ResponseHelper.ok?(response)
132
+ handle_succeed_events_response(response)
133
+ else
134
+ ResponseHelper.handle_failed_response(response)
187
135
  end
188
136
  end
189
137
 
190
- def check_activity_items_state(activity_items, containers_spinners)
191
- finished_activity_items = activity_items.filter do |activity_item|
192
- activity_item[:state] == 'deployed' || activity_item[:state] == 'failed'
193
- end
194
- finished_activity_items.each do |activity_item|
195
- container_spinner = containers_spinners.detect { |spinner| spinner[:name] == activity_item[:name] }
196
- spinner = container_spinner[:spinner]
197
- case activity_item[:state]
198
- when 'deployed'
199
- spinner.success
200
- when 'failed'
201
- spinner.error
202
- end
203
- end
138
+ def handle_succeed_events_response(response)
139
+ Uffizzi.ui.pretty_say(response[:body][:events])
204
140
  end
205
141
 
206
142
  def handle_delete_command(deployment_name, project_slug)
207
143
  deployment_id = PreviewService.read_deployment_id(deployment_name)
208
144
 
209
- return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
145
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
210
146
 
211
147
  response = delete_deployment(ConfigFile.read_option(:server), project_slug, deployment_id)
212
148
 
@@ -220,7 +156,7 @@ module Uffizzi
220
156
  def handle_describe_command(deployment_name, project_slug)
221
157
  deployment_id = PreviewService.read_deployment_id(deployment_name)
222
158
 
223
- return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
159
+ raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
224
160
 
225
161
  response = describe_deployment(ConfigFile.read_option(:server), project_slug, deployment_id)
226
162
 
@@ -231,16 +167,9 @@ module Uffizzi
231
167
  end
232
168
  end
233
169
 
234
- def handle_activity_items_response(response)
235
- unless ResponseHelper.ok?(response)
236
- @spinner.error
237
- ResponseHelper.handle_failed_response(response)
238
- end
239
- end
240
-
241
170
  def handle_succeed_list_response(response)
242
171
  deployments = response[:body][:deployments] || []
243
- return Uffizzi.ui.say('The project has no active deployments') if deployments.empty?
172
+ raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
244
173
 
245
174
  deployments.each do |deployment|
246
175
  Uffizzi.ui.say("deployment-#{deployment[:id]}")
@@ -253,11 +182,26 @@ module Uffizzi
253
182
 
254
183
  def handle_succeed_describe_response(response)
255
184
  deployment = response[:body][:deployment]
185
+ deployment[:containers] = deployment[:containers].map do |container|
186
+ unless container[:secret_variables].nil?
187
+ container[:secret_variables] = hide_secrets(container[:secret_variables])
188
+ end
189
+
190
+ container
191
+ end
256
192
  deployment.each_key do |key|
257
193
  Uffizzi.ui.say("#{key}: #{deployment[key]}")
258
194
  end
259
195
  end
260
196
 
197
+ def hide_secrets(secret_variables)
198
+ secret_variables.map do |secret_variable|
199
+ secret_variable[:value] = '******'
200
+
201
+ secret_variable
202
+ end
203
+ end
204
+
261
205
  def prepare_params(file_path)
262
206
  begin
263
207
  compose_file_data = File.read(file_path)
@@ -280,10 +224,33 @@ module Uffizzi
280
224
  }
281
225
  end
282
226
 
283
- def build_output_data(output_data)
227
+ def handle_preview_interruption(deployment_id, server, project_slug)
228
+ deletion_response = delete_deployment(server, project_slug, deployment_id)
229
+ deployment_name = "deployment-#{deployment_id}"
230
+ preview_deletion_message = if ResponseHelper.no_content?(deletion_response)
231
+ "The preview #{deployment_name} has been disabled."
232
+ else
233
+ "Couldn't disable the deployment #{deployment_name} - please disable maually."
234
+ end
235
+
236
+ raise Uffizzi::Error.new("The preview creation was interrupted. #{preview_deletion_message}")
237
+ end
238
+
239
+ def display_deployment_data(deployment, success)
240
+ if Uffizzi.ui.output_format.nil?
241
+ Uffizzi.ui.say('Done')
242
+ preview_url = "https://#{deployment[:preview_url]}"
243
+ Uffizzi.ui.say(preview_url) if success
244
+ else
245
+ deployment_data = build_deployment_data(deployment)
246
+ Uffizzi.ui.output(deployment_data)
247
+ end
248
+ end
249
+
250
+ def build_deployment_data(deployment)
284
251
  {
285
- id: "deployment-#{output_data[:id]}",
286
- url: "https://#{output_data[:preview_url]}",
252
+ id: "deployment-#{deployment[:id]}",
253
+ url: "https://#{deployment[:preview_url]}",
287
254
  }
288
255
  end
289
256
  end
@@ -5,22 +5,23 @@ require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
6
  require 'uffizzi/services/compose_file_service'
7
7
  require 'uffizzi/services/env_variables_service'
8
+ require 'uffizzi/services/command_service'
8
9
 
9
10
  module Uffizzi
10
- class CLI::Project::Compose < Thor
11
+ class Cli::Project::Compose < Thor
11
12
  include ApiClient
12
13
 
13
- desc 'set [OPTIONS]', 'set'
14
+ desc 'set [OPTIONS]', 'Set the configuration of a project with a compose file'
14
15
  def set
15
16
  run('set')
16
17
  end
17
18
 
18
- desc 'unset', 'unset'
19
+ desc 'unset', 'Unset the compose file for a project'
19
20
  def unset
20
21
  run('unset')
21
22
  end
22
23
 
23
- desc 'describe', 'describe'
24
+ desc 'describe', 'Display details of a compose file'
24
25
  def describe
25
26
  run('describe')
26
27
  end
@@ -29,26 +30,25 @@ module Uffizzi
29
30
 
30
31
  def run(command)
31
32
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
32
- return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?(options)
33
+ return Uffizzi.ui.say('This command needs project to be set in config file') unless CommandService.project_set?(options)
33
34
 
34
- @project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
35
- @server = ConfigFile.read_option(:server)
35
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
36
36
  file_path = options[:file]
37
37
  case command
38
38
  when 'set'
39
- handle_set_command(file_path)
39
+ handle_set_command(project_slug, file_path)
40
40
  when 'unset'
41
- handle_unset_command
41
+ handle_unset_command(project_slug)
42
42
  when 'describe'
43
- handle_describe_command
43
+ handle_describe_command(project_slug)
44
44
  end
45
45
  end
46
46
 
47
- def handle_set_command(file_path)
47
+ def handle_set_command(project_slug, file_path)
48
48
  return Uffizzi.ui.say('No file provided') if file_path.nil?
49
49
 
50
50
  params = prepare_params(file_path)
51
- response = set_compose_file(@server, params, @project_slug)
51
+ response = set_compose_file(ConfigFile.read_option(:server), params, project_slug)
52
52
 
53
53
  if ResponseHelper.created?(response)
54
54
  Uffizzi.ui.say('compose file created')
@@ -57,9 +57,8 @@ module Uffizzi
57
57
  end
58
58
  end
59
59
 
60
- def handle_unset_command
60
+ def handle_unset_command(project_slug)
61
61
  server = ConfigFile.read_option(:server)
62
- project_slug = ConfigFile.read_option(:project)
63
62
  response = unset_compose_file(server, project_slug)
64
63
 
65
64
  if ResponseHelper.no_content?(response)
@@ -69,9 +68,8 @@ module Uffizzi
69
68
  end
70
69
  end
71
70
 
72
- def handle_describe_command
71
+ def handle_describe_command(project_slug)
73
72
  server = ConfigFile.read_option(:server)
74
- project_slug = ConfigFile.read_option(:project)
75
73
  response = describe_compose_file(server, project_slug)
76
74
  compose_file = response[:body][:compose_file]
77
75
 
@@ -3,23 +3,25 @@
3
3
  require 'uffizzi'
4
4
  require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
+ require 'uffizzi/date_helper'
6
7
  require 'uffizzi/shell'
8
+ require 'time'
7
9
 
8
10
  module Uffizzi
9
- class CLI::Project::Secret < Thor
11
+ class Cli::Project::Secret < Thor
10
12
  include ApiClient
11
13
 
12
- desc 'list', 'List Secrets'
14
+ desc 'list', 'Show metadata for all secrets of a project'
13
15
  def list
14
16
  run('list')
15
17
  end
16
18
 
17
- desc 'create [SECRET_ID]', 'Create secrets from $stdout'
19
+ desc 'create [SECRET_ID]', 'Create a secret for a project'
18
20
  def create(id)
19
21
  run('create', id)
20
22
  end
21
23
 
22
- desc 'delete [SECRET_ID]', 'Delete a secret'
24
+ desc 'delete [SECRET_ID]', 'Delete a secret for a project'
23
25
  def delete(id)
24
26
  run('delete', id)
25
27
  end
@@ -30,7 +32,7 @@ module Uffizzi
30
32
  Cli::Common.show_manual(:project, :secret, command) if options[:help] || args.include?('help')
31
33
  return Uffizzi.ui.say('You are not logged in') unless AuthHelper.signed_in?
32
34
 
33
- project_slug = ConfigFile.read_option(:project)
35
+ project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
34
36
  return Uffizzi.ui.say('Please use the --project option to specify the project name') if project_slug.nil?
35
37
 
36
38
  case command
@@ -50,11 +52,20 @@ module Uffizzi
50
52
  def handle_list_command(project_slug)
51
53
  server = ConfigFile.read_option(:server)
52
54
  response = fetch_secrets(server, project_slug)
53
- secrets = response[:body][:secrets].map { |secret| [secret[:name]] }
55
+ secrets = response[:body][:secrets]
56
+
54
57
  return Uffizzi.ui.say('There are no secrets for the project') if secrets.empty?
55
58
 
56
- table_header = 'NAME'
57
- table_data = [[table_header], *secrets]
59
+ current_date = Time.now.utc
60
+ prepared_secrets = secrets.map do |secret|
61
+ [
62
+ secret[:name],
63
+ DateHelper.count_distanse(current_date, Time.parse(secret[:created_at])),
64
+ DateHelper.count_distanse(current_date, Time.parse(secret[:updated_at])),
65
+ ]
66
+ end
67
+ table_header = ['NAME', 'CREATED', 'UPDATED']
68
+ table_data = [table_header, *prepared_secrets]
58
69
  return Uffizzi.ui.print_table(table_data) if ResponseHelper.ok?(response)
59
70
 
60
71
  ResponseHelper.handle_failed_response(response)
@@ -5,31 +5,40 @@ require 'uffizzi/auth_helper'
5
5
  require 'uffizzi/response_helper'
6
6
 
7
7
  module Uffizzi
8
- class CLI::Project < Thor
8
+ class Cli::Project < Thor
9
9
  include ApiClient
10
10
 
11
- desc 'compose', 'compose'
11
+ desc 'compose', 'Manage the compose file for a project'
12
12
  method_option :file, required: false, aliases: '-f'
13
13
  require_relative 'project/compose'
14
- subcommand 'compose', Uffizzi::CLI::Project::Compose
14
+ subcommand 'compose', Uffizzi::Cli::Project::Compose
15
15
 
16
- desc 'secret', 'Secrets Actions'
16
+ desc 'secret', 'Manage secrets for a project'
17
17
  require_relative 'project/secret'
18
- subcommand 'secret', Uffizzi::CLI::Project::Secret
18
+ subcommand 'secret', Uffizzi::Cli::Project::Secret
19
19
 
20
- desc 'list', 'list'
20
+ desc 'list', 'List all projects in the account'
21
21
  def list
22
22
  run('list')
23
23
  end
24
24
 
25
+ desc 'set-default PROJECT_SLUG', 'set-default'
26
+ def set_default(project_slug)
27
+ run('set-default', project_slug: project_slug)
28
+ end
29
+
30
+ map('set-default' => :set_default)
31
+
25
32
  private
26
33
 
27
- def run(command)
34
+ def run(command, project_slug: nil)
28
35
  return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
29
36
 
30
37
  case command
31
38
  when 'list'
32
39
  handle_list_command
40
+ when 'set-default'
41
+ handle_set_default_command(project_slug)
33
42
  end
34
43
  end
35
44
 
@@ -52,6 +61,21 @@ module Uffizzi
52
61
  print_projects(projects)
53
62
  end
54
63
 
64
+ def handle_set_default_command(project_slug)
65
+ response = describe_project(ConfigFile.read_option(:server), project_slug)
66
+
67
+ if ResponseHelper.ok?(response)
68
+ handle_succeed_set_default_response(response)
69
+ else
70
+ ResponseHelper.handle_failed_response(response)
71
+ end
72
+ end
73
+
74
+ def handle_succeed_set_default_response(response)
75
+ set_default_project(response[:body][:project])
76
+ Uffizzi.ui.say('Default project has been updated.')
77
+ end
78
+
55
79
  def print_projects(projects)
56
80
  projects_list = projects.reduce('') do |acc, project|
57
81
  "#{acc}#{project[:slug]}\n"
data/lib/uffizzi/cli.rb CHANGED
@@ -3,23 +3,20 @@
3
3
  require 'uffizzi'
4
4
 
5
5
  module Uffizzi
6
- class CLI < Thor
7
- require_relative 'cli/common'
8
-
9
- class_option :help, type: :boolean, aliases: HELP_MAPPINGS
6
+ class Cli < Thor
10
7
  class_option :project, type: :string
11
8
 
12
9
  def self.exit_on_failure?
13
10
  true
14
11
  end
15
12
 
16
- desc 'version', 'Show Version'
13
+ desc 'version', 'Print version information for uffizzi CLI'
17
14
  def version
18
15
  require_relative 'version'
19
16
  Uffizzi.ui.say(Uffizzi::VERSION)
20
17
  end
21
18
 
22
- desc 'login [OPTIONS]', 'Login into Uffizzi'
19
+ desc 'login [OPTIONS]', 'Login to Uffizzi to view and manage your previews'
23
20
  method_option :server, required: false, aliases: '-s'
24
21
  method_option :username, required: false, aliases: '-u'
25
22
  def login
@@ -27,38 +24,30 @@ module Uffizzi
27
24
  Login.new(options).run
28
25
  end
29
26
 
30
- desc 'logout', 'Logout from Uffizzi'
27
+ desc 'logout', 'Log out of a Uffizzi user account'
31
28
  def logout
32
29
  require_relative 'cli/logout'
33
30
  Logout.new(options).run
34
31
  end
35
32
 
36
- desc 'projects', 'projects'
37
- def projects
38
- require_relative 'cli/projects'
39
- Projects.new.run
40
- end
41
-
42
33
  desc 'project', 'project'
43
34
  require_relative 'cli/project'
44
- subcommand 'project', CLI::Project
35
+ subcommand 'project', Cli::Project
45
36
 
46
37
  desc 'config', 'config'
47
38
  require_relative 'cli/config'
48
- subcommand 'config', CLI::Config
39
+ subcommand 'config', Cli::Config
49
40
 
50
41
  desc 'preview', 'preview'
51
42
  method_option :project, required: false
52
43
  require_relative 'cli/preview'
53
- subcommand 'preview', CLI::Preview
44
+ subcommand 'preview', Cli::Preview
54
45
 
55
- desc 'connect CREDENTIAL_TYPE', 'Connect credentials into Uffizzi'
56
- def connect(credential_type, credential_file_path = nil)
57
- require_relative 'cli/connect'
58
- Connect.new.run(credential_type, credential_file_path)
59
- end
46
+ desc 'connect', 'connect'
47
+ require_relative 'cli/connect'
48
+ subcommand 'connect', Cli::Connect
60
49
 
61
- desc 'disconect CREDENTIAL_TYPE', 'Disonnect credentials from Uffizzi'
50
+ desc 'disconect CREDENTIAL_TYPE', 'Revoke a Uffizzi user account access to external services'
62
51
  def disconnect(credential_type)
63
52
  require_relative 'cli/disconnect'
64
53
  Disconnect.new.run(credential_type)
@@ -67,11 +56,14 @@ module Uffizzi
67
56
  class << self
68
57
  protected
69
58
 
59
+ require_relative 'cli/common'
70
60
  def dispatch(meth, given_args, given_opts, config)
71
61
  args, opts = Thor::Options.split(given_args)
72
- return Cli::Common.show_manual(filename(args)) if show_help?(args, opts)
62
+ return Common.show_manual(filename(args)) if show_help?(args, opts)
73
63
 
74
64
  super
65
+ rescue SystemExit, Interrupt, SocketError
66
+ raise Uffizzi::Error.new('The command was interrupted')
75
67
  end
76
68
 
77
69
  private