Class: TsykvasRailsTemplate::Generators::InstallGenerator
- Inherits:
-
Rails::Generators::Base
- Object
- Rails::Generators::Base
- TsykvasRailsTemplate::Generators::InstallGenerator
show all
- Includes:
- BootstrapInstaller
- Defined in:
- lib/generators/tsykvas_rails_template/install/install_generator.rb
Constant Summary
collapse
- SHIPPED_DOCS =
%w[
architecture
authentication
background-jobs
code-style
commands
companions
concepts-refactoring
database
deployment
design-system
documentation
forms
i18n
routing-and-namespaces
security
stimulus-controllers
testing
testing-examples
tsykvas_rails_template
ui-components
].freeze
BootstrapInstaller::APPLICATION_JS_BOOTSTRAP_BLOCK, BootstrapInstaller::APPLICATION_JS_PATH, BootstrapInstaller::BOOTSTRAP_SCSS_ENTRY_BODY, BootstrapInstaller::BOOTSTRAP_SCSS_ENTRY_PATH, BootstrapInstaller::DARTSASS_INITIALIZER_BODY, BootstrapInstaller::DARTSASS_INITIALIZER_PATH, BootstrapInstaller::DARTSASS_MANAGED_HEADER, BootstrapInstaller::IMPORTMAP_PINS, BootstrapInstaller::PROCFILE_DEV_BODY, BootstrapInstaller::PROCFILE_DEV_PATH
Instance Method Summary
collapse
Instance Method Details
#add_concepts_to_autoload_paths ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 71
def add_concepts_to_autoload_paths
return if options[:skip_autoload_paths]
target = destination_path("config/application.rb")
return unless File.exist?(target)
marker = "app/concepts"
contents = File.read(target)
if contents.include?("#{marker}]") || contents.include?("#{marker}\"]")
say_status :exist, "config.autoload_paths already includes #{marker}", :blue
return
end
application "config.autoload_paths += %W[\#{config.root}/app/concepts]\n"
end
|
#add_root_route ⇒ Object
127
128
129
130
131
132
133
134
135
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 127
def add_root_route
return if options[:skip_home_example]
routes_path = destination_path("config/routes.rb")
return unless File.exist?(routes_path)
return if File.read(routes_path).match?(/^\s*root\s/)
route 'root "home#index"'
end
|
#announce_completion ⇒ Object
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 228
def announce_completion
say ""
say " tsykvas_rails_template installed.", :green
say " A working Home example landed at /app/concepts/home/ with"
say " `root \"home#index\"` already in routes — start `bin/rails server`"
say " and visit http://localhost:3000 to see it (unless you passed"
say " --skip-home-example)."
say ""
say " Next steps:"
say " 1. rails g tsykvas_rails_template:companions"
say " (adds devise / simple_form / rspec stack / mini_magick / etc."
say " and runs their :install sub-generators)"
say " 2. rails g tsykvas_rails_template:concept <Name> [--controller]"
say " scaffolds your domain concepts."
say " 3. Open Claude Code and run /tsykvas-claude to refresh"
say " probe-driven sections in CLAUDE.md + .claude/docs/"
say " (concept folders, gem versions, branch names) when"
say " your stack changes."
say ""
end
|
#clean_propshaft_cache ⇒ Object
Propshaft serves from ‘public/assets/` whenever a `.manifest.json` is there, completely bypassing live `app/assets/builds/` and `app/javascript/`. A stale dir from a prior `rails assets:precompile` silently freezes the dev environment. Clean it here — but only if `.gitignore` lists it (so we know it’s a transient cache, not checked-in content). ‘rails new` adds `/public/assets` by default.
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 155
def clean_propshaft_cache
require "fileutils"
cache_dir = destination_path("public/assets")
return unless File.directory?(cache_dir)
gitignore = destination_path(".gitignore")
listed = File.exist?(gitignore) && File.read(gitignore).match?(%r{^/?public/assets\b})
unless listed
say_status :skip,
"public/assets/ exists but is not in .gitignore — leaving alone " \
"(it might be checked-in content rather than a Propshaft cache).",
:yellow
return
end
FileUtils.rm_rf(cache_dir)
say_status :clean,
"Removed stale public/assets/ (Propshaft would otherwise shadow live " \
"app/assets/builds/ and app/javascript/ in dev).",
:green
end
|
#copy_claude_payload ⇒ Object
201
202
203
204
205
206
207
208
209
210
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 201
def copy_claude_payload
return if options[:skip_claude]
directory ".claude/agents", ".claude/agents"
directory ".claude/commands", ".claude/commands"
empty_directory ".claude/docs" unless File.directory?(destination_path(".claude/docs"))
SHIPPED_DOCS.each do |name|
copy_file ".claude/docs/#{name}.md", ".claude/docs/#{name}.md"
end
end
|
#copy_concepts_base ⇒ Object
62
63
64
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 62
def copy_concepts_base
directory "app/concepts/base", "app/concepts/base"
end
|
#copy_operations_methods_concern ⇒ Object
66
67
68
69
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 66
def copy_operations_methods_concern
copy_file "app/controllers/concerns/operations_methods.rb",
"app/controllers/concerns/operations_methods.rb"
end
|
#create_application_policy ⇒ Object
103
104
105
106
107
108
109
110
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 103
def create_application_policy
return if options[:skip_application_policy]
return if File.exist?(destination_path("app/policies/application_policy.rb"))
empty_directory "app/policies" unless File.directory?(destination_path("app/policies"))
copy_file "app/policies/application_policy.rb",
"app/policies/application_policy.rb"
end
|
#generate_home_example ⇒ Object
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 112
def generate_home_example
return if options[:skip_home_example]
return if File.exist?(destination_path("app/controllers/home_controller.rb"))
return if File.directory?(destination_path("app/concepts/home"))
copy_file "app/controllers/home_controller.rb",
"app/controllers/home_controller.rb"
directory "app/concepts/home", "app/concepts/home"
empty_directory "app/policies" unless File.directory?(destination_path("app/policies"))
return if File.exist?(destination_path("app/policies/home_policy.rb"))
copy_file "app/policies/home_policy.rb", "app/policies/home_policy.rb"
end
|
#install_bootstrap ⇒ Object
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 137
def install_bootstrap
return if options[:skip_bootstrap]
install_bootstrap_steps
say_status :bootstrap,
"Bootstrap 5.3 + dartsass-rails wired. Run `bin/dev` for the live SCSS watcher, " \
"or `bin/rails dartsass:build` once before `bin/rails server`. " \
"Pass --skip-bootstrap to opt out.",
:green
end
|
#swap_database_to_postgresql ⇒ Object
55
56
57
58
59
60
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 55
def swap_database_to_postgresql
return if options[:keep_sqlite]
swap_gemfile_to_pg
swap_database_yml_to_pg
end
|
#wire_application_controller ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 87
def wire_application_controller
target_rel = "app/controllers/application_controller.rb"
target_abs = destination_path(target_rel)
return unless File.exist?(target_abs)
contents = File.read(target_abs)
unless contents.include?("Pundit::Authorization") || contents.include?("include Pundit\n")
inject_into_class target_rel, "ApplicationController", " include Pundit::Authorization\n"
end
return if contents.include?("OperationsMethods")
inject_into_class target_rel, "ApplicationController", " include OperationsMethods\n"
end
|
#write_claude_md ⇒ Object
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/generators/tsykvas_rails_template/install/install_generator.rb', line 212
def write_claude_md
return if options[:skip_claude]
if File.exist?(destination_path("CLAUDE.md"))
say_status :skip,
"CLAUDE.md already exists; not overwriting. " \
"Run `/tsykvas-claude` in Claude Code to integrate the gem's " \
"must-know-rules and routing table inside fence markers without " \
"touching your existing content.",
:yellow
return
end
template "CLAUDE.md.tt", "CLAUDE.md"
end
|