rockette 0.0.1 → 0.0.5

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 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