cpl 0.2.0 → 0.3.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/Gemfile.lock +4 -3
- data/README.md +7 -8
- data/docs/commands.md +17 -8
- data/examples/circleci.yml +4 -4
- data/lib/command/base.rb +14 -2
- data/lib/command/cleanup_old_images.rb +2 -2
- data/lib/command/cleanup_stale_apps.rb +2 -2
- data/lib/command/delete.rb +1 -1
- data/lib/command/{promote_image.rb → deploy_image.rb} +5 -5
- data/lib/command/env.rb +1 -1
- data/lib/command/no_command.rb +19 -0
- data/lib/command/open.rb +1 -1
- data/lib/command/run.rb +1 -1
- data/lib/command/run_detached.rb +1 -1
- data/lib/command/setup.rb +5 -2
- data/lib/command/test.rb +0 -2
- data/lib/command/version.rb +16 -0
- data/lib/core/config.rb +49 -16
- data/lib/core/controlplane.rb +16 -2
- data/lib/core/controlplane_api_direct.rb +2 -1
- data/lib/core/shell.rb +31 -0
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +5 -3
- data/rakelib/create_release.rake +80 -0
- data/script/generate_commands_docs +3 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fb78a893e74bb1d23dad21fe62a08ce903bd87cbcc85b0cb3affb9a6b47a185
|
4
|
+
data.tar.gz: df6aec1b0be09b95ad65c61ee8c92fc4e44084985907920624868909adc78cc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 961373f6642feac2ecf0bbea2f36ae13c8d70fe64d049b21d1e998b39edd9563772da1a1f4b5038a69e54bbabf2e6c6c6149a6410f3bb5b8be1f61c592619b5d
|
7
|
+
data.tar.gz: dcb5099f234926d9b84697f5c4e58556daeee3d245d4a8f97d092ab1b95547d250ef72908ef9f81cac252f19c0a5d8ca19c4eb3c822c20346e06cb402d97c413
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cpl (0.
|
4
|
+
cpl (0.3.0)
|
5
5
|
debug (~> 1.7.1)
|
6
6
|
dotenv (~> 2.8.1)
|
7
7
|
psych (~> 5.1.0)
|
@@ -18,7 +18,7 @@ GEM
|
|
18
18
|
docile (1.4.0)
|
19
19
|
dotenv (2.8.1)
|
20
20
|
io-console (0.6.0)
|
21
|
-
irb (1.6.
|
21
|
+
irb (1.6.3)
|
22
22
|
reline (>= 0.3.0)
|
23
23
|
json (2.6.3)
|
24
24
|
parallel (1.22.1)
|
@@ -76,6 +76,7 @@ GEM
|
|
76
76
|
unicode-display_width (2.4.2)
|
77
77
|
|
78
78
|
PLATFORMS
|
79
|
+
ruby
|
79
80
|
x86_64-linux
|
80
81
|
|
81
82
|
DEPENDENCIES
|
@@ -88,4 +89,4 @@ DEPENDENCIES
|
|
88
89
|
simplecov (~> 0.22.0)
|
89
90
|
|
90
91
|
BUNDLED WITH
|
91
|
-
2.
|
92
|
+
2.3.26
|
data/README.md
CHANGED
@@ -74,7 +74,7 @@ For the typical Rails app, this means:
|
|
74
74
|
|
75
75
|
## Installation
|
76
76
|
|
77
|
-
**Note:** `cpl` CLI is configured either a Ruby gem, [`cpl`](https://rubygems.org/gems/cpl) install or a local clone
|
77
|
+
**Note:** `cpl` CLI is configured either as a Ruby gem, [`cpl`](https://rubygems.org/gems/cpl) install or a local clone. For information on the latter, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
78
78
|
|
79
79
|
1. Install `node` (required for Control Plane CLI).
|
80
80
|
2. Install `ruby` (required for these helpers).
|
@@ -86,8 +86,8 @@ cpln login
|
|
86
86
|
```
|
87
87
|
|
88
88
|
## Tips
|
89
|
-
Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to Control Plane playbook CLI. The `cpln` CLI is the Control Plane CLI.
|
90
89
|
|
90
|
+
Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to Control Plane playbook CLI. The `cpln` CLI is the Control Plane CLI.
|
91
91
|
|
92
92
|
- For each Git project that you want to deploy to Control Plane, copy project-specific configs to a `.controlplane` directory at the top of your project. `cpl` will pick those up depending on which project
|
93
93
|
folder tree it runs. Thus, this automates running several projects with different configs without explicitly switching configs.
|
@@ -114,8 +114,8 @@ cpl build-image -a myapp --commit 456
|
|
114
114
|
# Prepare database.
|
115
115
|
cpl run:detached rails db:prepare -a myapp --image latest
|
116
116
|
|
117
|
-
#
|
118
|
-
cpl
|
117
|
+
# Deploy latest image.
|
118
|
+
cpl deploy-image -a myapp
|
119
119
|
|
120
120
|
# Open app in browser.
|
121
121
|
cpl open -a myapp
|
@@ -134,13 +134,12 @@ cpl build-image -a ror-tutorial --commit ABCD
|
|
134
134
|
# Run database migrations (or other release tasks) with latest image,
|
135
135
|
# while app is still running on previous image.
|
136
136
|
# This is analogous to the release phase.
|
137
|
-
cpl
|
137
|
+
cpl run:detached rails db:migrate -a ror-tutorial --image latest
|
138
138
|
|
139
|
-
#
|
140
|
-
cpl
|
139
|
+
# Deploy latest image to app
|
140
|
+
cpl deploy-image -a ror-tutorial
|
141
141
|
```
|
142
142
|
|
143
|
-
|
144
143
|
## Example project modifications for Control Plane
|
145
144
|
|
146
145
|
_See this for a complete example._
|
data/docs/commands.md
CHANGED
@@ -65,6 +65,14 @@ cpl config -a $APP_NAME
|
|
65
65
|
cpl delete -a $APP_NAME
|
66
66
|
```
|
67
67
|
|
68
|
+
### `deploy-image`
|
69
|
+
|
70
|
+
- Deploys the latest image to app workloads
|
71
|
+
|
72
|
+
```sh
|
73
|
+
cpl deploy-image -a $APP_NAME
|
74
|
+
```
|
75
|
+
|
68
76
|
### `env`
|
69
77
|
|
70
78
|
- Displays app-specific environment variables
|
@@ -113,14 +121,6 @@ cpl open -a $APP_NAME
|
|
113
121
|
cpl open -a $APP_NAME -w $WORKLOAD_NAME
|
114
122
|
```
|
115
123
|
|
116
|
-
### `promote-image`
|
117
|
-
|
118
|
-
- Promotes the latest image to app workloads
|
119
|
-
|
120
|
-
```sh
|
121
|
-
cpl promote-image -a $APP_NAME
|
122
|
-
```
|
123
|
-
|
124
124
|
### `ps`
|
125
125
|
|
126
126
|
- Shows running replicas in app
|
@@ -240,3 +240,12 @@ cpl setup redis -a $APP_NAME
|
|
240
240
|
# Applies several templates (practically creating full app).
|
241
241
|
cpl setup gvc postgres redis rails -a $APP_NAME
|
242
242
|
```
|
243
|
+
|
244
|
+
### `version`
|
245
|
+
|
246
|
+
- Displays the current version of the CLI
|
247
|
+
- Can also be done with `cpl --version` or `cpl -v`
|
248
|
+
|
249
|
+
```sh
|
250
|
+
cpl version
|
251
|
+
```
|
data/examples/circleci.yml
CHANGED
@@ -30,8 +30,8 @@ build-staging:
|
|
30
30
|
name: Database tasks
|
31
31
|
command: cpl run:detached rails db:migrate -a ${APP_NAME} --image latest
|
32
32
|
- run:
|
33
|
-
name:
|
34
|
-
command: cpl
|
33
|
+
name: Deploy image
|
34
|
+
command: cpl deploy-image -a ${APP_NAME}
|
35
35
|
|
36
36
|
# Example config for review app:
|
37
37
|
# - triggers manually if needed
|
@@ -82,8 +82,8 @@ build-review-app:
|
|
82
82
|
cpl run:detached 'LOG_LEVEL=warn rails db:migrate' -a ${APP_NAME} --image latest
|
83
83
|
fi
|
84
84
|
- run:
|
85
|
-
name:
|
86
|
-
command: cpl
|
85
|
+
name: Deploy image
|
86
|
+
command: cpl deploy-image -a ${APP_NAME}
|
87
87
|
|
88
88
|
review-app:
|
89
89
|
jobs:
|
data/lib/command/base.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Command
|
4
4
|
class Base # rubocop:disable Metrics/ClassLength
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :config
|
6
6
|
|
7
7
|
# Used to call the command (`cpl NAME`)
|
8
8
|
# NAME = ""
|
@@ -27,7 +27,6 @@ module Command
|
|
27
27
|
NO_IMAGE_AVAILABLE = "NO_IMAGE_AVAILABLE"
|
28
28
|
|
29
29
|
def initialize(config)
|
30
|
-
@thor_shell = Thor::Shell::Color.new
|
31
30
|
@config = config
|
32
31
|
end
|
33
32
|
|
@@ -104,6 +103,19 @@ module Command
|
|
104
103
|
}
|
105
104
|
end
|
106
105
|
|
106
|
+
def self.version_option(required: false)
|
107
|
+
{
|
108
|
+
name: :version,
|
109
|
+
params: {
|
110
|
+
aliases: ["-v"],
|
111
|
+
banner: "VERSION",
|
112
|
+
desc: "Displays the current version of the CLI",
|
113
|
+
type: :boolean,
|
114
|
+
required: required
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
107
119
|
def self.all_options
|
108
120
|
methods.grep(/_option$/).map { |method| send(method.to_s) }
|
109
121
|
end
|
@@ -20,7 +20,7 @@ module Command
|
|
20
20
|
|
21
21
|
progress.puts "Old images:"
|
22
22
|
old_images.each do |image|
|
23
|
-
progress.puts " #{image[:name]} (#{
|
23
|
+
progress.puts " #{image[:name]} (#{Shell.color((image[:date]).to_s, :red)})"
|
24
24
|
end
|
25
25
|
|
26
26
|
return unless confirm_delete
|
@@ -63,7 +63,7 @@ module Command
|
|
63
63
|
def confirm_delete
|
64
64
|
return true if config.options[:yes]
|
65
65
|
|
66
|
-
|
66
|
+
Shell.confirm("\nAre you sure you want to delete these #{old_images.length} images?")
|
67
67
|
end
|
68
68
|
|
69
69
|
def delete_images
|
@@ -23,7 +23,7 @@ module Command
|
|
23
23
|
|
24
24
|
progress.puts "Stale apps:"
|
25
25
|
stale_apps.each do |app|
|
26
|
-
progress.puts " #{app[:name]} (#{
|
26
|
+
progress.puts " #{app[:name]} (#{Shell.color((app[:date]).to_s, :red)})"
|
27
27
|
end
|
28
28
|
|
29
29
|
return unless confirm_delete
|
@@ -70,7 +70,7 @@ module Command
|
|
70
70
|
def confirm_delete
|
71
71
|
return true if config.options[:yes]
|
72
72
|
|
73
|
-
|
73
|
+
Shell.confirm("\nAre you sure you want to delete these #{stale_apps.length} apps?")
|
74
74
|
end
|
75
75
|
|
76
76
|
def delete_gvc(app)
|
data/lib/command/delete.rb
CHANGED
@@ -25,7 +25,7 @@ module Command
|
|
25
25
|
def confirm_delete
|
26
26
|
return true if config.options[:yes]
|
27
27
|
|
28
|
-
confirmed =
|
28
|
+
confirmed = Shell.confirm("Are you sure you want to delete '#{config.app}'?")
|
29
29
|
return false unless confirmed
|
30
30
|
|
31
31
|
progress.puts
|
@@ -1,21 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Command
|
4
|
-
class
|
5
|
-
NAME = "
|
4
|
+
class DeployImage < Base
|
5
|
+
NAME = "deploy-image"
|
6
6
|
OPTIONS = [
|
7
7
|
app_option(required: true)
|
8
8
|
].freeze
|
9
|
-
DESCRIPTION = "
|
9
|
+
DESCRIPTION = "Deploys the latest image to app workloads"
|
10
10
|
LONG_DESCRIPTION = <<~HEREDOC
|
11
|
-
-
|
11
|
+
- Deploys the latest image to app workloads
|
12
12
|
HEREDOC
|
13
13
|
|
14
14
|
def call
|
15
15
|
image = latest_image
|
16
16
|
|
17
17
|
config[:app_workloads].each do |workload|
|
18
|
-
cp.
|
18
|
+
cp.workload_get_and_ensure(workload).dig("spec", "containers").each do |container|
|
19
19
|
next unless container["image"].match?(%r{^/org/#{config[:cpln_org]}/image/#{config.app}:})
|
20
20
|
|
21
21
|
cp.workload_set_image_ref(workload, container: container["name"], image: image)
|
data/lib/command/env.rb
CHANGED
@@ -12,7 +12,7 @@ module Command
|
|
12
12
|
HEREDOC
|
13
13
|
|
14
14
|
def call
|
15
|
-
cp.
|
15
|
+
cp.gvc_get_and_ensure.dig("spec", "env").map do |prop|
|
16
16
|
# NOTE: atm no special chars handling, consider adding if needed
|
17
17
|
puts "#{prop['name']}=#{prop['value']}"
|
18
18
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class NoCommand < Base
|
5
|
+
NAME = "no-command"
|
6
|
+
OPTIONS = [version_option].freeze
|
7
|
+
DESCRIPTION = "Called when no command was specified"
|
8
|
+
LONG_DESCRIPTION = <<~HEREDOC
|
9
|
+
- Called when no command was specified
|
10
|
+
HEREDOC
|
11
|
+
HIDE = true
|
12
|
+
|
13
|
+
def call
|
14
|
+
return unless config.options[:version]
|
15
|
+
|
16
|
+
Version.new(config).call
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/command/open.rb
CHANGED
@@ -23,7 +23,7 @@ module Command
|
|
23
23
|
|
24
24
|
def call
|
25
25
|
workload = config.options[:workload] || config[:one_off_workload]
|
26
|
-
data = cp.
|
26
|
+
data = cp.workload_get_and_ensure(workload)
|
27
27
|
url = data["status"]["endpoint"]
|
28
28
|
opener = `which xdg-open open`.split("\n").grep_v("not found").first
|
29
29
|
|
data/lib/command/run.rb
CHANGED
@@ -59,7 +59,7 @@ module Command
|
|
59
59
|
progress.puts "- Cloning workload '#{workload}' on '#{config.options[:app]}' to '#{one_off}'"
|
60
60
|
|
61
61
|
# Create a base copy of workload props
|
62
|
-
spec = cp.
|
62
|
+
spec = cp.workload_get_and_ensure(workload).fetch("spec")
|
63
63
|
container = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
|
64
64
|
|
65
65
|
# remove other containers if any
|
data/lib/command/run_detached.rb
CHANGED
@@ -57,7 +57,7 @@ module Command
|
|
57
57
|
progress.puts "- Cloning workload '#{workload}' on '#{config.options[:app]}' to '#{one_off}'"
|
58
58
|
|
59
59
|
# Get base specs of workload
|
60
|
-
spec = cp.
|
60
|
+
spec = cp.workload_get_and_ensure(workload).fetch("spec")
|
61
61
|
container = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
|
62
62
|
|
63
63
|
# remove other containers if any
|
data/lib/command/setup.rb
CHANGED
@@ -37,8 +37,7 @@ module Command
|
|
37
37
|
def call
|
38
38
|
config.args.each do |template|
|
39
39
|
filename = "#{config.app_cpln_dir}/templates/#{template}.yml"
|
40
|
-
|
41
|
-
|
40
|
+
ensure_template(template, filename)
|
42
41
|
apply_template(filename)
|
43
42
|
progress.puts(template)
|
44
43
|
end
|
@@ -46,6 +45,10 @@ module Command
|
|
46
45
|
|
47
46
|
private
|
48
47
|
|
48
|
+
def ensure_template(template, filename)
|
49
|
+
Shell.abort("Can't find template '#{template}' at '#{filename}', please create it.") unless File.exist?(filename)
|
50
|
+
end
|
51
|
+
|
49
52
|
def apply_template(filename)
|
50
53
|
data = File.read(filename)
|
51
54
|
.gsub("APP_GVC", config.app)
|
data/lib/command/test.rb
CHANGED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class Version < Base
|
5
|
+
NAME = "version"
|
6
|
+
DESCRIPTION = "Displays the current version of the CLI"
|
7
|
+
LONG_DESCRIPTION = <<~HEREDOC
|
8
|
+
- Displays the current version of the CLI
|
9
|
+
- Can also be done with `cpl --version` or `cpl -v`
|
10
|
+
HEREDOC
|
11
|
+
|
12
|
+
def call
|
13
|
+
puts Cpl::VERSION
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/core/config.rb
CHANGED
@@ -15,26 +15,19 @@ class Config
|
|
15
15
|
|
16
16
|
load_app_config
|
17
17
|
pick_current_config if app
|
18
|
+
warn_deprecated_options if current
|
18
19
|
end
|
19
20
|
|
20
|
-
def [](key)
|
21
|
-
|
22
|
-
|
23
|
-
logger = $stderr
|
21
|
+
def [](key)
|
22
|
+
ensure_current_config
|
24
23
|
|
24
|
+
old_key = old_option_keys[key]
|
25
25
|
if current.key?(key)
|
26
26
|
current.fetch(key)
|
27
|
-
elsif
|
28
|
-
|
29
|
-
current.fetch(:org)
|
30
|
-
elsif key == :default_location && current.key?(:location)
|
31
|
-
logger.puts("DEPRECATED: option 'location' is deprecated, use 'default_location' instead\n")
|
32
|
-
current.fetch(:location)
|
33
|
-
elsif key == :match_if_app_name_starts_with && current.key?(:prefix)
|
34
|
-
logger.puts("DEPRECATED: option 'prefix' is deprecated, use 'match_if_app_name_starts_with' instead\n")
|
35
|
-
current.fetch(:prefix)
|
27
|
+
elsif old_key && current.key?(old_key)
|
28
|
+
current.fetch(old_key)
|
36
29
|
else
|
37
|
-
abort("
|
30
|
+
Shell.abort("Can't find option '#{key}' for app '#{app}' in 'controlplane.yml'.")
|
38
31
|
end
|
39
32
|
end
|
40
33
|
|
@@ -48,13 +41,37 @@ class Config
|
|
48
41
|
|
49
42
|
private
|
50
43
|
|
44
|
+
def ensure_current_config
|
45
|
+
Shell.abort("Can't find current config, please specify an app.") unless current
|
46
|
+
end
|
47
|
+
|
48
|
+
def ensure_current_config_app(app)
|
49
|
+
Shell.abort("Can't find app '#{app}' in 'controlplane.yml'.") unless current
|
50
|
+
end
|
51
|
+
|
52
|
+
def ensure_config
|
53
|
+
Shell.abort("'controlplane.yml' is empty.") unless config
|
54
|
+
end
|
55
|
+
|
56
|
+
def ensure_config_apps
|
57
|
+
Shell.abort("Can't find key 'apps' in 'controlplane.yml'.") unless config[:apps]
|
58
|
+
end
|
59
|
+
|
60
|
+
def ensure_config_app(app, options)
|
61
|
+
Shell.abort("App '#{app}' is empty in 'controlplane.yml'.") unless options
|
62
|
+
end
|
63
|
+
|
51
64
|
def pick_current_config
|
65
|
+
ensure_config
|
66
|
+
ensure_config_apps
|
52
67
|
config[:apps].each do |c_app, c_data|
|
68
|
+
ensure_config_app(c_app, c_data)
|
53
69
|
if c_app.to_s == app || (c_data[:match_if_app_name_starts_with] && app.start_with?(c_app.to_s))
|
54
70
|
@current = c_data
|
55
71
|
break
|
56
72
|
end
|
57
73
|
end
|
74
|
+
ensure_current_config_app(app)
|
58
75
|
end
|
59
76
|
|
60
77
|
def load_app_config
|
@@ -73,8 +90,24 @@ class Config
|
|
73
90
|
path = path.parent
|
74
91
|
|
75
92
|
if path.root?
|
76
|
-
|
77
|
-
|
93
|
+
Shell.abort("Can't find project config file at 'project_folder/#{CONFIG_FILE_LOCATIION}', please create it.")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def old_option_keys
|
99
|
+
{
|
100
|
+
cpln_org: :org,
|
101
|
+
default_location: :location,
|
102
|
+
match_if_app_name_starts_with: :prefix
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def warn_deprecated_options
|
107
|
+
old_option_keys.each do |new_key, old_key|
|
108
|
+
if current.key?(old_key)
|
109
|
+
Shell.warn_deprecated("Option '#{old_key}' is deprecated, " \
|
110
|
+
"please use '#{new_key}' instead (in 'controlplane.yml').")
|
78
111
|
end
|
79
112
|
end
|
80
113
|
end
|
data/lib/core/controlplane.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Controlplane
|
3
|
+
class Controlplane # rubocop:disable Metrics/ClassLength
|
4
4
|
attr_reader :config, :api, :gvc, :org
|
5
5
|
|
6
6
|
def initialize(config)
|
@@ -42,6 +42,13 @@ class Controlplane
|
|
42
42
|
api.gvc_get(gvc: a_gvc, org: org)
|
43
43
|
end
|
44
44
|
|
45
|
+
def gvc_get_and_ensure(a_gvc = gvc)
|
46
|
+
gvc_data = gvc_get(a_gvc)
|
47
|
+
return gvc_data if gvc_data
|
48
|
+
|
49
|
+
Shell.abort("Can't find GVC '#{gvc}', please create it with 'cpl setup gvc -a #{config.app}'.")
|
50
|
+
end
|
51
|
+
|
45
52
|
def gvc_delete(a_gvc = gvc)
|
46
53
|
api.gvc_delete(gvc: a_gvc, org: org)
|
47
54
|
end
|
@@ -52,6 +59,13 @@ class Controlplane
|
|
52
59
|
api.workload_get(workload: workload, gvc: gvc, org: org)
|
53
60
|
end
|
54
61
|
|
62
|
+
def workload_get_and_ensure(workload)
|
63
|
+
workload_data = workload_get(workload)
|
64
|
+
return workload_data if workload_data
|
65
|
+
|
66
|
+
Shell.abort("Can't find workload '#{workload}', please create it with 'cpl setup #{workload} -a #{config.app}'.")
|
67
|
+
end
|
68
|
+
|
55
69
|
def workload_get_replicas(workload, location:)
|
56
70
|
cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml"
|
57
71
|
perform_yaml(cmd)
|
@@ -64,7 +78,7 @@ class Controlplane
|
|
64
78
|
end
|
65
79
|
|
66
80
|
def workload_set_suspend(workload, value)
|
67
|
-
data =
|
81
|
+
data = workload_get_and_ensure(workload)
|
68
82
|
data["spec"]["defaultOptions"]["suspend"] = value
|
69
83
|
apply(data)
|
70
84
|
end
|
@@ -37,6 +37,7 @@ class ControlplaneApiDirect
|
|
37
37
|
@@api_token = ENV.fetch("CPLN_TOKEN", `cpln profile token`.chomp) # rubocop:disable Style/ClassVars
|
38
38
|
return @@api_token if @@api_token.match?(API_TOKEN_REGEX)
|
39
39
|
|
40
|
-
abort("
|
40
|
+
Shell.abort("Unknown API token format. " \
|
41
|
+
"Please re-run 'cpln profile login' or set the correct CPLN_TOKEN env variable.")
|
41
42
|
end
|
42
43
|
end
|
data/lib/core/shell.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Shell
|
4
|
+
def self.shell
|
5
|
+
@shell ||= Thor::Shell::Color.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.stderr
|
9
|
+
@stderr ||= $stderr
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.color(message, color_key)
|
13
|
+
shell.set_color(message, color_key)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.confirm(message)
|
17
|
+
shell.yes?("#{message} (y/n)")
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.warn(message)
|
21
|
+
stderr.puts(color("WARNING: #{message}\n", :yellow))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.warn_deprecated(message)
|
25
|
+
stderr.puts(color("DEPRECATED: #{message}\n", :yellow))
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.abort(message)
|
29
|
+
Kernel.abort(color("ERROR: #{message}\n", :red))
|
30
|
+
end
|
31
|
+
end
|
data/lib/cpl/version.rb
CHANGED
data/lib/cpl.rb
CHANGED
@@ -37,6 +37,7 @@ module Cpl
|
|
37
37
|
|
38
38
|
class Cli < Thor
|
39
39
|
package_name "cpl"
|
40
|
+
default_task :no_command
|
40
41
|
|
41
42
|
def self.start(*args)
|
42
43
|
fix_help_option
|
@@ -71,7 +72,8 @@ module Cpl
|
|
71
72
|
def self.deprecated_commands
|
72
73
|
{
|
73
74
|
build: ::Command::BuildImage,
|
74
|
-
promote: ::Command::
|
75
|
+
promote: ::Command::DeployImage,
|
76
|
+
promote_image: ::Command::DeployImage,
|
75
77
|
runner: ::Command::RunDetached
|
76
78
|
}
|
77
79
|
end
|
@@ -109,8 +111,8 @@ module Cpl
|
|
109
111
|
|
110
112
|
define_method(name_for_method) do |*provided_args| # rubocop:disable Metrics/MethodLength
|
111
113
|
if deprecated
|
112
|
-
|
113
|
-
|
114
|
+
::Shell.warn_deprecated("Command '#{command_key}' is deprecated, " \
|
115
|
+
"please use '#{name}' instead.")
|
114
116
|
end
|
115
117
|
|
116
118
|
args = if provided_args.length.positive?
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
|
5
|
+
desc("Releases the gem package using the given version.
|
6
|
+
|
7
|
+
IMPORTANT: the gem version must be in valid rubygem format (no dashes).
|
8
|
+
This task depends on the gem-release ruby gem.
|
9
|
+
|
10
|
+
1st argument: The new version in rubygem format (no dashes). Pass no argument to
|
11
|
+
automatically perform a patch version bump.
|
12
|
+
2nd argument: Perform a dry run by passing 'true' as a second argument.
|
13
|
+
|
14
|
+
Example: `rake create_release[2.1.0,false]`")
|
15
|
+
|
16
|
+
task :create_release, %i[gem_version dry_run] do |_t, args|
|
17
|
+
args_hash = args.to_hash
|
18
|
+
|
19
|
+
is_dry_run = Release.object_to_boolean(args_hash[:dry_run])
|
20
|
+
gem_version = args_hash.fetch(:gem_version, "").strip
|
21
|
+
gem_root = Release.gem_root
|
22
|
+
|
23
|
+
Release.update_the_local_project
|
24
|
+
Release.ensure_there_is_nothing_to_commit
|
25
|
+
Release.sh_in_dir(gem_root,
|
26
|
+
"gem bump --no-commit #{gem_version == '' ? '' : %(--version #{gem_version})}")
|
27
|
+
Release.sh_in_dir(gem_root, "bundle install")
|
28
|
+
Release.sh_in_dir(gem_root, "git commit -am 'Bump version to #{gem_version}'")
|
29
|
+
|
30
|
+
# See https://github.com/svenfuchs/gem-release
|
31
|
+
Release.release_the_new_gem_version unless is_dry_run
|
32
|
+
end
|
33
|
+
|
34
|
+
module Release
|
35
|
+
extend FileUtils
|
36
|
+
class << self
|
37
|
+
def gem_root
|
38
|
+
File.expand_path("..", __dir__)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Executes a string or an array of strings in a shell in the given directory in an unbundled environment
|
42
|
+
def sh_in_dir(dir, *shell_commands)
|
43
|
+
shell_commands.flatten.each { |shell_command| sh %(cd #{dir} && #{shell_command.strip}) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def ensure_there_is_nothing_to_commit
|
47
|
+
status = `git status --porcelain`
|
48
|
+
|
49
|
+
return if $CHILD_STATUS.success? && status == ""
|
50
|
+
|
51
|
+
error = if $CHILD_STATUS.success?
|
52
|
+
"You have uncommitted code. Please commit or stash your changes before continuing"
|
53
|
+
else
|
54
|
+
"You do not have Git installed. Please install Git, and commit your changes before continuing"
|
55
|
+
end
|
56
|
+
raise(error)
|
57
|
+
end
|
58
|
+
|
59
|
+
def object_to_boolean(value)
|
60
|
+
[true, "true", "yes", 1, "1", "t"].include?(value.instance_of?(String) ? value.downcase : value)
|
61
|
+
end
|
62
|
+
|
63
|
+
def update_the_local_project
|
64
|
+
puts "Pulling latest commits from remote repository"
|
65
|
+
|
66
|
+
sh_in_dir(gem_root, "git pull --rebase")
|
67
|
+
raise "Failed in pulling latest changes from default remore repository." unless $CHILD_STATUS.success?
|
68
|
+
rescue Errno::ENOENT
|
69
|
+
raise "Ensure you have Git and Bundler installed before continuing."
|
70
|
+
end
|
71
|
+
|
72
|
+
def release_the_new_gem_version
|
73
|
+
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
|
74
|
+
puts "Use the OTP for RubyGems!"
|
75
|
+
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
|
76
|
+
|
77
|
+
sh_in_dir(gem_root, "gem release")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -6,7 +6,9 @@ require_relative "../lib/cpl"
|
|
6
6
|
commands_str_arr = []
|
7
7
|
|
8
8
|
commands = Command::Base.all_commands
|
9
|
-
commands.each do |
|
9
|
+
commands.keys.sort.each do |command_key|
|
10
|
+
command_class = commands[command_key]
|
11
|
+
|
10
12
|
next if command_class::HIDE
|
11
13
|
|
12
14
|
name = command_class::NAME
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cpl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Gordon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-03-
|
12
|
+
date: 2023-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: debug
|
@@ -173,12 +173,13 @@ files:
|
|
173
173
|
- lib/command/cleanup_stale_apps.rb
|
174
174
|
- lib/command/config.rb
|
175
175
|
- lib/command/delete.rb
|
176
|
+
- lib/command/deploy_image.rb
|
176
177
|
- lib/command/env.rb
|
177
178
|
- lib/command/exists.rb
|
178
179
|
- lib/command/latest_image.rb
|
179
180
|
- lib/command/logs.rb
|
181
|
+
- lib/command/no_command.rb
|
180
182
|
- lib/command/open.rb
|
181
|
-
- lib/command/promote_image.rb
|
182
183
|
- lib/command/ps.rb
|
183
184
|
- lib/command/ps_restart.rb
|
184
185
|
- lib/command/ps_start.rb
|
@@ -187,15 +188,18 @@ files:
|
|
187
188
|
- lib/command/run_detached.rb
|
188
189
|
- lib/command/setup.rb
|
189
190
|
- lib/command/test.rb
|
191
|
+
- lib/command/version.rb
|
190
192
|
- lib/core/config.rb
|
191
193
|
- lib/core/controlplane.rb
|
192
194
|
- lib/core/controlplane_api.rb
|
193
195
|
- lib/core/controlplane_api_cli.rb
|
194
196
|
- lib/core/controlplane_api_direct.rb
|
195
197
|
- lib/core/scripts.rb
|
198
|
+
- lib/core/shell.rb
|
196
199
|
- lib/cpl.rb
|
197
200
|
- lib/cpl/version.rb
|
198
201
|
- lib/main.rb
|
202
|
+
- rakelib/create_release.rake
|
199
203
|
- script/generate_commands_docs
|
200
204
|
- templates/gvc.yml
|
201
205
|
- templates/identity.yml
|