cpl 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 940fc95a21ea2771a453b12e646d182ed42ef448fd83081ac822af26d1820ad3
4
- data.tar.gz: 4405dd3555275a1bbe135d52abaf072ed683cb183d0ee36e0060c38262ca8017
3
+ metadata.gz: 3fb78a893e74bb1d23dad21fe62a08ce903bd87cbcc85b0cb3affb9a6b47a185
4
+ data.tar.gz: df6aec1b0be09b95ad65c61ee8c92fc4e44084985907920624868909adc78cc6
5
5
  SHA512:
6
- metadata.gz: 579a48aff74172dfe8ac8652e3538006d897ad2ce82459869227889d1e294595c0a698f846f2fe9db3970950e1f0372a6149f75ce06f6a2ab526fa451fea6649
7
- data.tar.gz: 26581dbe132fea73f6066ba4a030738a1b08978e17d02fe6ba95ebed74d879f25a103ce5ddbeff8ba33c4508d7b302fc9f28c0d822f77c423c74c07cdf95006b
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.1.1)
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.2)
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.4.6
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 clone. For information on the latter, see [CONTRIBUTING.md](CONTRIBUTING.md).
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
- # Promote latest image.
118
- cpl promote-image -a myapp
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 runner rails db:migrate -a ror-tutorial --image latest
137
+ cpl run:detached rails db:migrate -a ror-tutorial --image latest
138
138
 
139
- # Pomote latest image to app
140
- cpl promote-image -a ror-tutorial
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
+ ```
@@ -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: Promote image
34
- command: cpl promote-image -a ${APP_NAME}
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: Promote image
86
- command: cpl promote-image -a ${APP_NAME}
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 :thor_shell, :config
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]} (#{thor_shell.set_color((image[:date]).to_s, :red)})"
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
- thor_shell.yes?("\nAre you sure you want to delete these #{old_images.length} images (y/n)?")
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]} (#{thor_shell.set_color((app[:date]).to_s, :red)})"
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
- thor_shell.yes?("\nAre you sure you want to delete these #{stale_apps.length} apps (y/n)?")
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)
@@ -25,7 +25,7 @@ module Command
25
25
  def confirm_delete
26
26
  return true if config.options[:yes]
27
27
 
28
- confirmed = thor_shell.yes?("Are you sure you want to delete '#{config.app}' (y/n)?")
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 PromoteImage < Base
5
- NAME = "promote-image"
4
+ class DeployImage < Base
5
+ NAME = "deploy-image"
6
6
  OPTIONS = [
7
7
  app_option(required: true)
8
8
  ].freeze
9
- DESCRIPTION = "Promotes the latest image to app workloads"
9
+ DESCRIPTION = "Deploys the latest image to app workloads"
10
10
  LONG_DESCRIPTION = <<~HEREDOC
11
- - Promotes the latest image to app workloads
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.workload_get(workload).dig("spec", "containers").each do |container|
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.gvc_get.dig("spec", "env").map do |prop|
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.workload_get(workload)
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.workload_get(workload).fetch("spec")
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
@@ -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.workload_get(workload).fetch("spec")
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
- abort("ERROR: Can't find template for '#{template}' at #{filename}") unless File.exist?(filename)
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
@@ -3,7 +3,6 @@
3
3
  # Be sure to have run: gem install debug
4
4
  require "debug"
5
5
 
6
- # rubocop:disable Lint/Debugger
7
6
  module Command
8
7
  class Test < Base
9
8
  NAME = "test"
@@ -23,4 +22,3 @@ module Command
23
22
  end
24
23
  end
25
24
  end
26
- # rubocop:enable Lint/Debugger
@@ -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) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
21
- abort("ERROR: should specify app") unless app
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 key == :cpln_org && current.key?(:org)
28
- logger.puts("DEPRECATED: option 'org' is deprecated, use 'cpln_org' instead\n")
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("ERROR: should specify #{key} in controlplane.yml")
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
- puts "ERROR: Can't find project config file, should be 'project_folder/#{CONFIG_FILE_LOCATIION}'"
77
- exit(-1)
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
@@ -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 = workload_get(workload)
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("ERROR: Unknown API token format. Please re-run 'cpln profile login' or set correct CPLN_TOKEN env variable")
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpl
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
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::PromoteImage,
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
- logger = $stderr
113
- logger.puts("DEPRECATED: command '#{command_key}' is deprecated, use '#{name}' instead\n")
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 |_command_key, command_class|
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.2.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-10 00:00:00.000000000 Z
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