rrx_rails 8.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: db43a3ee8af420b253b5acb01cfa2aacf243d3f0c11949875f2b8a4e0fa22c98
4
+ data.tar.gz: ef0812fce588a4bad3745f250d9754bd48bc1b36be546fafc1e23af81831b343
5
+ SHA512:
6
+ metadata.gz: fc16df4c7281679d06f3ab1b1042ff61c1bb3abc3785adb7b4fdb9ca95a051a814865118b533fd61237be178e2f81ff03632627bf51ac1450d1986830a02a40a
7
+ data.tar.gz: 8f454487afbaa2167f578e62e0d80bb8cd3479e606144e4dfed8554344a07daa2d3d12586b96994aabf236cc199ce73f606e36eaafe4af6229dab75173f334aa
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: single_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
14
+
15
+ Metrics/MethodLength:
16
+ Max: 20
17
+
18
+ Metrics/AbcSize:
19
+ Max: 20
20
+
21
+ Layout/BeginEndAlignment:
22
+ EnforcedStyleAlignWith: begin
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.2.8
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at dan.drew@hotmail.com. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,93 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rrx_rails (8.0.2)
5
+ rake
6
+ thor
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.3)
12
+ binding_of_caller (1.0.1)
13
+ debug_inspector (>= 1.2.0)
14
+ debug_inspector (1.2.0)
15
+ diff-lcs (1.6.2)
16
+ json (2.13.2)
17
+ language_server-protocol (3.17.0.5)
18
+ lint_roller (1.1.0)
19
+ parallel (1.27.0)
20
+ parser (3.3.9.0)
21
+ ast (~> 2.4.1)
22
+ racc
23
+ prism (1.4.0)
24
+ proc_to_ast (0.2.0)
25
+ parser
26
+ rouge
27
+ unparser
28
+ racc (1.8.1)
29
+ rainbow (3.1.1)
30
+ rake (13.3.0)
31
+ regexp_parser (2.11.2)
32
+ rouge (4.6.0)
33
+ rspec (3.13.1)
34
+ rspec-core (~> 3.13.0)
35
+ rspec-expectations (~> 3.13.0)
36
+ rspec-mocks (~> 3.13.0)
37
+ rspec-core (3.13.5)
38
+ rspec-support (~> 3.13.0)
39
+ rspec-expectations (3.13.5)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.13.0)
42
+ rspec-mocks (3.13.5)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.13.0)
45
+ rspec-parameterized (2.0.0)
46
+ rspec-parameterized-core (>= 2, < 3)
47
+ rspec-parameterized-table_syntax (>= 2, < 3)
48
+ rspec-parameterized-core (2.0.0)
49
+ parser
50
+ prism
51
+ proc_to_ast (>= 0.2.0)
52
+ rspec (>= 2.13, < 4)
53
+ unparser
54
+ rspec-parameterized-table_syntax (2.0.0)
55
+ binding_of_caller
56
+ rspec-parameterized-core (>= 2, < 3)
57
+ rspec-support (3.13.5)
58
+ rubocop (1.80.0)
59
+ json (~> 2.3)
60
+ language_server-protocol (~> 3.17.0.2)
61
+ lint_roller (~> 1.1.0)
62
+ parallel (~> 1.10)
63
+ parser (>= 3.3.0.2)
64
+ rainbow (>= 2.2.2, < 4.0)
65
+ regexp_parser (>= 2.9.3, < 3.0)
66
+ rubocop-ast (>= 1.46.0, < 2.0)
67
+ ruby-progressbar (~> 1.7)
68
+ unicode-display_width (>= 2.4.0, < 4.0)
69
+ rubocop-ast (1.46.0)
70
+ parser (>= 3.3.7.2)
71
+ prism (~> 1.4)
72
+ ruby-progressbar (1.13.0)
73
+ thor (1.4.0)
74
+ unicode-display_width (3.1.5)
75
+ unicode-emoji (~> 4.0, >= 4.0.4)
76
+ unicode-emoji (4.0.4)
77
+ unparser (0.8.0)
78
+ diff-lcs (~> 1.6)
79
+ parser (>= 3.3.0)
80
+ prism (>= 1.4)
81
+
82
+ PLATFORMS
83
+ x86_64-linux
84
+
85
+ DEPENDENCIES
86
+ rrx_rails!
87
+ rspec
88
+ rspec-core
89
+ rspec-parameterized
90
+ rubocop
91
+
92
+ BUNDLED WITH
93
+ 2.4.19
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Dan Drew
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # RRX Rails
2
+
3
+ RRX Rails is the command-line interface to creating RRX-based Ruby on Rails web services and gems.
4
+
5
+ ## Installation
6
+
7
+ This gem is intended to be installed globally:
8
+
9
+ ```shell
10
+ gem install rrx_rails
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ For full command-line syntax and options, please use `rrx_rails help`.
16
+
17
+ **Example: Creating a new Ruby on Rails API project with background jobs**
18
+
19
+ ```shell
20
+ rrx_rails api path/to/new_project --jobs
21
+ ```
22
+
23
+ ## Development
24
+
25
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
26
+
27
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
+
29
+ ### Update all gem versions
30
+
31
+ ```shell
32
+ bundle exec rake rrx:update_versions[<NEW VERSION>]
33
+ ```
34
+
35
+ ### Install all gems locally
36
+
37
+ ```shell
38
+ bundle exec rake rrx:install
39
+ ```
40
+
41
+ ## Contributing
42
+
43
+ Bug reports and pull requests are welcome on GitHub at https://github.com/rails-rrx/rrx_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/rrx_rails/blob/main/CODE_OF_CONDUCT.md).
44
+
45
+ ## License
46
+
47
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
48
+
49
+ ## Code of Conduct
50
+
51
+ Everyone interacting in the RrxRails project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rrx_rails/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require 'pathname'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ require "rubocop/rake_task"
10
+
11
+ RuboCop::RakeTask.new
12
+
13
+ Pathname(__FILE__).join('../lib/tasks').glob('**/*.rake').each { |f| load f }
14
+
15
+ task default: %i[spec rubocop]
data/exe/rrx_rails ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/rrx_rails/cli'
5
+
6
+ RrxRails::Cli.start
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ RRX_VERSION = '<%= rrx_version %>'
6
+
7
+ <% if gem? %>
8
+ gemspec
9
+
10
+ <%= rrx_gem_spec 'rrx_dev' %>
11
+ <% else %>
12
+ ruby '~> <%= ruby_version %>'
13
+
14
+ <%= gem_list.join("\n") %>
15
+
16
+ group :development, :test do
17
+ <%= dev_gem_list.map { |s| " #{s}" }.join("\n") %>
18
+ end
19
+ <% end %>
20
+
21
+ # Please review Rails-generated Gemfile and include/delete as needed.
22
+ # -------------------------------------------------------------------
23
+ <%= commented_existing_gemfile %>
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/<%= name %>/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ source_uri = 'https://github.com/your-account/<%= name %>'
7
+ home_uri = source_uri # Replace with home page, if there is one
8
+
9
+ spec.name = "<%= name %>"
10
+ spec.version = <%= module_name %>::VERSION
11
+ spec.authors = ["YOUR NAME"]
12
+ spec.email = ["YOUR EMAIL"]
13
+
14
+ spec.summary = "DESCRIPTION"
15
+ # spec.description = "TODO: Write a longer description or delete this line."
16
+ spec.homepage = home_uri
17
+ spec.license = "MIT"
18
+ spec.required_ruby_version = ">= <%= ruby_version %>"
19
+
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
21
+
22
+ spec.metadata["homepage_uri"] = spec.homepage
23
+ spec.metadata["source_code_uri"] = source_uri
24
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(__dir__) do
29
+ `git ls-files -z`.split("\x0").reject do |f|
30
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
31
+ end
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ # Gem dependencies
38
+ <% dependencies.sort.each do |dep| -%>spec.add_dependency '<%= dep %>'
39
+ <% end %>
40
+ # spec.add_dependency "some-other-gem", "version"
41
+ end
@@ -0,0 +1,294 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+ require 'pathname'
5
+ require_relative './version'
6
+
7
+ # rubocop:disable Style/Documentation
8
+ # rubocop:disable Metrics/ClassLength
9
+
10
+ module RrxRails
11
+ class Cli < Thor
12
+ include Thor::Actions
13
+
14
+ add_runtime_options!
15
+
16
+ class_option :rrx_local, type: :boolean, desc: 'Use local RRX gems', default: false, hide: true
17
+ class_option :skip_git, type: :boolean, desc: 'Disable Git repo creation', default: false
18
+ class_option :update, type: :boolean, desc: 'Update an existing project', default: false
19
+
20
+ class << self
21
+ def exit_on_failure?
22
+ true
23
+ end
24
+
25
+ def comment(str)
26
+ str.gsub(/^([^#])/m, '#\1')
27
+ end
28
+
29
+ private
30
+
31
+ def mail!
32
+ option :mail, type: :boolean, desc: 'Include ActionMailer support'
33
+ end
34
+
35
+ def storage!
36
+ option :storage, type: :boolean, desc: 'Include ActiveStorage support'
37
+ end
38
+
39
+ def jobs!
40
+ option :jobs, type: :boolean, desc: 'Include ActiveJob support'
41
+ end
42
+
43
+ def sockets!
44
+ option :sockets, type: :boolean, desc: 'Include ActionCable support'
45
+ end
46
+ end
47
+
48
+ #
49
+ # # default_command :api
50
+ source_root Pathname(__FILE__).parent.join('cli/sources').freeze
51
+ #
52
+ # attr_reader :name,
53
+ # :type,
54
+ # :dependencies,
55
+ # :existed,
56
+ # :project_path
57
+
58
+ desc 'api APP_PATH', 'Create a new API project'
59
+ mail!
60
+ storage!
61
+ jobs!
62
+ sockets!
63
+
64
+ def api(name)
65
+ validate_options!
66
+ init name, type: :api
67
+ create_project
68
+ inside do
69
+ create_gemfile
70
+ bundle_install
71
+ generate 'rrx_api:install'
72
+ generate 'rrx_jobs:install' if options[:jobs]
73
+ end
74
+ end
75
+
76
+ desc 'railtie APP_PATH', 'Create a new Railtie project'
77
+ def railtie(name)
78
+ validate_options!
79
+ setup_gem name
80
+ end
81
+
82
+ desc 'engine APP_PATH', 'Create a new Rails Engine project'
83
+ mail!
84
+ storage!
85
+
86
+ def engine(name)
87
+ validate_options!
88
+ setup_gem name, engine: true
89
+ end
90
+
91
+ private
92
+
93
+ GEM_ROOT = begin
94
+ path = Pathname(__FILE__)
95
+ path = path.parent until path.join('lib').exist? || path.root?
96
+ raise "Cannot find gem root from #{__FILE__}" if path.root?
97
+
98
+ path.realpath.freeze
99
+ end
100
+
101
+ RRX_ROOT = GEM_ROOT.parent.freeze
102
+ RAILS_NEW_SKIP = %w[js hotwire jbuilder rubocop test bundle action-mailbox asset-pipeline].freeze
103
+ RAILS_NEW_OPTIONS = %w[--api].concat(RAILS_NEW_SKIP.map { |s| "--skip-#{s}" }).freeze
104
+
105
+ attr_reader :app_name, :type, :dependencies, :app_path
106
+
107
+ def setup_gem(name, engine: false)
108
+ @engine = engine
109
+
110
+ init name, deps: %w[rrx_logging rrx_config]
111
+ create_project
112
+ create_gemspec
113
+ create_gemfile
114
+ bundle_install
115
+ generate 'rrx_dev:install'
116
+ end
117
+
118
+ # @param [String] app_path
119
+ # @param [Symbol] type
120
+ # @param [Array<String>] deps
121
+ def init(app_path, type: :gem, deps: [])
122
+ raise Thor::Error, 'Invalid app name' if app_path !~ /^[a-z][a-z0-9_]*$/
123
+
124
+ @app_path = Pathname(app_path).expand_path
125
+ @app_name = @app_path.basename.to_s
126
+ @type = type
127
+ @dependencies = deps
128
+ end
129
+
130
+ def validate_options!
131
+ return unless [force?, skip?, pretend?, quiet?].count(true) > 1
132
+
133
+ raise Thor::Error, 'Only one of --force, --skip, --pretend or --quiet is allowed'
134
+ end
135
+
136
+ def comment(str)
137
+ Cli.comment str
138
+ end
139
+
140
+ def force?
141
+ options[:force]
142
+ end
143
+
144
+ def quiet?
145
+ options[:quiet]
146
+ end
147
+
148
+ def pretend?
149
+ options[:pretend]
150
+ end
151
+
152
+ def skip?
153
+ options[:skip]
154
+ end
155
+
156
+ def runtime_options
157
+ @runtime_options ||= begin
158
+ cmd = []
159
+ cmd << '--force' if force?
160
+ cmd << '--quiet' if quiet?
161
+ cmd << '--pretend' if pretend?
162
+ cmd << '--skip' if skip?
163
+ cmd.sort.freeze
164
+ end
165
+ @runtime_options
166
+ end
167
+
168
+ def rails_skip_options
169
+ cmd = []
170
+ cmd << '--skip-git' if options[:skip_git]
171
+ cmd << '--skip-action-mailer' unless options[:mail]
172
+ cmd << '--skip-active-storage' unless options[:storage]
173
+ cmd << '--skip-active-job' unless options[:jobs]
174
+ cmd << '--skip-action-cable' unless options[:sockets]
175
+ cmd
176
+ end
177
+
178
+ def rrx_version
179
+ @rrx_version ||= "~> #{RrxRails::VERSION}"
180
+ end
181
+
182
+ alias rails_version rrx_version
183
+
184
+ def rails_cmd(*args)
185
+ ['gem', 'exec', '-g', 'rails', '--version', rails_version, 'rails', *args].flatten
186
+ end
187
+
188
+ def rails_new_cmd
189
+ cmd = gem? ? %w[plugin new] : %w[new]
190
+ cmd << app_path.to_s
191
+
192
+ cmd_options = runtime_options.dup
193
+ cmd_options << '--mountable' if engine?
194
+ cmd_options.concat RAILS_NEW_OPTIONS
195
+ cmd_options.concat rails_skip_options
196
+
197
+ rails_cmd cmd + cmd_options.sort
198
+ end
199
+
200
+ def bundle_install
201
+ inside(destination_root) { run 'bundle config --delete bin' }
202
+ inside(destination_root) { run 'bundle install' }
203
+ fix_rails_binstubs
204
+ end
205
+
206
+ def fix_rails_binstubs
207
+ run_cmd rails_cmd('app:update:bin')
208
+ end
209
+
210
+ def gem?
211
+ type == :gem
212
+ end
213
+
214
+ def api?
215
+ type == :api
216
+ end
217
+
218
+ def engine?
219
+ gem? && @engine
220
+ end
221
+
222
+ def ruby_version
223
+ RUBY_VERSION
224
+ end
225
+
226
+ def generate(name)
227
+ inside { run_cmd %w[bundle exec rails generate], name, runtime_options }
228
+ end
229
+
230
+ def create_project
231
+ run_cmd rails_new_cmd unless options[:update]
232
+ self.destination_root = app_path
233
+ end
234
+
235
+ def create_gemspec
236
+ template 'gemspec.rb.erb', "#{name}.gemspec"
237
+ end
238
+
239
+ def create_gemfile
240
+ template 'gemfile.rb.erb', 'Gemfile', force: force_gemfile?
241
+ end
242
+
243
+ def force_gemfile?
244
+ return false if skip?
245
+
246
+ !existing_gemfile.include?('rrx')
247
+ end
248
+
249
+ def existing_gemfile
250
+ @existing_gemfile ||= begin
251
+ text = app_path.join('Gemfile').read
252
+ idx = text.index('# Please review')
253
+ @commented_existing_gemfile = text[idx...].lines[2...].join('') if idx
254
+ text
255
+ end
256
+ end
257
+
258
+ def commented_existing_gemfile
259
+ @commented_existing_gemfile ||= comment(existing_gemfile)
260
+ end
261
+
262
+ def run_cmd(*command, **config)
263
+ run(
264
+ command.flatten.map do |s|
265
+ s =~ /\s/ ? "'#{s}'" : s
266
+ end.join(' '),
267
+ config
268
+ )
269
+ end
270
+
271
+ def rrx_gem_spec(name)
272
+ spec = "gem '#{name}', RRX_VERSION"
273
+ spec += ", path: '#{RRX_ROOT.join(name)}'" if options[:rrx_local]
274
+ spec
275
+ end
276
+
277
+ def gem_list
278
+ gems = [
279
+ rrx_gem_spec('rrx_api')
280
+ ]
281
+ gems << rrx_gem_spec('rrx_jobs') if options[:jobs]
282
+ gems
283
+ end
284
+
285
+ def dev_gem_list
286
+ [rrx_gem_spec('rrx_dev')]
287
+ end
288
+
289
+ end
290
+
291
+ end
292
+
293
+ # rubocop:enable Style/Documentation
294
+ # rubocop:enable Metrics/ClassLength
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RrxRails
4
+ VERSION = '8.0.2'
5
+ end
data/lib/rrx_rails.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rrx_rails/version"
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ # Base class for RRX tasks.
6
+ class RrxTask
7
+ ROOT_PATH = begin
8
+ it = Pathname(__FILE__).expand_path
9
+ it = it.parent until it.join('lib').exist?
10
+ it.parent.freeze
11
+ end
12
+ GEMS = %w[dev config logging api jobs rails].map { |n| "rrx_#{n}" }.freeze
13
+
14
+ def each_gem(&block)
15
+ puts ROOT_PATH.to_s
16
+ GEMS.map { |name| ROOT_PATH.join(name) }.select(&:directory?).each do |path|
17
+ block.call path
18
+ end
19
+ end
20
+ end
21
+
22
+ # Updates RRX gem versions.
23
+ class UpdateGems < RrxTask
24
+ attr_reader :version
25
+
26
+ # @param [String] version
27
+ def initialize(version)
28
+ super()
29
+
30
+ # @type [String]
31
+ @version = version.to_s.strip
32
+
33
+ raise ArgumentError, 'Invalid version' if @version.empty?
34
+ end
35
+
36
+ def update_gems
37
+ each_gem { |dir| update_directory dir }
38
+ end
39
+
40
+ private
41
+
42
+ # @param [Pathname] path
43
+ def update_file(path)
44
+ text = path.read
45
+ new_contents = text.gsub(/(\sVERSION\s*=\s*['"])([^'"]+)(['"])/, "\\1#{version}\\3")
46
+ return if new_contents == text
47
+
48
+ puts "Updating #{path} to version #{version}"
49
+ path.write new_contents
50
+ end
51
+
52
+ # @param [Pathname] path
53
+ def update_directory(path)
54
+ path.glob('**/version.rb').each do |version_path|
55
+ update_file version_path
56
+ end
57
+ end
58
+ end
59
+
60
+ # Installs RRX gems locally.
61
+ class InstallTask < RrxTask
62
+ def install_gems
63
+ each_gem { |dir| install_directory dir }
64
+ end
65
+
66
+ private
67
+
68
+ # @param [Pathname] path
69
+ def install_directory(path)
70
+ Dir.chdir path do
71
+ raise 'Failed to build gem!' unless build(path)
72
+ raise 'Failed to install gem!' unless install(path)
73
+ end
74
+ end
75
+
76
+ def build(path)
77
+ Dir.chdir path do
78
+ return system('rake build')
79
+ end
80
+ end
81
+
82
+ def install(path)
83
+ pkg = path.join('pkg').glob('*.gem').max_by(&:mtime)
84
+ pkg && system("gem install -N --ignore-dependencies #{pkg}")
85
+ end
86
+ end
87
+
88
+ namespace :rrx do
89
+
90
+ desc 'Update RRX gem versions.'
91
+ task :update_versions, [:version] do |t, args|
92
+ updater = UpdateGems.new(args[:version])
93
+ updater.update_gems
94
+ end
95
+
96
+ desc 'Install RRX gems locally.'
97
+ task :install do
98
+ InstallTask.new.install_gems
99
+ end
100
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rrx_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 8.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dan Drew
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-core
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-parameterized
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ - dan.drew@hotmail.com
100
+ executables:
101
+ - rrx_rails
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".rspec"
106
+ - ".rubocop.yml"
107
+ - ".tool-versions"
108
+ - CODE_OF_CONDUCT.md
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - exe/rrx_rails
115
+ - lib/rrx_rails.rb
116
+ - lib/rrx_rails/cli.rb
117
+ - lib/rrx_rails/cli/sources/gemfile.rb.erb
118
+ - lib/rrx_rails/cli/sources/gemspec.rb.erb
119
+ - lib/rrx_rails/version.rb
120
+ - lib/tasks/rrx.rake
121
+ homepage: https://github.com/rails-rrx/rrx_rails
122
+ licenses:
123
+ - MIT
124
+ metadata:
125
+ homepage_uri: https://github.com/rails-rrx/rrx_rails
126
+ source_code_uri: https://github.com/rails-rrx/rrx_rails
127
+ post_install_message:
128
+ rdoc_options: []
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: 3.1.0
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubygems_version: 3.4.19
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Command line for creating RRX projects
146
+ test_files: []