Ruby Bytes template project generator

Public
Generate a new project to build an application template with Ruby Bytes
Icons/chart bar
Used 36 times
Created by
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
Comments

Sign up or Login to leave a comment.