chris_lib 2.2.1 → 2.2.2
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 +4 -4
- data/lib/chris_lib/chris_math.rb +117 -23
- data/lib/chris_lib/date_ext.rb +13 -1
- data/lib/chris_lib/for_chris_lib.rb +835 -0
- data/lib/chris_lib/shell_methods.rb +80 -10
- data/lib/chris_lib/test_access.rb +25 -6
- data/lib/chris_lib/version.rb +1 -1
- data/lib/chris_lib.rb +3 -0
- metadata +62 -8
@@ -1,40 +1,89 @@
|
|
1
|
-
#
|
1
|
+
# Helpers for shell-friendly Ruby scripts and deployment utilities.
|
2
2
|
module ShellMethods
|
3
3
|
require 'dotenv'
|
4
4
|
require 'bundler'
|
5
5
|
require 'optparse'
|
6
6
|
Dotenv.load
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# arg1
|
8
|
+
# Run an R script via `Rscript --vanilla`
|
9
|
+
#
|
10
|
+
# @param script_path [String] absolute path to the R script
|
11
|
+
# @param arg1 [String] first argument passed to the script (accessible in R via `commandArgs(trailingOnly=TRUE)[1]`)
|
12
|
+
# @return [String] stdout from the R script
|
13
|
+
# @note Warns and returns `nil` when the script is missing.
|
12
14
|
def r_runner(script_path, arg1)
|
13
|
-
|
15
|
+
raise ArgumentError, 'script_path must be provided' unless script_path.respond_to?(:to_s)
|
16
|
+
path = script_path.to_s
|
17
|
+
unless File.exist?(path)
|
18
|
+
warn "r_runner: #{path} does not exist"
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
arg = arg1.to_s
|
22
|
+
`Rscript --vanilla #{path} #{arg}`
|
14
23
|
end
|
15
24
|
|
25
|
+
# @param file_path [String]
|
26
|
+
# @return [Integer] file size in bytes
|
27
|
+
# @note Returns 0 and warns when the file is missing.
|
16
28
|
def file_size(file_path)
|
17
|
-
|
29
|
+
raise ArgumentError, 'file_path must be provided' unless file_path.respond_to?(:to_s)
|
30
|
+
path = file_path.to_s
|
31
|
+
unless File.exist?(path)
|
32
|
+
warn "file_size: #{path} does not exist"
|
33
|
+
return 0
|
34
|
+
end
|
35
|
+
`stat -f%z #{path}`.to_i
|
18
36
|
end
|
19
37
|
|
38
|
+
# Send an iMessage to the "admin" buddy on macOS.
|
39
|
+
# @param msg [String]
|
40
|
+
# @return [String]
|
41
|
+
# @note Warns and no-ops when `msg` is blank.
|
20
42
|
def osx_imessage_admin(msg)
|
43
|
+
if msg.nil? || msg.strip.empty?
|
44
|
+
warn 'osx_imessage_admin called without a message; skipping'
|
45
|
+
return nil
|
46
|
+
end
|
21
47
|
`osascript -e 'tell application "Messages" to send "#{msg}" to buddy "admin"'`
|
22
48
|
end
|
23
49
|
|
50
|
+
# Trigger a macOS notification via AppleScript.
|
51
|
+
# @param msg [String]
|
52
|
+
# @param title [String]
|
53
|
+
# @return [String]
|
54
|
+
# @note Warns and no-ops when `msg` is blank. Supplies a default title when missing.
|
24
55
|
def osx_notification(msg, title)
|
56
|
+
if msg.nil? || msg.strip.empty?
|
57
|
+
warn 'osx_notification called without a message; skipping'
|
58
|
+
return nil
|
59
|
+
end
|
60
|
+
if title.nil? || title.strip.empty?
|
61
|
+
warn 'osx_notification called without a title; using default'
|
62
|
+
title = 'Notification'
|
63
|
+
end
|
25
64
|
`osascript -e 'display notification "#{msg}" with title "#{title}"'`
|
26
65
|
end
|
27
66
|
|
67
|
+
# @return [String] hostname of the current machine
|
28
68
|
def osx_hostname
|
29
69
|
`hostname`
|
30
70
|
end
|
31
71
|
|
32
|
-
#
|
33
|
-
#
|
72
|
+
# Mail the signed-in macOS user using the BSD `mail` command.
|
73
|
+
# @param subject [String]
|
74
|
+
# @param body [String]
|
75
|
+
# @return [String]
|
76
|
+
# @note Warns and no-ops when `subject` is blank.
|
34
77
|
def osx_send_mail(subject, body = nil)
|
78
|
+
if subject.nil? || subject.strip.empty?
|
79
|
+
warn 'osx_send_mail called without a subject; skipping'
|
80
|
+
return nil
|
81
|
+
end
|
35
82
|
`echo "#{body}" | mail -s "#{subject}" 'Chris'`
|
36
83
|
end
|
37
84
|
|
85
|
+
# Parse CLI options for deployment scripts.
|
86
|
+
# @return [Hash] options hash with keys :skip_migration, :fast, :special_rake
|
38
87
|
def parse_options
|
39
88
|
@options = {}
|
40
89
|
OptionParser.new do |opts|
|
@@ -51,16 +100,22 @@ module ShellMethods
|
|
51
100
|
@options[:skip_migration] = true if @options[:fast]
|
52
101
|
end
|
53
102
|
|
103
|
+
# Placeholder for future custom rake tasks.
|
104
|
+
# @raise [RuntimeError] always, prompting implementers to override
|
54
105
|
def run_special_rake_task
|
55
106
|
fail 'Need to implement by asking for name of rake task and
|
56
107
|
also requiring confirmation'
|
57
108
|
end
|
58
109
|
|
110
|
+
# Create a Postgres snapshot by delegating to `script/getSnapShot.sh`.
|
111
|
+
# @return [Boolean] command exit status
|
59
112
|
def backup_database
|
60
113
|
file_path = "../backups/prod#{time_hash}.dump"
|
61
114
|
system('./script/getSnapShot.sh production ' + file_path)
|
62
115
|
end
|
63
116
|
|
117
|
+
# Notify users of an impending deploy via Heroku and progress bar countdown.
|
118
|
+
# @return [void]
|
64
119
|
def warn_users
|
65
120
|
system('heroku run rake util:three_min_warning --remote production')
|
66
121
|
# spend one minute precompiling
|
@@ -76,6 +131,8 @@ module ShellMethods
|
|
76
131
|
system('heroku run rake util:warn_under_maintenance --remote production')
|
77
132
|
end
|
78
133
|
|
134
|
+
# Timestamp helper used to build backup filenames.
|
135
|
+
# @return [String]
|
79
136
|
def time_hash
|
80
137
|
time = Time.now
|
81
138
|
time.day.to_s + time.month.to_s + time.year.to_s + '-' + time.hour.to_s + time.min.to_s
|
@@ -84,6 +141,9 @@ module ShellMethods
|
|
84
141
|
# change in response to
|
85
142
|
#[DEPRECATED] `Bundler.with_clean_env` has been deprecated in favor of `Bundler.with_unbundled_env`. If you instead want the environment before bundler was originally loaded, use `Bundler.with_original_env`
|
86
143
|
# remove this comment when clear that this works.
|
144
|
+
# Compare local and remote database schema versions.
|
145
|
+
# @param remote [String, nil] Heroku remote name
|
146
|
+
# @return [Boolean, nil] true when versions match, false when mismatched, nil when versions cannot be read
|
87
147
|
def same_db_version(remote: nil)
|
88
148
|
destination = (remote.nil? ? nil : "--remote #{remote}")
|
89
149
|
lv = `rake db:version`
|
@@ -102,6 +162,7 @@ module ShellMethods
|
|
102
162
|
l_version == h_version
|
103
163
|
end
|
104
164
|
|
165
|
+
# Ensure git workspace is clean before deploying.
|
105
166
|
def check_git_clean
|
106
167
|
puts "Checking git status"
|
107
168
|
gs = `git status`
|
@@ -110,6 +171,7 @@ module ShellMethods
|
|
110
171
|
exit 1
|
111
172
|
end
|
112
173
|
|
174
|
+
# Verify that `chris_lib` is up to date before deploying.
|
113
175
|
def check_chris_lib_status
|
114
176
|
gs=`cd ../chris_lib;git status`; lr=$?.successful?
|
115
177
|
return unless gs['working tree clean'].nil? && gs['up-to-date'].nil?
|
@@ -118,6 +180,10 @@ module ShellMethods
|
|
118
180
|
system('cd $OLDPWD')
|
119
181
|
end
|
120
182
|
|
183
|
+
# Optionally run migrations if local and remote schema versions differ.
|
184
|
+
# @param remote [String, nil]
|
185
|
+
# @param skip_migration [Boolean]
|
186
|
+
# @return [void]
|
121
187
|
def migrate_if_necessary(remote: nil, skip_migration: false)
|
122
188
|
if skip_migration
|
123
189
|
puts "No migration will be performed due to --fast or --skip_migration options"
|
@@ -137,7 +203,11 @@ module ShellMethods
|
|
137
203
|
end
|
138
204
|
end
|
139
205
|
|
206
|
+
# Notify Rollbar of a new deploy via its API.
|
207
|
+
# @param access_token [String, nil]
|
208
|
+
# @return [void]
|
140
209
|
def notify_rollbar_of_deploy(access_token: nil)
|
210
|
+
warn 'notify_rollbar_of_deploy called without access token' if access_token.nil? || access_token.empty?
|
141
211
|
system("ACCESS_TOKEN=#{access_token}")
|
142
212
|
system("ENVIRONMENT=production")
|
143
213
|
system("LOCAL_USERNAME=`whoami`")
|
@@ -158,4 +228,4 @@ module ShellMethods
|
|
158
228
|
puts "Failure to notify Rollbar of deploy of v#{TGM_VERSION} with SHA #{sha[0..5]}", cr
|
159
229
|
end
|
160
230
|
end
|
161
|
-
end
|
231
|
+
end
|
@@ -1,15 +1,30 @@
|
|
1
1
|
module TestAccess
|
2
|
-
#
|
3
|
-
# where path is a string of the form <tt>url_path</tt> and actions is a hash of symbols
|
4
|
-
# that represent actions to be protected.
|
5
|
-
# An example call is <tt>it_should_route_to('login_path',:edit,:update)</tt>. The call is
|
6
|
-
# made in a describe or context block with a preceding <tt>require TestAccess</tt>.
|
2
|
+
# An RSpec helper that verifies protected controller actions redirect to a login path.
|
7
3
|
#
|
4
|
+
# Include the module and call {.it_should_route_to} with the protected actions:
|
5
|
+
#
|
6
|
+
# it_should_route_to('login_path', [:edit, :update])
|
7
|
+
#
|
8
|
+
# Optionally provide a `flash_message` expectation.
|
9
|
+
# @!visibility private
|
8
10
|
module ExampleMethods
|
9
11
|
end
|
12
|
+
|
13
|
+
# @!visibility private
|
10
14
|
module ExampleGroupMethods
|
15
|
+
# Define a set of expectations that each action redirects to the provided path.
|
16
|
+
# @param path [String] helper method name that resolves to the desired redirect URL
|
17
|
+
# @param actions [Array<Symbol>]
|
18
|
+
# @param flash_message [String, nil] text to match in `flash[:error]`
|
11
19
|
def it_should_route_to(path,actions,flash_message=nil)
|
20
|
+
raise ArgumentError, 'path must respond to #to_s' unless path.respond_to?(:to_s)
|
21
|
+
actions = Array(actions)
|
22
|
+
if actions.empty?
|
23
|
+
warn 'it_should_route_to called with no actions; nothing to verify'
|
24
|
+
return
|
25
|
+
end
|
12
26
|
actions.each do |a|
|
27
|
+
raise ArgumentError, "action #{a.inspect} must respond to #to_sym" unless a.respond_to?(:to_sym)
|
13
28
|
it "should deny access to #{a}" do
|
14
29
|
if Rails::VERSION::MAJOR >= 5
|
15
30
|
get a.to_sym, params: { id: 1}
|
@@ -31,8 +46,12 @@ module TestAccess
|
|
31
46
|
end
|
32
47
|
end
|
33
48
|
end
|
49
|
+
# @!visibility private
|
34
50
|
def self.included(receiver)
|
51
|
+
unless receiver.respond_to?(:it)
|
52
|
+
warn 'TestAccess included into an object without RSpec example support'
|
53
|
+
end
|
35
54
|
receiver.extend ExampleGroupMethods
|
36
55
|
receiver.send :include, ExampleMethods
|
37
56
|
end
|
38
|
-
end
|
57
|
+
end
|
data/lib/chris_lib/version.rb
CHANGED
data/lib/chris_lib.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chris_lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: dotenv
|
@@ -39,19 +38,47 @@ dependencies:
|
|
39
38
|
- !ruby/object:Gem::Version
|
40
39
|
version: '0'
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
41
|
+
name: minimization
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '0'
|
48
|
-
type: :
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: ostruct
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
type: :runtime
|
49
62
|
prerelease: false
|
50
63
|
version_requirements: !ruby/object:Gem::Requirement
|
51
64
|
requirements:
|
52
65
|
- - ">="
|
53
66
|
- !ruby/object:Gem::Version
|
54
67
|
version: '0'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rails
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '8.0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '8.0'
|
55
82
|
- !ruby/object:Gem::Dependency
|
56
83
|
name: actionpack
|
57
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +177,34 @@ dependencies:
|
|
150
177
|
- - ">="
|
151
178
|
- !ruby/object:Gem::Version
|
152
179
|
version: '0'
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
name: yard
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
type: :development
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
- !ruby/object:Gem::Dependency
|
195
|
+
name: webrick
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
type: :development
|
202
|
+
prerelease: false
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
153
208
|
description: It includes maths, datetime, and rspec access test libraries.
|
154
209
|
email:
|
155
210
|
- obromios@gmail.com
|
@@ -162,6 +217,7 @@ files:
|
|
162
217
|
- lib/chris_lib.rb
|
163
218
|
- lib/chris_lib/chris_math.rb
|
164
219
|
- lib/chris_lib/date_ext.rb
|
220
|
+
- lib/chris_lib/for_chris_lib.rb
|
165
221
|
- lib/chris_lib/shell_methods.rb
|
166
222
|
- lib/chris_lib/test_access.rb
|
167
223
|
- lib/chris_lib/version.rb
|
@@ -172,7 +228,6 @@ licenses:
|
|
172
228
|
metadata:
|
173
229
|
source_code_uri: https://github.com/obromios/chris_lib
|
174
230
|
changelog_uri: https://github.com/obromios/chris_lib/blob/master/CHANGELOG.md
|
175
|
-
post_install_message:
|
176
231
|
rdoc_options: []
|
177
232
|
require_paths:
|
178
233
|
- lib
|
@@ -187,8 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
242
|
- !ruby/object:Gem::Version
|
188
243
|
version: '0'
|
189
244
|
requirements: []
|
190
|
-
rubygems_version: 3.
|
191
|
-
signing_key:
|
245
|
+
rubygems_version: 3.7.2
|
192
246
|
specification_version: 4
|
193
247
|
summary: This an eclectic collection of methods. It include maths, datetime, and rspec
|
194
248
|
access test libraries.
|