Generate a new project to build an application template with Ruby Bytes
Used 56 times
V
Vladimir Dementyev
Usage
Run this command in your Rails app directory in the terminal:
rails app:template LOCATION="https://railsbytes.com/script/V2GsbB"
Template Source
Review the code before running this template on your machine.
# frozen_string_literal: true
name = nil
loop do
name = ask("What is the name of your template?") || ""
if name.empty?
say "Hm, empty name doesn't work. Let's try again"
else
break
end
end
root_dir = ask("Where do you want to store the code? (Default: #{File.join(Dir.pwd, name)})")
if root_dir.nil? || root_dir.empty?
root_dir = File.join(Dir.pwd, name)
end
human_name = name.split(/[-_]/).map(&:capitalize).join(" ")
needs_rails = yes? "Is this a Rails application template?"
inside(root_dir) do
file "template/_example.rb", <<~CODE
say "Hey from the included template!"
CODE
file "template/#{name}.rb", <<~CODE
say "Hey! Let's start withe the #{human_name} installation"
<%= include "example" %>
CODE
file "Gemfile", <<~CODE
# frozen_string_literal: true
source "https://rubygems.org"
gem "debug"
gem "rbytes"
gem "rake"
gem "minitest"
gem "minitest-focus"
gem "minitest-reporters"
CODE
file "Rakefile", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/*_test.rb"]
t.warning = false
end
namespace :test do
task :isolated do
Dir.glob("test/**/*_test.rb").all? do |file|
sh(Gem.ruby, "-I#{__dir__}/lib:#{__dir__}/test", file)
end || raise("Failures")
end
end
desc "Generate installation template"
task :compile do
require "ruby_bytes/cli"
RubyBytes::CLI.new.run("compile", "./template/<%= name %>.rb")
end
task default: %w[test:isolated]
TCODE
], trim_mode: "<>").result(binding)
file "README.md", ERB.new(
*[
<<~'TCODE'
# <%= human_name %> template
TODO: Provide a description for your template.
## Usage
<% if needs_rails %>
You can install this template via RailsBytes by running the following command:
```sh
bin/rails app:template LOCATION=<TODO:url>
```
Alternatively, you can install it via [Ruby Bytes][] as follows:
```sh
rbytes install <TODO:url>
```
<% else %>
You can install this template via [Ruby Bytes][] as follows:
```sh
rbytes install <TODO:url>
```
<% end %>
[Ruby Bytes]: https://github.com/palkan/rbytes
TCODE
], trim_mode: "<>").result(binding)
file ".gitignore", ERB.new(
*[
<<~'TCODE'
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.vi
*~
*.sass-cache
*.iml
.idea/
# Sublime
*.sublime-project
*.sublime-workspace
# OS or Editor folders
.DS_Store
.cache
.project
.settings
.tmproj
Thumbs.db
.bundle/
log/*.log
pkg/
spec/dummy/db/*.sqlite3
spec/dummy/db/*.sqlite3-journal
spec/dummy/tmp/
Gemfile.lock
Gemfile.local
.rspec-local
.ruby-version
*.gem
tmp/
.rbnext/
gemfiles/*.lock
TCODE
], trim_mode: "<>").result(binding)
file "test/test_helper.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
begin
require "debug"
rescue LoadError
end
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
require "rbytes"
require "ruby_bytes/test_case"
require "minitest/autorun"
require "minitest/focus"
require "minitest/reporters"
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
class GeneratorTestCase < RubyBytes::TestCase
root File.join(__dir__, "../template")
<% if needs_rails %>
dummy_app File.join(__dir__, "fixtures", "basic_rails_app")
<% end %>
end
TCODE
], trim_mode: "<>").result(binding)
file "test/template_test.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
require "test_helper"
class TemplateTest < Minitest::Test
def test_template_compiles
assert RubyBytes::Compiler.new(File.join(__dir__, "../template/<%= name %>.rb")).render
end
end
TCODE
], trim_mode: "<>").result(binding)
file "test/template/example_test.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
require "test_helper"
class ExampleTest < GeneratorTestCase
template <<~'CODE'
<%%= include "example" %>
CODE
def test_name
run_generator do |output|
assert_line_printed(
output,
"Hey from the included template!"
)
end
end
end
TCODE
], trim_mode: "<>").result(binding)
if needs_rails
file "test/fixtures/basic_rails_app/config.ru", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
# This file is used by Rack-based servers to start the application.
require_relative "config/environment"
run Rails.application
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/Gemfile", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
source "https://rubygems.org"
ruby "~> 3.0"
gem "rails"
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/Gemfile.lock", ERB.new(
*[
<<~'TCODE'
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.4.3)
actionpack (= 7.0.4.3)
activejob (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.4.3)
actionpack (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activesupport (= 7.0.4.3)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.4.3)
actionview (= 7.0.4.3)
activesupport (= 7.0.4.3)
rack (~> 2.0, >= 2.2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.4.3)
actionpack (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.4.3)
activesupport (= 7.0.4.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.4.3)
activesupport (= 7.0.4.3)
globalid (>= 0.3.6)
activemodel (7.0.4.3)
activesupport (= 7.0.4.3)
activerecord (7.0.4.3)
activemodel (= 7.0.4.3)
activesupport (= 7.0.4.3)
activestorage (7.0.4.3)
actionpack (= 7.0.4.3)
activejob (= 7.0.4.3)
activerecord (= 7.0.4.3)
activesupport (= 7.0.4.3)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
builder (3.2.4)
concurrent-ruby (1.2.2)
crass (1.0.6)
date (3.3.3)
erubi (1.12.0)
globalid (1.1.0)
activesupport (>= 5.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
minitest (5.18.0)
net-imap (0.3.4)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.2-arm64-darwin)
racc (~> 1.4)
racc (1.6.2)
rack (2.2.6.4)
rack-test (2.1.0)
rack (>= 1.3)
rails (7.0.4.3)
actioncable (= 7.0.4.3)
actionmailbox (= 7.0.4.3)
actionmailer (= 7.0.4.3)
actionpack (= 7.0.4.3)
actiontext (= 7.0.4.3)
actionview (= 7.0.4.3)
activejob (= 7.0.4.3)
activemodel (= 7.0.4.3)
activerecord (= 7.0.4.3)
activestorage (= 7.0.4.3)
activesupport (= 7.0.4.3)
bundler (>= 1.15.0)
railties (= 7.0.4.3)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
railties (7.0.4.3)
actionpack (= 7.0.4.3)
activesupport (= 7.0.4.3)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rake (13.0.6)
thor (1.2.1)
timeout (0.3.2)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.6.7)
PLATFORMS
arm64-darwin-21
DEPENDENCIES
rails
RUBY VERSION
ruby 3.2.1p31
BUNDLED WITH
2.4.8
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/config/environment.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
# Load the Rails application.
require_relative "application"
# Initialize the Rails application.
Rails.application.initialize!
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/config/application.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
require_relative "boot"
require "action_controller/railtie"
module Dummy
class Application < Rails::Application
config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil))
config.log_level = :fatal
config.eager_load = true
end
end
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/config/environments/development.rb", ERB.new(
*[
<<~'TCODE'
# frozen_string_literal: true
Rails.application.configure do
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
end
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/config/database.yml", ERB.new(
*[
<<~'TCODE'
development:
adapter: postgresql
database: my_database
host: localhost
TCODE
], trim_mode: "<>").result(binding)
file "test/fixtures/basic_rails_app/.gitignore", ERB.new(
*[
<<~'TCODE'
!Gemfile.lock
TCODE
], trim_mode: "<>").result(binding)
end
needs_ci = yes? "Would you like to configure GitHub Actions to test and publish your template?"
if needs_ci
file ".github/workflows/test.yml", ERB.new(
*[
<<~'TCODE'
name: Build
on:
push:
branches:
- main
pull_request:
jobs:
test:
runs-on: ubuntu-latest
env:
BUNDLE_JOBS: 4
BUNDLE_RETRY: 3
CI: true
strategy:
fail-fast: false
matrix:
ruby: ["3.2"]
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run tests
run: |
bundle exec rake test
TCODE
], trim_mode: "<>").result(binding)
file ".github/workflows/publish.yml", ERB.new(
*[
<<~'TCODE'
name: Publish
on:
push:
tags:
- v*
workflow_dispatch:
jobs:
publish:
uses: palkan/rbytes/.github/workflows/railsbytes.yml@master
with:
template: template/<%= name %>.rb
secrets:
RAILS_BYTES_ACCOUNT_ID: "${{ secrets.RAILS_BYTES_ACCOUNT_ID }}"
RAILS_BYTES_TOKEN: "${{ secrets.RAILS_BYTES_TOKEN }}"
RAILS_BYTES_TEMPLATE_ID: "${{ secrets.RAILS_BYTES_TEMPLATE_ID }}"
TCODE
], trim_mode: "<>").result(binding)
end
end