capistrano-ops 0.2.2 → 0.2.4

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: 686aab7630f72e2ca576bc58f02862bf8b5762510ff40f2ce604be0d1ada88bd
4
- data.tar.gz: f875a5b4c61817a51f7997595a0f68fa4f83e6fccfa0613f089918ff28dd568d
3
+ metadata.gz: 6897d38c35cb8b0dfb713d16d0eb0c390c431636ea5c6565e1dc457b96a29c6b
4
+ data.tar.gz: 9789f0e37f0767403324c1ca68c97759a8ebdbdb5a3e4ac6d362b76dfc5064ad
5
5
  SHA512:
6
- metadata.gz: 9c8a40071b97244aebb277e4aaeb97530852260fe5e2d0f15e494b251e39e19fc3842bf37bcc5e21afaa81b4acb2059e142b6b869c3d22dea7a725adc1570ff6
7
- data.tar.gz: 31db42f2591646789b7ce809e3bc7fd3ea5a9d4ee6b6fd5466d5777fe62d085716b6b73bb9f92bd4503494c58da48f33791223ca4adf0ec27e2061146f157587
6
+ metadata.gz: 4607175b27284ed6d19ca2fe3032dccde17f54cb62dfbfc43c614af031abf9990b873b89b1d905c74d2acb48dc4e94a3eec6b50bbff18dee0079b2a5264d04dd
7
+ data.tar.gz: 1ce1060464559ce566320e9ef7a1700d5d94ee688e6f8aea85f7dbd2548e78bfc5e6cb1f5e751b38e9b566e7411e89587d4207eb6c0349592d0cacab854e6ffc
data/.rubocop.yml ADDED
@@ -0,0 +1,21 @@
1
+ AllCops:
2
+ NewCops: disable
3
+ TargetRubyVersion: 2.7
4
+ Layout/LineLength:
5
+ Max: 160
6
+ Metrics/MethodLength:
7
+ Max: 50
8
+ Metrics/ClassLength:
9
+ Max: 750
10
+ Metrics/BlockLength:
11
+ Max: 50
12
+ Metrics/ParameterLists:
13
+ Max: 6
14
+ Metrics/AbcSize:
15
+ Max: 60
16
+ Metrics/CyclomaticComplexity:
17
+ Max: 25
18
+ Metrics/PerceivedComplexity:
19
+ Max: 25
20
+ Style/Documentation:
21
+ Enabled: false
data/README.md CHANGED
@@ -9,6 +9,9 @@ Library of useful scripts for DevOps using capistrano with rails.
9
9
  ```ruby
10
10
  'capistrano', '~> 3.0'
11
11
  'whenever'
12
+ 'capistrano-figaro-yml'
13
+
14
+ # hint: if you use other aws-sdk gems, its possible that you have to update them too
12
15
  ```
13
16
 
14
17
  ## Installation
@@ -43,8 +46,12 @@ require 'capistrano/ops'
43
46
 
44
47
  | Script | Description |
45
48
  | ------------------------------------------------ | ----------------------------------------------------------------- |
46
- | `cap <environment> backup:create` | creates backup of postgres database on the server |
47
- | `cap <environment> backup:pull` | download latest postgres backup from server |
49
+ | `cap <environment> backup:create` | creates backup of postgres database on the server (deprecated) |
50
+ | `cap <environment> backup:pull` | download latest postgres backup from server (deprecated) |
51
+ | `cap <environment> backup:database:create` | creates backup of postgres database on the server |
52
+ | `cap <environment> backup:database:pull` | download latest postgres backup from server |
53
+ | `cap <environment> backup:storage:create` | creates backup of storage on the server |
54
+ | `cap <environment> backup:storage:pull` | download latest storage backup from server |
48
55
  | `cap <environment> figaro_yml:compare` | compare local application.yml with server application.yml |
49
56
  | `cap <environment> figaro_yml:get` | shows env vars from server application.yml configured thru figaro |
50
57
  | `cap <environment> logs:rails` | display server log live |
@@ -52,6 +59,8 @@ require 'capistrano/ops'
52
59
  | `cap <environment> invoke:rake TASK=<your:task>` | invoke rake task on server |
53
60
  | `rake pg:dump` | creates postgres database backup |
54
61
  | `rake pg:remove_old_dumps` | remove old postgres backups |
62
+ | `rake storage:backup` | creates backup of storage |
63
+ | `rake storage:remove_old_backups` | remove old storage backups |
55
64
 
56
65
  ## Usage
57
66
 
@@ -69,17 +78,26 @@ production:
69
78
 
70
79
  ### Optional Settings for backup task
71
80
 
72
- | env | description | type/options |
73
- | ------------------ | ---------------------------------------------------------------------- | :----------------------------------------------------------------: |
74
- | NUMBER_OF_BACKUPS | number of backups to keep (default: 1) | `number` |
75
- | BACKUPS_ENABLED | enable/disable backup task (default: Rails.env == 'production') | `boolean` |
76
- | DEFAULT_URL | notification message title (default: "#{database} Backup") | `string` |
77
- | NOTIFICATION_TYPE | for notification (default: nil) | `string` (`webhook`/`slack`) |
78
- | NOTIFICATION_LEVEL | for notification (default: nil) | `string` (`info`/`error`) |
79
- | SLACK_SECRET | for slack integration | `string` (e.g. `xoxb-1234567890-1234567890-1234567890-1234567890`) |
80
- | SLACK_CHANNEL | for slack integration | `string` (e.g. `C234567890`) |
81
- | WEBHOOK_URL | Webhook server to send message | e.g `http://example.com` |
82
- | WEBHOOK_SECRET | Secret to send with uses md5-hmac hexdigest in header`x-hub-signature` | --- |
81
+ | env | description | type/options |
82
+ | -------------------------- | --------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------: |
83
+ | NUMBER_OF_BACKUPS | number of backups to keep (default: 7) | `number` |
84
+ | NUMBER_OF_LOCAL_BACKUPS | number of backups to keep locally (default: nil) | `number` |
85
+ | NUMBER_OF_EXTERNAL_BACKUPS | number of backups to keep externally (default: nil) | `number` |
86
+ | BACKUPS_ENABLED | enable/disable backup task (default: Rails.env == 'production') | `boolean` |
87
+ | EXTERNAL_BACKUP_ENABLED | enable/disable external backup (default: false) (only if 'BACKUPS_ENABLED', needs additional setup) | `boolean` |
88
+ | DEFAULT_URL | notification message title (default: "#{database} Backup") | `string` |
89
+ | NOTIFICATION_TYPE | for notification (default: nil) | `string` (`webhook`/`slack`) |
90
+ | NOTIFICATION_LEVEL | for notification (default: nil) | `string` (`info`/`error`) |
91
+ | SLACK_SECRET | for slack integration | `string` (e.g. `xoxb-1234567890-1234567890-1234567890-1234567890`) |
92
+ | SLACK_CHANNEL | for slack integration | `string` (e.g. `C234567890`) |
93
+ | WEBHOOK_URL | Webhook server to send message | e.g `http://example.com` |
94
+ | WEBHOOK_SECRET | Secret to send with uses md5-hmac hexdigest in header`x-hub-signature` | --- |
95
+ | BACKUP_PROVIDER | Backup provider (default: nil) | `string` (`s3`) |
96
+ | S3_BACKUP_BUCKET | S3 bucket name for backups | `string` |
97
+ | S3_BACKUP_REGION | S3 region for backups | `string` |
98
+ | S3_BACKUP_KEY | S3 access key for backups | `string` |
99
+ | S3_BACKUP_SECRET | S3 secret key for backups | `string` |
100
+ | S3_BACKUP_ENDPOINT | S3 endpoint for backups (optional, used for other S3 compatible services) | `string` |
83
101
 
84
102
  ### use with whenever/capistrano
85
103
 
@@ -93,10 +111,12 @@ set :output, -> { '2>&1 | logger -t whenever_cron' }
93
111
 
94
112
  every :day, at: '2:00 am' do
95
113
  rake 'pg:dump'
114
+ rake 'storage:backup'
96
115
  end
97
116
 
98
117
  every :day, at: '3:00 am' do
99
118
  rake 'pg:remove_old_dumps'
119
+ rake 'storage:remove_old_backups'
100
120
  end
101
121
  ```
102
122
 
@@ -144,6 +164,34 @@ if you want to use notification level you have to add this to your `application.
144
164
  NOTIFICATION_LEVEL: 'info' # default is 'error'
145
165
  ```
146
166
 
167
+ ## Backups
168
+
169
+ if you want to configure the number of backups you have to add this to your `application.yml`
170
+
171
+ ```ruby
172
+ NUMBER_OF_BACKUPS: 7 # default is 7 (local + external)
173
+ ```
174
+
175
+ to fine tune the number of local and external backups you can use this:
176
+
177
+ ```ruby
178
+ NUMBER_OF_LOCAL_BACKUPS: 7 # default is nil (local)
179
+ NUMBER_OF_EXTERNAL_BACKUPS: 7 # default is nil (local)
180
+ ```
181
+
182
+ ### Backup provider
183
+
184
+ if you want to use an external backup provider you have to add this to your `application.yml`
185
+
186
+ ```ruby
187
+ BACKUP_PROVIDER: 's3'
188
+ S3_BACKUP_BUCKET: '<your-s3-bucket>'
189
+ S3_BACKUP_REGION: '<your-s3-region>'
190
+ S3_BACKUP_KEY: '<your-s3-key>'
191
+ S3_BACKUP_SECRET: '<your-s3-secret>'
192
+ S3_BACKUP_ENDPOINT: '<your-s3-endpoint>' # optional, used for other S3 compatible services
193
+ ```
194
+
147
195
  ## Contributing
148
196
 
149
197
  1. Fork it ( https://github.com/zauberware/capistrano-ops/fork )
@@ -18,12 +18,12 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- test/{functional,unit}/*`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
20
  s.require_paths = ['lib']
21
-
22
- s.required_ruby_version = '>= 2.5.0', '< 3.0.0'
23
-
24
- s.add_dependency 'rails'
21
+
22
+ s.required_ruby_version = '~> 2.7.0'
23
+ s.add_dependency 'aws-sdk-s3', '~> 1.128'
24
+ s.add_dependency 'faraday'
25
25
  s.add_dependency 'nokogiri'
26
-
26
+ s.add_dependency 'rails'
27
27
  s.add_development_dependency 'bundler', '~> 2.4.12'
28
28
  s.add_development_dependency 'rake', '~> 10.0'
29
29
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ class Api
5
+ attr_accessor :backup_provider, :provider_config
6
+
7
+ def initialize(provider: ENV['BACKUP_PROVIDER'], provider_config: {})
8
+ self.backup_provider = provider
9
+ self.provider_config = provider_config
10
+ end
11
+
12
+ def upload(backup_file, filename)
13
+ case backup_provider
14
+ when 's3'
15
+ s3 = Backup::S3.new(**provider_config)
16
+ s3.upload(backup_file, filename)
17
+ when 'scp'
18
+ p 'SCP backup not implemented yet'
19
+ when 'rsync'
20
+ p 'Rsync backup not implemented yet'
21
+ else
22
+ raise Backup::Error, 'Backup provider not configured'
23
+ end
24
+ end
25
+
26
+ def remove_old_backups(basename, keep)
27
+ case backup_provider
28
+ when 's3'
29
+ s3 = Backup::S3.new(**provider_config)
30
+ s3.remove_old_backups(basename, keep: keep)
31
+ when 'scp'
32
+ p 'SCP backup not implemented yet'
33
+ when 'rsync'
34
+ p 'Rsync backup not implemented yet'
35
+ else
36
+ raise Backup::Error, 'Backup provider not configured'
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Backup
4
+ require 'aws-sdk-s3'
5
+ class S3
6
+ attr_accessor :endpoint, :region, :access_key_id, :secret_access_key, :s3_client
7
+
8
+ def initialize(endpoint: ENV['S3_BACKUP_ENDPOINT'], region: ENV['S3_BACKUP_REGION'], access_key_id: ENV['S3_BACKUP_KEY'],
9
+ secret_access_key: ENV['S3_BACKUP_SECRET'])
10
+ self.endpoint = endpoint
11
+ self.region = region
12
+ self.access_key_id = access_key_id
13
+ self.secret_access_key = secret_access_key
14
+ config = {
15
+ region: region,
16
+ access_key_id: access_key_id,
17
+ secret_access_key: secret_access_key
18
+ }
19
+ config[:endpoint] = endpoint unless endpoint.nil?
20
+ self.s3_client = Aws::S3::Client.new(config)
21
+ end
22
+
23
+ def upload(backup_file, key)
24
+ begin
25
+ s3_client.put_object(
26
+ bucket: ENV['S3_BACKUP_BUCKET'],
27
+ key: key,
28
+ body: File.open(backup_file)
29
+ )
30
+ rescue StandardError => e
31
+ puts "Error uploading backup to S3: #{e.message}"
32
+ raise e
33
+ end
34
+ 'File uploaded to S3'
35
+ end
36
+
37
+ def remove_old_backups(basename, keep: 5)
38
+ bucket = ENV['S3_BACKUP_BUCKET']
39
+ all_items = s3_client.list_objects_v2(bucket: bucket, prefix: basename).contents
40
+ count = all_items.count
41
+ if count <= keep
42
+ p 'Nothing to remove'
43
+ return
44
+ end
45
+ items = all_items.sort_by(&:last_modified).reverse.slice(keep..-1).map(&:key)
46
+ items.each do |item|
47
+ p "Removing #{item} from S3"
48
+ s3_client.delete_object(bucket: bucket, key: item)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'capistrano/ops/backup/api'
4
+ require 'capistrano/ops/backup/s3'
5
+
6
+ module Backup
7
+ class Error < StandardError; end
8
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BackupHelper
4
+ def backup_file_name(type)
5
+ regex = type == 'storage' ? "'.{0,}\.tar.gz'" : "'.{0,}\.dump'"
6
+ @backup_file_name ||= capture "cd #{shared_path}/backups && ls -lt | grep -E -i #{regex} | head -n 1 | awk '{print $9}'"
7
+ end
8
+
9
+ def backup_file_size
10
+ @backup_file_size ||= capture "cd #{shared_path}/backups && wc -c #{@backup_file_name} | awk '{print $1}'"
11
+ end
12
+
13
+ def download_backup(backup_file, type)
14
+ puts "Downloading #{type} backup"
15
+ download! "#{shared_path}/backups/#{backup_file}"
16
+ puts "Download finished\nDeleting temporary backup..."
17
+ cleanup_backup(backup_file, "Download finished\nDeleting temporary backup...")
18
+ end
19
+
20
+ def cleanup_backup(backup_file, message)
21
+ puts message
22
+ execute "cd #{shared_path}/backups && rm #{backup_file}"
23
+ puts 'Temporary backup deleted'
24
+ end
25
+
26
+ def question(question, default = 'n', &block)
27
+ print "#{question} #{default.downcase == 'n' ? '(y/N)' : '(Y/n)'}: "
28
+ input = $stdin.gets.strip.downcase
29
+ answer = (input.empty? ? default : input).downcase.to_s
30
+
31
+ if %w[y n].include?(answer)
32
+ block.call(answer == 'y')
33
+ else
34
+ question(question, default, &block)
35
+ end
36
+ end
37
+
38
+ def prepare_env
39
+ @env = "RAILS_ENV=#{fetch(:stage)}"
40
+ @path_cmd = "PATH=$HOME/.rbenv/versions/#{RUBY_VERSION}/bin:$PATH"
41
+ @test_command = "cd #{release_path} && #{@path_cmd} && #{@env}"
42
+ end
43
+
44
+ def size_str(size)
45
+ units = %w[B KB MB GB TB]
46
+ e = (Math.log(size) / Math.log(1024)).floor
47
+ s = format('%.2f', size.to_f / 1024**e)
48
+ s.sub(/\.?0*$/, units[e])
49
+ end
50
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../backup_helper'
4
+ namespace :backup do
5
+ namespace :database do
6
+ include BackupHelper
7
+ # Default to :app role
8
+ rake_roles = fetch(:rake_roles, :app)
9
+
10
+ desc 'create a backup of the server database'
11
+ task :create do
12
+ on roles(rake_roles) do
13
+ puts 'Creating backup...'
14
+ execute "#{prepare_env} BACKUPS_ENABLED=true bundle exec rake pg:dump"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../backup_helper'
4
+ namespace :backup do
5
+ namespace :database do
6
+ include BackupHelper
7
+ # Default to :app role
8
+ rake_roles = fetch(:rake_roles, :app)
9
+
10
+ desc 'pull latest database dump from server to local'
11
+ task :pull do
12
+ on roles(rake_roles) do
13
+ puts 'Creating temporary backup...'
14
+ execute "#{prepare_env} BACKUPS_ENABLED=true EXTERNAL_BACKUP_ENABLED=false bundle exec rake pg:dump"
15
+ puts "Backup created\nPrepare download..."
16
+ backup_file = backup_file_name('database')
17
+ backup_size = backup_file_size
18
+ question("Backup size: #{size_str(backup_size.to_i)}. Continue?", 'n') do |answer|
19
+ if answer
20
+ download_backup(backup_file, 'database')
21
+ else
22
+ cleanup_backup(backup_file, "Aborting...\nDeleting temporary backup...")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../backup_helper'
4
+ namespace :backup do
5
+ namespace :storage do
6
+ include BackupHelper
7
+ # Default to :app role
8
+ rake_roles = fetch(:rake_roles, :app)
9
+
10
+ desc 'create storage dump on server'
11
+ task :create do
12
+ on roles(rake_roles) do
13
+ puts 'Creating backup...'
14
+ execute "#{prepare_env} BACKUPS_ENABLED=true EXTERNAL_BACKUP_ENABLED=false bundle exec rake storage:backup"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../backup_helper'
4
+ namespace :backup do
5
+ namespace :storage do
6
+ include BackupHelper
7
+ # Default to :app role
8
+ rake_roles = fetch(:rake_roles, :app)
9
+ desc 'pull latest storage dump from server to local'
10
+ task :pull do
11
+ on roles(rake_roles) do
12
+ puts 'Creating temporary backup...'
13
+ execute "#{prepare_env} BACKUPS_ENABLED=true EXTERNAL_BACKUP_ENABLED=false bundle exec rake storage:backup"
14
+ puts 'Backup created'
15
+ backup_file = backup_file_name('storage')
16
+ backup_size = backup_file_size
17
+
18
+ puts 'Prepare download...'
19
+
20
+ question("Backup size: #{size_str(backup_size.to_i)}. Continue?", 'n') do |answer|
21
+ if answer
22
+ download_backup(backup_file, 'storage')
23
+ else
24
+ cleanup_backup(backup_file, "Aborting...\nDeleting temporary backup...")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,29 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'backup/backup_helper'
4
+
3
5
  namespace :backup do
6
+ include BackupHelper
4
7
  # Default to :app role
5
8
  rake_roles = fetch(:rake_roles, :app)
6
9
 
7
- desc 'create a backup of the server database'
10
+ desc 'create a backup of the server database (deprecated, use backup:database:create instead)'
8
11
  task :create do
9
12
  on roles(rake_roles) do
10
- env = "RAILS_ENV=#{fetch(:stage)}"
11
- # rubocop:disable Layout/LineLength
12
- path_cmd = "PATH=$HOME/.rbenv/versions/#{RUBY_VERSION}/bin:$PATH"
13
- # rubocop:enable Layout/LineLength
14
- execute "cd #{release_path} && #{path_cmd} && #{env} BACKUPS_ENABLED=true bundle exec rake pg:dump"
13
+ warn "deprecated: use 'backup:database:create' instead, in future versions this task will be removed"
14
+ execute "#{prepare_env} BACKUPS_ENABLED=true EXTERNAL_BACKUP_ENABLED=false bundle exec rake pg:dump"
15
15
  end
16
16
  end
17
- desc 'pull latest database backups from server to local'
17
+ desc 'pull latest database backups from server to local (deprecated, use backup:database:pull instead)'
18
18
  task :pull do
19
19
  on roles(rake_roles) do
20
- # rubocop:disable Layout/LineLength
21
- execute "cd #{shared_path}/backups && tar -czf #{shared_path}/backups.tar.gz $(ls -lt | grep -E -i '.{0,}\.dump' | head -n 1 | awk '{print $9}')"
22
- # rubocop:enable Layout/LineLength
23
- download! "#{shared_path}/backups.tar.gz", 'backups.tar.gz'
24
- execute "rm #{shared_path}/backups.tar.gz"
25
- system 'tar -xzf backups.tar.gz'
26
- system 'rm backups.tar.gz'
20
+ warn "deprecated: use 'backup:database:pull' instead, in future versions this task will be removed"
21
+ backup_file = backup_file_name('database')
22
+ download! "#{shared_path}/backups/#{backup_file}"
27
23
  end
28
24
  end
29
25
  end
@@ -7,63 +7,63 @@ namespace :figaro_yml do
7
7
 
8
8
  desc 'get the `application.yml` file from server and create local if it does not exist'
9
9
  task :get do
10
- env = fetch(:stage)
11
- if !File.exist?('config/application.yml')
12
- puts "config/application.yml does not exist, creating it from all stages"
13
- run_locally do
14
- yamls={}
15
- stages = Dir.glob('config/deploy/*.rb')
16
- puts "found #{stages.count} stages"
17
- stages.map do |f|
18
- stage =File.basename(f, '.rb')
19
- puts "download #{stage} application.yml"
20
- begin
10
+ env = fetch(:stage)
11
+ if !File.exist?('config/application.yml')
12
+ puts 'config/application.yml does not exist, creating it from all stages'
13
+ run_locally do
14
+ yamls = {}
15
+ stages = Dir.glob('config/deploy/*.rb')
16
+ puts "found #{stages.count} stages"
17
+ stages.map do |f|
18
+ stage = File.basename(f, '.rb')
19
+ puts "download #{stage} application.yml"
20
+ begin
21
21
  res = capture "cap #{stage} figaro_yml:get_stage"
22
- yamls= yamls.merge(YAML.safe_load(res))
23
- rescue
24
- puts "could not get #{stage} application.yml"
25
- end
26
- yamls
22
+ yamls = yamls.merge(YAML.safe_load(res))
23
+ rescue StandardError
24
+ puts "could not get #{stage} application.yml"
27
25
  end
28
- # write to new file
29
- puts "writing to config/application.yml"
30
- write_to_file('config/application.yml', yamls.to_yaml)
26
+ yamls
31
27
  end
32
- else
33
- local_yml = YAML.safe_load(File.read('config/application.yml'))
34
- on roles(rake_roles) do
35
- remote = capture("cat #{shared_path}/config/application.yml")
36
- remote_yml = YAML.safe_load(remote)
37
- remote_stage = remote_yml[env.to_s]
38
- puts "remote application.yml stage '#{env.to_s}':\n\n"
39
- puts remote + "\r\n"
40
- puts "\r\n"
41
- loop do
42
- print "Overwrite local application.yml stage '#{env.to_s}'? (y/N): "
43
- input = $stdin.gets.strip.downcase
44
- answer = (input.empty? ? 'N' : input).downcase.to_s
45
-
46
- next unless %w(y n).include?(answer)
47
-
48
- if answer == 'y'
49
- puts 'Updating local application.yml'
50
- local_yml[env.to_s] = remote_stage
51
- write_to_file('config/application.yml', local_yml.to_yaml)
52
- exit
53
- end
54
- break
28
+ # write to new file
29
+ puts 'writing to config/application.yml'
30
+ write_to_file('config/application.yml', yamls.to_yaml)
31
+ end
32
+ else
33
+ local_yml = YAML.safe_load(File.read('config/application.yml'))
34
+ on roles(rake_roles) do
35
+ remote = capture("cat #{shared_path}/config/application.yml")
36
+ remote_yml = YAML.safe_load(remote)
37
+ remote_stage = remote_yml[env.to_s]
38
+ puts "remote application.yml stage '#{env}':\n\n"
39
+ puts "#{remote}\r\n"
40
+ puts "\r\n"
41
+ loop do
42
+ print "Overwrite local application.yml stage '#{env}'? (y/N): "
43
+ input = $stdin.gets.strip.downcase
44
+ answer = (input.empty? ? 'N' : input).downcase.to_s
45
+
46
+ next unless %w[y n].include?(answer)
47
+
48
+ if answer == 'y'
49
+ puts 'Updating local application.yml'
50
+ local_yml[env.to_s] = remote_stage
51
+ write_to_file('config/application.yml', local_yml.to_yaml)
52
+ exit
55
53
  end
56
- puts 'Nothing written to local application.yml'
57
- exit
54
+ break
58
55
  end
56
+ puts 'Nothing written to local application.yml'
57
+ exit
59
58
  end
60
59
  end
61
-
62
- task :get_stage do
63
- on roles(rake_roles) do
64
- puts capture "cat #{shared_path}/config/application.yml"
65
- end
60
+ end
61
+
62
+ task :get_stage do
63
+ on roles(rake_roles) do
64
+ puts capture "cat #{shared_path}/config/application.yml"
66
65
  end
66
+ end
67
67
 
68
68
  desc 'compare and set the figaro_yml file on the server'
69
69
  task :compare do
@@ -93,12 +93,12 @@ namespace :figaro_yml do
93
93
  result2 = compare_hashes(local_stage_env, remote_stage_env)
94
94
  if !result1.empty? || !result2.empty?
95
95
  loop do
96
- print 'Update remote application.yml? (y/N): '
96
+ print 'Update remote application.yml? (y/N): '
97
97
  input = $stdin.gets.strip.downcase
98
98
  answer = (input.empty? ? 'N' : input).downcase.to_s
99
99
 
100
- next unless %w(y n).include?(answer)
101
-
100
+ next unless %w[y n].include?(answer)
101
+
102
102
  if answer == 'y'
103
103
  puts 'Updating remote application.yml'
104
104
  invoke 'figaro_yml:setup'
@@ -116,25 +116,24 @@ namespace :figaro_yml do
116
116
  changes = false
117
117
  local_server = hash1.to_a - hash2.to_a
118
118
  server_local = hash2.to_a - hash1.to_a
119
-
120
- [local_server + server_local].flatten(1).to_h.keys.each do |k|
119
+
120
+ [local_server + server_local].flatten(1).to_h.each_key do |k|
121
121
  new_value = hash1[k].to_s
122
- new_value = new_value.empty? ? "nil" : new_value
122
+ new_value = new_value.empty? ? 'nil' : new_value
123
123
  old_value = hash2[k].to_s
124
- old_value = old_value.empty? ? "nil" : old_value
124
+ old_value = old_value.empty? ? 'nil' : old_value
125
125
 
126
126
  if old_value != new_value
127
- puts "#{k}: #{old_value} => #{new_value} \r\n"
128
- changes = true
127
+ puts "#{k}: #{old_value} => #{new_value} \r\n"
128
+ changes = true
129
129
  end
130
130
  end
131
- end
131
+ end
132
132
 
133
133
  def write_to_file(file, content)
134
134
  File.open(file, 'w') do |f|
135
135
  f.write(content)
136
136
  end
137
137
  end
138
-
139
138
  end
140
139
  # rubocop:enable Metrics/BlockLength