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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +134 -0
  4. data/CHANGELOG.md +29 -0
  5. data/CLAUDE.md +84 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +174 -0
  8. data/RELEASE.md +25 -0
  9. data/Rakefile +10 -0
  10. data/exe/better_app_gen +6 -0
  11. data/lib/better_app_gen/app_generator.rb +75 -0
  12. data/lib/better_app_gen/cli.rb +136 -0
  13. data/lib/better_app_gen/configuration.rb +90 -0
  14. data/lib/better_app_gen/dependency_checker.rb +129 -0
  15. data/lib/better_app_gen/errors.rb +56 -0
  16. data/lib/better_app_gen/generators/base.rb +219 -0
  17. data/lib/better_app_gen/generators/database.rb +64 -0
  18. data/lib/better_app_gen/generators/docker.rb +73 -0
  19. data/lib/better_app_gen/generators/gemfile.rb +26 -0
  20. data/lib/better_app_gen/generators/home_controller.rb +34 -0
  21. data/lib/better_app_gen/generators/locale.rb +24 -0
  22. data/lib/better_app_gen/generators/rails_app.rb +60 -0
  23. data/lib/better_app_gen/generators/simple_form.rb +33 -0
  24. data/lib/better_app_gen/generators/solid_stack.rb +18 -0
  25. data/lib/better_app_gen/generators/vite.rb +122 -0
  26. data/lib/better_app_gen/templates/app/controllers/home_controller.rb.erb +4 -0
  27. data/lib/better_app_gen/templates/app/helpers/home_helper.rb.erb +2 -0
  28. data/lib/better_app_gen/templates/app/views/home/index.html.erb.erb +2 -0
  29. data/lib/better_app_gen/templates/app/views/layouts/application.html.erb.erb +33 -0
  30. data/lib/better_app_gen/templates/bin/dev.erb +11 -0
  31. data/lib/better_app_gen/templates/bin/docker-entrypoint.erb +7 -0
  32. data/lib/better_app_gen/templates/bin/docker-entrypoint.prod.erb +12 -0
  33. data/lib/better_app_gen/templates/config/application.rb.erb +80 -0
  34. data/lib/better_app_gen/templates/config/database.yml.erb +65 -0
  35. data/lib/better_app_gen/templates/config/initializers/active_record_schema_settings.rb.erb +3 -0
  36. data/lib/better_app_gen/templates/config/initializers/better_vite_helper.rb.erb +5 -0
  37. data/lib/better_app_gen/templates/config/initializers/simple_form.rb.erb +21 -0
  38. data/lib/better_app_gen/templates/config/locales/it.yml.erb +68 -0
  39. data/lib/better_app_gen/templates/config/locales/simple_form.it.yml.erb +49 -0
  40. data/lib/better_app_gen/templates/config/routes.rb.erb +15 -0
  41. data/lib/better_app_gen/templates/db/cable_migrate/create_solid_cable_schema.rb.erb +15 -0
  42. data/lib/better_app_gen/templates/db/cache_migrate/create_solid_cache_schema.rb.erb +16 -0
  43. data/lib/better_app_gen/templates/db/migrate/create_shared_schema.rb.erb +31 -0
  44. data/lib/better_app_gen/templates/db/migrate/enable_uuid_extension.rb.erb +7 -0
  45. data/lib/better_app_gen/templates/db/queue_migrate/create_solid_queue_schema.rb.erb +133 -0
  46. data/lib/better_app_gen/templates/docker/DEPLOY.md.erb +129 -0
  47. data/lib/better_app_gen/templates/docker/Dockerfile.dev.erb +58 -0
  48. data/lib/better_app_gen/templates/docker/Dockerfile.prod.erb +172 -0
  49. data/lib/better_app_gen/templates/docker/compose.runner.yml.erb +6 -0
  50. data/lib/better_app_gen/templates/docker/compose.yml.erb +86 -0
  51. data/lib/better_app_gen/templates/docker/env.docker.erb +28 -0
  52. data/lib/better_app_gen/templates/lib/tasks/db.rake.erb +28 -0
  53. data/lib/better_app_gen/templates/public/robots.txt.erb +1 -0
  54. data/lib/better_app_gen/templates/root/Procfile.dev.erb +2 -0
  55. data/lib/better_app_gen/templates/root/env.example.erb +27 -0
  56. data/lib/better_app_gen/templates/root/gitignore.erb +404 -0
  57. data/lib/better_app_gen/templates/root/yarnrc.yml.erb +6 -0
  58. data/lib/better_app_gen/templates/script/dc-attach.erb +13 -0
  59. data/lib/better_app_gen/templates/script/dc-build.erb +8 -0
  60. data/lib/better_app_gen/templates/script/dc-down.erb +8 -0
  61. data/lib/better_app_gen/templates/script/dc-logs-tail.erb +16 -0
  62. data/lib/better_app_gen/templates/script/dc-logs.erb +17 -0
  63. data/lib/better_app_gen/templates/script/dc-rails.erb +8 -0
  64. data/lib/better_app_gen/templates/script/dc-restart.erb +11 -0
  65. data/lib/better_app_gen/templates/script/dc-shell.erb +12 -0
  66. data/lib/better_app_gen/templates/script/dc-up.erb +11 -0
  67. data/lib/better_app_gen/templates/vite/application.css.erb +12 -0
  68. data/lib/better_app_gen/templates/vite/application.js.erb +6 -0
  69. data/lib/better_app_gen/templates/vite/controllers/application.js.erb +9 -0
  70. data/lib/better_app_gen/templates/vite/controllers/hello_controller.js.erb +7 -0
  71. data/lib/better_app_gen/templates/vite/controllers/index.js.erb +8 -0
  72. data/lib/better_app_gen/templates/vite/postcss.config.js.erb +5 -0
  73. data/lib/better_app_gen/templates/vite/vite.config.js.erb +48 -0
  74. data/lib/better_app_gen/version.rb +5 -0
  75. data/lib/better_app_gen.rb +23 -0
  76. metadata +182 -0
@@ -0,0 +1,172 @@
1
+ # syntax=docker/dockerfile:1
2
+ # Production multi-stage Dockerfile for Rails 8.1 with Vite assets
3
+ # Optimized for Alpine Linux with Jemalloc and YJIT
4
+
5
+ ARG RUBY_VERSION=3.4.7
6
+ ARG NODE_VERSION=24.1.0
7
+ ARG BUNDLER_VERSION=2.7.2
8
+
9
+ # ==============================================================================
10
+ # Stage 1: Base - Common Ruby runtime with system dependencies
11
+ # ==============================================================================
12
+ FROM ruby:${RUBY_VERSION}-alpine AS base
13
+
14
+ # Install runtime dependencies
15
+ RUN apk add --no-cache \
16
+ bash \
17
+ curl \
18
+ gcompat \
19
+ imagemagick \
20
+ imagemagick-libs \
21
+ jemalloc \
22
+ jpeg-dev \
23
+ libheif \
24
+ libpng-dev \
25
+ libpq \
26
+ libwebp \
27
+ libwebp-tools \
28
+ postgresql17-client \
29
+ tzdata \
30
+ && rm -rf /var/cache/apk/*
31
+
32
+ # Configure Jemalloc and YJIT
33
+ ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
34
+ ENV RUBY_YJIT_ENABLE=1
35
+ ENV MALLOC_CONF=dirty_decay_ms:1000,narenas:2,background_thread:true
36
+
37
+ # Rails production defaults with vendor/bundle path
38
+ ENV RAILS_ENV=production \
39
+ BUNDLE_DEPLOYMENT=1 \
40
+ BUNDLE_PATH=vendor/bundle \
41
+ BUNDLE_WITHOUT=development:test
42
+
43
+ WORKDIR /app
44
+
45
+ # Create non-root user for security
46
+ RUN addgroup -g 1000 rails && \
47
+ adduser -u 1000 -G rails -h /app -D rails
48
+
49
+ # ==============================================================================
50
+ # Stage 2: Gem Builder - Install Ruby dependencies first
51
+ # ==============================================================================
52
+ FROM base AS gem-builder
53
+
54
+ # Install build dependencies for native gems
55
+ RUN apk add --no-cache \
56
+ build-base \
57
+ git \
58
+ imagemagick-dev \
59
+ libheif-dev \
60
+ libwebp-dev \
61
+ libxml2-dev \
62
+ libxslt-dev \
63
+ postgresql17-dev \
64
+ yaml-dev
65
+
66
+ WORKDIR /app
67
+
68
+ # Copy Gemfile for dependency caching
69
+ COPY Gemfile Gemfile.lock ./
70
+
71
+ # Install bundler and gems into vendor/bundle
72
+ ARG BUNDLER_VERSION
73
+ RUN gem install bundler -v ${BUNDLER_VERSION} --no-document && \
74
+ bundle config set --local frozen true && \
75
+ bundle config set --local path vendor/bundle && \
76
+ bundle config set --local jobs $(nproc) && \
77
+ bundle install && \
78
+ rm -rf vendor/bundle/ruby/*/cache/*.gem && \
79
+ find vendor/bundle/ruby/*/gems/ -name "*.c" -delete && \
80
+ find vendor/bundle/ruby/*/gems/ -name "*.o" -delete
81
+
82
+ # ==============================================================================
83
+ # Stage 3: Node Builder - Build Vite assets (needs gems + full code for Tailwind)
84
+ # ==============================================================================
85
+ FROM base AS node-builder
86
+
87
+ # Install Node.js from Alpine repos + build dependencies
88
+ RUN apk add --no-cache \
89
+ build-base \
90
+ git \
91
+ nodejs \
92
+ npm \
93
+ python3
94
+
95
+ # Install and enable Corepack for Yarn
96
+ RUN npm install -g corepack && \
97
+ corepack enable && \
98
+ corepack prepare yarn@stable --activate
99
+
100
+ WORKDIR /app
101
+
102
+ # Copy gems from gem-builder (Tailwind scans gem views for classes)
103
+ COPY --from=gem-builder /app/vendor/bundle /app/vendor/bundle
104
+
105
+ # Copy package files first for better caching
106
+ COPY package.json yarn.lock .yarnrc.yml ./
107
+
108
+ # Install Node dependencies
109
+ RUN yarn install --immutable
110
+
111
+ # Copy ALL application code (Tailwind v4 needs to scan for classes)
112
+ COPY . .
113
+
114
+ # Build production assets
115
+ # Tailwind v4 will scan app/views, app/helpers, app/controllers, etc.
116
+ RUN yarn build
117
+
118
+ # ==============================================================================
119
+ # Stage 4: Production - Final optimized image
120
+ # ==============================================================================
121
+ FROM base AS production
122
+
123
+ WORKDIR /app
124
+
125
+ # Enable Solid Queue to run inside Puma (single-container deployment)
126
+ ENV SOLID_QUEUE_IN_PUMA=true
127
+
128
+ # Copy installed gems from gem-builder
129
+ COPY --from=gem-builder /app/vendor/bundle /app/vendor/bundle
130
+
131
+ # Copy only what Rails needs to run (selective COPY, no rm -rf needed)
132
+ # App directories (excluding app/assets - source files not needed)
133
+ COPY --chown=rails:rails app/controllers app/controllers
134
+ COPY --chown=rails:rails app/helpers app/helpers
135
+ COPY --chown=rails:rails app/jobs app/jobs
136
+ COPY --chown=rails:rails app/mailers app/mailers
137
+ COPY --chown=rails:rails app/models app/models
138
+ COPY --chown=rails:rails app/views app/views
139
+
140
+ # Core Rails directories
141
+ COPY --chown=rails:rails bin bin
142
+ COPY --chown=rails:rails config config
143
+ COPY --chown=rails:rails db db
144
+ COPY --chown=rails:rails lib lib
145
+ COPY --chown=rails:rails public public
146
+
147
+ # Copy built assets from node-builder (AFTER public to override)
148
+ COPY --from=node-builder /app/public/assets /app/public/assets
149
+
150
+ # Root files needed by Rails
151
+ COPY --chown=rails:rails Gemfile Gemfile.lock Rakefile config.ru ./
152
+
153
+ # Precompile bootsnap for faster boot
154
+ RUN bundle exec bootsnap precompile app/ lib/
155
+
156
+ # Create required directories with proper ownership
157
+ RUN mkdir -p tmp/pids tmp/cache tmp/sockets log storage && \
158
+ chown -R rails:rails tmp log storage db
159
+
160
+ # Copy production entrypoint (with db:prepare support)
161
+ COPY --chown=rails:rails bin/docker-entrypoint.prod /app/bin/docker-entrypoint.prod
162
+ RUN chmod +x /app/bin/docker-entrypoint.prod
163
+
164
+ # Switch to non-root user
165
+ USER rails
166
+
167
+ # Expose Rails server port
168
+ EXPOSE 3000
169
+
170
+ # Set entrypoint and default command
171
+ ENTRYPOINT ["bin/docker-entrypoint.prod"]
172
+ CMD ["bundle", "exec", "thrust", "puma", "-C", "config/puma.rb"]
@@ -0,0 +1,6 @@
1
+ services:
2
+ puma:
3
+ tty: true
4
+ stdin_open: true
5
+ command: bash
6
+ ports: []
@@ -0,0 +1,86 @@
1
+ services:
2
+ puma: &puma
3
+ build:
4
+ context: .
5
+ dockerfile: .docker/Dockerfile.dev
6
+ container_name: <%= app_name_dash %>_puma
7
+ env_file:
8
+ - .env.docker
9
+ environment:
10
+ AWS_ACCESS_KEY_ID:
11
+ AWS_SECRET_ACCESS_KEY:
12
+ AWS_SESSION_TOKEN:
13
+ ports:
14
+ - "<%= rails_port %>:3000"
15
+ - "<%= vite_port %>:5173"
16
+ stdin_open: true
17
+ tty: true
18
+ networks:
19
+ default:
20
+ aliases:
21
+ - puma
22
+ pandev-multi-app_postgres-network:
23
+ aliases:
24
+ - <%= app_name_dash %>_puma
25
+ pandev-multi-app_dapr-network:
26
+ aliases:
27
+ - <%= app_name_dash %>_puma
28
+ volumes:
29
+ - <%= app_name_snake %>_bash_history:/root/hist
30
+ - <%= app_name_snake %>_bundle:/bundle
31
+ - <%= app_name_snake %>_node_modules:/app/node_modules
32
+ - /app/tmp
33
+ - ./:/app/
34
+ - ./.psqlrc:/root/.psqlrc:ro
35
+
36
+ vite:
37
+ <<: *puma
38
+ container_name: <%= app_name_dash %>_vite
39
+ command: yarn dev
40
+ ports: []
41
+ networks: []
42
+ network_mode: "service:puma"
43
+
44
+ # Dapr sidecar for the Rails application
45
+ puma-dapr:
46
+ image: daprio/daprd:1.15.0
47
+ container_name: <%= app_name_dash %>_dapr
48
+ command: [
49
+ "./daprd",
50
+ "--app-id", "<%= app_name_dash %>",
51
+ "--app-port", "3000",
52
+ "--app-protocol", "http",
53
+ "--placement-host-address", "dapr-placement:50006",
54
+ "--scheduler-host-address", "dapr-scheduler:50007",
55
+ "--dapr-http-port", "3500",
56
+ "--dapr-grpc-port", "50001",
57
+ "--resources-path", "/dapr/components",
58
+ "--config", "/dapr/config/config.yaml",
59
+ "--log-level", "info",
60
+ "--enable-api-logging"
61
+ ]
62
+ volumes:
63
+ - ../../dapr/components:/dapr/components:ro
64
+ - ../../dapr/config:/dapr/config:ro
65
+ depends_on:
66
+ - puma
67
+ network_mode: "service:puma"
68
+ environment:
69
+ - DAPR_HTTP_PORT=3500
70
+ - DAPR_GRPC_PORT=50001
71
+
72
+ networks:
73
+ default:
74
+ driver: bridge
75
+ name: <%= app_name_dash %>_network
76
+ pandev-multi-app_postgres-network:
77
+ external: true
78
+ pandev-multi-app_dapr-network:
79
+ external: true
80
+
81
+ volumes:
82
+ <%= app_name_snake %>_bash_history:
83
+ <%= app_name_snake %>_bundle:
84
+ <%= app_name_snake %>_node_modules:
85
+ smtp4dev_data:
86
+ postgres_bash_history:
@@ -0,0 +1,28 @@
1
+ # Core config
2
+ HISTFILE=/root/hist/.bash_history
3
+
4
+ # Database Configuration
5
+ DATABASE_URL=postgresql://postgres:postgres@postgres-17:5432/
6
+ CACHE_DATABASE_URL=postgresql://postgres:postgres@postgres-17:5432/
7
+ QUEUE_DATABASE_URL=postgresql://postgres:postgres@postgres-17:5432/
8
+ CABLE_DATABASE_URL=postgresql://postgres:postgres@postgres-17:5432/
9
+ VITE_DEV_SERVER_URL=http://localhost:<%= vite_port %>
10
+
11
+ # Rails Configuration
12
+ PORT=<%= rails_port %>
13
+ RAILS_LOG_LEVEL=info
14
+ RAILS_SERVE_STATIC_FILES=false
15
+
16
+ # SMTP Configuration
17
+ SMTP_ADDRESS=smtp.gmail.com
18
+ SMTP_PORT=587
19
+ SMTP_DOMAIN=yourdomain.com
20
+ SMTP_USERNAME=your-email@gmail.com
21
+ SMTP_PASSWORD=your-app-password
22
+ SMTP_AUTHENTICATION=plain
23
+ SMTP_ENABLE_STARTTLS_AUTO=true
24
+ SMTP_OPEN_TIMEOUT=5
25
+ SMTP_READ_TIMEOUT=5
26
+
27
+ # Application Configuration
28
+ SECRET_KEY_BASE=<%= SecureRandom.hex(64) %>
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :db do
4
+ at_exit do
5
+ # Dynamically read database configuration for current environment
6
+ db_config = Rails.application.config.database_configuration[Rails.env]
7
+
8
+ # Generate structure file names based on configured databases
9
+ structure_files = db_config.keys.map do |db_name|
10
+ case db_name
11
+ when "primary"
12
+ "structure.sql"
13
+ else
14
+ "#{db_name}_structure.sql"
15
+ end
16
+ end
17
+
18
+ # Process all database structure files
19
+ structure_files.each do |filename|
20
+ schema_filename = Rails.root.join("db", filename)
21
+
22
+ next unless File.exist?(schema_filename)
23
+
24
+ schema = File.readlines(schema_filename, chomp: true).grep_v(/--/)
25
+ File.open(schema_filename, "w") { |file| file.puts schema }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1 @@
1
+ # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
@@ -0,0 +1,2 @@
1
+ web: env RUBY_DEBUG_OPEN=true bin/rails server -p <%= rails_port %>
2
+ vite: yarn dev
@@ -0,0 +1,27 @@
1
+ # Database Configuration
2
+ DATABASE_URL=postgresql://postgres:postgres@localhost:5432/
3
+ CACHE_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/
4
+ QUEUE_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/
5
+ CABLE_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/
6
+
7
+ # Vite Configuration
8
+ VITE_DEV_SERVER_URL=http://localhost:<%= vite_port %>
9
+
10
+ # Rails Configuration
11
+ PORT=<%= rails_port %>
12
+ RAILS_LOG_LEVEL=info
13
+ RAILS_SERVE_STATIC_FILES=false
14
+
15
+ # SMTP Configuration
16
+ SMTP_ADDRESS=smtp.gmail.com
17
+ SMTP_PORT=587
18
+ SMTP_DOMAIN=yourdomain.com
19
+ SMTP_USERNAME=your-email@gmail.com
20
+ SMTP_PASSWORD=your-app-password
21
+ SMTP_AUTHENTICATION=plain
22
+ SMTP_ENABLE_STARTTLS_AUTO=true
23
+ SMTP_OPEN_TIMEOUT=5
24
+ SMTP_READ_TIMEOUT=5
25
+
26
+ # Application Configuration
27
+ SECRET_KEY_BASE=your-secret-key-base-here