rockette 0.0.2 → 0.0.6

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: 0f2bd092666b9d3952a13d9009337006088e6953db8f418274bf645ba98ea99c
4
- data.tar.gz: ed1e3372aae98f79c10845c67a726a8b83a7cf7bd68edf6d8b7ef2fe382feea2
3
+ metadata.gz: 26e8d73d2c9b1c9a543b41dfd95dda73efea46e5bb14d444a5f50ada2af968ce
4
+ data.tar.gz: 44b7d193c2ad1ff6dcb9efad3ab7b5a70c87ba8942fb919aec5fa2302c4282b4
5
5
  SHA512:
6
- metadata.gz: ea97f6f7946d19d31879ce554d825ed2303ccf511761645529e0213df1cdfdb0ce5b18fb94dd493fa21597703bef54575b6fdd2254c0582f3c36a1089a00d028
7
- data.tar.gz: ff75dcaf8d481ff7f2a63e4212634dec0e2e60172b6da158cd9dc5f8d51505f9daa6c0a26a0097113ffec2216d72b3b7aef505a8fb5521afce9e549df93571a2
6
+ metadata.gz: 0124ec971be8e538d810582967a512dc26efbaa2ed9e6e9f61fd9f1a954b40b2d3e6625e0b91aa813eac9902350cb3df2ce9f8c1f018edcc9aabdfaa87c73e43
7
+ data.tar.gz: aabc39c4210d4ec7dc7ca56cede861c433349fe395088657eba03744c3ced88ca91d7227ddba1488a48d238e87d1d92c05bda232a0d0907a057e7b90d61a193e
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
@@ -16,4 +16,18 @@
16
16
 
17
17
  - Add copy switch to deploy command
18
18
  - Use file name passed via -f switch
19
- - Try to find export file and let caller know if file not found
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/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,14 +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
26
  desc: "Provide a valid APEX deployment url"
27
- option :copy, aliases: "-c", required: false,
28
- desc: "Use this flag if you are copying an application instead of overwriting"
27
+ option :secret, aliases: "-s", required: false,
28
+ desc: "Use this flag if you are using managed secrets"
29
29
  def deploy(*)
30
30
  if options[:help]
31
31
  invoke :help, ["deploy"]
@@ -42,6 +42,9 @@ module Rockette
42
42
  desc: "Provide an APEX application ID"
43
43
  option :url, aliases: "-u", required: true,
44
44
  desc: "Provide a valid url"
45
+ option :file, aliases: "-f", required: false,
46
+ desc: "Save export with this file name"
47
+
45
48
  def export(*)
46
49
  if options[:help]
47
50
  invoke :help, ["export"]
@@ -51,9 +54,9 @@ module Rockette
51
54
  end
52
55
  end
53
56
 
54
- desc "config", "Command description..."
57
+ desc "config", "Set configuration options..."
55
58
  method_option :help, aliases: "-h", type: :boolean,
56
- desc: "Display usage information"
59
+ desc: "Not implemented yet..."
57
60
  def config(*)
58
61
  if options[:help]
59
62
  invoke :help, ["config"]
@@ -62,5 +65,19 @@ module Rockette
62
65
  Rockette::Commands::Config.new(options).execute
63
66
  end
64
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
65
82
  end
66
83
  end
@@ -12,10 +12,37 @@ module Rockette
12
12
  super()
13
13
  @options = options
14
14
  @filey = @options[:file]
15
- @body = CONF["deploy_body"]
16
- @body["app_id_src"] = "1" # @options[:app_id]
17
- @body["app_id_tgt"] = @options[:copy] ? 0 : @options[:app_id]
18
- @body["blob_url"] = @filey
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 = Psych.load(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
+ @hdrs["Authorization"] = @conf["web_creds"][@options[:cred]] if @options[:cred]
28
+ @token = get_token
29
+ @hdrs["Authorization"] = "Bearer " + @token
30
+ end
31
+
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
35
+ bail unless 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
19
46
  end
20
47
 
21
48
  def file_finder
@@ -25,22 +52,21 @@ module Rockette
25
52
  end
26
53
  end
27
54
 
28
- def importer
29
- url = "#{@options[:url]}deploy/app"
30
- response = Rester.new(meth: "Post", params: @body, url: url).rest_try
31
- bail unless response
32
- abort padder("Error. Got back response code: #{response.code}") unless (200..201).include? response.code
33
- response
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"]
34
59
  end
35
60
 
36
- def pusher
37
- push_hdrs = CONF["push_hdrs"]
38
- push_hdrs["file_name"] = @filey
39
- push_url = "#{@options[:url]}data_loader/blob"
40
- # Push the chosen export file to the target system
61
+ def deployer
62
+ push_url = "#{@options[:url]}deploy/app/#{@options[:app_id]}/"
41
63
  filey = file_finder
42
64
  file_not_found if filey.is_a?(Array)
43
- response = Rester.new(headers: push_hdrs, meth: "Post", params: File.open(filey), url: push_url).rest_try
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
+ @hdrs["Content-Type"] = "application/sql"
69
+ response = Rester.new(headers: @hdrs, meth: "Post", params: File.open(filey), url: push_url).rest_try
44
70
  bail unless response
45
71
  abort padder("Error. Got back response code: #{response.code}") unless (200..201).include? response.code
46
72
  response
@@ -48,13 +74,10 @@ module Rockette
48
74
 
49
75
  def execute(input: $stdin, output: $stdout)
50
76
  check_input(input)
51
- # Create and download export
77
+ filey = file_finder
78
+ file_not_found if filey.is_a?(Array)
52
79
  output.puts padder("Attempting to deploy export file #{@filey}...")
53
- pusher
54
- output.puts padder("Pushed #{@filey} to instance and attempting import now...")
55
- # If push was successful, request application import
56
- sleep 1
57
- importer
80
+ deployer
58
81
  output.puts padder("Deployed #{@filey} to target APEX instance: #{@options[:url]}")
59
82
  end
60
83
  end
@@ -11,12 +11,18 @@ 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"]
17
+ @hdrs["Authorization"] = @conf["web_creds"][@options[:cred]] if @options[:cred]
14
18
  @filey = "f#{@options[:app_id]}.sql"
19
+ @token = get_token
20
+ @hdrs["Authorization"] = "Bearer " + @token
15
21
  end
16
22
 
17
23
  def checker
18
24
  app_url = "#{@options[:url]}deploy/apps/#{@options[:app_id]}"
19
- response = Rester.new(url: app_url).rest_try
25
+ response = Rester.new(url: app_url, headers: @hdrs).rest_try
20
26
  bail unless response
21
27
  abort padder("App ID: #{@options[:app_id]}, not found. Received: #{response.code}") unless response.code == 200
22
28
  end
@@ -24,32 +30,26 @@ module Rockette
24
30
  def exporter
25
31
  checker
26
32
  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
33
+ export_url = "#{@options[:url]}deploy/app/#{@options[:app_id]}"
34
+ response = Rester.new(url: export_url, headers: @hdrs).rest_try
30
35
  bail unless response
31
- abort padder("Export failed for App ID: #{@options[:app_id]}.") unless (200..201).include? response.code
36
+ abort padder("Download failed for App ID: #{@options[:app_id]}.") unless (200..201).include? response.code
32
37
  response
33
38
  end
34
39
 
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
40
+ def get_token
41
+ token_url = "#{@options[:url]}oauth/token"
42
+ response = Rester.new(headers: @hdrs, meth: "Post", params: @body, url: token_url).rest_try
43
+ return JSON.parse(response.body)["access_token"]
41
44
  end
42
45
 
43
46
  def execute(input: $stdin, output: $stdout)
44
47
  check_input(input)
45
- # Create and download export
46
- exporter
47
- output.puts padder("Export created, downloading...")
48
- sleep 1
49
- response = grabber
48
+ response = exporter
50
49
  # 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!")
50
+ save_file = @options[:file] || @filey
51
+ File.open(File.join(EXPORT_DIR, save_file), "wb") { |file| file.write(response.body) }
52
+ output.puts padder("Finished downloading #{save_file}. Have a good one!")
53
53
  end
54
54
  end
55
55
  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,98 @@
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_controller_cred
51
+ puts "Now that you have entered a controller url, please enter the OAuth client credentials for the controller."
52
+ user = @prompt.ask("User:")
53
+ pass = @prompt.ask("Pass:")
54
+ basey = 'Basic ' + Base64.encode64(user + ":" + pass).tr("\n", "")
55
+ @config.set(:rockette, :controller_cred, value: basey)
56
+ @config.write(force: true)
57
+ refresh_conf
58
+ puts "Choose View Resources and then All Applications to automate adding client credentials for each environment."
59
+ puts "You will need these credentials to use Rockette to deploy, export, and update applications."
60
+ end
61
+
62
+ def add_url
63
+ uri = @prompt.ask("Please enter APEX deployment URI (base path):") do |u|
64
+ u.validate(%r{^https://\w+.\w+})
65
+ end
66
+ @config.set(:rockette, :controller_url, value: uri)
67
+ @config.write(force: true)
68
+ refresh_conf
69
+ end
70
+
71
+ def edit_config
72
+ edit = TTY::Editor.open(CONF)
73
+ puts "There seems to have been an issue trying to open the file: #{CONF}" unless edit
74
+ refresh_conf if edit
75
+ end
76
+
77
+ def first_run
78
+ puts
79
+ puts "I see this is your first time running Rockette. Entering an APEX deployment"
80
+ puts "uri will allow me to discover more about your environments."
81
+ puts
82
+ response = @prompt.yes?("Would you like to enter a URI?")
83
+ if response == true
84
+ add_url
85
+ add_controller_cred
86
+ else
87
+ response = @prompt.yes?("Would you like to disable these checks in the future?")
88
+ @config.set(:rockette, :check_for_url, value: false) if response == true
89
+ end
90
+ @config.write(force: true) if response == true
91
+ refresh_conf
92
+ end
93
+
94
+ def refresh_conf
95
+ @config.read
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,108 @@
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
+ env = choose_env
49
+ url = env[0]
50
+ puts padder("You chose to add #{file} to the environment at #{url}")
51
+ puts
52
+ return unless @prompt.yes?("Proceed with the deployment?")
53
+
54
+ options = Thor::CoreExt::HashWithIndifferentAccess.new "app_id" => "0", "url" => url, "file" => file,
55
+ "cred" => env[1], "force" => true
56
+ Rockette::Commands::Deploy.new(options).execute
57
+ puts
58
+ end
59
+
60
+ def choose_app(apps_url, cred)
61
+ apps = Rockette::Viewer.new.applications(apps_url, cred)
62
+ list = list_builder(apps)
63
+ action = @prompt.slider("Application to update => ", list, default: 1)
64
+
65
+ apps[action - 1]
66
+ end
67
+
68
+ def choose_env
69
+ enviros = Rockette::Viewer.new.environments
70
+ list = list_builder(enviros)
71
+ action = @prompt.select("Which environment?", list)
72
+ [enviros[action - 1]["deployment_api"], enviros[action - 1]["web_cred"]]
73
+ end
74
+
75
+ def choose_file
76
+ list = Dir.children(EXPORT_DIR)
77
+ @prompt.select("Which export from #{EXPORT_DIR}?", list)
78
+ end
79
+
80
+ def list_builder(array)
81
+ names = [] # Start building selection list
82
+ if array[0].key?("name")
83
+ array.each { |n| names << n["name"] }
84
+ else
85
+ array.each { |n| names << "#{n["application_name"]} App ID: #{n["application_id"]}" }
86
+ end
87
+ names << "Go Back"
88
+ names.map.with_index { |n, x| [n, x + 1] }.to_h
89
+ end
90
+
91
+ def updater
92
+ puts padder("Please choose the export with your updated application code")
93
+ file = choose_file
94
+ env = choose_env
95
+ url = env[0]
96
+ app = choose_app(url, env[1])
97
+ puts "Application: #{app["application_name"]} | App ID: #{app["application_id"]} | Env URI: #{url}"
98
+ puts "will be updated with the code from export: #{file}"
99
+ puts
100
+ return unless @prompt.yes?("Proceed with the deployment?")
101
+
102
+ options = Thor::CoreExt::HashWithIndifferentAccess.new "app_id" => app["application_id"], "url" => url,
103
+ "cred" => env[1], "file" => file, "force" => true
104
+ Rockette::Commands::Deploy.new(options).execute
105
+ puts
106
+ end
107
+ end
108
+ end