nextgen 0.18.0 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -5
- data/config/generators.yml +7 -10
- data/lib/nextgen/actions/yarn.rb +6 -0
- data/lib/nextgen/commands/create.rb +23 -3
- data/lib/nextgen/generators/base.rb +10 -9
- data/lib/nextgen/generators/bundler_audit.rb +22 -0
- data/lib/nextgen/generators/eslint.rb +26 -0
- data/lib/nextgen/generators/rspec_github_actions.rb +63 -0
- data/lib/nextgen/generators/rubocop.rb +3 -2
- data/lib/nextgen/generators/stylelint.rb +26 -0
- data/lib/nextgen/generators/vite.rb +24 -5
- data/lib/nextgen/rails_options.rb +35 -18
- data/lib/nextgen/tidy_gemfile.rb +2 -1
- data/lib/nextgen/version.rb +1 -1
- data/template/.rubocop.yml.tt +3 -0
- data/template/bin/{dev-yarn → dev-node} +1 -1
- data/template/run-pty.json +16 -0
- metadata +8 -10
- data/lib/nextgen/generators/brakeman.rb +0 -4
- data/lib/nextgen/generators/github_actions.rb +0 -5
- data/template/.github/dependabot.yml +0 -9
- data/template/.github/workflows/ci.yml.tt +0 -142
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08e56651b3e6d88022098471a5b3e04b20ca703ac5e973425fb68f806b271e4a'
|
4
|
+
data.tar.gz: fed2715b9bdb7625434ef6983a15118e1fe29cd3f64a0f182928c1805920f7ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5481874c31115de5229ba346ede332453731c46604b01e974ee1d34471ff1dfcc290dbcdbf2170f03e64b44333d1c83ced987204c6c43abf58637c416e18628c
|
7
|
+
data.tar.gz: 679b4f278c8493da2ed8b34df79c761073f010262bf66eff305a974051f1a1ff52dd89542dc6a852bbacbe7e4a4a46fda95355d68e7cc0e8e6bfb55c53c31682
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ Nextgen is an **interactive** and flexible alternative to `rails new` that inclu
|
|
26
26
|
|
27
27
|
## Requirements
|
28
28
|
|
29
|
-
Nextgen generates apps using **Rails 7.
|
29
|
+
Nextgen generates apps using **Rails 7.2**.
|
30
30
|
|
31
31
|
- **Ruby 3.1+** is required
|
32
32
|
- **Rubygems 3.4.8+** is required (run `gem update --system` to get it)
|
@@ -54,7 +54,7 @@ Check out the [examples directory](./examples) to see some Rails apps that were
|
|
54
54
|
|
55
55
|
## What's included
|
56
56
|
|
57
|
-
**Nextgen starts with the "omakase" default behavior of `rails new`,** so you get the great things included in Rails 7.
|
57
|
+
**Nextgen starts with the "omakase" default behavior of `rails new`,** so you get the great things included in Rails 7.2 like RuboCop, a GitHub Actions CI workflow, your choice of database platform, CSS framework, etc. You can also interactively disable parts of the default stack that you don't need, like JBuilder or Action Mailbox.
|
58
58
|
|
59
59
|
On top of that foundation, Nextgen offers dozens of useful enhancements to the vanilla Rails experience. You are free to pick and choose which (if any) of these to apply to your new project. Behind the scenes, **each enhancement is applied in a separate git commit,** so that you can later see what was applied and why, and revert the suggestions if necessary.
|
60
60
|
|
@@ -65,18 +65,21 @@ Here are some highlights of what Nextgen brings to the table:
|
|
65
65
|
|
66
66
|
### GitHub Actions
|
67
67
|
|
68
|
-
|
68
|
+
If you've opted into GitHub Actions, Nextgen will automatically add jobs to your CI workflow based on the gems and packages you have installed.
|
69
69
|
|
70
70
|
### Minitest or RSpec
|
71
71
|
|
72
72
|
Prefer RSpec? Nextgen can set you up with RSpec, plus the gems and configuration you need for system specs (browser testing). Or stick with the Rails Minitest defaults. In either case, Nextgen will set up a good default Rake task and appropriate CI job.
|
73
73
|
|
74
|
+
### Opinionated RuboCop Config
|
75
|
+
|
76
|
+
By default, Rails apps include RuboCop with a config defined by the [rubocop-rails-omakase](https://github.com/rails/rubocop-rails-omakase) gem. Nextgen allows you to opt out of RuboCop entirely, or use Nextgen's own custom RuboCop config. Nextgen's config will automatically include Capybara, FactoryBot, and RSpec rules, should your app include those frameworks.
|
77
|
+
|
74
78
|
### Gems
|
75
79
|
|
76
80
|
Nextgen can install and configure your choice of these recommended gems:
|
77
81
|
|
78
82
|
- [annotate](https://github.com/ctran/annotate_models)
|
79
|
-
- [brakeman](https://github.com/presidentbeef/brakeman)
|
80
83
|
- [bundler-audit](https://github.com/rubysec/bundler-audit)
|
81
84
|
- [capybara-lockstep](https://github.com/makandra/capybara-lockstep)
|
82
85
|
- [dotenv](https://github.com/bkeepers/dotenv)
|
@@ -88,7 +91,6 @@ Nextgen can install and configure your choice of these recommended gems:
|
|
88
91
|
- [pgcli-rails](https://github.com/mattbrictson/pgcli-rails)
|
89
92
|
- [rack-canonical-host](https://github.com/tylerhunt/rack-canonical-host)
|
90
93
|
- [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler)
|
91
|
-
- [rubocop](https://github.com/rubocop/rubocop)
|
92
94
|
- [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers)
|
93
95
|
- [sidekiq](https://github.com/sidekiq/sidekiq)
|
94
96
|
- [thor](https://github.com/rails/thor)
|
data/config/generators.yml
CHANGED
@@ -16,6 +16,10 @@ rspec_system_testing:
|
|
16
16
|
- rspec
|
17
17
|
- system_testing
|
18
18
|
|
19
|
+
rspec_github_actions:
|
20
|
+
description: "Add RSpec job to GitHub Actions CI workflow"
|
21
|
+
requires: rspec
|
22
|
+
|
19
23
|
node:
|
20
24
|
description: "Set up Node and Yarn"
|
21
25
|
|
@@ -37,10 +41,6 @@ basic_auth:
|
|
37
41
|
prompt: "BasicAuth controller concern"
|
38
42
|
description: "Allow app to be secured with ENV-based basic auth credentials"
|
39
43
|
|
40
|
-
brakeman:
|
41
|
-
prompt: "Brakeman"
|
42
|
-
description: "Install brakeman gem for security checks"
|
43
|
-
|
44
44
|
bundler_audit:
|
45
45
|
prompt: "Bundler Audit"
|
46
46
|
description: "Install bundler-audit gem to detect CVEs in Ruby dependencies"
|
@@ -143,13 +143,10 @@ vcr:
|
|
143
143
|
requires: test_framework
|
144
144
|
|
145
145
|
rubocop:
|
146
|
-
prompt: "RuboCop"
|
147
|
-
description: "
|
146
|
+
prompt: "RuboCop (nextgen custom config)"
|
147
|
+
description: "Replace rubocop-rails-omakase with a custom config"
|
148
|
+
requires: rubocop
|
148
149
|
|
149
150
|
overcommit:
|
150
151
|
prompt: "Overcommit"
|
151
152
|
description: "Configure overcommit pre-commit git hooks"
|
152
|
-
|
153
|
-
github_actions:
|
154
|
-
prompt: "GitHub Actions"
|
155
|
-
description: "Configure GitHub Actions workflow for CI"
|
data/lib/nextgen/actions/yarn.rb
CHANGED
@@ -22,6 +22,12 @@ module Nextgen
|
|
22
22
|
end
|
23
23
|
alias add_package_json_script add_package_json_scripts
|
24
24
|
|
25
|
+
def remove_package_json_script(name)
|
26
|
+
cmd = "npm pkg delete scripts.#{name.to_s.shellescape}"
|
27
|
+
say_status :run, cmd.truncate(60), :green
|
28
|
+
run! cmd, verbose: false
|
29
|
+
end
|
30
|
+
|
25
31
|
def yarn_command(cmd, capture: false)
|
26
32
|
say_status :yarn, cmd, :green
|
27
33
|
output = run! "yarn #{cmd}", capture: true, verbose: false
|
@@ -45,6 +45,7 @@ module Nextgen
|
|
45
45
|
ask_frontend_management unless rails_opts.api?
|
46
46
|
ask_css unless rails_opts.api? || rails_opts.skip_asset_pipeline?
|
47
47
|
ask_javascript unless rails_opts.api? || rails_opts.skip_asset_pipeline?
|
48
|
+
ask_rails_tools
|
48
49
|
ask_rails_frameworks
|
49
50
|
ask_test_framework
|
50
51
|
ask_system_testing if rails_opts.frontend? && rails_opts.test_framework?
|
@@ -165,8 +166,7 @@ module Nextgen
|
|
165
166
|
)
|
166
167
|
|
167
168
|
if frontend == :vite
|
168
|
-
rails_opts.
|
169
|
-
rails_opts.javascript = "vite"
|
169
|
+
rails_opts.vite!
|
170
170
|
else
|
171
171
|
rails_opts.asset_pipeline = frontend
|
172
172
|
end
|
@@ -196,6 +196,26 @@ module Nextgen
|
|
196
196
|
)
|
197
197
|
end
|
198
198
|
|
199
|
+
def ask_rails_tools
|
200
|
+
opt_out = {
|
201
|
+
"Brakeman" => "brakeman",
|
202
|
+
"GitHub Actions CI" => "ci",
|
203
|
+
"RuboCop" => "rubocop"
|
204
|
+
}
|
205
|
+
opt_in = {
|
206
|
+
"devcontainer files" => "devcontainer"
|
207
|
+
}
|
208
|
+
|
209
|
+
answers = prompt.multi_select(
|
210
|
+
"Rails can preinstall the following. Which do you need?",
|
211
|
+
opt_out.merge(opt_in),
|
212
|
+
default: opt_out.keys.reverse
|
213
|
+
)
|
214
|
+
|
215
|
+
rails_opts.devcontainer! if answers.delete("devcontainer")
|
216
|
+
(opt_out.values - answers).each { rails_opts.skip_optional_feature!(_1) }
|
217
|
+
end
|
218
|
+
|
199
219
|
def ask_rails_frameworks
|
200
220
|
frameworks = {
|
201
221
|
"JBuilder" => "jbuilder",
|
@@ -222,7 +242,7 @@ module Nextgen
|
|
222
242
|
default: frameworks.keys.reverse
|
223
243
|
)
|
224
244
|
|
225
|
-
(frameworks.values - answers).each { rails_opts.
|
245
|
+
(frameworks.values - answers).each { rails_opts.skip_optional_feature!(_1) }
|
226
246
|
end
|
227
247
|
|
228
248
|
def ask_test_framework
|
@@ -40,14 +40,15 @@ if File.exist?("test/application_system_test_case.rb")
|
|
40
40
|
gsub_file "Gemfile", /gem "selenium-webdriver"$/, '\0, require: false'
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
missing_ruby_decl = !File.read("Gemfile").match?(/^ruby /)
|
44
|
+
if missing_ruby_decl && File.exist?(".ruby-version") && File.read(".ruby-version").match?(/\A\d+\.\d+.\d+.\s*\z/m)
|
45
|
+
say_git "Add ruby declaration to Gemfile"
|
46
|
+
ruby_decl = if bundler_ruby_file_supported?
|
47
|
+
'ruby file: ".ruby-version"'
|
48
|
+
else
|
49
|
+
'ruby Pathname.new(__dir__).join(".ruby-version").read.strip'
|
50
|
+
end
|
51
|
+
gsub_file "Gemfile", /^source .*$/, '\0' + "\n#{ruby_decl}"
|
51
52
|
end
|
52
53
|
|
53
54
|
if File.exist?("app/views/layouts/application.html.erb")
|
@@ -70,7 +71,7 @@ gsub_file "config/environments/production.rb",
|
|
70
71
|
|
71
72
|
if File.exist?("config/database.yml")
|
72
73
|
say_git "Create initial schema.rb"
|
73
|
-
rails_command "db:
|
74
|
+
rails_command "db:create db:migrate"
|
74
75
|
end
|
75
76
|
|
76
77
|
if (time_zone = read_system_time_zone_name)
|
@@ -2,3 +2,25 @@
|
|
2
2
|
|
3
3
|
install_gem "bundler-audit", group: :development, require: false
|
4
4
|
binstub "bundler-audit"
|
5
|
+
|
6
|
+
if File.exist?(".github/workflows/ci.yml")
|
7
|
+
say_git "Add bundle-audit job to CI workflow"
|
8
|
+
inject_into_file ".github/workflows/ci.yml", <<-YAML, after: /^jobs:\n/
|
9
|
+
scan_gems:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
|
12
|
+
steps:
|
13
|
+
- name: Checkout code
|
14
|
+
uses: actions/checkout@v4
|
15
|
+
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: .ruby-version
|
20
|
+
bundler-cache: true
|
21
|
+
|
22
|
+
- name: Scan for security vulnerabilities in Ruby dependencies
|
23
|
+
run: bundle exec bundle-audit check --update -v
|
24
|
+
|
25
|
+
YAML
|
26
|
+
end
|
@@ -24,5 +24,31 @@ say_git "Add eslint to default rake task"
|
|
24
24
|
copy_file "lib/tasks/eslint.rake"
|
25
25
|
add_lint_task "eslint"
|
26
26
|
|
27
|
+
if File.exist?(".github/workflows/ci.yml")
|
28
|
+
say_git "Add eslint job to CI workflow"
|
29
|
+
node_spec = File.exist?(".node-version") ? 'node-version-file: ".node-version"' : 'node-version: "lts/*"'
|
30
|
+
inject_into_file ".github/workflows/ci.yml", <<-YAML, after: /^jobs:\n/
|
31
|
+
eslint:
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
|
34
|
+
steps:
|
35
|
+
- name: Checkout code
|
36
|
+
uses: actions/checkout@v4
|
37
|
+
|
38
|
+
- name: Set up Node
|
39
|
+
uses: actions/setup-node@v4
|
40
|
+
with:
|
41
|
+
#{node_spec}
|
42
|
+
cache: yarn
|
43
|
+
|
44
|
+
- name: Install Yarn packages
|
45
|
+
run: npx --yes ci
|
46
|
+
|
47
|
+
- name: Lint JavaScript files with eslint
|
48
|
+
run: yarn lint:js
|
49
|
+
|
50
|
+
YAML
|
51
|
+
end
|
52
|
+
|
27
53
|
say_git "Auto-correct any existing issues"
|
28
54
|
run "yarn fix:js", capture: true
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
return unless File.exist?(".github/workflows/ci.yml")
|
4
|
+
|
5
|
+
erb = <<~YAML
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
|
9
|
+
<%- if gems.include?("pg") -%>
|
10
|
+
services:
|
11
|
+
postgres:
|
12
|
+
image: postgres
|
13
|
+
env:
|
14
|
+
POSTGRES_USER: postgres
|
15
|
+
POSTGRES_PASSWORD: postgres
|
16
|
+
ports:
|
17
|
+
- 5432:5432
|
18
|
+
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
|
19
|
+
|
20
|
+
<%- end -%>
|
21
|
+
steps:
|
22
|
+
<%- if gems.include?("capybara") -%>
|
23
|
+
- name: Install packages
|
24
|
+
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable
|
25
|
+
|
26
|
+
<%- end -%>
|
27
|
+
- name: Checkout code
|
28
|
+
uses: actions/checkout@v4
|
29
|
+
|
30
|
+
- name: Set up Ruby
|
31
|
+
uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: .ruby-version
|
34
|
+
bundler-cache: true
|
35
|
+
|
36
|
+
- name: Run tests
|
37
|
+
env:
|
38
|
+
RAILS_ENV: test
|
39
|
+
<%- if gems.include?("pg") -%>
|
40
|
+
DATABASE_URL: postgres://postgres:postgres@localhost:5432
|
41
|
+
<%- end -%>
|
42
|
+
<%- if File.exist?("config/database.yml") -%>
|
43
|
+
run: bin/rails db:test:prepare && bin/rspec
|
44
|
+
<%- else -%>
|
45
|
+
run: bundle exec rspec
|
46
|
+
<%- end -%>
|
47
|
+
<%- if gems.include?("capybara") -%>
|
48
|
+
|
49
|
+
- name: Keep screenshots from failed system tests
|
50
|
+
uses: actions/upload-artifact@v4
|
51
|
+
if: failure()
|
52
|
+
with:
|
53
|
+
name: screenshots
|
54
|
+
path: ${{ github.workspace }}/tmp/screenshots
|
55
|
+
if-no-files-found: ignore
|
56
|
+
<%- end -%>
|
57
|
+
|
58
|
+
YAML
|
59
|
+
|
60
|
+
require "erb"
|
61
|
+
gems = File.exist?("Gemfile") ? File.read("Gemfile").scan(/^\s*gem ["'](.+?)["']/).flatten : []
|
62
|
+
job = ERB.new(erb, trim_mode: "-").result(binding)
|
63
|
+
inject_into_file ".github/workflows/ci.yml", job.gsub(/^/, " "), after: /^jobs:\n/
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
say_git "Install rubocop gems"
|
4
|
+
remove_gem "rubocop-rails-omakase"
|
4
5
|
gemfile = File.read("Gemfile")
|
5
6
|
plugins = []
|
6
7
|
plugins << "capybara" if gemfile.match?(/^\s*gem ['"]capybara['"]/)
|
@@ -12,8 +13,8 @@ install_gem("rubocop-rails", version: ">= 2.22.0", group: :development, require:
|
|
12
13
|
install_gems(*plugins.map { "rubocop-#{_1}" }, "rubocop", group: :development, require: false)
|
13
14
|
binstub "rubocop"
|
14
15
|
|
15
|
-
say_git "
|
16
|
-
template ".rubocop.yml", context: binding
|
16
|
+
say_git "Replace .rubocop.yml"
|
17
|
+
template ".rubocop.yml", context: binding, force: true
|
17
18
|
|
18
19
|
if File.exist?(".erb-lint.yml")
|
19
20
|
say_git "Regenerate .erb-lint.yml with rubocop support"
|
@@ -22,5 +22,31 @@ say_git "Add stylelint to default rake task"
|
|
22
22
|
copy_file "lib/tasks/stylelint.rake"
|
23
23
|
add_lint_task "stylelint"
|
24
24
|
|
25
|
+
if File.exist?(".github/workflows/ci.yml")
|
26
|
+
say_git "Add stylelint job to CI workflow"
|
27
|
+
node_spec = File.exist?(".node-version") ? 'node-version-file: ".node-version"' : 'node-version: "lts/*"'
|
28
|
+
inject_into_file ".github/workflows/ci.yml", <<-YAML, after: /^jobs:\n/
|
29
|
+
stylelint:
|
30
|
+
runs-on: ubuntu-latest
|
31
|
+
|
32
|
+
steps:
|
33
|
+
- name: Checkout code
|
34
|
+
uses: actions/checkout@v4
|
35
|
+
|
36
|
+
- name: Set up Node
|
37
|
+
uses: actions/setup-node@v4
|
38
|
+
with:
|
39
|
+
#{node_spec}
|
40
|
+
cache: yarn
|
41
|
+
|
42
|
+
- name: Install Yarn packages
|
43
|
+
run: npx --yes ci
|
44
|
+
|
45
|
+
- name: Lint CSS files with stylelint
|
46
|
+
run: yarn lint:css
|
47
|
+
|
48
|
+
YAML
|
49
|
+
end
|
50
|
+
|
25
51
|
say_git "Auto-correct any existing issues"
|
26
52
|
run "yarn fix:css", capture: true
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
say_git "Remove esbuild"
|
4
|
+
remove_yarn_package "esbuild"
|
5
|
+
remove_package_json_script(:build)
|
6
|
+
|
3
7
|
say_git "Install the vite_rails gem"
|
4
8
|
install_gem "vite_rails", version: "~> 3.0"
|
5
9
|
|
@@ -92,11 +96,10 @@ copy_file "app/frontend/images/example.svg"
|
|
92
96
|
# TODO: rspec support
|
93
97
|
copy_file "test/helpers/inline_svg_helper_test.rb" if File.exist?("test/vite_helper.rb")
|
94
98
|
|
95
|
-
say_git "Add a `
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
copy_file "bin/dev-yarn", "bin/dev", mode: :preserve, force: true
|
99
|
+
say_git "Add a `bin/dev` script that uses run-pty"
|
100
|
+
add_yarn_package "run-pty@^5", dev: true
|
101
|
+
copy_file "bin/dev-node", "bin/dev", mode: :preserve, force: true
|
102
|
+
copy_file "run-pty.json"
|
100
103
|
remove_file "Procfile.dev"
|
101
104
|
|
102
105
|
say_git "Add Safari cache workaround in development"
|
@@ -116,3 +119,19 @@ comment_lines "config/environments/development.rb", /^\s*config\.assets\./
|
|
116
119
|
comment_lines "config/environments/production.rb", /^\s*config\.assets\./
|
117
120
|
gsub_file "app/views/layouts/application.html.erb", /^.*<%= stylesheet_link_tag.*$/, ""
|
118
121
|
remove_gem "sprockets-rails"
|
122
|
+
|
123
|
+
if File.exist?(".github/workflows/ci.yml")
|
124
|
+
say_git "Add Node steps to CI workflow"
|
125
|
+
node_spec = File.exist?(".node-version") ? 'node-version-file: ".node-version"' : 'node-version: "lts/*"'
|
126
|
+
inject_into_file ".github/workflows/ci.yml", <<-YAML, before: /^\s+- name: Run tests/
|
127
|
+
|
128
|
+
- name: Set up Node
|
129
|
+
uses: actions/setup-node@v4
|
130
|
+
with:
|
131
|
+
#{node_spec}
|
132
|
+
cache: yarn
|
133
|
+
|
134
|
+
- name: Install Yarn packages
|
135
|
+
run: npx --yes ci
|
136
|
+
YAML
|
137
|
+
end
|
@@ -19,15 +19,18 @@ module Nextgen
|
|
19
19
|
|
20
20
|
ASSET_PIPELINES = %w[sprockets propshaft].freeze
|
21
21
|
|
22
|
-
|
22
|
+
OPTIONAL_FEATURES = %w[
|
23
23
|
action_mailer
|
24
24
|
action_mailbox
|
25
25
|
action_text
|
26
26
|
active_job
|
27
27
|
active_storage
|
28
28
|
action_cable
|
29
|
+
brakeman
|
30
|
+
ci
|
29
31
|
hotwire
|
30
32
|
jbuilder
|
33
|
+
rubocop
|
31
34
|
].freeze
|
32
35
|
|
33
36
|
attr_reader :asset_pipeline, :css, :javascript, :database, :test_framework
|
@@ -35,7 +38,9 @@ module Nextgen
|
|
35
38
|
def initialize
|
36
39
|
@api = false
|
37
40
|
@edge = false
|
38
|
-
@
|
41
|
+
@vite = false
|
42
|
+
@devcontainer = nil
|
43
|
+
@skip_features = []
|
39
44
|
@skip_system_test = false
|
40
45
|
@test_framework = "minitest"
|
41
46
|
end
|
@@ -55,16 +60,19 @@ module Nextgen
|
|
55
60
|
|
56
61
|
def javascript=(framework)
|
57
62
|
raise ArgumentError, "Can't specify javascript in API mode" if api? && framework
|
58
|
-
|
59
|
-
if skip_asset_pipeline? && framework != "vite"
|
60
|
-
raise ArgumentError, "Can't specify javascript when asset pipeline is disabled"
|
61
|
-
end
|
63
|
+
raise ArgumentError, "Can't specify javascript when asset pipeline is disabled" if skip_asset_pipeline?
|
62
64
|
|
63
65
|
@javascript = framework
|
64
66
|
end
|
65
67
|
|
68
|
+
def vite!
|
69
|
+
self.asset_pipeline = nil
|
70
|
+
@javascript = "esbuild"
|
71
|
+
@vite = true
|
72
|
+
end
|
73
|
+
|
66
74
|
def vite?
|
67
|
-
@
|
75
|
+
@vite
|
68
76
|
end
|
69
77
|
|
70
78
|
def skip_javascript?
|
@@ -99,6 +107,10 @@ module Nextgen
|
|
99
107
|
@edge
|
100
108
|
end
|
101
109
|
|
110
|
+
def devcontainer!
|
111
|
+
@devcontainer = true
|
112
|
+
end
|
113
|
+
|
102
114
|
def api!
|
103
115
|
raise ArgumentError, "Can't specify API mode if css is already specified" if css
|
104
116
|
raise ArgumentError, "Can't specify API mode if javascript is already specified" if javascript
|
@@ -115,13 +127,17 @@ module Nextgen
|
|
115
127
|
end
|
116
128
|
|
117
129
|
def requires_node?
|
118
|
-
%w[bootstrap bulma postcss sass].include?(css) || %w[webpack esbuild rollup
|
130
|
+
%w[bootstrap bulma postcss sass].include?(css) || %w[webpack esbuild rollup].include?(javascript)
|
119
131
|
end
|
120
132
|
|
121
133
|
def rspec?
|
122
134
|
@test_framework == "rspec"
|
123
135
|
end
|
124
136
|
|
137
|
+
def rubocop?
|
138
|
+
!skip_optional_feature?("rubocop")
|
139
|
+
end
|
140
|
+
|
125
141
|
def active_record?
|
126
142
|
!skip_active_record?
|
127
143
|
end
|
@@ -151,23 +167,23 @@ module Nextgen
|
|
151
167
|
end
|
152
168
|
|
153
169
|
def action_mailer?
|
154
|
-
!
|
170
|
+
!skip_optional_feature?("action_mailer")
|
155
171
|
end
|
156
172
|
|
157
173
|
def active_job?
|
158
|
-
!
|
174
|
+
!skip_optional_feature?("active_job")
|
159
175
|
end
|
160
176
|
|
161
|
-
def
|
162
|
-
raise ArgumentError, "Unknown
|
177
|
+
def skip_optional_feature!(feature)
|
178
|
+
raise ArgumentError, "Unknown feature: #{feature}" unless OPTIONAL_FEATURES.include?(feature)
|
163
179
|
|
164
|
-
|
180
|
+
skip_features << feature
|
165
181
|
end
|
166
182
|
|
167
|
-
def
|
168
|
-
raise ArgumentError, "Unknown
|
183
|
+
def skip_optional_feature?(feature)
|
184
|
+
raise ArgumentError, "Unknown feature: #{feature}" unless OPTIONAL_FEATURES.include?(feature)
|
169
185
|
|
170
|
-
|
186
|
+
skip_features.include?(feature)
|
171
187
|
end
|
172
188
|
|
173
189
|
def to_args # rubocop:disable Metrics/PerceivedComplexity
|
@@ -183,12 +199,13 @@ module Nextgen
|
|
183
199
|
args << "--database=#{database}" if database
|
184
200
|
args << "--css=#{css}" if css
|
185
201
|
args << "--javascript=#{javascript}" if javascript
|
186
|
-
args
|
202
|
+
args << "--devcontainer" if @devcontainer
|
203
|
+
args.push(*skip_features.map { "--skip-#{_1.tr("_", "-")}" })
|
187
204
|
end
|
188
205
|
end
|
189
206
|
|
190
207
|
private
|
191
208
|
|
192
|
-
attr_reader :
|
209
|
+
attr_reader :skip_features
|
193
210
|
end
|
194
211
|
end
|
data/lib/nextgen/tidy_gemfile.rb
CHANGED
@@ -21,7 +21,8 @@ module Nextgen
|
|
21
21
|
@gemfile = gemfile
|
22
22
|
.gsub(/^\s*#.*/, "") # remove comments
|
23
23
|
.gsub(/(\s*\n)+/, "\n") # remove blank lines
|
24
|
-
.
|
24
|
+
.sub(/^(ruby.*)/, "\n\\1") # ensure blank space before "ruby" line
|
25
|
+
.sub(/^(gem.*)/, "\n\\1") # ensure blank space before first "gem" line
|
25
26
|
.gsub(/^(group.*)/, "\n\\1") # ensure blank space before each "group" block
|
26
27
|
nil
|
27
28
|
end
|
data/lib/nextgen/version.rb
CHANGED
data/template/.rubocop.yml.tt
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nextgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Brictson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-08-
|
11
|
+
date: 2024-08-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.
|
19
|
+
version: 7.2.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.
|
26
|
+
version: 7.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,7 +107,6 @@ files:
|
|
107
107
|
- lib/nextgen/generators/annotate.rb
|
108
108
|
- lib/nextgen/generators/base.rb
|
109
109
|
- lib/nextgen/generators/basic_auth.rb
|
110
|
-
- lib/nextgen/generators/brakeman.rb
|
111
110
|
- lib/nextgen/generators/bundler_audit.rb
|
112
111
|
- lib/nextgen/generators/capybara_lockstep.rb
|
113
112
|
- lib/nextgen/generators/clean_gemfile.rb
|
@@ -116,7 +115,6 @@ files:
|
|
116
115
|
- lib/nextgen/generators/eslint.rb
|
117
116
|
- lib/nextgen/generators/factory_bot_rails.rb
|
118
117
|
- lib/nextgen/generators/git_safe.rb
|
119
|
-
- lib/nextgen/generators/github_actions.rb
|
120
118
|
- lib/nextgen/generators/github_pr_template.rb
|
121
119
|
- lib/nextgen/generators/good_migrations.rb
|
122
120
|
- lib/nextgen/generators/home_controller.rb
|
@@ -128,6 +126,7 @@ files:
|
|
128
126
|
- lib/nextgen/generators/pgcli_rails.rb
|
129
127
|
- lib/nextgen/generators/rack_canonical_host.rb
|
130
128
|
- lib/nextgen/generators/rack_mini_profiler.rb
|
129
|
+
- lib/nextgen/generators/rspec_github_actions.rb
|
131
130
|
- lib/nextgen/generators/rspec_rails.rb
|
132
131
|
- lib/nextgen/generators/rspec_system_testing.rb
|
133
132
|
- lib/nextgen/generators/rubocop.rb
|
@@ -148,8 +147,6 @@ files:
|
|
148
147
|
- template/.env.sample
|
149
148
|
- template/.erb-lint.yml.tt
|
150
149
|
- template/.github/PULL_REQUEST_TEMPLATE.md.tt
|
151
|
-
- template/.github/dependabot.yml
|
152
|
-
- template/.github/workflows/ci.yml.tt
|
153
150
|
- template/.overcommit.yml.tt
|
154
151
|
- template/.prettierrc.cjs
|
155
152
|
- template/.rubocop.yml.tt
|
@@ -168,7 +165,7 @@ files:
|
|
168
165
|
- template/app/helpers/inline_svg_helper.rb
|
169
166
|
- template/app/views/home/index.html.erb.tt
|
170
167
|
- template/bin/dev
|
171
|
-
- template/bin/dev-
|
168
|
+
- template/bin/dev-node
|
172
169
|
- template/bin/setup
|
173
170
|
- template/config/environments/staging.rb
|
174
171
|
- template/config/initializers/generators.rb
|
@@ -186,6 +183,7 @@ files:
|
|
186
183
|
- template/lib/vite_inline_svg_file_loader.rb
|
187
184
|
- template/package.json
|
188
185
|
- template/postcss.config.cjs
|
186
|
+
- template/run-pty.json
|
189
187
|
- template/spec/support/factory_bot.rb
|
190
188
|
- template/spec/support/mailer.rb
|
191
189
|
- template/spec/support/shoulda.rb
|
@@ -224,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
222
|
- !ruby/object:Gem::Version
|
225
223
|
version: '0'
|
226
224
|
requirements: []
|
227
|
-
rubygems_version: 3.5.
|
225
|
+
rubygems_version: 3.5.11
|
228
226
|
signing_key:
|
229
227
|
specification_version: 4
|
230
228
|
summary: Generate your next Rails app interactively!
|
@@ -1,142 +0,0 @@
|
|
1
|
-
name: CI
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
env:
|
8
|
-
RAILS_ENV: test
|
9
|
-
jobs:
|
10
|
-
<% if minitest? || rspec? -%>
|
11
|
-
test:
|
12
|
-
name: "<%= minitest? ? "Test" : "RSpec" %>"
|
13
|
-
runs-on: ubuntu-latest
|
14
|
-
<% if gems.include?("pg") -%>
|
15
|
-
env:
|
16
|
-
DATABASE_URL: postgres://postgres:postgres@localhost:5432/ci
|
17
|
-
services:
|
18
|
-
postgres:
|
19
|
-
image: postgres:16-alpine
|
20
|
-
env:
|
21
|
-
POSTGRES_DB: ci
|
22
|
-
POSTGRES_USER: postgres
|
23
|
-
POSTGRES_PASSWORD: postgres
|
24
|
-
ports:
|
25
|
-
- 5432:5432
|
26
|
-
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
27
|
-
<% end -%>
|
28
|
-
steps:
|
29
|
-
- uses: actions/checkout@v4
|
30
|
-
- uses: ruby/setup-ruby@v1
|
31
|
-
with:
|
32
|
-
bundler-cache: true
|
33
|
-
<% if File.exist?("package.json") -%>
|
34
|
-
- uses: actions/setup-node@v4
|
35
|
-
with:
|
36
|
-
<% if File.exist?(".node-version") -%>
|
37
|
-
node-version-file: ".node-version"
|
38
|
-
<% else -%>
|
39
|
-
node-version: "lts/*"
|
40
|
-
<% end -%>
|
41
|
-
cache: yarn
|
42
|
-
- run: npx --yes ci
|
43
|
-
<% end -%>
|
44
|
-
<% if gems.include?("capybara") -%>
|
45
|
-
- run: mkdir -p ./tmp/screenshots
|
46
|
-
<% end -%>
|
47
|
-
<% if File.exist?("config/database.yml") -%>
|
48
|
-
- run: bundle exec rake db:prepare
|
49
|
-
<% end -%>
|
50
|
-
<% if rspec? -%>
|
51
|
-
- run: bundle exec rspec
|
52
|
-
<% else -%>
|
53
|
-
- run: bundle exec rake test:all
|
54
|
-
<% end -%>
|
55
|
-
<% if gems.include?("capybara") -%>
|
56
|
-
- uses: actions/upload-artifact@v4
|
57
|
-
if: failure()
|
58
|
-
with:
|
59
|
-
name: capybara-screenshots
|
60
|
-
path: ./tmp/screenshots/
|
61
|
-
retention-days: 7
|
62
|
-
if-no-files-found: ignore
|
63
|
-
<% end -%>
|
64
|
-
<% end -%>
|
65
|
-
<% if gems.include?("erb_lint") -%>
|
66
|
-
erblint:
|
67
|
-
name: "Lint / erblint"
|
68
|
-
runs-on: ubuntu-latest
|
69
|
-
steps:
|
70
|
-
- uses: actions/checkout@v4
|
71
|
-
- uses: ruby/setup-ruby@v1
|
72
|
-
with:
|
73
|
-
bundler-cache: true
|
74
|
-
- run: bin/erblint --lint-all
|
75
|
-
<% end -%>
|
76
|
-
<% if Dir["eslint.config.*"].any? -%>
|
77
|
-
eslint:
|
78
|
-
name: "Lint / eslint"
|
79
|
-
runs-on: ubuntu-latest
|
80
|
-
steps:
|
81
|
-
- uses: actions/checkout@v4
|
82
|
-
- uses: actions/setup-node@v4
|
83
|
-
with:
|
84
|
-
<% if File.exist?(".node-version") -%>
|
85
|
-
node-version-file: ".node-version"
|
86
|
-
<% else -%>
|
87
|
-
node-version: "lts/*"
|
88
|
-
<% end -%>
|
89
|
-
cache: yarn
|
90
|
-
- run: npx --yes ci
|
91
|
-
- run: yarn lint:js
|
92
|
-
<% end -%>
|
93
|
-
<% if gems.include?("rubocop") -%>
|
94
|
-
rubocop:
|
95
|
-
name: "Lint / rubocop"
|
96
|
-
runs-on: ubuntu-latest
|
97
|
-
steps:
|
98
|
-
- uses: actions/checkout@v4
|
99
|
-
- uses: ruby/setup-ruby@v1
|
100
|
-
with:
|
101
|
-
bundler-cache: true
|
102
|
-
- run: bin/rubocop
|
103
|
-
<% end -%>
|
104
|
-
<% if Dir[".stylelintrc*"].any? -%>
|
105
|
-
stylelint:
|
106
|
-
name: "Lint / stylelint"
|
107
|
-
runs-on: ubuntu-latest
|
108
|
-
steps:
|
109
|
-
- uses: actions/checkout@v4
|
110
|
-
- uses: actions/setup-node@v4
|
111
|
-
with:
|
112
|
-
<% if File.exist?(".node-version") -%>
|
113
|
-
node-version-file: ".node-version"
|
114
|
-
<% else -%>
|
115
|
-
node-version: "lts/*"
|
116
|
-
<% end -%>
|
117
|
-
cache: yarn
|
118
|
-
- run: npx --yes ci
|
119
|
-
- run: yarn lint:css
|
120
|
-
<% end -%>
|
121
|
-
<% if gems.include?("brakeman") -%>
|
122
|
-
brakeman:
|
123
|
-
name: "Security / brakeman"
|
124
|
-
runs-on: ubuntu-latest
|
125
|
-
steps:
|
126
|
-
- uses: actions/checkout@v4
|
127
|
-
- uses: ruby/setup-ruby@v1
|
128
|
-
with:
|
129
|
-
bundler-cache: true
|
130
|
-
- run: bundle exec brakeman --exit-on-warn --no-progress --color --output /dev/stdout
|
131
|
-
<% end -%>
|
132
|
-
<% if gems.include?("bundler-audit") -%>
|
133
|
-
bundle-audit:
|
134
|
-
name: "Security / bundle-audit"
|
135
|
-
runs-on: ubuntu-latest
|
136
|
-
steps:
|
137
|
-
- uses: actions/checkout@v4
|
138
|
-
- uses: ruby/setup-ruby@v1
|
139
|
-
with:
|
140
|
-
bundler-cache: true
|
141
|
-
- run: bundle exec bundle-audit check --update -v
|
142
|
-
<% end -%>
|