uffizzi-cli 0.1.4.3 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile.lock +5 -1
- data/README.md +67 -26
- data/config/config.rb +17 -0
- data/lib/uffizzi/auth_helper.rb +5 -0
- data/lib/uffizzi/cli/config.rb +28 -20
- data/lib/uffizzi/cli/login.rb +3 -6
- data/lib/uffizzi/cli/preview.rb +267 -0
- data/lib/uffizzi/cli/project/compose.rb +119 -0
- data/lib/uffizzi/cli/project.rb +64 -0
- data/lib/uffizzi/cli.rb +15 -14
- data/lib/uffizzi/clients/api/api_client.rb +71 -5
- data/lib/uffizzi/clients/api/api_routes.rb +24 -0
- data/lib/uffizzi/clients/api/http_client.rb +21 -3
- data/lib/uffizzi/config_file.rb +17 -13
- data/lib/uffizzi/response_helper.rb +24 -0
- data/lib/uffizzi/services/compose_file_service.rb +102 -0
- data/lib/uffizzi/services/env_variables_service.rb +48 -0
- data/lib/uffizzi/version.rb +1 -1
- data/lib/uffizzi.rb +5 -4
- data/man/uffizzi-create +50 -0
- data/man/uffizzi-create.ronn +41 -0
- data/man/uffizzi-delete +37 -0
- data/man/uffizzi-delete.ronn +28 -0
- data/man/uffizzi-describe +38 -0
- data/man/uffizzi-describe.ronn +29 -0
- data/man/uffizzi-list +33 -0
- data/man/uffizzi-list.ronn +25 -0
- data/man/uffizzi-preview +39 -0
- data/man/uffizzi-preview.ronn +33 -0
- data/uffizzi.gemspec +1 -0
- metadata +32 -3
- data/lib/uffizzi/cli/projects.rb +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4cfb476e78f4f753db221ae22db4f6a697c9570b53f5ed9c607cf53b8bae22f
|
4
|
+
data.tar.gz: 9c81c733aaef45544d9a012ea70bef7e52e11838643243519d3d3c655e6ac6ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c912e51e896f064d74e8c42c0903eac6ccc31311dae189cd27261b31b8f218b8db596957fd98cdcf8ba19d340bdac3b5dc7104ab9eecbf75e7c45daa9d031d29
|
7
|
+
data.tar.gz: a4c2e7f02463a12552d3205d5aa525baef3426796bd935c1bcbd087a452f11e467a55839e2a07b511e53e3df843db9f2af28068fa719946c7cc880c0d27e2616
|
data/.rubocop.yml
CHANGED
@@ -23,6 +23,9 @@ Style/AsciiComments:
|
|
23
23
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments'
|
24
24
|
Enabled: false
|
25
25
|
|
26
|
+
Style/OptionalBooleanParameter:
|
27
|
+
Enabled: false
|
28
|
+
|
26
29
|
Naming/AsciiIdentifiers:
|
27
30
|
Description: 'Use only ascii symbols in identifiers.'
|
28
31
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers'
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
uffizzi-cli (0.
|
4
|
+
uffizzi-cli (0.2.0)
|
5
5
|
thor
|
6
6
|
|
7
7
|
GEM
|
@@ -78,6 +78,9 @@ GEM
|
|
78
78
|
rubocop (~> 1.0)
|
79
79
|
ruby-progressbar (1.11.0)
|
80
80
|
thor (1.2.1)
|
81
|
+
tty-cursor (0.7.1)
|
82
|
+
tty-spinner (0.9.3)
|
83
|
+
tty-cursor (~> 0.7)
|
81
84
|
tzinfo (2.0.4)
|
82
85
|
concurrent-ruby (~> 1.0)
|
83
86
|
unicode (0.4.4.4)
|
@@ -106,6 +109,7 @@ DEPENDENCIES
|
|
106
109
|
rubocop
|
107
110
|
rubocop-minitest
|
108
111
|
rubocop-rake
|
112
|
+
tty-spinner
|
109
113
|
uffizzi-cli!
|
110
114
|
webmock
|
111
115
|
|
data/README.md
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
# Uffizzi CLI
|
1
|
+
# Uffizzi CLI
|
2
2
|
|
3
|
-
A command-line interace (CLI) for [Uffizzi App](https://github.com/UffizziCloud/uffizzi_app)
|
3
|
+
A command-line interace (CLI) for [Uffizzi App](https://github.com/UffizziCloud/uffizzi_app)
|
4
4
|
|
5
5
|
## Uffizzi Overview
|
6
6
|
|
7
|
-
Uffizzi is the Full-stack Previews Engine that makes it easy for your team to preview code changes before merging—whether frontend, backend or microserivce. Define your full-stack apps with a familiar syntax based on Docker Compose, and Uffizzi will create on-demand test environments when you open pull requests or build new images. Preview URLs are updated when there’s a new commit, so your team can catch issues early, iterate quickly, and accelerate your release cycles.
|
7
|
+
Uffizzi is the Full-stack Previews Engine that makes it easy for your team to preview code changes before merging—whether frontend, backend or microserivce. Define your full-stack apps with a familiar syntax based on Docker Compose, and Uffizzi will create on-demand test environments when you open pull requests or build new images. Preview URLs are updated when there’s a new commit, so your team can catch issues early, iterate quickly, and accelerate your release cycles.
|
8
8
|
|
9
|
-
## Getting started with Uffizzi
|
9
|
+
## Getting started with Uffizzi
|
10
10
|
|
11
|
-
The fastest and easiest way to get started with Uffizzi is via the fully hosted version available at https://uffizzi.com, which includes free plans for small teams and qualifying open-source projects.
|
11
|
+
The fastest and easiest way to get started with Uffizzi is via the fully hosted version available at https://uffizzi.com, which includes free plans for small teams and qualifying open-source projects.
|
12
12
|
|
13
13
|
Alternatively, you can self-host Uffizzi via the open-source repositories available here on GitHub. The remainder of this README is intended for users interested in self-hosting Uffizzi or for those who are just curious about how Uffizzi works.
|
14
14
|
|
15
|
-
## Uffizzi Architecture
|
15
|
+
## Uffizzi Architecture
|
16
16
|
|
17
|
-
Uffizzi consists of the following components:
|
17
|
+
Uffizzi consists of the following components:
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
- [Uffizzi App](https://github.com/UffizziCloud/uffizzi_app) - The primary REST API for creating and managing Previews
|
20
|
+
- [Uffizzi Controller](https://github.com/UffizziCloud/uffizzi_controller) - A smart proxy service that handles requests from Uffizzi App to the Kubernetes API
|
21
|
+
- Uffizzi CLI (this repository) - A command-line interface for Uffizzi App
|
22
|
+
- [Uffizzi Dashboard](https://app.uffizzi.com) - A graphical user interface for Uffizzi App, available as a paid service at https://uffizzi.com
|
23
23
|
|
24
|
-
To host Uffizzi yourself, you will also need the following external dependencies:
|
24
|
+
To host Uffizzi yourself, you will also need the following external dependencies:
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
- Kubernetes (k8s) cluster
|
27
|
+
- Postgres database
|
28
|
+
- Redis cache
|
29
29
|
|
30
30
|
## Installation
|
31
31
|
|
@@ -54,40 +54,81 @@ Run rubocop:
|
|
54
54
|
|
55
55
|
## Commands
|
56
56
|
|
57
|
-
### login
|
57
|
+
### login
|
58
58
|
|
59
59
|
```
|
60
|
-
$ uffizzi login -u your@email.com
|
60
|
+
$ uffizzi login -u your@email.com --hostname localhost:8080
|
61
61
|
```
|
62
|
-
Logging you into the app which you set in the hostname option.
|
63
62
|
|
63
|
+
Logging you into the app which you set in the hostname option.
|
64
64
|
|
65
|
-
### login options
|
65
|
+
### login options
|
66
66
|
|
67
|
-
Option
|
68
|
-
|
69
|
-
`--user`
|
70
|
-
`--hostname
|
67
|
+
| Option | Aliase | Description |
|
68
|
+
| ------------ | ------ | ------------------------- |
|
69
|
+
| `--user` | `-u` | Your email for logging in |
|
70
|
+
| `--hostname` | | Adress of your app |
|
71
71
|
|
72
72
|
If hostname uses basic authentication you can specify options for it by setting `basic_auth_user` and `basic_auth_password` via `config set` command.
|
73
73
|
|
74
|
-
###
|
74
|
+
### project
|
75
75
|
|
76
76
|
```
|
77
|
-
$ uffizzi
|
77
|
+
$ uffizzi project
|
78
|
+
```
|
79
|
+
|
80
|
+
Use this command to configure your projects. This command has 2 subcommands `list` and `compose`.
|
81
|
+
|
82
|
+
```
|
83
|
+
$ uffizzi project list
|
78
84
|
```
|
79
85
|
|
80
86
|
Shows all your projects' slugs
|
81
87
|
|
82
88
|
If you have only one project it will be added to your config file automatically, if there's more than one project you need to set up your project manually with the command `uffizzi config set YOUR_PROJECT_SLUG`
|
83
89
|
|
84
|
-
###
|
90
|
+
### compose
|
91
|
+
|
92
|
+
```
|
93
|
+
$ uffizzi project compose
|
94
|
+
```
|
95
|
+
|
96
|
+
That's the subcommand for project command. Use it to configure your compose file. This command has 3 subcommands `set`, `describe` and `unset`.
|
97
|
+
|
98
|
+
```
|
99
|
+
$ uffizzi project compose set -f path_to_your_compose_file.yml
|
100
|
+
```
|
101
|
+
|
102
|
+
Creates a new or updates existed compose file in uffizzi app for project specified in config file
|
103
|
+
|
104
|
+
```
|
105
|
+
$ uffizzi project compose describe
|
106
|
+
```
|
107
|
+
|
108
|
+
Shows the content of compose file related to project specified in config file if it's valid or validation errors if it's not
|
109
|
+
|
110
|
+
```
|
111
|
+
$ uffizzi project compose unset
|
112
|
+
```
|
113
|
+
|
114
|
+
Removes compose file related to project specified in config file
|
115
|
+
|
116
|
+
You need to set project before use any of these commands via `uffizzi config set project YOUR_PROJECT_SLUG` command
|
117
|
+
|
118
|
+
### compose options
|
119
|
+
|
120
|
+
| Option | Aliase | Description |
|
121
|
+
| -------- | ------ | ------------------------- |
|
122
|
+
| `--file` | `-f` | Path to your compose file |
|
123
|
+
|
124
|
+
### config
|
85
125
|
|
86
126
|
Use this command to configure your cli app. This command has 4 subcommands `list`, `get`, `set`, and `delete`.
|
87
127
|
|
88
128
|
```
|
89
129
|
$ uffizzi config list
|
90
130
|
```
|
131
|
+
|
91
132
|
Shows all options and their values from the config file.
|
92
133
|
|
93
134
|
```
|
data/config/config.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Uffizzi
|
6
|
+
def self.configuration
|
7
|
+
@configuration ||= OpenStruct.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configure
|
11
|
+
yield(configuration)
|
12
|
+
end
|
13
|
+
|
14
|
+
configure do |config|
|
15
|
+
config.hostname = 'http://web:7000'
|
16
|
+
end
|
17
|
+
end
|
data/lib/uffizzi/auth_helper.rb
CHANGED
data/lib/uffizzi/cli/config.rb
CHANGED
@@ -2,12 +2,35 @@
|
|
2
2
|
|
3
3
|
require 'io/console'
|
4
4
|
require 'uffizzi'
|
5
|
+
require 'uffizzi/clients/api/api_client'
|
5
6
|
|
6
7
|
module Uffizzi
|
7
|
-
class Config
|
8
|
+
class CLI::Config < Thor
|
8
9
|
include ApiClient
|
9
10
|
|
10
|
-
|
11
|
+
desc 'list', 'list'
|
12
|
+
def list
|
13
|
+
run('list')
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'get', 'get'
|
17
|
+
def get(property)
|
18
|
+
run('get', property)
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'set', 'set'
|
22
|
+
def set(property, value)
|
23
|
+
run('set', property, value)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'delete', 'delete'
|
27
|
+
def delete(property)
|
28
|
+
run('delete', property)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def run(command, property = nil, value = nil)
|
11
34
|
case command
|
12
35
|
when 'list'
|
13
36
|
handle_list_command
|
@@ -17,40 +40,25 @@ module Uffizzi
|
|
17
40
|
handle_set_command(property, value)
|
18
41
|
when 'delete'
|
19
42
|
handle_delete_command(property)
|
20
|
-
else
|
21
|
-
puts "#{command} is not a uffizzi config command"
|
22
43
|
end
|
23
44
|
end
|
24
45
|
|
25
|
-
private
|
26
|
-
|
27
46
|
def handle_list_command
|
28
47
|
ConfigFile.list
|
29
48
|
end
|
30
49
|
|
31
50
|
def handle_get_command(property)
|
32
|
-
if property.nil?
|
33
|
-
puts 'No property provided'
|
34
|
-
return
|
35
|
-
end
|
36
51
|
option = ConfigFile.read_option(property.to_sym)
|
37
|
-
|
52
|
+
message = option.nil? ? "The option #{property} doesn't exist in config file" : option
|
53
|
+
|
54
|
+
Uffizzi.ui.say(message)
|
38
55
|
end
|
39
56
|
|
40
57
|
def handle_set_command(property, value)
|
41
|
-
if property.nil? || value.nil?
|
42
|
-
puts 'No property provided' if property.nil?
|
43
|
-
puts 'No value provided' if value.nil?
|
44
|
-
return
|
45
|
-
end
|
46
58
|
ConfigFile.write_option(property.to_sym, value)
|
47
59
|
end
|
48
60
|
|
49
61
|
def handle_delete_command(property)
|
50
|
-
if property.nil?
|
51
|
-
puts 'No property provided'
|
52
|
-
return
|
53
|
-
end
|
54
62
|
ConfigFile.delete_option(property.to_sym)
|
55
63
|
end
|
56
64
|
end
|
data/lib/uffizzi/cli/login.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'io/console'
|
4
4
|
require 'uffizzi'
|
5
5
|
require 'uffizzi/response_helper'
|
6
|
+
require 'uffizzi/clients/api/api_client'
|
6
7
|
|
7
8
|
module Uffizzi
|
8
9
|
class CLI::Login
|
@@ -17,10 +18,10 @@ module Uffizzi
|
|
17
18
|
params = prepare_request_params(password)
|
18
19
|
response = create_session(@options[:hostname], params)
|
19
20
|
|
20
|
-
if
|
21
|
+
if ResponseHelper.created?(response)
|
21
22
|
handle_succeed_response(response)
|
22
23
|
else
|
23
|
-
handle_failed_response(response)
|
24
|
+
ResponseHelper.handle_failed_response(response)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
@@ -35,10 +36,6 @@ module Uffizzi
|
|
35
36
|
}
|
36
37
|
end
|
37
38
|
|
38
|
-
def handle_failed_response(response)
|
39
|
-
print_errors(response[:body][:errors])
|
40
|
-
end
|
41
|
-
|
42
39
|
def handle_succeed_response(response)
|
43
40
|
account = response[:body][:user][:accounts].first
|
44
41
|
return Uffizzi.ui.say('No account related to this email') unless account_valid?(account)
|
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'uffizzi'
|
4
|
+
require 'tty-spinner'
|
5
|
+
require 'uffizzi/auth_helper'
|
6
|
+
|
7
|
+
module Uffizzi
|
8
|
+
class CLI::Preview < Thor
|
9
|
+
include ApiClient
|
10
|
+
|
11
|
+
@spinner
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def help(_shell, _subcommand)
|
15
|
+
Cli::Common.show_manual(:preview)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'list', 'list'
|
20
|
+
def list
|
21
|
+
return Cli::Common.show_manual(:list) if options[:help]
|
22
|
+
|
23
|
+
run(options, 'list', nil, nil)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'create', 'create'
|
27
|
+
def create(file_path = nil)
|
28
|
+
return Cli::Common.show_manual(:create) if options[:help]
|
29
|
+
|
30
|
+
run(options, 'create', file_path, nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'delete', 'delete'
|
34
|
+
def delete(deployment)
|
35
|
+
return Cli::Common.show_manual(:delete) if options[:help]
|
36
|
+
|
37
|
+
run(options, 'delete', nil, deployment)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'describe', 'describe'
|
41
|
+
def describe(deployment)
|
42
|
+
return Cli::Common.show_manual(:describe) if options[:help]
|
43
|
+
|
44
|
+
run(options, 'describe', nil, deployment)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def run(options, command, file_path, deployment)
|
50
|
+
return Uffizzi.ui.say('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
|
51
|
+
return Uffizzi.ui.say('This command needs project to be set in config file') unless Uffizzi::AuthHelper.project_set?
|
52
|
+
|
53
|
+
project_slug = options[:project].nil? ? ConfigFile.read_option(:project) : options[:project]
|
54
|
+
|
55
|
+
case command
|
56
|
+
when 'list'
|
57
|
+
handle_list_command(project_slug)
|
58
|
+
when 'create'
|
59
|
+
handle_create_command(file_path, project_slug)
|
60
|
+
when 'delete'
|
61
|
+
handle_delete_command(deployment, project_slug)
|
62
|
+
when 'describe'
|
63
|
+
handle_describe_command(deployment, project_slug)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def handle_list_command(project_slug)
|
68
|
+
hostname = ConfigFile.read_option(:hostname)
|
69
|
+
response = fetch_deployments(hostname, project_slug)
|
70
|
+
|
71
|
+
if ResponseHelper.ok?(response)
|
72
|
+
handle_succeed_list_response(response)
|
73
|
+
else
|
74
|
+
ResponseHelper.handle_failed_response(response)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def handle_create_command(file_path, project_slug)
|
79
|
+
hostname = ConfigFile.read_option(:hostname)
|
80
|
+
params = file_path.nil? ? {} : prepare_params(file_path)
|
81
|
+
response = create_deployment(hostname, project_slug, params)
|
82
|
+
|
83
|
+
if ResponseHelper.created?(response)
|
84
|
+
handle_succeed_create_response(hostname, project_slug, response)
|
85
|
+
else
|
86
|
+
ResponseHelper.handle_failed_response(response)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def handle_succeed_create_response(hostname, project_slug, response)
|
91
|
+
deployment = response[:body][:deployment]
|
92
|
+
deployment_id = deployment[:id]
|
93
|
+
params = { id: deployment_id }
|
94
|
+
|
95
|
+
response = deploy_containers(hostname, project_slug, deployment_id, params)
|
96
|
+
|
97
|
+
if ResponseHelper.no_content?(response)
|
98
|
+
Uffizzi.ui.say("Preview created with name deployment-#{deployment_id}")
|
99
|
+
print_deployment_progress(hostname, deployment, project_slug)
|
100
|
+
else
|
101
|
+
ResponseHelper.handle_failed_response(response)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def print_deployment_progress(hostname, deployment, project_slug)
|
106
|
+
deployment_id = deployment[:id]
|
107
|
+
|
108
|
+
@spinner = TTY::Spinner.new('[:spinner] Creating containers...', format: :dots)
|
109
|
+
@spinner.auto_spin
|
110
|
+
|
111
|
+
activity_items = []
|
112
|
+
|
113
|
+
loop do
|
114
|
+
response = get_activity_items(hostname, project_slug, deployment_id)
|
115
|
+
handle_activity_items_response(response)
|
116
|
+
return unless @spinner.spinning?
|
117
|
+
|
118
|
+
activity_items = response[:body][:activity_items]
|
119
|
+
break unless activity_items.empty?
|
120
|
+
|
121
|
+
sleep(5)
|
122
|
+
end
|
123
|
+
|
124
|
+
@spinner.success
|
125
|
+
|
126
|
+
Uffizzi.ui.say('Done')
|
127
|
+
|
128
|
+
@spinner = TTY::Spinner::Multi.new('[:spinner] Deploying preview...', format: :dots, style: {
|
129
|
+
middle: ' ',
|
130
|
+
bottom: ' ',
|
131
|
+
})
|
132
|
+
|
133
|
+
containers_spinners = create_containers_spinners(activity_items)
|
134
|
+
|
135
|
+
loop do
|
136
|
+
response = get_activity_items(hostname, project_slug, deployment_id)
|
137
|
+
handle_activity_items_response(response)
|
138
|
+
return if @spinner.done?
|
139
|
+
|
140
|
+
activity_items = response[:body][:activity_items]
|
141
|
+
check_activity_items_state(activity_items, containers_spinners)
|
142
|
+
break if activity_items.all? { |activity_item| activity_item[:state] == 'deployed' || activity_item[:state] == 'failed' }
|
143
|
+
|
144
|
+
sleep(5)
|
145
|
+
end
|
146
|
+
|
147
|
+
Uffizzi.ui.say('Done')
|
148
|
+
preview_url = "http://#{deployment[:preview_url]}"
|
149
|
+
Uffizzi.ui.say(preview_url) if @spinner.success?
|
150
|
+
end
|
151
|
+
|
152
|
+
def create_containers_spinners(activity_items)
|
153
|
+
activity_items.map do |activity_item|
|
154
|
+
container_spinner = @spinner.register("[:spinner] #{activity_item[:name]}")
|
155
|
+
container_spinner.auto_spin
|
156
|
+
{
|
157
|
+
name: activity_item[:name],
|
158
|
+
spinner: container_spinner,
|
159
|
+
}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_activity_items_state(activity_items, containers_spinners)
|
164
|
+
finished_activity_items = activity_items.filter do |activity_item|
|
165
|
+
activity_item[:state] == 'deployed' || activity_item[:state] == 'failed'
|
166
|
+
end
|
167
|
+
finished_activity_items.each do |activity_item|
|
168
|
+
container_spinner = containers_spinners.detect { |spinner| spinner[:name] == activity_item[:name] }
|
169
|
+
spinner = container_spinner[:spinner]
|
170
|
+
case activity_item[:state]
|
171
|
+
when 'deployed'
|
172
|
+
spinner.success
|
173
|
+
when 'failed'
|
174
|
+
spinner.error
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def handle_delete_command(deployment, project_slug)
|
180
|
+
return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") unless deployment_name_valid?(deployment)
|
181
|
+
|
182
|
+
hostname = ConfigFile.read_option(:hostname)
|
183
|
+
deployment_id = deployment.split('-').last
|
184
|
+
|
185
|
+
response = delete_deployment(hostname, project_slug, deployment_id)
|
186
|
+
|
187
|
+
if ResponseHelper.no_content?(response)
|
188
|
+
handle_succeed_delete_response(deployment_id)
|
189
|
+
else
|
190
|
+
ResponseHelper.handle_failed_response(response)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def handle_describe_command(deployment, project_slug)
|
195
|
+
return Uffizzi.ui.say("Preview should be specified in 'deployment-PREVIEW_ID' format") unless deployment_name_valid?(deployment)
|
196
|
+
|
197
|
+
hostname = ConfigFile.read_option(:hostname)
|
198
|
+
deployment_id = deployment.split('-').last
|
199
|
+
|
200
|
+
response = describe_deployment(hostname, project_slug, deployment_id)
|
201
|
+
|
202
|
+
if ResponseHelper.ok?(response)
|
203
|
+
handle_succeed_describe_response(response)
|
204
|
+
else
|
205
|
+
ResponseHelper.handle_failed_response(response)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def handle_activity_items_response(response)
|
210
|
+
unless ResponseHelper.ok?(response)
|
211
|
+
@spinner.error
|
212
|
+
ResponseHelper.handle_failed_response(response)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def handle_succeed_list_response(response)
|
217
|
+
deployments = response[:body][:deployments] || []
|
218
|
+
return Uffizzi.ui.say('The project has no active deployments') if deployments.empty?
|
219
|
+
|
220
|
+
deployments.each do |deployment|
|
221
|
+
Uffizzi.ui.say("deployment-#{deployment[:id]}")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def handle_succeed_delete_response(deployment_id)
|
226
|
+
Uffizzi.ui.say("Preview deployment-#{deployment_id} deleted")
|
227
|
+
end
|
228
|
+
|
229
|
+
def handle_succeed_describe_response(response)
|
230
|
+
deployment = response[:body][:deployment]
|
231
|
+
deployment.each_key do |key|
|
232
|
+
Uffizzi.ui.say("#{key}: #{deployment[key]}")
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def prepare_params(file_path)
|
237
|
+
begin
|
238
|
+
compose_file_data = File.read(file_path)
|
239
|
+
rescue Errno::ENOENT => e
|
240
|
+
Uffizzi.ui.say(e)
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
compose_file_dir = File.dirname(file_path)
|
245
|
+
dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
|
246
|
+
absolute_path = File.absolute_path(file_path)
|
247
|
+
compose_file_params = {
|
248
|
+
path: absolute_path,
|
249
|
+
content: Base64.encode64(compose_file_data),
|
250
|
+
source: absolute_path,
|
251
|
+
}
|
252
|
+
|
253
|
+
{
|
254
|
+
compose_file: compose_file_params,
|
255
|
+
dependencies: dependencies,
|
256
|
+
}
|
257
|
+
end
|
258
|
+
|
259
|
+
def deployment_name_valid?(deployment)
|
260
|
+
return false unless deployment.start_with?('deployment-')
|
261
|
+
return false unless deployment.split('-').size == 2
|
262
|
+
|
263
|
+
deployment_id = deployment.split('-').last
|
264
|
+
deployment_id.to_i.to_s == deployment_id
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|