rolemodel-rails 1.1.0 → 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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -7
  3. data/lib/generators/rolemodel/all_generator.rb +0 -1
  4. data/lib/generators/rolemodel/optics/icons/README.md +6 -1
  5. data/lib/generators/rolemodel/optics/icons/icons_generator.rb +14 -9
  6. data/lib/generators/rolemodel/optics/icons/templates/app/helpers/icon_helper.rb.tt +4 -2
  7. data/lib/generators/rolemodel/testing/README.md +4 -1
  8. data/lib/generators/rolemodel/testing/all_generator.rb +3 -3
  9. data/lib/generators/rolemodel/testing/jasmine_playwright/jasmine_playwright_generator.rb +1 -1
  10. data/lib/generators/rolemodel/testing/rspec/README.md +1 -1
  11. data/lib/generators/rolemodel/testing/rspec/USAGE +1 -1
  12. data/lib/generators/rolemodel/testing/rspec/rspec_generator.rb +15 -14
  13. data/lib/generators/rolemodel/testing/rspec/templates/spec/support/capybara_config.rb.tt +9 -0
  14. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/custom_icon_builder.rb +1 -1
  15. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/feather_icon_builder.rb +1 -1
  16. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/icon_builder.rb +10 -19
  17. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/lucide_icon_builder.rb +1 -1
  18. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/material_icon_builder.rb +1 -1
  19. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/phosphor_icon_builder.rb +1 -1
  20. data/lib/{generators/rolemodel/optics/icons/templates/app/icon_builders → rolemodel/optics}/tabler_icon_builder.rb +1 -1
  21. data/lib/rolemodel/optics.rb +9 -0
  22. data/lib/rolemodel/utility/task_tools.rb +69 -0
  23. data/lib/rolemodel/utility.rb +3 -0
  24. data/lib/rolemodel/version.rb +1 -1
  25. data/lib/rolemodel-rails.rb +2 -0
  26. metadata +35 -42
  27. data/lib/generators/rolemodel/mcp/README.md +0 -13
  28. data/lib/generators/rolemodel/mcp/USAGE +0 -8
  29. data/lib/generators/rolemodel/mcp/mcp_generator.rb +0 -110
  30. data/lib/generators/rolemodel/mcp/templates/app/assets/stylesheets/components/doorkeeper.css +0 -140
  31. data/lib/generators/rolemodel/mcp/templates/app/controllers/doorkeeper/base_controller.rb +0 -7
  32. data/lib/generators/rolemodel/mcp/templates/app/controllers/mcp_controller.rb.tt +0 -91
  33. data/lib/generators/rolemodel/mcp/templates/app/controllers/oauth_registrations_controller.rb +0 -46
  34. data/lib/generators/rolemodel/mcp/templates/app/controllers/well_known_controller.rb +0 -39
  35. data/lib/generators/rolemodel/mcp/templates/app/mcp/prompts/sample.rb +0 -36
  36. data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/controller.rb +0 -57
  37. data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/docs/SAMPLE_DOC.md +0 -4
  38. data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/docs_controller.rb +0 -46
  39. data/lib/generators/rolemodel/mcp/templates/app/mcp/tools/sample.rb +0 -42
  40. data/lib/generators/rolemodel/mcp/templates/app/views/doorkeeper/authorizations/error.html.slim.tt +0 -13
  41. data/lib/generators/rolemodel/mcp/templates/app/views/doorkeeper/authorizations/new.html.slim.tt +0 -41
  42. data/lib/generators/rolemodel/mcp/templates/app/views/layouts/doorkeeper.html.slim +0 -7
  43. data/lib/generators/rolemodel/mcp/templates/config/initializers/doorkeeper.rb +0 -537
  44. data/lib/generators/rolemodel/mcp/templates/spec/mcp/prompts/sample_spec.rb +0 -15
  45. data/lib/generators/rolemodel/mcp/templates/spec/mcp/resources/controller_spec.rb +0 -16
  46. data/lib/generators/rolemodel/mcp/templates/spec/mcp/resources/docs_controller_spec.rb +0 -55
  47. data/lib/generators/rolemodel/mcp/templates/spec/mcp/tools/sample_spec.rb +0 -15
  48. data/lib/generators/rolemodel/mcp/templates/spec/requests/mcp_controller_spec.rb +0 -84
  49. data/lib/generators/rolemodel/mcp/templates/spec/requests/oauth_registrations_controller_spec.rb +0 -62
  50. data/lib/generators/rolemodel/mcp/templates/spec/requests/well_known_controller_spec.rb +0 -30
  51. data/lib/generators/rolemodel/testing/rspec/templates/support/capybara_testid.rb +0 -5
  52. /data/lib/generators/rolemodel/testing/rspec/templates/{rails_helper.rb → spec/rails_helper.rb.tt} +0 -0
  53. /data/lib/generators/rolemodel/testing/rspec/templates/{spec_helper.rb → spec/spec_helper.rb.tt} +0 -0
  54. /data/lib/generators/rolemodel/testing/rspec/templates/{support/capybara_drivers.rb → spec/support/capybara_drivers.rb.tt} +0 -0
  55. /data/lib/generators/rolemodel/testing/rspec/templates/{support → spec/support}/helpers/action_cable_helper.rb +0 -0
  56. /data/lib/generators/rolemodel/testing/rspec/templates/{support → spec/support}/helpers/capybara_helper.rb +0 -0
  57. /data/lib/generators/rolemodel/testing/rspec/templates/{support → spec/support}/helpers/playwright_helper.rb +0 -0
  58. /data/lib/generators/rolemodel/testing/rspec/templates/{support → spec/support}/helpers/select_helper.rb +0 -0
  59. /data/lib/generators/rolemodel/testing/rspec/templates/{support → spec/support}/helpers/test_element_helper.rb +0 -0
  60. /data/lib/generators/rolemodel/testing/rspec/templates/{support/helpers.rb → spec/support/helpers.rb.tt} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3e11cf41b7d9e5afb68a8eaca61a30785b10dcb9032fc327a52f40ea8271a2e
4
- data.tar.gz: 4b4388ba6e3b2608135be47000bc9ba655b32bd4936e096d2e3ba8cafe4904c3
3
+ metadata.gz: 4af0b11896cbe75d88cf7934e0322e9c8145656e115d13888473c642aac86716
4
+ data.tar.gz: ad3a3ab92a726d9ce7333ae9db2f45762ce02d5ded8a1c8b86b0923eb685c3c0
5
5
  SHA512:
6
- metadata.gz: 173f38c6b5f5f0101a143aaf8a5301afd7a69295d68e1c8eb54a5bd2cf06b57254f658e312a19a3a2605f6920ddab05f6f8941a0797ce7400e83c2e3ff13ac38
7
- data.tar.gz: 77b6be040efd20cd738c14c44c92c57ac84241a75685cc157bfa86ddc3b6b7b6675eec3b2ad8a3b8c6dfb83c7e568aca7420746b6b81ef7d1172d6392c490c47
6
+ metadata.gz: 0c3cbd55ba285c70505447bc34b0509b98df66093e4fe35b5ae1007cb2252cd080a5779c434a4033302096d461a63c0365ea11b6b288d488adbbc8e31267a797
7
+ data.tar.gz: 41ba42965a2ab047098f450cf3c1fe3d7b69cffda6b4a634da757c6df229f4173b0b1dabc403d77493d1feb891ad9b364f221b6ef61e6c739e76663658feb91f
data/README.md CHANGED
@@ -14,7 +14,7 @@ Attempts to solve the pain of:
14
14
  The rolemodel-rails gem expects to be added to an existing Rails project. Typically those are started with:
15
15
 
16
16
  ```shell
17
- rails new <app-name> --javascript=webpack --database=postgresql --skip-test
17
+ rails new <app-name> --javascript=webpack --database=postgresql --skip-test --skip-solid
18
18
  ```
19
19
 
20
20
  The Devise generator requires your database to exist before running.
@@ -28,12 +28,15 @@ rails db:create
28
28
  Add this line to your application's Gemfile:
29
29
 
30
30
  ```ruby
31
- gem 'rolemodel-rails', group: :development
31
+ gem 'rolemodel-rails'
32
32
  ```
33
33
 
34
+ > [!IMPORTANT]
35
+ > We used to recommend putting rolemodel-rails in the development gem group. This is no longer supported, because some Rolemodel namespaced utility modules and classes are expected to be available at runtime.
36
+
34
37
  And then execute:
35
38
 
36
- $ bundle
39
+ $ bundle install
37
40
 
38
41
  ## Usage
39
42
 
@@ -99,6 +102,117 @@ bin/rails g
99
102
  * [Tailored Select](./lib/generators/rolemodel/tailored_select)
100
103
  * [Lograge](./lib/generators/rolemodel/lograge)
101
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
+
102
216
  ## Development
103
217
 
104
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`.
@@ -116,10 +230,6 @@ bin/new_generator testing/fantasitic_specs 'A Fantastic Testing Framework'
116
230
  We use the embeded Rails apps (`example_rails_current` & `example_rails_legacy`) to test generators against. They reference the rolemodel-rails gem by local path,
117
231
  so you can navigate into one of them and run your generator for immediate feedback while developing.
118
232
 
119
- > [!IMPORTANT]
120
- > Before submitting a PR, run `bin/bump_version` to ensure the Gem builds successfully & that everything continues to stay in sync & up-to-date.<br /><br />
121
- > For very small changes & bug fixes, prefer `bin/bump_version --patch`.
122
-
123
233
  ## Testing
124
234
 
125
235
  Generator specs should be added to the [spec](./spec) directory.
@@ -24,7 +24,6 @@ module Rolemodel
24
24
  generate 'rolemodel:editors'
25
25
  # generate 'rolemodel:tailored_select' # Not production ready
26
26
  generate 'rolemodel:lograge'
27
- generate 'rolemodel:mcp'
28
27
  end
29
28
  end
30
29
  end
@@ -4,4 +4,9 @@
4
4
 
5
5
  ## What you get
6
6
 
7
- Adds icon helper for handling material icons and custom icons
7
+ Adds icon helper for handling icon generation using the provider of your choice.
8
+
9
+ ## Icon Builder Customization
10
+
11
+ Run the generator with the `-i` option to install the IconBuilders themselves in your
12
+ application's `lib/rolemodel/optics` directory.
@@ -4,6 +4,7 @@ module Rolemodel
4
4
  module Optics
5
5
  # Generates the icon helper and icon builders for the chosen icon library
6
6
  class IconsGenerator < Rolemodel::GeneratorBase
7
+ BUILDER_DIR = 'rolemodel/optics'
7
8
  SUPPORTED_LIBRARIES = HashWithIndifferentAccess.new(
8
9
  material: 'filled, size, weight, emphasis, additional_classes, color, hover_text',
9
10
  phosphor: 'duotone, filled, size, weight, additional_classes, color, hover_text',
@@ -14,30 +15,34 @@ module Rolemodel
14
15
  ).freeze
15
16
 
16
17
  source_root File.expand_path('templates', __dir__)
18
+ class_option :install_builders, aliases: '-i', type: :boolean, default: false,
19
+ desc: "Install IconBuilder classes for customization"
20
+
17
21
  class_exclusive do
18
22
  SUPPORTED_LIBRARIES.keys.each do |library|
19
23
  class_option library, type: :boolean, lazy_default: false, desc: "Use #{library} icon library"
20
24
  end
21
25
  end
22
26
 
23
- def remove_existing_icon_helper_and_builders
24
- remove_dir 'app/icon_builders'
25
- remove_file 'app/helpers/icon_helper.rb'
26
- end
27
-
28
27
  def add_view_helper
29
28
  @chosen_library = capture_user_selection
30
29
  @supported_properties = SUPPORTED_LIBRARIES.fetch(@chosen_library)
31
30
 
32
- template 'app/icon_builders/icon_builder.rb'
33
- template "app/icon_builders/#{@chosen_library}_icon_builder.rb"
34
- template 'app/helpers/icon_helper.rb'
31
+ template 'app/helpers/icon_helper.rb', force: true
32
+ end
33
+
34
+ def install_builders
35
+ return unless options.install_builders?
36
+
37
+ source_paths << File.expand_path(BUILDER_DIR, Rolemodel::GEM_LIB)
38
+ copy_file 'icon_builder.rb', "lib/#{BUILDER_DIR}/icon_builder.rb", force: true
39
+ copy_file "#{@chosen_library}_icon_builder.rb", "lib/#{BUILDER_DIR}/#{@chosen_library}_icon_builder.rb", force: true
35
40
  end
36
41
 
37
42
  private
38
43
 
39
44
  def capture_user_selection
40
- options.except(*%i[skip_namespace skip_collision_check]).invert[true] || ask(
45
+ options.slice(*SUPPORTED_LIBRARIES.keys).invert[true] || ask(
41
46
  'What icon library would you like to add?',
42
47
  default: SUPPORTED_LIBRARIES.keys.first.to_s,
43
48
  limited_to: SUPPORTED_LIBRARIES.keys.map(&:to_s)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rolemodel/optics'
4
+
3
5
  # Helper method that renders icons from your icon library of choice.
4
6
  #
5
7
  # Usage:
@@ -14,11 +16,11 @@
14
16
  module IconHelper
15
17
  # <%= @supported_properties %>
16
18
  def icon(name, **)
17
- <%= @chosen_library.classify %>IconBuilder.new(name, **).build
19
+ Rolemodel::Optics::<%= @chosen_library.classify %>IconBuilder.new(name, **).build
18
20
  end
19
21
 
20
22
  # <%= @supported_properties %>
21
23
  def flash_icon(type, **)
22
- <%= @chosen_library.classify %>IconBuilder.flash_icon(type, **).build
24
+ Rolemodel::Optics::<%= @chosen_library.classify %>IconBuilder.flash_icon(type, **).build
23
25
  end
24
26
  end
@@ -5,7 +5,10 @@
5
5
  ## What you get
6
6
 
7
7
  * [RSpec](./rspec)
8
- * [JasminePlaywright](./jasmine_playwright)
9
8
  * [FactoryBot](./factory_bot)
10
9
  * [TestProf](./test_prof)
11
10
  * [ParallelTests](./parallel_tests)
11
+
12
+ Include the `--js-runner` flag (off by default) to also install the private `@rolemodel/jasmine-playwright-runner` package.
13
+
14
+ * [JasminePlaywright](./jasmine_playwright)
@@ -3,11 +3,11 @@ module Rolemodel
3
3
  class AllGenerator < GeneratorBase
4
4
  source_root File.expand_path('templates', __dir__)
5
5
 
6
+ class_option :js_runner, type: :boolean, default: false, desc: 'Include jasmine-playwright-runner for browser testing'
7
+
6
8
  def run_all_the_generators
7
9
  generate 'rolemodel:testing:factory_bot'
8
- if yes?('Would you like to add jasmine-playwright-runner for browser testing?')
9
- generate 'rolemodel:testing:jasmine_playwright'
10
- end
10
+ generate 'rolemodel:testing:jasmine_playwright' if options.js_runner?
11
11
  generate 'rolemodel:testing:parallel_tests'
12
12
  generate 'rolemodel:testing:rspec'
13
13
  generate 'rolemodel:testing:test_prof'
@@ -15,7 +15,7 @@ module Rolemodel
15
15
  ].freeze
16
16
 
17
17
  def fail_without_github_token
18
- raise 'a --github_package_token option or GITHUB_PACKAGES_TOKEN environment variable is required' if options[:github_package_token].blank?
18
+ raise Thor::InvocationError, 'a --github_package_token option or GITHUB_PACKAGES_TOKEN environment variable is required' if options[:github_package_token].blank?
19
19
  end
20
20
 
21
21
  def yarn_init_unless_package_json_exists
@@ -29,7 +29,7 @@ it 'saves the form data', :js do
29
29
  end
30
30
  ```
31
31
 
32
- #### Chrome - visible browser
32
+ #### Chrome - visible browser (For debugging only - do not commit headful system specs)
33
33
 
34
34
  ```rb
35
35
  it 'saves the form data', :chrome do
@@ -8,7 +8,7 @@ Example:
8
8
  spec/rails_helper.rb
9
9
  spec/spec_helper.rb
10
10
  spec/support/capybara_drivers.rb
11
- spec/support/capybara_testid.rb
11
+ spec/support/capybara_config.rb
12
12
  spec/support/helpers.rb
13
13
  spec/support/webpacker.rb
14
14
  .rspec
@@ -5,16 +5,24 @@ module Rolemodel
5
5
  class RspecGenerator < GeneratorBase
6
6
  source_root File.expand_path('templates', __dir__)
7
7
 
8
+ class_option :marsh_grass, type: :boolean, default: false, desc: 'Include marsh_grass for debugging RSpec tests'
9
+
8
10
  def install_rspec
11
+ say 'Installing RSpec-rails', :green
12
+
9
13
  gem_group :development, :test do
10
14
  gem 'rspec-rails'
11
15
  end
12
- run_bundle
16
+
17
+ say 'Installing capybara-playwright-driver for system tests', :green
13
18
 
14
19
  gem_group :test do
15
20
  gem 'capybara-playwright-driver'
16
- gem 'marsh_grass'
17
- gem 'pry'
21
+
22
+ if options.marsh_grass?
23
+ gem 'marsh_grass'
24
+ gem 'pry'
25
+ end
18
26
  end
19
27
  run_bundle
20
28
  end
@@ -27,17 +35,10 @@ module Rolemodel
27
35
  end
28
36
 
29
37
  def add_spec_files
30
- template 'rails_helper.rb', 'spec/rails_helper.rb'
31
- template 'spec_helper.rb', 'spec/spec_helper.rb'
32
- template '.rspec', '.rspec'
33
- template 'support/capybara_drivers.rb', 'spec/support/capybara_drivers.rb'
34
- template 'support/capybara_testid.rb', 'spec/support/capybara_testid.rb'
35
- template 'support/helpers/action_cable_helper.rb', 'spec/support/helpers/action_cable_helper.rb'
36
- template 'support/helpers/capybara_helper.rb', 'spec/support/helpers/capybara_helper.rb'
37
- template 'support/helpers/playwright_helper.rb', 'spec/support/helpers/playwright_helper.rb'
38
- template 'support/helpers/select_helper.rb', 'spec/support/helpers/select_helper.rb'
39
- template 'support/helpers/test_element_helper.rb', 'spec/support/helpers/test_element_helper.rb'
40
- template 'support/helpers.rb', 'spec/support/helpers.rb'
38
+ say 'Adding Support Files', :green
39
+
40
+ directory 'spec'
41
+
41
42
  append_file '.gitignore', 'spec/examples.txt'
42
43
  end
43
44
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara.configure do |config|
4
+ config.test_id = 'data-testid'
5
+ config.default_normalize_ws = true
6
+ config.save_path = './tmp/screenshots'
7
+ config.automatic_label_click = true
8
+ config.threadsafe = true
9
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # CustomIconBuilder is an IconBuilder that allows for custom SVG icons to be used in the application.
4
- class CustomIconBuilder < IconBuilder
4
+ class Rolemodel::Optics::CustomIconBuilder < Rolemodel::Optics::IconBuilder
5
5
  def self.flash_icons
6
6
  {
7
7
  notice: 'circle-check',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # FeatherIconBuilder is an IconBuilder that allows for Feather icons to be used in the application.
4
4
  # https://feathericons.com/
5
- class FeatherIconBuilder < IconBuilder
5
+ class Rolemodel::Optics::FeatherIconBuilder < Rolemodel::Optics::IconBuilder
6
6
  def self.flash_icons
7
7
  {
8
8
  notice: 'check-circle',
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class IconBuilder
3
+ class Rolemodel::Optics::IconBuilder
4
4
  include ActionView::Helpers::TagHelper
5
5
 
6
6
  attr_reader :name, :filled, :size, :weight, :emphasis, :duotone, :additional_classes, :color, :hover_text
7
+ alias title hover_text
7
8
 
8
9
  DEFAULT_SIZE = 'medium'
9
10
  DEFAULT_WEIGHT = 'normal'
10
11
  DEFAULT_EMPHASIS = 'normal'
11
12
 
13
+ # TODO: consider Data.define a custom options object if all of these parameters are indeed necessary.
12
14
  def initialize( # rubocop:disable Metrics/ParameterLists
13
15
  name,
14
16
  filled: false,
@@ -42,32 +44,21 @@ class IconBuilder
42
44
  def build
43
45
  options = {
44
46
  class: tag_classes.compact_blank.join(' '),
45
- title: hover_text
46
- }
47
-
48
- if color.present?
47
+ title: hover_text,
49
48
  # color: primary, neutral, alerts-notice, alerts-warning, alerts-danger, alerts-info
50
- options[:style] = "#{color_attribute}: var(--op-color-#{color}-base);"
51
- end
49
+ style: ("#{color_attribute}: var(--op-color-#{color}-base);" if color.present?)
50
+ }.compact_blank
52
51
 
53
- tag.send(tag_method, tag_contents, **options)
52
+ tag.public_send(tag_method, tag_contents, **options)
54
53
  end
55
54
 
56
55
  private
57
56
 
58
- def tag_method
59
- raise NotImplementedError
60
- end
61
-
62
- def tag_contents
63
- ''
64
- end
65
-
66
57
  def tag_classes
67
58
  ['icon', size == DEFAULT_SIZE ? '' : "icon--#{size}", additional_classes]
68
59
  end
69
60
 
70
- def color_attribute
71
- 'color'
72
- end
61
+ def color_attribute = 'color'
62
+ def tag_contents = ''
63
+ def tag_method = :i
73
64
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # LucideIconBuilder is an IconBuilder that allows for Lucide icons to be used in the application.
4
4
  # https://lucide.dev/icons/
5
- class LucideIconBuilder < IconBuilder
5
+ class Rolemodel::Optics::LucideIconBuilder < Rolemodel::Optics::IconBuilder
6
6
  def self.flash_icons
7
7
  {
8
8
  notice: 'circle-check',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # MaterialIconBuilder is an IconBuilder that allows for Material icons to be used in the application.
4
4
  # https://fonts.google.com/icons
5
- class MaterialIconBuilder < IconBuilder
5
+ class Rolemodel::Optics::MaterialIconBuilder < Rolemodel::Optics::IconBuilder
6
6
  def self.flash_icons
7
7
  {
8
8
  notice: 'check_circle',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # PhosphorIconBuilder is an IconBuilder that allows for Phosphor icons to be used in the application.
4
4
  # https://phosphoricons.com/
5
- class PhosphorIconBuilder < IconBuilder
5
+ class Rolemodel::Optics::PhosphorIconBuilder < Rolemodel::Optics::IconBuilder
6
6
  def self.flash_icons
7
7
  {
8
8
  notice: 'check-circle',
@@ -2,7 +2,7 @@
2
2
 
3
3
  # TablerIconBuilder is an IconBuilder that allows for Tabler icons to be used in the application.
4
4
  # https://tablericons.com/
5
- class TablerIconBuilder < IconBuilder
5
+ class Rolemodel::Optics::TablerIconBuilder < Rolemodel::Optics::IconBuilder
6
6
  def self.flash_icons
7
7
  {
8
8
  notice: 'circle-check',
@@ -0,0 +1,9 @@
1
+ module Rolemodel::Optics
2
+ autoload :IconBuilder, 'rolemodel/optics/icon_builder'
3
+ autoload :CustomIconBuilder, 'rolemodel/optics/custom_icon_builder'
4
+ autoload :FeatherIconBuilder, 'rolemodel/optics/feather_icon_builder'
5
+ autoload :LucideIconBuilder, 'rolemodel/optics/lucide_icon_builder'
6
+ autoload :MaterialIconBuilder, 'rolemodel/optics/material_icon_builder'
7
+ autoload :PhosphorIconBuilder, 'rolemodel/optics/phosphor_icon_builder'
8
+ autoload :TablerIconBuilder, 'rolemodel/optics/tabler_icon_builder'
9
+ end
@@ -0,0 +1,69 @@
1
+ require 'benchmark'
2
+
3
+ module Rolemodel
4
+ module Utility
5
+ module TaskTools
6
+ PROGRESS = %w[⠏ ⠇ ⠧ ⠦ ⠴ ⠼ ⠸ ⠹ ⠙ ⠋].cycle
7
+
8
+ # based on the migration helper of the same name
9
+ def say_with_time(message, &)
10
+ say message
11
+ time = Benchmark.measure(&)
12
+ say '%.4fs' % time.real, subitem: true
13
+ end
14
+
15
+ # based on the migration helper of the same name
16
+ def say(message, subitem: false)
17
+ puts "#{subitem ? ' ->' : '--'} #{message}" # rubocop:disable Rails/Output
18
+ end
19
+
20
+ ##
21
+ # Indicate the progress of a long-running process
22
+ #
23
+ # Usage (with a known total):
24
+ # 100.times do |i|
25
+ # indicate_progress(i, 100)
26
+ # end
27
+ #
28
+ # Only update every 'report_interval' iteration for eye-trackable animation speed
29
+ # Also displays a completion percentage if a total is provided
30
+ def indicate_progress(index, total = nil, report_interval: 9)
31
+ return unless (index % report_interval).zero?
32
+
33
+ print("#{PROGRESS.next} #{to_percent(index, total) if total}\r") # rubocop:disable Rails/Output
34
+ end
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
+
52
+ private
53
+
54
+ def to_percent(index, total)
55
+ '%3.f%%' % (index / total.to_f * 100.0)
56
+ end
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
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module Rolemodel::Utility
2
+ autoload :TaskTools, 'rolemodel/utility/task_tools'
3
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rolemodel
4
- VERSION = '1.1.0'
4
+ VERSION = '2.1.0'
5
5
  end
@@ -3,6 +3,8 @@
3
3
  module Rolemodel
4
4
  NODE_VERSION = '24.12.0'
5
5
  RUBY_VERSION = '4.0.1'
6
+
7
+ GEM_LIB = File.expand_path(__dir__)
6
8
  end
7
9
 
8
10
  require 'rolemodel/version'