Module: ShellMethods
- Defined in:
- lib/chris_lib/shell_methods.rb
Overview
Helpers for shell-friendly Ruby scripts and deployment utilities.
Instance Method Summary collapse
-
#backup_database ⇒ Boolean
Create a Postgres snapshot by delegating to ‘script/getSnapShot.sh`.
-
#check_chris_lib_status ⇒ Object
Verify that ‘chris_lib` is up to date before deploying.
-
#check_git_clean ⇒ Object
Ensure git workspace is clean before deploying.
-
#file_size(file_path) ⇒ Integer
File size in bytes.
-
#migrate_if_necessary(remote: nil, skip_migration: false) ⇒ void
Optionally run migrations if local and remote schema versions differ.
-
#notify_rollbar_of_deploy(access_token: nil) ⇒ void
Notify Rollbar of a new deploy via its API.
-
#osx_hostname ⇒ String
Hostname of the current machine.
-
#osx_imessage_admin(msg) ⇒ String
Send an iMessage to the “admin” buddy on macOS.
-
#osx_notification(msg, title) ⇒ String
Trigger a macOS notification via AppleScript.
-
#osx_send_mail(subject, body = nil) ⇒ String
Mail the signed-in macOS user using the BSD ‘mail` command.
-
#parse_options ⇒ Hash
Parse CLI options for deployment scripts.
-
#r_runner(script_path, arg1) ⇒ String
Run an R script via ‘Rscript –vanilla`.
-
#run_special_rake_task ⇒ Object
Placeholder for future custom rake tasks.
-
#same_db_version(remote: nil) ⇒ Boolean?
Compare local and remote database schema versions.
-
#time_hash ⇒ String
Timestamp helper used to build backup filenames.
-
#warn_users ⇒ void
Notify users of an impending deploy via Heroku and progress bar countdown.
Instance Method Details
#backup_database ⇒ Boolean
Create a Postgres snapshot by delegating to ‘script/getSnapShot.sh`.
112 113 114 115 |
# File 'lib/chris_lib/shell_methods.rb', line 112 def backup_database file_path = "../backups/prod#{time_hash}.dump" system('./script/getSnapShot.sh production ' + file_path) end |
#check_chris_lib_status ⇒ Object
Verify that ‘chris_lib` is up to date before deploying.
175 176 177 178 179 180 181 |
# File 'lib/chris_lib/shell_methods.rb', line 175 def check_chris_lib_status gs=`cd ../chris_lib;git status`; lr=$?.successful? return unless gs['working tree clean'].nil? && gs['up-to-date'].nil? puts "Exiting, chris_lib is not up to date with master." exit 3 system('cd $OLDPWD') end |
#check_git_clean ⇒ Object
Ensure git workspace is clean before deploying.
166 167 168 169 170 171 172 |
# File 'lib/chris_lib/shell_methods.rb', line 166 def check_git_clean puts "Checking git status" gs = `git status` return unless gs['working tree clean'].nil? puts "Exiting, you need to commit files" exit 1 end |
#file_size(file_path) ⇒ Integer
Returns 0 and warns when the file is missing.
Returns file size in bytes.
28 29 30 31 32 33 34 35 36 |
# File 'lib/chris_lib/shell_methods.rb', line 28 def file_size(file_path) raise ArgumentError, 'file_path must be provided' unless file_path.respond_to?(:to_s) path = file_path.to_s unless File.exist?(path) warn "file_size: #{path} does not exist" return 0 end `stat -f%z #{path}`.to_i end |
#migrate_if_necessary(remote: nil, skip_migration: false) ⇒ void
This method returns an undefined value.
Optionally run migrations if local and remote schema versions differ.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/chris_lib/shell_methods.rb', line 187 def migrate_if_necessary(remote: nil, skip_migration: false) if skip_migration puts "No migration will be performed due to --fast or --skip_migration options" else destination=(remote.nil? ? nil : "--remote #{remote}") puts "Checking local and remote databases have same version and migrates if necessary" if same_db_version(remote: remote) puts "No migration necessary" else puts "Warning, different db versions" system('tput bel') puts "Press m<cr> to migrate or q<cr> to exit" ans=$stdin.gets() exit 2 if ans[0]!='m' system("heroku run rake db:migrate #{destination}") end end end |
#notify_rollbar_of_deploy(access_token: nil) ⇒ void
This method returns an undefined value.
Notify Rollbar of a new deploy via its API.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/chris_lib/shell_methods.rb', line 209 def (access_token: nil) warn 'notify_rollbar_of_deploy called without access token' if access_token.nil? || access_token.empty? system("ACCESS_TOKEN=#{access_token}") system("ENVIRONMENT=production") system("LOCAL_USERNAME=`whoami`") system("COMMENT=v#{TGM_VERSION}") sha = `git log -n 1 --pretty=format:'%H'` system("REVISION=sha") puts "Notifiying of revision #{sha}" cr = `curl https://api.rollbar.com/api/1/deploy/ \ -F access_token=$ACCESS_TOKEN \ -F environment=$ENVIRONMENT \ -F revision=$REVISION \ -F comment=$COMMENT \ -F local_username=$LOCAL_USERNAME` if cr.class == Hash && cr['data'].empty? puts "Rollbar was notified of deploy of v#{TGM_VERSION} with SHA #{sha[0..5]}" else system('tput bel;tput bel') puts "Failure to notify Rollbar of deploy of v#{TGM_VERSION} with SHA #{sha[0..5]}", cr end end |
#osx_hostname ⇒ String
Returns hostname of the current machine.
68 69 70 |
# File 'lib/chris_lib/shell_methods.rb', line 68 def osx_hostname `hostname` end |
#osx_imessage_admin(msg) ⇒ String
Warns and no-ops when ‘msg` is blank.
Send an iMessage to the “admin” buddy on macOS.
42 43 44 45 46 47 48 |
# File 'lib/chris_lib/shell_methods.rb', line 42 def (msg) if msg.nil? || msg.strip.empty? warn 'osx_imessage_admin called without a message; skipping' return nil end `osascript -e 'tell application "Messages" to send "#{msg}" to buddy "admin"'` end |
#osx_notification(msg, title) ⇒ String
Warns and no-ops when ‘msg` is blank. Supplies a default title when missing.
Trigger a macOS notification via AppleScript.
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/chris_lib/shell_methods.rb', line 55 def osx_notification(msg, title) if msg.nil? || msg.strip.empty? warn 'osx_notification called without a message; skipping' return nil end if title.nil? || title.strip.empty? warn 'osx_notification called without a title; using default' title = 'Notification' end `osascript -e 'display notification "#{msg}" with title "#{title}"'` end |
#osx_send_mail(subject, body = nil) ⇒ String
Warns and no-ops when ‘subject` is blank.
Mail the signed-in macOS user using the BSD ‘mail` command.
77 78 79 80 81 82 83 |
# File 'lib/chris_lib/shell_methods.rb', line 77 def osx_send_mail(subject, body = nil) if subject.nil? || subject.strip.empty? warn 'osx_send_mail called without a subject; skipping' return nil end `echo "#{body}" | mail -s "#{subject}" 'Chris'` end |
#parse_options ⇒ Hash
Parse CLI options for deployment scripts.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/chris_lib/shell_methods.rb', line 87 def = {} OptionParser.new do |opts| opts.on("-s", "--skip_migration", "Skip migrations") do [:skip_migration] = true end opts.on("-f", "--fast", "Deploy without warnings and skip migrations") do [:fast] = true end opts.on("-r", "--special_rake", "Run special rake task") do [:special_rake] = true end end.parse! [:skip_migration] = true if [:fast] end |
#r_runner(script_path, arg1) ⇒ String
Warns and returns ‘nil` when the script is missing.
Run an R script via ‘Rscript –vanilla`
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/chris_lib/shell_methods.rb', line 14 def r_runner(script_path, arg1) raise ArgumentError, 'script_path must be provided' unless script_path.respond_to?(:to_s) path = script_path.to_s unless File.exist?(path) warn "r_runner: #{path} does not exist" return nil end arg = arg1.to_s `Rscript --vanilla #{path} #{arg}` end |
#run_special_rake_task ⇒ Object
Placeholder for future custom rake tasks.
105 106 107 108 |
# File 'lib/chris_lib/shell_methods.rb', line 105 def run_special_rake_task fail 'Need to implement by asking for name of rake task and also requiring confirmation' end |
#same_db_version(remote: nil) ⇒ Boolean?
Compare local and remote database schema versions.
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/chris_lib/shell_methods.rb', line 147 def same_db_version(remote: nil) destination = (remote.nil? ? nil : "--remote #{remote}") lv = `rake db:version` puts 'Local version: ', lv hv = Bundler.with_unbundled_env{ `heroku run rake db:version #{destination}` } puts hv return nil if hv.nil? || hv.empty? return nil if lv.nil? || lv.empty? key = 'version: ' nl = lv.index(key) + 9 l_version = lv.slice(nl..-1) nh = hv.index(key) + 9 h_version = hv.slice(nh..-1) l_version == h_version end |
#time_hash ⇒ String
Timestamp helper used to build backup filenames.
136 137 138 139 |
# File 'lib/chris_lib/shell_methods.rb', line 136 def time_hash time = Time.now time.day.to_s + time.month.to_s + time.year.to_s + '-' + time.hour.to_s + time.min.to_s end |
#warn_users ⇒ void
This method returns an undefined value.
Notify users of an impending deploy via Heroku and progress bar countdown.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/chris_lib/shell_methods.rb', line 119 def warn_users system('heroku run rake util:three_min_warning --remote production') # spend one minute precompiling = ProgressBar.create # now 2 minutes waiting increment = 3 * 60 / 100 (1..100).each do |_i| sleep increment .increment .refresh end system('heroku run rake util:delete_newest_announcement --remote production') system('heroku run rake util:warn_under_maintenance --remote production') end |