rolemodel-rails 2.0.1 → 2.1.0
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/README.md +111 -0
- data/lib/rolemodel/utility/task_tools.rb +27 -0
- data/lib/rolemodel/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4af0b11896cbe75d88cf7934e0322e9c8145656e115d13888473c642aac86716
|
|
4
|
+
data.tar.gz: ad3a3ab92a726d9ce7333ae9db2f45762ce02d5ded8a1c8b86b0923eb685c3c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c3cbd55ba285c70505447bc34b0509b98df66093e4fe35b5ae1007cb2252cd080a5779c434a4033302096d461a63c0365ea11b6b288d488adbbc8e31267a797
|
|
7
|
+
data.tar.gz: 41ba42965a2ab047098f450cf3c1fe3d7b69cffda6b4a634da757c6df229f4173b0b1dabc403d77493d1feb891ad9b364f221b6ef61e6c739e76663658feb91f
|
data/README.md
CHANGED
|
@@ -102,6 +102,117 @@ bin/rails g
|
|
|
102
102
|
* [Tailored Select](./lib/generators/rolemodel/tailored_select)
|
|
103
103
|
* [Lograge](./lib/generators/rolemodel/lograge)
|
|
104
104
|
|
|
105
|
+
## Utilities
|
|
106
|
+
|
|
107
|
+
### `Rolemodel::Utility::TaskTools`
|
|
108
|
+
|
|
109
|
+
A mixin of helper methods for writing friendlier, more informative Rake tasks. It provides consistent, migration-style console output, progress indication for long-running loops, an opt-in dry-run mode, and sanitized positional task arguments.
|
|
110
|
+
|
|
111
|
+
#### Requiring & Including
|
|
112
|
+
|
|
113
|
+
The module is available at runtime (rolemodel-rails must not be restricted to the `development` gem group). Require it and `include` it inside the `namespace` block of your `.rake` file:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
require 'rolemodel/utility/task_tools'
|
|
117
|
+
|
|
118
|
+
namespace :reports do
|
|
119
|
+
include Rolemodel::Utility::TaskTools
|
|
120
|
+
|
|
121
|
+
task total: :environment do
|
|
122
|
+
@total = GeneratedReport.count
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
namespace :clear do
|
|
126
|
+
desc 'Delete all non-current report records'
|
|
127
|
+
task expired: :total do
|
|
128
|
+
say_with_time "Detecting & Deleting Expired Reports among #{@total} Total" do
|
|
129
|
+
deleted_reports = 0
|
|
130
|
+
GeneratedReport.find_each.with_index do |report, index|
|
|
131
|
+
indicate_progress(index, @total)
|
|
132
|
+
next if report.current?
|
|
133
|
+
|
|
134
|
+
report.destroy unless dry_run?
|
|
135
|
+
deleted_reports += 1
|
|
136
|
+
end
|
|
137
|
+
say "#{deleted_reports}/#{@total} Records Deleted"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
> [!NOTE]
|
|
145
|
+
> `include` inside a `namespace` block adds the helper methods to the anonymous object that evaluates your task bodies, making them (and any plain methods you define alongside them) available to every task in that namespace.
|
|
146
|
+
|
|
147
|
+
#### Helper Methods
|
|
148
|
+
|
|
149
|
+
##### `say(message)`
|
|
150
|
+
|
|
151
|
+
Prints a message using the same style as Rails migrations. Pass `subitem: true` to indent the line beneath a preceding `say`.
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
say 'Doing some important stuff!'
|
|
155
|
+
say 'Like this one specific thing!', subitem: true
|
|
156
|
+
#=> -- Doing some important stuff!
|
|
157
|
+
#=> -> Like this one specific thing!
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
##### `say_with_time(message, &block)`
|
|
161
|
+
|
|
162
|
+
Wraps `say` and prints the block's real execution time as an indented subitem. Use it to announce and time a unit of work.
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
say_with_time "Deleting all #{@total} Records" do
|
|
166
|
+
GeneratedReport.destroy_all unless dry_run?
|
|
167
|
+
end
|
|
168
|
+
#=> -- Deleting all 42 Records
|
|
169
|
+
#=> -> 0.0198s
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
##### `indicate_progress(index, total = nil, report_interval: 9)`
|
|
173
|
+
|
|
174
|
+
Renders an animated spinner (and, when `total` is given, a completion percentage) for a long-running loop. Call it once per iteration with the current index; it only redraws every `report_interval` iterations so the animation stays eye-trackable. Pass a reduced `report_interval` when iterations are very slow.
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
GeneratedReport.find_each.with_index do |report, index|
|
|
178
|
+
indicate_progress(index, @total)
|
|
179
|
+
# ...
|
|
180
|
+
end
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
##### `dry_run?`
|
|
184
|
+
|
|
185
|
+
Returns `true` when the `DRY_RUN` environment variable is present, enabling a dry-run pattern for your tasks. Guard any code that writes to the database or file system with `unless dry_run?` so the task still produces its console feedback without performing the side effects.
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
report.destroy unless dry_run?
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```shell
|
|
192
|
+
DRY_RUN=true rake reports:clear:expired
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
##### `sanitize_arguments(args, defaults = {})`
|
|
196
|
+
|
|
197
|
+
Improves the usability of positional `Rake::Task` arguments, which cannot declare default values and are awkward to skip. Pass the task's `args` and a hash of defaults; it returns a hash with whitespace stripped, blank/skipped values (passed as `_`) replaced by your defaults.
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
desc 'Seed a dev user with the given name and email'
|
|
201
|
+
task :dev, %i[name email] => :environment do |_, args|
|
|
202
|
+
name, email = sanitize_arguments(args, name: 'RoleModel', email: 'it-support@rolemodelsoftware.com').values_at(:name, :email)
|
|
203
|
+
say_with_time "Seeding Dev User (name: #{name}, email: #{email}, role: Admin)" do
|
|
204
|
+
User.find_or_create(name:, email:, role: 'admin') unless dry_run?
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
```shell
|
|
210
|
+
# Skip the name argument with `_` to fall back to its default
|
|
211
|
+
DRY_RUN=true rake users:dev[_,bob@example.com]
|
|
212
|
+
#=> -- Seeding Dev User (name: RoleModel, email: bob@example.com, role: Admin)
|
|
213
|
+
#=> -> 0.0000s
|
|
214
|
+
```
|
|
215
|
+
|
|
105
216
|
## Development
|
|
106
217
|
|
|
107
218
|
Install the versions of Node and Ruby specified in `.node-version` and `.ruby-version` on your machine. https://asdf-vm.com/ is a great tool for managing language versions. Then run `npm install -g yarn`.
|
|
@@ -12,6 +12,7 @@ module Rolemodel
|
|
|
12
12
|
say '%.4fs' % time.real, subitem: true
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
# based on the migration helper of the same name
|
|
15
16
|
def say(message, subitem: false)
|
|
16
17
|
puts "#{subitem ? ' ->' : '--'} #{message}" # rubocop:disable Rails/Output
|
|
17
18
|
end
|
|
@@ -32,11 +33,37 @@ module Rolemodel
|
|
|
32
33
|
print("#{PROGRESS.next} #{to_percent(index, total) if total}\r") # rubocop:disable Rails/Output
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
##
|
|
37
|
+
# Enables a pattern for dry-run mode in tasks. Assumes usage of other utility methods
|
|
38
|
+
# like `say_with_time` and `indicate_progress` that provide user feedback, separate from the actions they perform.
|
|
39
|
+
#
|
|
40
|
+
# Tasks can be updated to support this mode by adding `unless dry_run?` to lines of code that write to the file system or database.
|
|
41
|
+
def dry_run?
|
|
42
|
+
ENV['DRY_RUN'].present?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Improves the usability of Rake::Task arguments which are positional and don't support default values.
|
|
47
|
+
# This method allows invocation with skipped arguments via `_` and supports a defaults hash.
|
|
48
|
+
def sanitize_arguments(args, defaults = {})
|
|
49
|
+
defaults.merge(ArgumentSanitizer.new(args).to_h)
|
|
50
|
+
end
|
|
51
|
+
|
|
35
52
|
private
|
|
36
53
|
|
|
37
54
|
def to_percent(index, total)
|
|
38
55
|
'%3.f%%' % (index / total.to_f * 100.0)
|
|
39
56
|
end
|
|
40
57
|
end
|
|
58
|
+
|
|
59
|
+
class ArgumentSanitizer
|
|
60
|
+
def initialize(args)
|
|
61
|
+
@args = args.to_h
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def to_h
|
|
65
|
+
@args.transform_values { it.to_s.strip.match?('_') ? nil : it.to_s.strip }.compact
|
|
66
|
+
end
|
|
67
|
+
end
|
|
41
68
|
end
|
|
42
69
|
end
|
data/lib/rolemodel/version.rb
CHANGED