rockette 0.0.1 → 0.0.5

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: 2870c274fb8f46b67ff9590364eeb0b68936e046a2a33c162de7410542c735af
4
- data.tar.gz: b2932d43fbd1562c79b86408afb907b1db2bf4c2fb8d072fdd36d61393dccd92
3
+ metadata.gz: ee0d2270c8442e3e6b696cce15e9ac765a5d2c42e6a7ab84dc2c2a9b057d90e8
4
+ data.tar.gz: 70d91cff0436629fe0cdcf50f7f5201047daee8a6504ef87a3ffc009c0143035
5
5
  SHA512:
6
- metadata.gz: c214dc82ce832ae90d328447062ba8ac98a56ff3ab1056d7724123c8ae0da01bb3909845671b45ce2f869f6c2d880b326d8b7105f2a42c7069ac3618c3aad357
7
- data.tar.gz: 1b9b8d76c9e547d8af19382d5b0eed3800f4e914f8f5dbe34933c75fdd1c766042ef289af4f0fd4f59167e8d71422a68edf35d88a71693cdba45e1c6781747f6
6
+ metadata.gz: 9c7afa7c6b7c0a4f39a4ebfa16ae70fa9b15e4a83e32930e30f2dbbae1aafa04850061de0b63e44f5023eb346e3ac42eaa68e56bd8d0a7db2b1b1cf3efc6b32f
7
+ data.tar.gz: 0ac4932e7d0302bcdf9e3df9b9c8d6c4ce12a16e0831b8de9fe947a3850ca45633fa79cbdf1409ecd833bd76a42172beb6b681128d72177421eea068d4b8c418
data/.rubocop.yml CHANGED
@@ -12,3 +12,6 @@ Style/StringLiteralsInInterpolation:
12
12
 
13
13
  Layout/LineLength:
14
14
  Max: 120
15
+
16
+ Metrics/MethodLength:
17
+ Max: 20
data/CHANGELOG.md CHANGED
@@ -10,4 +10,24 @@
10
10
  - Unify rest calls into Rester class
11
11
  - Improve exception handling including socket errors
12
12
  - Switch to yaml for config
13
- - Use ~/.rockette as consistent location for config and exports
13
+ - Use ~/.rockette as consistent location for config and exports
14
+
15
+ ## [0.0.2] - 2021-03-18
16
+
17
+ - Add copy switch to deploy command
18
+ - Use file name passed via -f switch
19
+ - Try to find export file and let caller know if file not found
20
+
21
+ ## [0.0.3] - 2021-03-29
22
+
23
+ - Improved handling of copy and file switches
24
+ - Check /usr/app for Docker
25
+ - Add interactive mode
26
+ - Add configuration option to interactive mode
27
+ - Add resource viewer mode to interactive
28
+ - Add exporter option to interactive
29
+ - Add deployer mode to interactive
30
+
31
+ ## [0.0.4] - 2021-03-29
32
+
33
+ - Bug fix for APP_DIR
data/Gemfile.lock CHANGED
@@ -1,9 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rockette (0.0.1)
4
+ rockette (0.0.5)
5
+ oci (~> 2.0)
6
+ pastel (~> 0.0)
5
7
  rest-client (~> 2.0)
6
8
  thor (~> 1.0)
9
+ tty-config (~> 0.0)
10
+ tty-editor (~> 0.0)
11
+ tty-font (~> 0.0)
12
+ tty-prompt (~> 0.0)
13
+ tty-spinner (~> 0.0)
14
+ tty-table (~> 0.0)
7
15
 
8
16
  GEM
9
17
  remote: https://rubygems.org/
@@ -13,46 +21,82 @@ GEM
13
21
  domain_name (0.5.20190701)
14
22
  unf (>= 0.0.5, < 1.0.0)
15
23
  http-accept (1.7.0)
16
- http-cookie (1.0.3)
24
+ http-cookie (1.0.4)
17
25
  domain_name (~> 0.5)
26
+ inifile (3.0.0)
27
+ json (2.5.1)
28
+ jwt (2.2.3)
18
29
  method_source (1.0.0)
19
30
  mime-types (3.3.1)
20
31
  mime-types-data (~> 3.2015)
21
- mime-types-data (3.2021.0212)
32
+ mime-types-data (3.2021.0901)
22
33
  minitest (5.14.4)
23
34
  netrc (0.11.0)
24
- parallel (1.20.1)
25
- parser (3.0.0.0)
35
+ oci (2.15.0)
36
+ inifile (~> 3.0, >= 3.0.0)
37
+ json (>= 1.4.6, < 3.0.0)
38
+ jwt (~> 2.1)
39
+ parallel (1.21.0)
40
+ parser (3.0.2.0)
26
41
  ast (~> 2.4.1)
27
- pry (0.14.0)
42
+ pastel (0.8.0)
43
+ tty-color (~> 0.5)
44
+ pry (0.14.1)
28
45
  coderay (~> 1.1)
29
46
  method_source (~> 1.0)
30
47
  rainbow (3.0.0)
31
- rake (13.0.3)
48
+ rake (13.0.6)
32
49
  regexp_parser (2.1.1)
33
50
  rest-client (2.1.0)
34
51
  http-accept (>= 1.7.0, < 2.0)
35
52
  http-cookie (>= 1.0.2, < 2.0)
36
53
  mime-types (>= 1.16, < 4.0)
37
54
  netrc (~> 0.8)
38
- rexml (3.2.4)
39
- rubocop (1.10.0)
55
+ rexml (3.2.5)
56
+ rubocop (1.21.0)
40
57
  parallel (~> 1.10)
41
58
  parser (>= 3.0.0.0)
42
59
  rainbow (>= 2.2.2, < 4.0)
43
60
  regexp_parser (>= 1.8, < 3.0)
44
61
  rexml
45
- rubocop-ast (>= 1.2.0, < 2.0)
62
+ rubocop-ast (>= 1.9.1, < 2.0)
46
63
  ruby-progressbar (~> 1.7)
47
64
  unicode-display_width (>= 1.4.0, < 3.0)
48
- rubocop-ast (1.4.1)
49
- parser (>= 2.7.1.5)
65
+ rubocop-ast (1.11.0)
66
+ parser (>= 3.0.1.1)
50
67
  ruby-progressbar (1.11.0)
68
+ strings (0.2.1)
69
+ strings-ansi (~> 0.2)
70
+ unicode-display_width (>= 1.5, < 3.0)
71
+ unicode_utils (~> 1.4)
72
+ strings-ansi (0.2.0)
51
73
  thor (1.1.0)
74
+ tty-color (0.6.0)
75
+ tty-config (0.5.0)
76
+ tty-cursor (0.7.1)
77
+ tty-editor (0.7.0)
78
+ tty-prompt (~> 0.22)
79
+ tty-font (0.5.0)
80
+ tty-prompt (0.23.1)
81
+ pastel (~> 0.8)
82
+ tty-reader (~> 0.8)
83
+ tty-reader (0.9.0)
84
+ tty-cursor (~> 0.7)
85
+ tty-screen (~> 0.8)
86
+ wisper (~> 2.0)
87
+ tty-screen (0.8.1)
88
+ tty-spinner (0.9.3)
89
+ tty-cursor (~> 0.7)
90
+ tty-table (0.12.0)
91
+ pastel (~> 0.8)
92
+ strings (~> 0.2.0)
93
+ tty-screen (~> 0.8)
52
94
  unf (0.1.4)
53
95
  unf_ext
54
- unf_ext (0.0.7.7)
55
- unicode-display_width (2.0.0)
96
+ unf_ext (0.0.8)
97
+ unicode-display_width (2.1.0)
98
+ unicode_utils (1.4.0)
99
+ wisper (2.0.1)
56
100
 
57
101
  PLATFORMS
58
102
  ruby
data/README.md CHANGED
@@ -22,6 +22,7 @@ Or install it yourself as:
22
22
 
23
23
  Run rockette export to create and download an exported application file.
24
24
  Run rockette deploy to push and import an application export.
25
+ Run rockette help or rockette 'command' help for more information.
25
26
 
26
27
  ## Development
27
28
 
data/exe/rockette CHANGED
@@ -3,23 +3,6 @@
3
3
 
4
4
  require "rockette"
5
5
 
6
- app_path = File.join(Dir.home, ".rockette")
7
- lib_path = File.expand_path("../lib", __dir__)
8
- tem_path = File.expand_path("../templates", __dir__)
9
- $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
10
-
11
- Dir.mkdir(app_path) unless File.exist?(app_path)
12
- unless File.exist?(File.join(app_path, "config.yml"))
13
- template = File.read(File.join(tem_path, "config.yml.erb"))
14
- data = ERB.new(template).result(binding)
15
- File.write(File.join(app_path, "config.yml"), data)
16
- end
17
- Dir.mkdir(File.join(app_path, "exports")) unless File.exist?(File.join(app_path, "exports"))
18
-
19
- CONF = Psych.load(File.read(File.join(app_path, "config.yml")))
20
- ENV["THOR_SILENCE_DEPRECATION"] = "true"
21
- EXPORT_DIR = File.join(app_path, "exports")
22
-
23
6
  Signal.trap("INT") do
24
7
  warn("\n#{caller.join("\n")}: interrupted")
25
8
  exit(1)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "erb"
5
+ require "json"
6
+ require "oci"
7
+ require "pastel"
8
+ require "psych"
9
+ require "rest-client"
10
+ require "thor"
11
+ require "tty-config"
12
+ require "tty-editor"
13
+ require "tty-font"
14
+ require "tty-prompt"
15
+ require "tty-spinner"
16
+ require "tty-table"
17
+ require_relative "rockette/cli"
18
+ require_relative "rockette/controller"
19
+ require_relative "rockette/rester"
20
+ require_relative "rockette/text_helper"
21
+ require_relative "rockette/version"
data/lib/rockette/cli.rb CHANGED
@@ -18,12 +18,14 @@ module Rockette
18
18
  desc "deploy", "Deploy chosen export file to target APEX instance"
19
19
  method_option :help, aliases: "-h", type: :boolean,
20
20
  desc: "Display usage information"
21
- option :app_id, aliases: "-a", required: true,
22
- desc: "Provide an APEX application ID"
21
+ option :app_id, aliases: "-a", default: "0",
22
+ desc: "Update this App ID with export set by '-f' Omitting '-a' copies export to target"
23
23
  option :file, aliases: "-f", required: true,
24
- desc: "Provide an APEX application export file (.sql)"
24
+ desc: "Provide an APEX application export file (sql)"
25
25
  option :url, aliases: "-u", required: true,
26
- desc: "Provide a valid url"
26
+ desc: "Provide a valid APEX deployment url"
27
+ option :secret, aliases: "-s", required: false,
28
+ desc: "Use this flag if you are using managed secrets"
27
29
  def deploy(*)
28
30
  if options[:help]
29
31
  invoke :help, ["deploy"]
@@ -40,6 +42,9 @@ module Rockette
40
42
  desc: "Provide an APEX application ID"
41
43
  option :url, aliases: "-u", required: true,
42
44
  desc: "Provide a valid url"
45
+ option :file, aliases: "-f", required: false,
46
+ desc: "Save export with this file name"
47
+
43
48
  def export(*)
44
49
  if options[:help]
45
50
  invoke :help, ["export"]
@@ -49,9 +54,9 @@ module Rockette
49
54
  end
50
55
  end
51
56
 
52
- desc "config", "Command description..."
57
+ desc "config", "Set configuration options..."
53
58
  method_option :help, aliases: "-h", type: :boolean,
54
- desc: "Display usage information"
59
+ desc: "Not implemented yet..."
55
60
  def config(*)
56
61
  if options[:help]
57
62
  invoke :help, ["config"]
@@ -60,5 +65,19 @@ module Rockette
60
65
  Rockette::Commands::Config.new(options).execute
61
66
  end
62
67
  end
68
+
69
+ desc "interactive", "Start Rockette in interactive mode"
70
+ method_option :help, aliases: "-h", type: :boolean,
71
+ desc: "'rockette' by itself will start interactive mode"
72
+ def interactive(*)
73
+ if options[:help]
74
+ invoke :help, ["interactive"]
75
+ else
76
+ require_relative "commands/interactive"
77
+ Rockette::Commands::Interactive.new(options).execute
78
+ end
79
+ end
80
+
81
+ default_task :interactive
63
82
  end
64
83
  end
@@ -11,28 +11,61 @@ module Rockette
11
11
  def initialize(options)
12
12
  super()
13
13
  @options = options
14
- @filey = "f#{@options[:app_id]}.sql"
14
+ @filey = @options[:file]
15
+ if @options[:secret]
16
+ secret_id = @options[:secret]
17
+ signer = OCI::Auth::Signers::InstancePrincipalsSecurityTokenSigner.new
18
+ identity_client = OCI::Identity::IdentityClient.new(config: OCI::Config.new, signer: signer)
19
+ secret_client = OCI::Secrets::SecretsClient.new(config: OCI::Config.new, signer: signer)
20
+ secret_response = secret_client.get_secret_bundle(secret_id).data.secret_bundle_content.content
21
+ @conf = JSON.parse(Base64.decode64(secret_response))
22
+ else
23
+ @conf = Psych.load(File.read(CONF))
24
+ end
25
+ @body = @conf["token_body"]
26
+ @hdrs = @conf["token_hdrs"]
27
+ @token = get_token
28
+ @hdrs["Authorization"] = "Bearer " + @token
29
+ @hdrs["Content-Type"] = "application/sql"
15
30
  end
16
31
 
17
- def importer
18
- body = CONF["deploy_body"]
19
- body["app_id_src"] = @options[:app_id]
20
- body["app_id_tgt"] = @options[:app_id]
21
- # body["app_id_tgt"] = "0" #test app copy
22
- url = "#{@options[:url]}deploy/app"
23
- response = Rester.new(meth: "Post", params: body, url: url).rest_try
32
+ def check_version(filey)
33
+ app_url = "#{@options[:url]}deploy/apps/#{@options[:app_id]}"
34
+ response = Rester.new(url: app_url, headers: @hdrs).rest_try
24
35
  bail unless response
25
- abort padder("Error. Got back response code: #{response.code}") unless (200..201).include? response.code
26
- response
36
+ abort padder("App ID: #{@options[:app_id]}, not found. Received: #{response.code}") unless response.code == 200
37
+ deployed_version = JSON.parse(response.body)["version"]
38
+ fh = File.open(filey, 'r')
39
+ export_version = ''
40
+ fh.each_line do |line|
41
+ if line.match(/,p_flow_version=>'/)
42
+ export_version = line.match(/^,p_flow_version=>'(.*?)'$/)[1]
43
+ end
44
+ end
45
+ return deployed_version == export_version
46
+ end
47
+
48
+ def file_finder
49
+ [EXPORT_DIR, "/usr/app", "/usr/local/app"].each do |f|
50
+ next unless File.exist?(File.join(f, @filey))
51
+ break File.join(f, @filey) if File.exist?(File.join(f, @filey)) # Take 1st match
52
+ end
53
+ end
54
+
55
+ def get_token
56
+ token_url = "#{@options[:url]}oauth/token"
57
+ response = Rester.new(headers: @hdrs, meth: "Post", params: @body, url: token_url).rest_try
58
+ return JSON.parse(response.body)["access_token"]
27
59
  end
28
60
 
29
- def pusher
30
- push_hdrs = CONF["push_hdrs"]
31
- push_hdrs["file_name"] = @filey
32
- push_url = "#{@options[:url]}data_loader/blob"
33
- # Push the chosen export file to the target system
34
- filey = File.join(EXPORT_DIR, @filey)
35
- response = Rester.new(headers: push_hdrs, meth: "Post", params: File.open(filey), url: push_url).rest_try
61
+ def deployer
62
+ push_url = "#{@options[:url]}deploy/app/#{@options[:app_id]}/"
63
+ filey = file_finder
64
+ file_not_found if filey.is_a?(Array)
65
+ if @options[:app_id] != '0' then
66
+ abort padder("Error. Versions are identical, unable to deploy export") if check_version(filey)
67
+ end
68
+ response = Rester.new(headers: @hdrs, meth: "Post", params: File.open(filey), url: push_url).rest_try
36
69
  bail unless response
37
70
  abort padder("Error. Got back response code: #{response.code}") unless (200..201).include? response.code
38
71
  response
@@ -40,13 +73,10 @@ module Rockette
40
73
 
41
74
  def execute(input: $stdin, output: $stdout)
42
75
  check_input(input)
43
- # Create and download export
44
- output.puts padder("OK, deploying export file #{@filey}")
45
- pusher
46
- output.puts padder("Pushed #{@filey} to instance and attempting import now...")
47
- # If push was successful, request application import
48
- sleep 1
49
- importer
76
+ filey = file_finder
77
+ file_not_found if filey.is_a?(Array)
78
+ output.puts padder("Attempting to deploy export file #{@filey}...")
79
+ deployer
50
80
  output.puts padder("Deployed #{@filey} to target APEX instance: #{@options[:url]}")
51
81
  end
52
82
  end
@@ -11,12 +11,17 @@ module Rockette
11
11
  def initialize(options)
12
12
  super()
13
13
  @options = options
14
+ @conf = Psych.load(File.read(CONF))
15
+ @body = @conf["token_body"]
16
+ @hdrs = @conf["token_hdrs"]
14
17
  @filey = "f#{@options[:app_id]}.sql"
18
+ @token = get_token
19
+ @hdrs["Authorization"] = "Bearer " + @token
15
20
  end
16
21
 
17
22
  def checker
18
23
  app_url = "#{@options[:url]}deploy/apps/#{@options[:app_id]}"
19
- response = Rester.new(url: app_url).rest_try
24
+ response = Rester.new(url: app_url, headers: @hdrs).rest_try
20
25
  bail unless response
21
26
  abort padder("App ID: #{@options[:app_id]}, not found. Received: #{response.code}") unless response.code == 200
22
27
  end
@@ -24,32 +29,26 @@ module Rockette
24
29
  def exporter
25
30
  checker
26
31
  puts padder("Found Application ID: #{@options[:app_id]}, proceeding...")
27
- body = { "app_id" => @options[:app_id] }
28
- export_url = "#{@options[:url]}deploy/app_export"
29
- response = Rester.new(meth: "Post", params: body, url: export_url).rest_try
32
+ export_url = "#{@options[:url]}deploy/app/#{@options[:app_id]}"
33
+ response = Rester.new(url: export_url, headers: @hdrs).rest_try
30
34
  bail unless response
31
- abort padder("Export failed for App ID: #{@options[:app_id]}.") unless (200..201).include? response.code
35
+ abort padder("Download failed for App ID: #{@options[:app_id]}.") unless (200..201).include? response.code
32
36
  response
33
37
  end
34
38
 
35
- def grabber
36
- export_url = "#{@options[:url]}deploy/app_export/#{@filey}"
37
- response = Rester.new(url: export_url).rest_try
38
- bail unless response
39
- abort padder("Download failed for App ID: #{@options[:app_id]}.") unless (200..201).include? response.code
40
- response
39
+ def get_token
40
+ token_url = "#{@options[:url]}oauth/token"
41
+ response = Rester.new(headers: @hdrs, meth: "Post", params: @body, url: token_url).rest_try
42
+ return JSON.parse(response.body)["access_token"]
41
43
  end
42
44
 
43
45
  def execute(input: $stdin, output: $stdout)
44
46
  check_input(input)
45
- # Create and download export
46
- exporter
47
- output.puts padder("Export created, downloading...")
48
- sleep 1
49
- response = grabber
47
+ response = exporter
50
48
  # Write file if export was grabbed.
51
- File.open(File.join(EXPORT_DIR, @filey), "wb") { |file| file.write(response.body) }
52
- output.puts padder("Finished downloading #{@filey}. Have a good one!")
49
+ save_file = @options[:file] || @filey
50
+ File.open(File.join(EXPORT_DIR, save_file), "wb") { |file| file.write(response.body) }
51
+ output.puts padder("Finished downloading #{save_file}. Have a good one!")
53
52
  end
54
53
  end
55
54
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+
5
+ module Rockette
6
+ module Commands
7
+ # Interactive Rockette
8
+ class Interactive < Rockette::Command
9
+ include TextHelper
10
+
11
+ def initialize(options)
12
+ super()
13
+ @options = options
14
+ end
15
+
16
+ def execute(input: $stdin, output: $stdout)
17
+ output.puts
18
+ check_input(input)
19
+ controller = Rockette::Controller.new
20
+ controller.launch!
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../text_helper"
4
+
5
+ module Rockette
6
+ # Configure Rockette application
7
+ class Configurator
8
+ include TextHelper
9
+
10
+ attr_reader :config
11
+
12
+ def initialize
13
+ @config = TTY::Config.new
14
+ @config.append_path APP_PATH
15
+ @config.read
16
+
17
+ @pastel = Pastel.new
18
+ @prompt = TTY::Prompt.new
19
+ end
20
+
21
+ def self.config
22
+ @config ||= self.class.new.config
23
+ end
24
+
25
+ def launch!
26
+ puts
27
+ puts @pastel.yellow("Configure Rockette here. Choosing 'editor' will let you edit the config file directly.")
28
+ puts @pastel.yellow("Choose 'url' to enter a controller url, the api endpoint with your environments, etc.")
29
+ puts
30
+ # input/action loop
31
+ loop do
32
+ action = @prompt.select("What will it be?", %w[editor url back])
33
+ break if action == "back"
34
+
35
+ do_action(action)
36
+ end
37
+ end
38
+
39
+ def do_action(action)
40
+ case action
41
+ when "editor"
42
+ edit_config
43
+ when "url"
44
+ add_url
45
+ else
46
+ puts "\nI don't understand that command.\n\n"
47
+ end
48
+ end
49
+
50
+ def add_url
51
+ uri = @prompt.ask("Please enter APEX deployment URI (base path):") do |u|
52
+ u.validate(%r{^https://\w+.\w+})
53
+ end
54
+ @config.set(:rockette, :controller_url, value: uri)
55
+ @config.write(force: true)
56
+ refresh_conf
57
+ end
58
+
59
+ def edit_config
60
+ edit = TTY::Editor.open(CONF)
61
+ puts "There seems to have been an issue trying to open the file: #{CONF}" unless edit
62
+ refresh_conf if edit
63
+ end
64
+
65
+ def first_run
66
+ puts
67
+ puts "I see this is your first time running Rockette. Entering an APEX deployment"
68
+ puts "uri will allow me to discover more about your environments."
69
+ puts
70
+ response = @prompt.yes?("Would you like to enter a URI?")
71
+ if response == true
72
+ add_url
73
+ else
74
+ response = @prompt.yes?("Would you like to disable these checks in the future?")
75
+ @config.set(:rockette, :check_for_url, value: false) if response == true
76
+ end
77
+ @config.write(force: true) if response == true
78
+ refresh_conf
79
+ end
80
+
81
+ def refresh_conf
82
+ @config.read
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../text_helper"
4
+ require_relative "../commands/deploy"
5
+
6
+ module Rockette
7
+ # Push APEX application to target instance
8
+ class Deployer
9
+ include TextHelper
10
+
11
+ def initialize
12
+ @pastel = Pastel.new
13
+ @prompt = TTY::Prompt.new
14
+ @spinner = TTY::Spinner.new
15
+ end
16
+
17
+ def launch!
18
+ @conf = Psych.load(File.read(CONF))
19
+ intro_text
20
+
21
+ # input/action loop
22
+ loop do
23
+ actions = { "🛸 Add" => 1, "📝 Update" => 2, "⬅️ Go Back" => 3 }
24
+ response = @prompt.select("Add application or update an existing application?", actions)
25
+ break if response == 3
26
+
27
+ add_app if response == 1
28
+ updater if response == 2
29
+ end
30
+ puts
31
+ end
32
+
33
+ protected
34
+
35
+ def intro_text
36
+ puts
37
+ puts @pastel.yellow("These are the two available options:")
38
+ print "1. Add application to an APEX instance. "
39
+ print "It's #{@pastel.green.bold("generally safe and creates a new application")} from the export\n"
40
+ print "2. Update an existing application with your chosen export. "
41
+ print "#{@pastel.red.bold("Tread carefully")} with this option!\n"
42
+ puts
43
+ end
44
+
45
+ def add_app
46
+ puts padder("Let's choose an export to add")
47
+ file = choose_file
48
+ url = choose_env
49
+ puts padder("You chose to add #{file} to the environment at #{url}")
50
+ puts
51
+ return unless @prompt.yes?("Proceed with the deployment?")
52
+
53
+ options = Thor::CoreExt::HashWithIndifferentAccess.new "app_id" => "0", "url" => url, "file" => file,
54
+ "force" => true
55
+ Rockette::Commands::Deploy.new(options).execute
56
+ puts
57
+ end
58
+
59
+ def choose_app(apps_url)
60
+ apps = Rockette::Viewer.new.applications(apps_url)
61
+ list = list_builder(apps)
62
+ action = @prompt.slider("Application to update => ", list, default: 1)
63
+
64
+ apps[action - 1]
65
+ end
66
+
67
+ def choose_env
68
+ enviros = Rockette::Viewer.new.environments
69
+ list = list_builder(enviros)
70
+ action = @prompt.select("Which environment?", list)
71
+ enviros[action - 1]["deployment_api"]
72
+ end
73
+
74
+ def choose_file
75
+ list = Dir.children(EXPORT_DIR)
76
+ @prompt.select("Which export from #{EXPORT_DIR}?", list)
77
+ end
78
+
79
+ def list_builder(array)
80
+ names = [] # Start building selection list
81
+ if array[0].key?("name")
82
+ array.each { |n| names << n["name"] }
83
+ else
84
+ array.each { |n| names << "#{n["application_name"]} App ID: #{n["application_id"]}" }
85
+ end
86
+ names << "Go Back"
87
+ names.map.with_index { |n, x| [n, x + 1] }.to_h
88
+ end
89
+
90
+ def updater
91
+ puts padder("Please choose the export with your updated application code")
92
+ file = choose_file
93
+ url = choose_env
94
+ app = choose_app(url)
95
+ puts "Application: #{app["application_name"]} | App ID: #{app["application_id"]} | Env URI: #{url}"
96
+ puts "will be updated with the code from export: #{file}"
97
+ puts
98
+ return unless @prompt.yes?("Proceed with the deployment?")
99
+
100
+ options = Thor::CoreExt::HashWithIndifferentAccess.new "app_id" => app["application_id"], "url" => url,
101
+ "file" => file, "force" => true
102
+ Rockette::Commands::Deploy.new(options).execute
103
+ puts
104
+ end
105
+ end
106
+ end