better_app_gen 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +134 -0
- data/CHANGELOG.md +29 -0
- data/CLAUDE.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +174 -0
- data/RELEASE.md +25 -0
- data/Rakefile +10 -0
- data/exe/better_app_gen +6 -0
- data/lib/better_app_gen/app_generator.rb +75 -0
- data/lib/better_app_gen/cli.rb +136 -0
- data/lib/better_app_gen/configuration.rb +90 -0
- data/lib/better_app_gen/dependency_checker.rb +129 -0
- data/lib/better_app_gen/errors.rb +56 -0
- data/lib/better_app_gen/generators/base.rb +219 -0
- data/lib/better_app_gen/generators/database.rb +64 -0
- data/lib/better_app_gen/generators/docker.rb +73 -0
- data/lib/better_app_gen/generators/gemfile.rb +26 -0
- data/lib/better_app_gen/generators/home_controller.rb +34 -0
- data/lib/better_app_gen/generators/locale.rb +24 -0
- data/lib/better_app_gen/generators/rails_app.rb +60 -0
- data/lib/better_app_gen/generators/simple_form.rb +33 -0
- data/lib/better_app_gen/generators/solid_stack.rb +18 -0
- data/lib/better_app_gen/generators/vite.rb +122 -0
- data/lib/better_app_gen/templates/app/controllers/home_controller.rb.erb +4 -0
- data/lib/better_app_gen/templates/app/helpers/home_helper.rb.erb +2 -0
- data/lib/better_app_gen/templates/app/views/home/index.html.erb.erb +2 -0
- data/lib/better_app_gen/templates/app/views/layouts/application.html.erb.erb +33 -0
- data/lib/better_app_gen/templates/bin/dev.erb +11 -0
- data/lib/better_app_gen/templates/bin/docker-entrypoint.erb +7 -0
- data/lib/better_app_gen/templates/bin/docker-entrypoint.prod.erb +12 -0
- data/lib/better_app_gen/templates/config/application.rb.erb +80 -0
- data/lib/better_app_gen/templates/config/database.yml.erb +65 -0
- data/lib/better_app_gen/templates/config/initializers/active_record_schema_settings.rb.erb +3 -0
- data/lib/better_app_gen/templates/config/initializers/better_vite_helper.rb.erb +5 -0
- data/lib/better_app_gen/templates/config/initializers/simple_form.rb.erb +21 -0
- data/lib/better_app_gen/templates/config/locales/it.yml.erb +68 -0
- data/lib/better_app_gen/templates/config/locales/simple_form.it.yml.erb +49 -0
- data/lib/better_app_gen/templates/config/routes.rb.erb +15 -0
- data/lib/better_app_gen/templates/db/cable_migrate/create_solid_cable_schema.rb.erb +15 -0
- data/lib/better_app_gen/templates/db/cache_migrate/create_solid_cache_schema.rb.erb +16 -0
- data/lib/better_app_gen/templates/db/migrate/create_shared_schema.rb.erb +31 -0
- data/lib/better_app_gen/templates/db/migrate/enable_uuid_extension.rb.erb +7 -0
- data/lib/better_app_gen/templates/db/queue_migrate/create_solid_queue_schema.rb.erb +133 -0
- data/lib/better_app_gen/templates/docker/DEPLOY.md.erb +129 -0
- data/lib/better_app_gen/templates/docker/Dockerfile.dev.erb +58 -0
- data/lib/better_app_gen/templates/docker/Dockerfile.prod.erb +172 -0
- data/lib/better_app_gen/templates/docker/compose.runner.yml.erb +6 -0
- data/lib/better_app_gen/templates/docker/compose.yml.erb +86 -0
- data/lib/better_app_gen/templates/docker/env.docker.erb +28 -0
- data/lib/better_app_gen/templates/lib/tasks/db.rake.erb +28 -0
- data/lib/better_app_gen/templates/public/robots.txt.erb +1 -0
- data/lib/better_app_gen/templates/root/Procfile.dev.erb +2 -0
- data/lib/better_app_gen/templates/root/env.example.erb +27 -0
- data/lib/better_app_gen/templates/root/gitignore.erb +404 -0
- data/lib/better_app_gen/templates/root/yarnrc.yml.erb +6 -0
- data/lib/better_app_gen/templates/script/dc-attach.erb +13 -0
- data/lib/better_app_gen/templates/script/dc-build.erb +8 -0
- data/lib/better_app_gen/templates/script/dc-down.erb +8 -0
- data/lib/better_app_gen/templates/script/dc-logs-tail.erb +16 -0
- data/lib/better_app_gen/templates/script/dc-logs.erb +17 -0
- data/lib/better_app_gen/templates/script/dc-rails.erb +8 -0
- data/lib/better_app_gen/templates/script/dc-restart.erb +11 -0
- data/lib/better_app_gen/templates/script/dc-shell.erb +12 -0
- data/lib/better_app_gen/templates/script/dc-up.erb +11 -0
- data/lib/better_app_gen/templates/vite/application.css.erb +12 -0
- data/lib/better_app_gen/templates/vite/application.js.erb +6 -0
- data/lib/better_app_gen/templates/vite/controllers/application.js.erb +9 -0
- data/lib/better_app_gen/templates/vite/controllers/hello_controller.js.erb +7 -0
- data/lib/better_app_gen/templates/vite/controllers/index.js.erb +8 -0
- data/lib/better_app_gen/templates/vite/postcss.config.js.erb +5 -0
- data/lib/better_app_gen/templates/vite/vite.config.js.erb +48 -0
- data/lib/better_app_gen/version.rb +5 -0
- data/lib/better_app_gen.rb +23 -0
- metadata +182 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Sets up Docker development environment
|
|
6
|
+
class Docker < Base
|
|
7
|
+
def generate!
|
|
8
|
+
create_directory(".docker")
|
|
9
|
+
create_directory("script")
|
|
10
|
+
|
|
11
|
+
create_dockerfile
|
|
12
|
+
create_dockerfile_prod
|
|
13
|
+
create_compose_files
|
|
14
|
+
create_docker_env
|
|
15
|
+
create_docker_entrypoint
|
|
16
|
+
create_docker_entrypoint_prod
|
|
17
|
+
create_management_scripts
|
|
18
|
+
create_robots_txt
|
|
19
|
+
create_deploy_docs
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def create_dockerfile
|
|
25
|
+
create_file_from_template(".docker/Dockerfile.dev", "docker/Dockerfile.dev.erb")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def create_dockerfile_prod
|
|
29
|
+
create_file_from_template(".docker/Dockerfile.prod", "docker/Dockerfile.prod.erb")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def create_compose_files
|
|
33
|
+
create_file_from_template("compose.yml", "docker/compose.yml.erb")
|
|
34
|
+
create_file_from_template("compose.runner.yml", "docker/compose.runner.yml.erb")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def create_docker_env
|
|
38
|
+
create_file_from_template(".env.docker", "docker/env.docker.erb")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create_docker_entrypoint
|
|
42
|
+
create_file_from_template("bin/docker-entrypoint", "bin/docker-entrypoint.erb")
|
|
43
|
+
chmod_executable("bin/docker-entrypoint")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_docker_entrypoint_prod
|
|
47
|
+
create_file_from_template("bin/docker-entrypoint.prod", "bin/docker-entrypoint.prod.erb")
|
|
48
|
+
chmod_executable("bin/docker-entrypoint.prod")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def create_deploy_docs
|
|
52
|
+
create_file_from_template(".docker/DEPLOY.md", "docker/DEPLOY.md.erb")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def create_management_scripts
|
|
56
|
+
scripts = %w[dc-up dc-down dc-shell dc-rails dc-logs dc-logs-tail dc-attach dc-build dc-restart]
|
|
57
|
+
|
|
58
|
+
scripts.each do |script|
|
|
59
|
+
template_name = "script/#{script}.erb"
|
|
60
|
+
template_path = BetterAppGen.templates_path.join(template_name)
|
|
61
|
+
next unless template_path.exist?
|
|
62
|
+
|
|
63
|
+
create_file_from_template("script/#{script}", template_name)
|
|
64
|
+
chmod_executable("script/#{script}")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def create_robots_txt
|
|
69
|
+
create_file_from_template("public/robots.txt", "public/robots.txt.erb")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Configures the Gemfile with required gems
|
|
6
|
+
class Gemfile < Base
|
|
7
|
+
SOLID_GEMS = [
|
|
8
|
+
'gem "solid_cache"',
|
|
9
|
+
'gem "solid_queue"',
|
|
10
|
+
'gem "solid_cable"'
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
BASE_GEMS = [
|
|
14
|
+
'gem "rails-i18n"',
|
|
15
|
+
'gem "better_vite_helper"'
|
|
16
|
+
].freeze
|
|
17
|
+
|
|
18
|
+
def generate!
|
|
19
|
+
gems_to_add = SOLID_GEMS + BASE_GEMS
|
|
20
|
+
gems_to_add << 'gem "simple_form"' if with_simple_form
|
|
21
|
+
|
|
22
|
+
merge_gemfile(gems_to_add)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Creates HomeController with index action and root route
|
|
6
|
+
class HomeController < Base
|
|
7
|
+
def generate!
|
|
8
|
+
create_directory("app/views/home")
|
|
9
|
+
create_controller
|
|
10
|
+
create_helper
|
|
11
|
+
create_view
|
|
12
|
+
create_routes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def create_controller
|
|
18
|
+
create_file_from_template("app/controllers/home_controller.rb", "app/controllers/home_controller.rb.erb")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_helper
|
|
22
|
+
create_file_from_template("app/helpers/home_helper.rb", "app/helpers/home_helper.rb.erb")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create_view
|
|
26
|
+
create_file_from_template("app/views/home/index.html.erb", "app/views/home/index.html.erb.erb")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_routes
|
|
30
|
+
create_file_from_template("config/routes.rb", "config/routes.rb.erb")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Configures i18n with the selected locale
|
|
6
|
+
class Locale < Base
|
|
7
|
+
def generate!
|
|
8
|
+
create_locale_file if locale != "en"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def create_locale_file
|
|
14
|
+
template_name = "config/locales/#{locale}.yml.erb"
|
|
15
|
+
|
|
16
|
+
# Only create if template exists for this locale
|
|
17
|
+
template_path = BetterAppGen.templates_path.join(template_name)
|
|
18
|
+
return unless template_path.exist?
|
|
19
|
+
|
|
20
|
+
create_file_from_template("config/locales/#{locale}.yml", template_name)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Creates the base Rails application with optimized skip flags
|
|
6
|
+
class RailsApp < Base
|
|
7
|
+
SKIP_FLAGS = %w[
|
|
8
|
+
--skip-git
|
|
9
|
+
--skip-docker
|
|
10
|
+
--skip-action-mailbox
|
|
11
|
+
--skip-action-text
|
|
12
|
+
--skip-active-storage
|
|
13
|
+
--skip-test
|
|
14
|
+
--skip-ci
|
|
15
|
+
--skip-kamal
|
|
16
|
+
--skip-devcontainer
|
|
17
|
+
--skip-jbuilder
|
|
18
|
+
--skip-javascript
|
|
19
|
+
--skip-asset-pipeline
|
|
20
|
+
--database=postgresql
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
def generate!
|
|
24
|
+
create_rails_app
|
|
25
|
+
cleanup_schema_files
|
|
26
|
+
setup_migration_directories
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def create_rails_app
|
|
32
|
+
command = "rails new #{app_name} #{SKIP_FLAGS.join(" ")}"
|
|
33
|
+
Dir.chdir(File.dirname(app_path)) do
|
|
34
|
+
# Run rails command outside of bundler environment
|
|
35
|
+
Bundler.with_unbundled_env do
|
|
36
|
+
success = system(command)
|
|
37
|
+
raise RailsGenerationError unless success
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def cleanup_schema_files
|
|
43
|
+
# Remove schema.rb files (we use structure.sql instead)
|
|
44
|
+
schema_files = Dir.glob(File.join(app_path, "db", "*schema.rb"))
|
|
45
|
+
schema_files << File.join(app_path, "db", "schema.rb")
|
|
46
|
+
|
|
47
|
+
schema_files.each do |file|
|
|
48
|
+
FileUtils.rm_f(file)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def setup_migration_directories
|
|
53
|
+
create_directory("db/migrate")
|
|
54
|
+
create_directory("db/cache_migrate")
|
|
55
|
+
create_directory("db/queue_migrate")
|
|
56
|
+
create_directory("db/cable_migrate")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Configures SimpleForm with Tailwind CSS styling
|
|
6
|
+
class SimpleForm < Base
|
|
7
|
+
def generate!
|
|
8
|
+
create_initializer
|
|
9
|
+
create_locale_file if locale != "en"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def create_initializer
|
|
15
|
+
create_file_from_template(
|
|
16
|
+
"config/initializers/simple_form.rb",
|
|
17
|
+
"config/initializers/simple_form.rb.erb"
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_locale_file
|
|
22
|
+
template_name = "config/locales/simple_form.#{locale}.yml.erb"
|
|
23
|
+
template_path = BetterAppGen.templates_path.join(template_name)
|
|
24
|
+
return unless template_path.exist?
|
|
25
|
+
|
|
26
|
+
create_file_from_template(
|
|
27
|
+
"config/locales/simple_form.#{locale}.yml",
|
|
28
|
+
template_name
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Configures Solid Stack (Cache, Queue, Cable) in application.rb
|
|
6
|
+
class SolidStack < Base
|
|
7
|
+
def generate!
|
|
8
|
+
create_application_rb
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def create_application_rb
|
|
14
|
+
create_file_from_template("config/application.rb", "config/application.rb.erb")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BetterAppGen
|
|
4
|
+
module Generators
|
|
5
|
+
# Sets up Vite 7 + Tailwind CSS 4 + Stimulus
|
|
6
|
+
class Vite < Base
|
|
7
|
+
DEPENDENCIES = {
|
|
8
|
+
"@hotwired/stimulus" => "^3.2.2",
|
|
9
|
+
"@hotwired/turbo-rails" => "^8.0.12"
|
|
10
|
+
}.freeze
|
|
11
|
+
|
|
12
|
+
DEV_DEPENDENCIES = {
|
|
13
|
+
"@tailwindcss/postcss" => "^4.0.0",
|
|
14
|
+
"autoprefixer" => "^10.4.20",
|
|
15
|
+
"postcss" => "^8.5.1",
|
|
16
|
+
"tailwindcss" => "^4.0.0",
|
|
17
|
+
"vite" => "^6.0.7"
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
20
|
+
SCRIPTS = {
|
|
21
|
+
"dev" => "vite --host 0.0.0.0 --port 5173",
|
|
22
|
+
"build" => "vite build"
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
def generate!
|
|
26
|
+
setup_directories
|
|
27
|
+
setup_package_json
|
|
28
|
+
create_vite_config
|
|
29
|
+
create_postcss_config
|
|
30
|
+
create_stylesheets
|
|
31
|
+
create_javascript
|
|
32
|
+
create_initializer
|
|
33
|
+
create_procfile
|
|
34
|
+
create_bin_dev
|
|
35
|
+
create_yarnrc
|
|
36
|
+
create_gitignore
|
|
37
|
+
create_env_files
|
|
38
|
+
create_layout
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def setup_directories
|
|
44
|
+
create_directory("app/assets/images")
|
|
45
|
+
create_directory("app/javascript/controllers")
|
|
46
|
+
create_directory("app/assets/stylesheets")
|
|
47
|
+
|
|
48
|
+
# Remove default application.css if exists
|
|
49
|
+
css_file = File.join(app_path, "app/assets/stylesheets/application.css")
|
|
50
|
+
FileUtils.rm_f(css_file)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def setup_package_json
|
|
54
|
+
scripts = SCRIPTS.dup
|
|
55
|
+
scripts["dev"] = "vite --host 0.0.0.0 --port #{vite_port}"
|
|
56
|
+
|
|
57
|
+
merge_package_json(
|
|
58
|
+
dependencies: DEPENDENCIES,
|
|
59
|
+
dev_dependencies: DEV_DEPENDENCIES,
|
|
60
|
+
scripts: scripts,
|
|
61
|
+
extra: {
|
|
62
|
+
"type" => "module",
|
|
63
|
+
"packageManager" => "yarn@4.5.3"
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def create_vite_config
|
|
69
|
+
create_file_from_template("vite.config.js", "vite/vite.config.js.erb")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def create_postcss_config
|
|
73
|
+
create_file_from_template("postcss.config.js", "vite/postcss.config.js.erb")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def create_stylesheets
|
|
77
|
+
create_file_from_template("app/assets/stylesheets/application.css", "vite/application.css.erb")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def create_javascript
|
|
81
|
+
create_file_from_template("app/javascript/application.js", "vite/application.js.erb")
|
|
82
|
+
create_file_from_template("app/javascript/controllers/application.js",
|
|
83
|
+
"vite/controllers/application.js.erb")
|
|
84
|
+
create_file_from_template("app/javascript/controllers/hello_controller.js",
|
|
85
|
+
"vite/controllers/hello_controller.js.erb")
|
|
86
|
+
create_file_from_template("app/javascript/controllers/index.js", "vite/controllers/index.js.erb")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def create_initializer
|
|
90
|
+
create_file_from_template("config/initializers/better_vite_helper.rb",
|
|
91
|
+
"config/initializers/better_vite_helper.rb.erb")
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def create_procfile
|
|
95
|
+
create_file_from_template("Procfile.dev", "root/Procfile.dev.erb")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def create_bin_dev
|
|
99
|
+
create_file_from_template("bin/dev", "bin/dev.erb")
|
|
100
|
+
chmod_executable("bin/dev")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def create_yarnrc
|
|
104
|
+
create_file_from_template(".yarnrc.yml", "root/yarnrc.yml.erb")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def create_gitignore
|
|
108
|
+
create_file_from_template(".gitignore", "root/gitignore.erb")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def create_env_files
|
|
112
|
+
create_file_from_template(".env.example", "root/env.example.erb")
|
|
113
|
+
create_file_from_template(".env", "root/env.example.erb")
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def create_layout
|
|
117
|
+
create_file_from_template("app/views/layouts/application.html.erb",
|
|
118
|
+
"app/views/layouts/application.html.erb.erb")
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<title><%%= content_for(:title) || "<%= app_name_pascal %>" %></title>
|
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
7
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
8
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
9
|
+
<%%= csrf_meta_tags %>
|
|
10
|
+
<%%= csp_meta_tag %>
|
|
11
|
+
|
|
12
|
+
<%%= yield :head %>
|
|
13
|
+
|
|
14
|
+
<%# Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!) %>
|
|
15
|
+
<%#= tag.link rel: "manifest", href: pwa_manifest_path(format: :json) %>
|
|
16
|
+
|
|
17
|
+
<link rel="icon" href="/icon.png" type="image/png">
|
|
18
|
+
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
|
19
|
+
<link rel="apple-touch-icon" href="/icon.png">
|
|
20
|
+
|
|
21
|
+
<%# Includes all stylesheet files in app/assets/stylesheets %>
|
|
22
|
+
<%# stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
|
23
|
+
<%# javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %>
|
|
24
|
+
|
|
25
|
+
<%%= vite_stylesheet_link_tag "application.css" %>
|
|
26
|
+
<%%= vite_javascript_include_tag "application.js" %>
|
|
27
|
+
</head>
|
|
28
|
+
|
|
29
|
+
<body>
|
|
30
|
+
<%%= yield %>
|
|
31
|
+
</body>
|
|
32
|
+
|
|
33
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
if gem list --no-installed --exact --silent foreman; then
|
|
4
|
+
echo "Installing foreman..."
|
|
5
|
+
gem install foreman
|
|
6
|
+
fi
|
|
7
|
+
|
|
8
|
+
# Default to port <%= rails_port %> if not specified
|
|
9
|
+
export PORT="${PORT:-<%= rails_port %>}"
|
|
10
|
+
|
|
11
|
+
exec foreman start -f Procfile.dev --env /dev/null "$@"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/bin/bash -e
|
|
2
|
+
|
|
3
|
+
# Remove stale PID
|
|
4
|
+
if [ -f /app/tmp/pids/server.pid ]; then
|
|
5
|
+
rm -f /app/tmp/pids/server.pid
|
|
6
|
+
fi
|
|
7
|
+
|
|
8
|
+
# Always run migrations in single-container setup
|
|
9
|
+
echo "Running database migrations..."
|
|
10
|
+
bundle exec rails db:prepare
|
|
11
|
+
|
|
12
|
+
exec "${@}"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require_relative "boot"
|
|
2
|
+
|
|
3
|
+
require "rails"
|
|
4
|
+
# Pick the frameworks you want:
|
|
5
|
+
require "active_model/railtie"
|
|
6
|
+
require "active_job/railtie"
|
|
7
|
+
require "active_record/railtie"
|
|
8
|
+
# require "active_storage/engine"
|
|
9
|
+
require "action_controller/railtie"
|
|
10
|
+
require "action_mailer/railtie"
|
|
11
|
+
# require "action_mailbox/engine"
|
|
12
|
+
# require "action_text/engine"
|
|
13
|
+
require "action_view/railtie"
|
|
14
|
+
require "action_cable/engine"
|
|
15
|
+
# require "rails/test_unit/railtie"
|
|
16
|
+
|
|
17
|
+
# Require the gems listed in Gemfile, including any gems
|
|
18
|
+
# you've limited to :test, :development, or :production.
|
|
19
|
+
Bundler.require(*Rails.groups)
|
|
20
|
+
|
|
21
|
+
module <%= app_name_pascal %>
|
|
22
|
+
class Application < Rails::Application
|
|
23
|
+
# Initialize configuration defaults for originally generated Rails version.
|
|
24
|
+
config.load_defaults 8.0
|
|
25
|
+
|
|
26
|
+
# Logging settings
|
|
27
|
+
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
|
|
28
|
+
|
|
29
|
+
# Autoload libs
|
|
30
|
+
config.autoload_lib(ignore: %w[assets tasks generators])
|
|
31
|
+
|
|
32
|
+
# Rails web console settings
|
|
33
|
+
config.web_console.permissions = "0.0.0.0/0"
|
|
34
|
+
|
|
35
|
+
# I18n default settings
|
|
36
|
+
config.i18n.load_path += Rails.root.glob("config/locales/**/*.{rb,yml}/*.{rb,yml}/**/*.{rb,yml}/*.{rb,yml}")
|
|
37
|
+
config.i18n.available_locales = [ :<%= locale %> ]
|
|
38
|
+
config.i18n.default_locale = :<%= locale %>
|
|
39
|
+
config.time_zone = "<%= timezone %>"
|
|
40
|
+
|
|
41
|
+
# Action Dispatch config
|
|
42
|
+
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
|
|
43
|
+
|
|
44
|
+
# Use structure.sql instead of schema.rb
|
|
45
|
+
config.active_record.schema_format = :sql
|
|
46
|
+
|
|
47
|
+
# SMTP Settings
|
|
48
|
+
config.action_mailer.delivery_method = :smtp
|
|
49
|
+
|
|
50
|
+
unless Rails.env.test?
|
|
51
|
+
config.action_mailer.smtp_settings = {
|
|
52
|
+
address: ENV.fetch("SMTP_ADDRESS", nil),
|
|
53
|
+
port: ENV.fetch("SMTP_PORT", nil).to_i,
|
|
54
|
+
domain: ENV.fetch("SMTP_DOMAIN", nil),
|
|
55
|
+
user_name: ENV.fetch("SMTP_USERNAME", nil),
|
|
56
|
+
password: ENV.fetch("SMTP_PASSWORD", nil),
|
|
57
|
+
authentication: ENV.fetch("SMTP_AUTHENTICATION", "plain"),
|
|
58
|
+
enable_starttls_auto: ActiveModel::Type::Boolean.new.cast(ENV.fetch("SMTP_ENABLE_STARTTLS_AUTO", true)),
|
|
59
|
+
open_timeout: ENV.fetch("SMTP_OPEN_TIMEOUT", 5).to_i,
|
|
60
|
+
read_timeout: ENV.fetch("SMTP_READ_TIMEOUT", 5).to_i
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Clear hosts
|
|
65
|
+
config.hosts.clear
|
|
66
|
+
|
|
67
|
+
# Don't generate system test files.
|
|
68
|
+
config.generators do |g|
|
|
69
|
+
g.orm :active_record, primary_key_type: :uuid
|
|
70
|
+
g.system_tests nil
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Cache with SolidCache
|
|
74
|
+
config.cache_store = :solid_cache_store
|
|
75
|
+
|
|
76
|
+
# ActiveJob with SolidCache
|
|
77
|
+
config.active_job.queue_adapter = :solid_queue
|
|
78
|
+
config.solid_queue.connects_to = { database: { writing: :queue } }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
default: &default
|
|
2
|
+
adapter: postgresql
|
|
3
|
+
encoding: unicode
|
|
4
|
+
schema_search_path: "public,shared"
|
|
5
|
+
pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
|
6
|
+
|
|
7
|
+
development:
|
|
8
|
+
primary: &primary_development
|
|
9
|
+
<<: *default
|
|
10
|
+
url: <%%= ENV['DATABASE_URL'] %>
|
|
11
|
+
database: <%= app_name_snake %>_development
|
|
12
|
+
cache:
|
|
13
|
+
<<: *primary_development
|
|
14
|
+
url: <%%= ENV['CACHE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
15
|
+
database: <%= app_name_snake %>_development_cache
|
|
16
|
+
migrations_paths: db/cache_migrate
|
|
17
|
+
queue:
|
|
18
|
+
<<: *primary_development
|
|
19
|
+
url: <%%= ENV['QUEUE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
20
|
+
database: <%= app_name_snake %>_development_queue
|
|
21
|
+
migrations_paths: db/queue_migrate
|
|
22
|
+
cable:
|
|
23
|
+
<<: *primary_development
|
|
24
|
+
url: <%%= ENV['CABLE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
25
|
+
database: <%= app_name_snake %>_development_cable
|
|
26
|
+
migrations_paths: db/cable_migrate
|
|
27
|
+
|
|
28
|
+
test:
|
|
29
|
+
primary: &primary_test
|
|
30
|
+
<<: *default
|
|
31
|
+
url: <%%= ENV['DATABASE_URL'] %>
|
|
32
|
+
database: <%= app_name_snake %>_test
|
|
33
|
+
cache:
|
|
34
|
+
<<: *primary_test
|
|
35
|
+
url: <%%= ENV['CACHE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
36
|
+
database: <%= app_name_snake %>_test_cache
|
|
37
|
+
migrations_paths: db/cache_migrate
|
|
38
|
+
queue:
|
|
39
|
+
<<: *primary_test
|
|
40
|
+
url: <%%= ENV['QUEUE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
41
|
+
database: <%= app_name_snake %>_test_queue
|
|
42
|
+
migrations_paths: db/queue_migrate
|
|
43
|
+
cable:
|
|
44
|
+
<<: *primary_test
|
|
45
|
+
url: <%%= ENV['CABLE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
46
|
+
database: <%= app_name_snake %>_test_cable
|
|
47
|
+
migrations_paths: db/cable_migrate
|
|
48
|
+
|
|
49
|
+
production:
|
|
50
|
+
primary: &primary_production
|
|
51
|
+
<<: *default
|
|
52
|
+
url: <%%= ENV['DATABASE_URL'] %>
|
|
53
|
+
database: <%= app_name_snake %>_production
|
|
54
|
+
cache:
|
|
55
|
+
<<: *primary_production
|
|
56
|
+
url: <%%= ENV['CACHE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
57
|
+
migrations_paths: db/cache_migrate
|
|
58
|
+
queue:
|
|
59
|
+
<<: *primary_production
|
|
60
|
+
url: <%%= ENV['QUEUE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
61
|
+
migrations_paths: db/queue_migrate
|
|
62
|
+
cable:
|
|
63
|
+
<<: *primary_production
|
|
64
|
+
url: <%%= ENV['CABLE_DATABASE_URL'] || ENV['DATABASE_URL'] %>
|
|
65
|
+
migrations_paths: db/cable_migrate
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
SimpleForm.setup do |config|
|
|
2
|
+
# Wrappers configuration with Tailwind classes
|
|
3
|
+
config.wrappers :default, class: "mb-4" do |b|
|
|
4
|
+
b.use :html5
|
|
5
|
+
b.use :placeholder
|
|
6
|
+
b.use :label, class: "block text-sm font-medium text-gray-700 mb-1"
|
|
7
|
+
b.use :input, class: "mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm", error_class: "border-red-300 focus:border-red-500 focus:ring-red-500"
|
|
8
|
+
b.use :error, wrap_with: { tag: :span, class: "text-red-600 text-sm mt-1" }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Default configuration
|
|
12
|
+
config.generate_additional_classes_for = []
|
|
13
|
+
config.default_wrapper = :default
|
|
14
|
+
config.button_class = "bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
|
15
|
+
config.label_text = lambda { |label, _, _| label }
|
|
16
|
+
config.error_notification_tag = :div
|
|
17
|
+
config.error_notification_class = "bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"
|
|
18
|
+
config.browser_validations = false
|
|
19
|
+
config.boolean_style = :nested
|
|
20
|
+
config.boolean_label_class = "inline-flex items-center"
|
|
21
|
+
end
|