Switch Dreams - Rails Template
Template for switch dreams`s rails apps
Used 40 times
P
Pedro Augusto
Usage
This template install:
# Development (test and linters)
- Rspec
- Factory_bot
- Simplecov
- Switchcop (rubocop for switch)
# FullStack (Choose between react and hotwired)
- ViteRuby
- Tailwind
## Hotwired
- Stimulus
- ViewComponent
## React
- Inertia
- React
# API Only
- RestApiGenerate
# Optionals
- AVO
for new apps:
- Factory_bot
- Simplecov
- Switchcop (rubocop for switch)
# FullStack (Choose between react and hotwired)
- ViteRuby
- Tailwind
## Hotwired
- Stimulus
- ViewComponent
## React
- Inertia
- React
# API Only
- RestApiGenerate
# Optionals
- AVO
for new apps:
rails new APP_PATH
--skip-javascript -T --asset-pipeline=propshaft -m https://railsbytes.com/script/VD7sey
# TODO:
- Eslint
Run this command in your Rails app directory in the terminal:
rails app:template LOCATION="https://www.railsbytes.com/script/VD7sey"
Template Source
Review the code before running this template on your machine.
# Add default quality gems
# Questions
is_full_stack = yes?("Is full stack rails? (y/n)")
if is_full_stack
is_react = yes?("Want to use react in frontend? (y/n)")
else
is_react = false
end
needs_admin = yes?("Needs avo admin? (y/n)")
github_files = yes?("Generate github actions file (y/n)")
# Maybe we can use another template? rails app:template LOCATION='https://railsbytes.com/script/z0gsLX'
gem_group :development, :test do
gem "rspec-rails"
gem "factory_bot_rails"
gem "switchcop"
gem "simplecov"
end
# Copy switchcop files
file '.rubocop.yaml', <<-CODE
inherit_gem:
switchcop: rubocop.yml
CODE
# Rspec setup
run "bundle install"
rails_command "generate rspec:install"
# FactoryBot
## Create support file
file 'spec/support/factory_bot.rb', <<-CODE
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
CODE
# Inject factory bot file inside
inject_into_file "spec/rails_helper.rb", after: "require 'rspec/rails'" do
<<~EOF
require 'support/factory_bot'
EOF
end
# Simplecov
inject_into_file "spec/rails_helper.rb", after: "require 'spec_helper'" do
<<~EOF
require "simplecov"
SimpleCov.start "rails" do
add_filter "/bin/"
add_filter "/db/"
add_filter "/spec/" # for rspec
end
EOF
end
# ./bin/dev
file 'bin/dev', <<-CODE
#!/usr/bin/env bash
if ! command -v foreman &> /dev/null
then
echo "Installing foreman..."
gem install foreman
fi
foreman start -f Procfile.dev "$@"
CODE
unless is_full_stack
gem "rest-api-generator"
end
if is_full_stack
# Default gems for full stack vite and tailwind
gem "vite_rails"
run "bundle install"
run "bundle exec vite install"
# Install yarn and tailwind
run "yarn add -D vite-plugin-rails tailwindcss postcss autoprefixer"
# Config for vite
file "vite.config.ts", <<-CODE
import { defineConfig } from 'vite'
import ViteRails from 'vite-plugin-rails'
export default defineConfig({
plugins: [
ViteRails(),
],
})
CODE
# Config for tailwind
#########################################
run "npx tailwindcss init -p"
file "tailwind.config.js", <<-CODE
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"app/**/*.html.erb",
],
theme: {
extend: {},
},
plugins: [],
}
CODE
file "app/frontend/entrypoints/application.css", <<-CODE
@tailwind base;
@tailwind components;
@tailwind utilities;
CODE
#########################################
# END Config for tailwind
inject_into_file "app/frontend/entrypoints/application.js" do
<<~EOF
import "./application.css"
EOF
end
end
if is_react
# Install Inertia
gem "inertia_rails"
run "yarn add react react-dom inertiajs @inertiajs/react @vitejs/plugin-react"
# Inertia entrypoint file
file "app/frontend/entrypoints/inertia.jsx", <<-CODE
import React from "react";
import { createRoot } from "react-dom/client";
import { createInertiaApp } from "@inertiajs/react";
createInertiaApp({
resolve: async (name) => {
const pages = import.meta.glob("../pages/**/*.tsx", { eager: true });
let page = pages[`../pages/${name}.tsx`];
return page;
},
setup({ el, App, props }) {
const container = document.getElementById(el.id);
const root = createRoot(container);
root.render(<App {...props} />);
},
});
CODE
inject_into_file "app/frontend/entrypoints/application.js" do
<<~EOF
import "./inertia";
EOF
end
else
# Install Turbo
gem "view_component"
gem "turbo-rails"
gem "stimulus-rails"
# Config for hotwired
run "yarn add @hotwired/turbo-rails @hotwired/stimulus"
# Stimulus configuration file
file "app/frontend/controllers/index.js", <<-CODE
import { Application } from "@hotwired/stimulus";
const application = Application.start();
const controllers = import.meta.globEager("./**/*_controller.js");
for (let path in controllers) {
let module = controllers[path];
let name = path.match(/\.\/(.+)_controller\.js$/)[1].replaceAll("/", "--");
application.register(name, module.default);
}
CODE
inject_into_file "app/frontend/entrypoints/application.js" do
<<~EOF
import "@hotwired/turbo-rails"
import "../controllers"
EOF
end
end
# Github templates
if github_files
file '.github/PULL_REQUEST_TEMPLATE.md', <<-CODE
### Descrição
<!-- Descreva brevemente o que foi feito na issue -->
### Observações
<!-- Nesse tópico coloque algum detalhe que faltou ou um possível ponto de melhoria futuro -->
### Prints
<!-- Em caso de uma issue que envolva alguma tela ou componente, coloque aqui o print -->
### Checklist
- [ ] Fiz o link com a task do clickup.
- [ ] Fiz minha própria revisão do código.
- [ ] Realizei os testes que compravam que a funcionalidade está funcionando corretamente.
CODE
file '.github/workflows/frontend-ci.yml', <<-CODE
name: Frontend CI
on:
pull_request:
branches:
- '**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@master
with:
cache: 'yarn'
registry-url: 'https://npm.pkg.github.com'
scope: '@switchdreams'
- name: Install modules
run: yarn
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGE_TOKEN }}
- name: Run ESLint
run: yarn lint
end
CODE
file '.github/workflows/backend-ci.yml', <<-CODE
name: Backend CI
env:
DB_USER: user
DB_PASSWORD: password
POSTGRES_DB: password
RUBY_VERSION: 3.3.0
on:
pull_request:
branches:
- '**'
jobs:
rubocop:
name: Rubocop
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
- name: Install Rubocop
run: |
gem install switchcop
gem install action_policy
- name: Check code
run: rubocop
rspec:
name: RSpec
runs-on: ubuntu-latest
services:
postgres:
image: postgres:latest
ports:
- 5432:5432
env:
POSTGRES_USER: ${{ env.DB_USER }}
POSTGRES_PASSWORD: ${{ env.DB_PASSWORD }}
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-cache: true
- uses: actions/setup-node@master
with:
registry-url: 'https://npm.pkg.github.com'
scope: '@switchdreams'
cache: yarn
- name: Install postgres client
run: sudo apt-get install libpq-dev
- name: Yarn Install
run: yarn install --frozen-lockfile
env:
NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGE_TOKEN }}
- name: Install Bundler
run: gem install bundler
- name: Bundle Install
run: bundle install
- name: Create database
run: |
bundle exec rails db:create RAILS_ENV=test
bundle exec rails db:migrate RAILS_ENV=test
- name: Assets precompile
run: bundle exec rails assets:precompile RAILS_ENV=test
- name: Run tests
run: bundle exec rspec spec
CODE
end
gem "avo" if needs_admin