├── .rspec ├── .github ├── FUNDING.yml ├── PULL_REQUEST_TEMPLATE │ └── pull_request_template.md └── workflows │ ├── rspec_rubocop.yml │ └── main.yml ├── bin ├── setup ├── console └── rails-interactive ├── lib ├── cli │ ├── version.rb │ ├── templates │ │ ├── setup_friendly_id.rb │ │ ├── setup_sassc_rails.rb │ │ ├── setup_minitest.rb │ │ ├── setup_faker.rb │ │ ├── setup_awesome_print.rb │ │ ├── setup_kaminari.rb │ │ ├── setup_cancancan.rb │ │ ├── setup_bullet.rb │ │ ├── setup_better_errors.rb │ │ ├── setup_brakeman.rb │ │ ├── setup_stimulus.rb │ │ ├── setup_active_admin.rb │ │ ├── setup_graphql.rb │ │ ├── setup_rubocop.rb │ │ ├── setup_standardrb.rb │ │ ├── setup_rspec.rb │ │ ├── setup_avo.rb │ │ ├── setup_rails_admin.rb │ │ ├── setup_pundit.rb │ │ ├── setup_letter_opener.rb │ │ ├── setup_devise.rb │ │ ├── setup_haml.rb │ │ ├── setup_slim.rb │ │ ├── setup_tailwind.rb │ │ ├── setup_capybara.rb │ │ ├── setup_sidekiq.rb │ │ ├── setup_omniauth.rb │ │ └── setup_react.rb │ ├── category.rb │ ├── command.rb │ ├── utils.rb │ ├── prompt.rb │ ├── config │ │ ├── categories.yml │ │ └── commands.yml │ ├── command_handler.rb │ └── message.rb └── rails_interactive.rb ├── spec ├── rails_interactive │ └── rails_interactive_spec.rb └── spec_helper.rb ├── Rakefile ├── .gitignore ├── Gemfile ├── CHANGELOG.md ├── .rubocop.yml ├── LICENSE.txt ├── rails-interactive.gemspec ├── README.md ├── CODE_OF_CONDUCT.md └── Gemfile.lock /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: oguzsh 2 | github: oguzsh 3 | custom: https://www.buymeacoffee.com/oguzhanince 4 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | chmod u+x bin/rails-interactive 6 | 7 | bundle install 8 | -------------------------------------------------------------------------------- /lib/cli/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RailsInteractive 4 | class CLI 5 | VERSION = "2.1.3" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_friendly_id.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add 'friendly_id'" 4 | 5 | rails_command "generate friendly_id" 6 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_sassc_rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add sassc-rails" 4 | Bundler.with_unbundled_env { run "bundle" } 5 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_minitest.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add minitest" 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "rails_interactive" 6 | 7 | require "pry" 8 | Pry.start 9 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_faker.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add faker --group 'development' 'test'" 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_awesome_print.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run 'bundle add awesome_print --group "development"' 4 | Bundler.with_unbundled_env { run "bundle install" } 5 | -------------------------------------------------------------------------------- /bin/rails-interactive: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "rails_interactive" 6 | 7 | RailsInteractive::CLI.new.perform(ARGV.first) 8 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_kaminari.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add kaminari" 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | 7 | puts "Kaminari is installed!" 8 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_cancancan.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add cancancan" 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | 7 | rails_command "generate cancan:ability" 8 | -------------------------------------------------------------------------------- /spec/rails_interactive/rails_interactive_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe RailsInteractive do 4 | it "does something useful" do 5 | expect(false).to eq(false) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_bullet.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add bullet --group 'development'" 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | 7 | run "bundle exec rails g bullet:install" 8 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_better_errors.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem_group :development do 4 | gem "better_errors" 5 | gem "binding_of_caller" 6 | end 7 | 8 | Bundler.with_unbundled_env { run "bundle install" } 9 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_brakeman.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run 'bundle add brakeman --group "development"' 4 | Bundler.with_unbundled_env { run "bundle install" } 5 | run "bundle binstubs brakeman" 6 | run "bin/brakeman" 7 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_stimulus.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add turbo-rails" 4 | run "bundle add stimulus-rails" 5 | 6 | Bundler.with_unbundled_env { run "bundle install" } 7 | 8 | rails_command "turbo:install stimulus:install" 9 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_active_admin.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add activeadmin" 4 | run "bundle add bcrypt" 5 | Bundler.with_unbundled_env { run "bundle" } 6 | 7 | rails_command "generate active_admin:install" 8 | rails_command "db:migrate" 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | require "rspec/core/rake_task" 5 | 6 | RSpec::Core::RakeTask.new(:spec) 7 | 8 | require "rubocop/rake_task" 9 | 10 | RuboCop::RakeTask.new 11 | 12 | task default: %i[spec rubocop] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /spec/reports/ 8 | /tmp/ 9 | .DS_Store 10 | /Gemfile.lock 11 | *.bundle 12 | *.so 13 | *.o 14 | *.a 15 | mkmf.log 16 | *.gem 17 | # rspec failure tracking 18 | .rspec_status 19 | .idea -------------------------------------------------------------------------------- /lib/cli/templates/setup_graphql.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "rails db:prepare" 4 | run "bundle add graphql" 5 | 6 | Bundler.with_unbundled_env { run "bundle install" } 7 | 8 | rails_command("generate graphql:install") 9 | 10 | puts "GraphQL is installed!" 11 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_rubocop.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem_group :development do 4 | gem "rubocop", require: false 5 | end 6 | 7 | Bundler.with_unbundled_env { run "bundle install" } 8 | 9 | run "rubocop --auto-gen-config" 10 | run "bundle binstubs rubocop" 11 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_standardrb.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem_group :development, :test do 4 | gem "standard" 5 | end 6 | 7 | Bundler.with_unbundled_env { run "bundle install" } 8 | 9 | puts "You can then run Standard from the command line with:" 10 | puts "bundle exec standardrb" 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in rails_interactive.gemspec 6 | gemspec 7 | 8 | gem "rails" 9 | 10 | gem "rake", "~> 13.0" 11 | 12 | gem "rspec", "~> 3.0" 13 | 14 | gem "rubocop", "~> 1.7" 15 | 16 | gem "tty-prompt" 17 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_rspec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "spring stop" 4 | 5 | gem_group :development, :test do 6 | gem "rspec-rails" 7 | end 8 | 9 | Bundler.with_unbundled_env { run "bundle install" } 10 | 11 | rails_command "generate rspec:install" 12 | 13 | puts "RSpec is installed!" 14 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_avo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "rails db:prepare" 4 | run "bundle add avo" 5 | 6 | Bundler.with_unbundled_env { run "bundle install" } 7 | 8 | rails_command("generate avo:install") 9 | 10 | puts "Avo is installed! You can go to http://localhost:3000/avo for next steps" 11 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_rails_admin.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "rails db:prepare" 4 | run "bundle add rails_admin" 5 | 6 | Bundler.with_unbundled_env { run "bundle install" } 7 | 8 | rails_command("generate rails_admin:install") 9 | 10 | puts "RailsAdmin is installed! You can go to your admin panel at /admin" 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## What's up? 2 | 3 | In this PR, Rails interactive have `gem` integration. In this way, when users select `gem` to install their rails project, CLI will install `gem` to the related project with the use of rails templates 4 | 5 | ## Issue 6 | Related Issue: `issue_link` 7 | 8 | ## Closed Issue 9 | Closes `issue_link` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ### [0.1.9](https://www.github.com/oguzsh/rails-interactive/compare/v0.1.8...v0.1.9) (2022-04-24) 4 | 5 | 6 | ### Bug Fixes 7 | 8 | * file name typo ([#60](https://www.github.com/oguzsh/rails-interactive/issues/60)) ([542c76f](https://www.github.com/oguzsh/rails-interactive/commit/542c76fa57fd37cf583a7238b2a9b527aeba1778)) 9 | 10 | ## [0.1.0] - 2022-03-11 11 | 12 | - Initial release 13 | -------------------------------------------------------------------------------- /.github/workflows/rspec_rubocop.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | name: Run tests 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Set up Ruby 12 | uses: ruby/setup-ruby@v1 13 | with: 14 | ruby-version: 3.0.2 15 | bundler-cache: true 16 | - name: Run the default task 17 | run: bundle exec rake 18 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_pundit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add pundit" 4 | 5 | puts "Add - Pundit module to Application Controller" 6 | puts "" 7 | 8 | inject_into_file "app/controllers/application_controller.rb", 9 | after: "class ApplicationController < ActionController::Base\n" do 10 | " include Pundit\n" 11 | end 12 | 13 | puts "Run - Pundit Generator" 14 | 15 | rails_command("generate pundit:install") 16 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_interactive" 4 | 5 | RSpec.configure do |config| 6 | # Enable flags like --only-failures and --next-failure 7 | config.example_status_persistence_file_path = ".rspec_status" 8 | 9 | # Disable RSpec exposing methods globally on `Module` and `main` 10 | config.disable_monkey_patching! 11 | 12 | config.expect_with :rspec do |c| 13 | c.syntax = :expect 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/cli/category.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "yaml" 4 | 5 | module RailsInteractive 6 | class CLI 7 | # Categories class for the interactive CLI module 8 | class Category 9 | def initialize 10 | @categories = YAML.load_file("#{__dir__}/config/categories.yml").uniq 11 | end 12 | 13 | def all 14 | @categories.sort_by { |category| category["weight"] } 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_letter_opener.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run 'bundle add letter_opener --group "development"' 4 | 5 | Bundler.with_unbundled_env { run "bundle install" } 6 | 7 | inject_into_file "config/environments/development.rb", after: "config.action_mailer.perform_caching = false\n" do 8 | <<-RUBY 9 | 10 | config.action_mailer.delivery_method = :letter_opener 11 | config.action_mailer.perform_deliveries = true 12 | RUBY 13 | end 14 | 15 | puts "Letter Opener is now installed!" 16 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_devise.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | run "bundle add devise" 4 | Bundler.with_unbundled_env { run "bundle install" } 5 | 6 | rails_command "generate devise:install" 7 | 8 | model_name = ask("What do you want to call your Devise model?") 9 | model_name = model_name.empty? ? "user" : model_name 10 | 11 | File.open("devise-model.txt", "w") { |f| f.write(model_name) } 12 | 13 | run "rails generate devise #{model_name.capitalize}" 14 | run "rails db:prepare" 15 | run "rails db:migrate" 16 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.7 3 | 4 | Style/StringLiterals: 5 | Enabled: true 6 | EnforcedStyle: double_quotes 7 | 8 | Style/StringLiteralsInInterpolation: 9 | Enabled: true 10 | EnforcedStyle: double_quotes 11 | 12 | Layout/LineLength: 13 | Max: 120 14 | 15 | Style/Documentation: 16 | Enabled: false 17 | 18 | Metrics/MethodLength: 19 | Max: 12 20 | 21 | Metrics/CyclomaticComplexity: 22 | Max: 25 23 | 24 | Metrics/PerceivedComplexity: 25 | Max: 10 26 | 27 | Metrics/AbcSize: 28 | Enabled: false -------------------------------------------------------------------------------- /lib/cli/templates/setup_haml.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | def bundle_install 4 | Bundler.with_unbundled_env { run "bundle install" } 5 | end 6 | 7 | run "bundle add haml" 8 | bundle_install 9 | 10 | if yes?("Would you like to convert your existing *.erb files to *.haml files? [y/n]") 11 | run "bundle add erb2haml --group 'development'" 12 | bundle_install 13 | if yes?("Would you like to keep the original *.erb files? [y/n]") 14 | rake "haml:convert_erbs" 15 | else 16 | rake "haml:replace_erbs" 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_slim.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | def bundle_install 4 | Bundler.with_unbundled_env { run "bundle install" } 5 | end 6 | 7 | run "bundle add slim-rails" 8 | 9 | bundle_install 10 | 11 | if yes?("Would you like to convert your existing *.erb files to *.slim files? [y/n]") 12 | run "bundle add html2slim --group 'development'" 13 | bundle_install 14 | if yes?("Would you like to keep the original *.erb files? [y/n]") 15 | run "erb2slim app/views" 16 | else 17 | run "erb2slim app/views -d" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_tailwind.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | def package?(package) 4 | require "json" 5 | 6 | file = File.open("package.json") if File.file?("package.json") 7 | 8 | packages = JSON.parse(file.read) if file 9 | 10 | packages["dependencies"].include?(package) if packages 11 | end 12 | 13 | run "bundle add tailwindcss-rails" 14 | 15 | if package?("react") 16 | run "rm Procfile.dev" 17 | run "rm bin/dev" 18 | end 19 | 20 | rails_command "tailwindcss:install" 21 | 22 | if package?("react") 23 | run "rm Procfile.dev" 24 | run "echo 'web: bin/rails server -p 3000\njs: yarn build --watch\ncss: bin/rails tailwindcss:watch' > Procfile.dev" 25 | end 26 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | gem_group :development, :test do 4 | gem "capybara" 5 | end 6 | 7 | Bundler.with_unbundled_env { run "bundle install" } 8 | 9 | if defined? RSpec 10 | inject_into_file "spec/spec_helper.rb", before: "RSpec.configure do |config|" do 11 | <<~RB 12 | require 'capybara/rspec' 13 | RB 14 | end 15 | elsif defined? MiniTest && !defined? RSpec 16 | inject_into_file "test/test_helper.rb", before: "class ActiveSupport::TestCase" do 17 | <<~RB 18 | require 'capybara/rails' 19 | require 'capybara/minitest' 20 | RB 21 | end 22 | else 23 | puts "No test framework detected or related test framework does not exist in RailsInteractive" 24 | end 25 | -------------------------------------------------------------------------------- /lib/cli/command.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "yaml" 4 | 5 | module RailsInteractive 6 | class CLI 7 | # Commands class for the interactive CLI module 8 | class Command 9 | def initialize 10 | @commands = YAML.load_file("#{__dir__}/config/commands.yml").uniq 11 | end 12 | 13 | def all 14 | @commands 15 | end 16 | 17 | def find_by_identifier(identifier) 18 | @commands.find { |command| command["identifier"] == identifier } 19 | end 20 | 21 | def dependencies(identifier) 22 | identifier = identifier.is_a?(Array) ? identifier.join("") : identifier 23 | command ||= find_by_identifier(identifier) 24 | 25 | command["dependencies"] 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/cli/utils.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "fileutils" 4 | 5 | module RailsInteractive 6 | class CLI 7 | class Utils 8 | def self.humanize(value) 9 | return nil if value.nil? 10 | 11 | value 12 | .gsub(/^[\s_]+|[\s_]+$/, "") 13 | .gsub(/[_\s]+/, " ") 14 | .gsub(/^[a-z]/, &:upcase) 15 | end 16 | 17 | def self.remove_templates(_project_name) 18 | FileUtils.rm_rf("templates") 19 | end 20 | 21 | def self.go_to_project_directory(project_name) 22 | Dir.chdir "./#{project_name}" 23 | end 24 | 25 | def self.copy_templates_to_project(project_name) 26 | FileUtils.cp_r "#{__dir__}/templates", "./#{project_name}" 27 | 28 | go_to_project_directory(project_name) 29 | end 30 | 31 | def self.sign_project 32 | file = "README.md" 33 | msg = "\n> This project was generated by [Rails Interactive CLI](https://github.com/oguzsh/rails-interactive)" 34 | File.write(file, msg, mode: "a+") 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_sidekiq.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | def file_contains?(filename, string) 4 | File.foreach(filename).detect { |line| line.include?(string) } 5 | end 6 | 7 | run "bundle add sidekiq" 8 | run "bundle add redis" unless file_contains? "Gemfile", "Gem 'redis'" 9 | 10 | Bundler.with_unbundled_env { run "bundle install" } 11 | 12 | # rubocop:disable Naming/HeredocDelimiterNaming 13 | application do 14 | <<~EOF 15 | config.active_job.queue_adapter = :sidekiq 16 | EOF 17 | end 18 | 19 | inject_into_file "config/routes.rb" do 20 | <<~EOF 21 | require "sidekiq/web" 22 | if Rails.env.production? 23 | Sidekiq::Web.use Rack::Auth::Basic do |username, password| 24 | ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_USERNAME"])) & 25 | ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_PASSWORD"])) 26 | end 27 | end 28 | EOF 29 | end 30 | # rubocop:enable Naming/HeredocDelimiterNaming 31 | 32 | route 'mount Sidekiq::Web => "/sidekiq"' 33 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 Oguzhan Ince 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/cli/prompt.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "tty/prompt" 4 | 5 | module RailsInteractive 6 | class CLI 7 | # Prompt class for commands 8 | class Prompt 9 | # Create a new instance 10 | # 11 | # @param msg [String] the message to display 12 | # @param type [String] the type of prompt 13 | # @param options [Array] the options to display 14 | # @param required [Boolean] whether the prompt value is required 15 | # 16 | # @return [Interactive::Prompt] the new instance 17 | def initialize(msg, type, options = nil, required: false) 18 | @msg = msg 19 | @type = type 20 | @options = options 21 | @required = required 22 | @prompt = TTY::Prompt.new 23 | end 24 | 25 | # Perform the prompt 26 | # 27 | # @return [String] the value of the prompt 28 | def perform 29 | case @type 30 | when "ask" 31 | @prompt.ask(@msg, required: @required) 32 | when "select" 33 | @prompt.select(@msg, @options, required: @required) 34 | when "multi_select" 35 | @prompt.multi_select(@msg, @options) 36 | else 37 | puts "Invalid parameter" 38 | end 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/cli/config/categories.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - 3 | name: authentication 4 | weight: 1 5 | type: "multi_select" 6 | required: false 7 | - 8 | name: authorization 9 | weight: 2 10 | type: "select" 11 | required: false 12 | - 13 | name: testing 14 | weight: 3 15 | type: "select" 16 | required: false 17 | - 18 | name: end_to_end_testing 19 | weight: 4 20 | type: "select" 21 | required: false 22 | - 23 | name: template_engine 24 | weight: 5 25 | type: "select" 26 | required: false 27 | - 28 | name: frontend 29 | weight: 6 30 | type: "select" 31 | required: false 32 | - 33 | name: css_framework 34 | weight: 7 35 | type: "select" 36 | required: false 37 | - 38 | name: background_job 39 | weight: 8 40 | type: "select" 41 | required: false 42 | - 43 | name: code_quality 44 | weight: 9 45 | type: "select" 46 | required: false 47 | - 48 | name: security 49 | weight: 10 50 | type: "select" 51 | required: false 52 | - 53 | name: admin_panel 54 | weight: 11 55 | type: "select" 56 | required: false 57 | - 58 | name: features 59 | weight: 12 60 | type: "multi_select" 61 | required: false 62 | - 63 | name: development 64 | weight: 13 65 | type: "multi_select" 66 | required: false -------------------------------------------------------------------------------- /lib/cli/command_handler.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cli/command" 4 | require "yaml" 5 | 6 | module RailsInteractive 7 | class CLI 8 | # Commands class for the interactive CLI module 9 | class CommandHandler 10 | def initialize 11 | @commands = Command.new.all 12 | @installed_commands = [] 13 | @installed_dependencies = [] 14 | end 15 | 16 | def handle_multi_options(options, dependencies = nil) 17 | handle_dependencies(dependencies) 18 | 19 | options.each do |option| 20 | @installed_commands << option 21 | system("bin/rails app:template LOCATION=templates/setup_#{option}.rb") 22 | end 23 | end 24 | 25 | def handle_option(option, dependencies = nil) 26 | @installed_commands << option 27 | handle_dependencies(dependencies) 28 | 29 | system("bin/rails app:template LOCATION=templates/setup_#{option}.rb") 30 | end 31 | 32 | def handle_dependencies(dependencies) 33 | dependencies&.each do |dependency| 34 | next if duplicated_gem?(dependency) 35 | 36 | puts ">> Dependency Detected: #{dependency} " 37 | @installed_dependencies << dependency 38 | 39 | system("bin/rails app:template LOCATION=templates/setup_#{dependency}.rb") 40 | end 41 | end 42 | 43 | private 44 | 45 | def duplicated_gem?(option) 46 | @installed_commands.include?(option) || @installed_dependencies.include?(option) 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /rails-interactive.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "lib/cli/version" 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "rails-interactive" 7 | spec.version = RailsInteractive::CLI::VERSION 8 | spec.authors = ["Oguzhan Ince"] 9 | spec.email = ["oguzhan824@gmail.com"] 10 | 11 | spec.summary = "The gem for setup rails development with interactive mode" 12 | spec.homepage = "https://github.com/oguzsh/rails-interactive" 13 | spec.license = "MIT" 14 | spec.required_ruby_version = ">= 2.7.5" 15 | 16 | spec.metadata["homepage_uri"] = spec.homepage 17 | spec.metadata["source_code_uri"] = "https://github.com/oguzsh/rails-interactive" 18 | spec.metadata["changelog_uri"] = "https://github.com/oguzsh/rails-interactive/blob/main/CHANGELOG.md" 19 | 20 | # Specify which files should be added to the gem when it is released. 21 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 22 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 23 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) } 24 | end 25 | spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) } 26 | spec.require_paths = ["lib"] 27 | 28 | # Uncomment to register a new dependency of your gem 29 | spec.add_development_dependency "bundler" 30 | spec.add_development_dependency "byebug", "~> 11.1.2" 31 | spec.add_development_dependency "colorize" 32 | spec.add_development_dependency "pry" 33 | spec.add_development_dependency "rake" 34 | spec.add_development_dependency "rspec" 35 | spec.add_development_dependency "rubocop" 36 | spec.add_development_dependency "yaml" 37 | 38 | spec.add_dependency "tty-prompt" 39 | 40 | # For more information and examples about making a new gem, checkout our 41 | # guide at: https://bundler.io/guides/creating_gem.html 42 | end 43 | -------------------------------------------------------------------------------- /lib/cli/message.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "colorize" 4 | 5 | module RailsInteractive 6 | class CLI 7 | # Utils class for the interactive CLI module 8 | class Message 9 | def self.greet 10 | render_ascii 11 | puts "Welcome to Rails Interactive CLI".colorize(:yellow) 12 | end 13 | 14 | def self.help 15 | puts "bin/interactive new - Create a new Rails Project".colorize(:yellow) 16 | puts "bin/interactive help - List all commands".colorize(:yellow) 17 | exit 18 | end 19 | 20 | def self.render_ascii 21 | # rubocop:disable Naming/HeredocDelimiterNaming 22 | puts <<-'EOF' 23 | _____ _ _ _____ _ _ _ 24 | | __ \ (_) | |_ _| | | | | (_) 25 | | |__) |__ _ _| |___ | | _ __ | |_ ___ _ __ __ _ ___| |_ ___ _____ 26 | | _ // _` | | / __| | | | '_ \| __/ _ \ '__/ _` |/ __| __| \ \ / / _ \ 27 | | | \ \ (_| | | \__ \_| |_| | | | || __/ | | (_| | (__| |_| |\ V / __/ 28 | |_| \_\__,_|_|_|___/_____|_| |_|\__\___|_| \__,_|\___|\__|_| \_/ \___| 29 | 30 | EOF 31 | # rubocop:enable Naming/HeredocDelimiterNaming 32 | end 33 | 34 | def self.prepare 35 | puts "" 36 | puts "Project created successfully ✅".colorize(:green) 37 | puts "Go to your project folder and ready to go 🎉".colorize(:green) 38 | rails_commands 39 | end 40 | 41 | def self.rails_commands 42 | puts "You can run several commands:".colorize(:green) 43 | 44 | puts "Starts the webpack development server".colorize(:cyan) 45 | puts "> bin/webpack-dev-server".colorize(:yellow) 46 | 47 | puts "Starts the rails server".colorize(:cyan) 48 | puts "> bin/rails s or bin/rails server".colorize(:yellow) 49 | 50 | puts "Starts the rails console".colorize(:cyan) 51 | puts "> bin/rails c or bin/rails console".colorize(:yellow) 52 | end 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # name: Release and Publish 2 | # on: 3 | # push: 4 | # branches: 5 | # - main 6 | # jobs: 7 | # build: 8 | # runs-on: ubuntu-latest 9 | # steps: 10 | # - name: Wait for tests to succeed 11 | # uses: lewagon/wait-on-check-action@v1.0.0 12 | # with: 13 | # ref: ${{ github.ref }} 14 | # check-name: 'Run tests' 15 | # repo-token: ${{ secrets.GITHUB_TOKEN }} 16 | # wait-interval: 10 17 | # - uses: GoogleCloudPlatform/release-please-action@v2 18 | # id: release 19 | # with: 20 | # release-type: ruby 21 | # package-name: rails-interactive 22 | # version-file: 'lib/rails_interactive/version.rb' 23 | # - uses: actions/checkout@v2 24 | # if: ${{ steps.release.outputs.release_created }} 25 | # - name: Set up Ruby 26 | # uses: ruby/setup-ruby@v1 27 | # if: ${{ steps.release.outputs.release_created }} 28 | # with: 29 | # ruby-version: 3.0.2 30 | # bundler-cache: true 31 | # - name: Bundle Install 32 | # run: bundle install 33 | # if: ${{ steps.release.outputs.release_created }} 34 | # - name: Set Credentials 35 | # run: | 36 | # mkdir -p $HOME/.gem 37 | # touch $HOME/.gem/credentials 38 | # chmod 0600 $HOME/.gem/credentials 39 | # printf -- "---\n:github: Bearer ${GITHUB_TOKEN}\n" > $HOME/.gem/credentials 40 | # printf -- "---\n:rubygems_api_key: ${RUBYGEMS_TOKEN}\n" > $HOME/.gem/credentials 41 | # if: ${{ steps.release.outputs.release_created }} 42 | # env: 43 | # GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 44 | # RUBYGEMS_TOKEN: '${{secrets.RUBYGEMS_TOKEN}}' 45 | # - name: Publish to GitHub Packages 46 | # run: | 47 | # export OWNER=$( echo ${{ github.repository }} | cut -d "/" -f 1 ) 48 | # gem build *.gemspec 49 | # gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem 50 | # gem push *.gem 51 | # if: ${{ steps.release.outputs.release_created }} 52 | # - name: Publish to RubyGems 53 | # run: | 54 | # gem build *.gemspec 55 | # gem push --host https://rubygems.pkg.github.com/${OWNER} *.gem 56 | # gem push *.gem 57 | # if: ${{ steps.release.outputs.release_created }} 58 | -------------------------------------------------------------------------------- /lib/cli/templates/setup_omniauth.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "fileutils" 4 | 5 | run "bundle add omniauth" 6 | 7 | run "bundle install" 8 | 9 | devise_model_name = File.read("devise-model.txt") 10 | FileUtils.rm("devise-model.txt") 11 | 12 | # rubocop:disable Layout/LineLength 13 | rails_command "generate model identity #{devise_model_name}:references provider:string:index uid:string:index token:string:index refresh_token:string:index" 14 | # rubocop:enable Layout/LineLength 15 | 16 | rails_command "generate migration AddIdentityTo#{devise_model_name.capitalize}s identities_count:integer" 17 | 18 | rails_command "db:migrate" 19 | 20 | inject_into_file "config/routes.rb", after: "devise_for :#{devise_model_name}s\n" do 21 | " # devise_for :#{devise_model_name}s, controllers: { omniauth_callbacks: 'omniauth' }" 22 | end 23 | 24 | inject_into_file "app/models/#{devise_model_name}.rb", after: ":database_authenticatable, " do 25 | ":omniauthable, " 26 | end 27 | 28 | inject_into_file "app/models/identity.rb", after: "belongs_to :#{devise_model_name}" do 29 | ", counter_cache: true" 30 | end 31 | 32 | inject_into_file "app/models/#{devise_model_name}.rb", 33 | after: "class #{devise_model_name.capitalize} < ApplicationRecord\n" do 34 | # rubocop:disable Naming/HeredocDelimiterNaming 35 | <<-EOF 36 | has_many :identities, dependent: :destroy 37 | 38 | def self.from_omniauth(auth) 39 | if auth.present? && auth.provider.present? && auth.uid.present? 40 | identity = Identity.where(provider: auth.provider, uid: auth.uid).first_or_initialize 41 | if auth.credentials.present? 42 | identity.token = auth.credentials.token 43 | identity.refresh_token = auth.credentials.refresh_token 44 | end 45 | if identity.#{devise_model_name}.nil? && auth.info.email.present? 46 | user = #{devise_model_name}.where(email: auth.info.email).first_or_initialize 47 | user.name = auth.info.name 48 | user.password = Devise.friendly_token if user.new_record? 49 | user.save! 50 | identity.#{devise_model_name} = user 51 | end 52 | identity.save! 53 | identity.#{devise_model_name} 54 | end 55 | end 56 | 57 | EOF 58 | # rubocop:enable Naming/HeredocDelimiterNaming 59 | end 60 | 61 | file "app/controllers/omniauth_controller.rb", <<~CODE 62 | class OmniauthController < Devise::OmniauthCallbacksController 63 | 64 | end 65 | CODE 66 | # rubocop:disable Layout/LineLength 67 | puts "IMPORTANT: Add devise_for :#{devise_model_name}s, controllers: { omniauth_callbacks: 'omniauth' } to your routes.rb" 68 | # rubocop:enable Layout/LineLength 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
8 | Rails Interactive is a CLI for Rails 7. Developers can create their Ruby on Rails projects with just a few keyboard clicks 🎉
9 |
10 |
11 | ·
12 | Report Bug
13 | ·
14 | Request Feature
15 |
| [@sahin](https://github.com/sahin) | Gold Sponsor |
61 | |
| [@sadikay](https://github.com/sadikay) | Silver Sponsor |
62 | |
| [@adamdilek](https://github.com/adamdilek) | Silver Sponsor |
63 |
64 | ## ⚠️ License
65 |
66 | The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
67 |
68 | ## Contact
69 |
70 | Oguzhan Ince - [@oguz_sh](https://twitter.com/oguz_sh) - oguzhan824@gmail.com
71 |
--------------------------------------------------------------------------------
/lib/cli/templates/setup_react.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # NPM
4 | run "yarn init -y"
5 | run "yarn add esbuild react react-dom"
6 |
7 | # rubocop:disable Layout/LineLength
8 | run "npm set-script build 'esbuild app/javascript/*.* --bundle --sourcemap --loader:.js=jsx --outdir=app/assets/javascripts'"
9 | # rubocop:enable Layout/LineLength
10 | #
11 | # Foreman
12 | run "gem install foreman"
13 | run 'echo "#!/usr/bin/env bash\nforeman start -f Procfile.dev "$@"" > bin/dev'
14 | run "echo 'web: bin/rails server -p 3000\njs: yarn build --watch' > Procfile.dev"
15 | run "chmod u+x bin/dev"
16 |
17 | # Component Helper from Ruby on Rails
18 | inject_into_file "app/helpers/application_helper.rb", after: "module ApplicationHelper" do
19 | <<~RB
20 |
21 | def react_component(component_name, **props)
22 | tag.div(data: {
23 | react_component: component_name,
24 | props: props.to_json
25 | }) { '' }
26 | end
27 | RB
28 | end
29 |
30 | # Include JS to application.html.erb
31 | inject_into_file "app/views/layouts/application.html.erb", after: "<%= javascript_importmap_tags %>" do
32 | <<~ERB
33 |
34 | <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
35 | ERB
36 | end
37 |
38 | # Component Mounter for JS
39 | create_file "app/javascript/mount.js" do
40 | <<~JAVASCRIPT
41 | import React from 'react';
42 | import ReactDOM from 'react-dom';
43 |
44 | export default function mount(components = {}) {
45 | const mountPoints = document.querySelectorAll('[data-react-component]');
46 | mountPoints.forEach((mountPoint) => {
47 | const { dataset } = mountPoint;
48 | const componentName = dataset.reactComponent;
49 | const Component = components[componentName];
50 |
51 | if (Component) {
52 | const props = JSON.parse(dataset.props);
53 | ReactDOM.render(Find me in app/views/home/index.html.erb
" do 94 | <<~ERB 95 | 96 | <%= react_component "Hello" %> 97 | ERB 98 | end 99 | 100 | puts "React is installed! You can run bin/dev then go to home/index and see the Hello World component." 101 | -------------------------------------------------------------------------------- /lib/rails_interactive.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cli/prompt" 4 | require "cli/message" 5 | require "cli/command" 6 | require "cli/category" 7 | require "cli/utils" 8 | require "cli/command_handler" 9 | 10 | module RailsInteractive 11 | # CLI class for the interactive CLI module 12 | class CLI 13 | def initialize 14 | @inputs = {} 15 | @commands = Command.new 16 | @categories = Category.new 17 | @handler = CommandHandler.new 18 | end 19 | 20 | def perform(key) 21 | case key 22 | when "new" 23 | Message.greet 24 | initialize_project 25 | when "help" 26 | Message.help 27 | else 28 | puts "Invalid parameter" 29 | end 30 | end 31 | 32 | private 33 | 34 | def categories_with_commands 35 | @categories.all.each do |category| 36 | commands = [] 37 | @commands.all.each { |command| commands << command if command["category"] == category["name"] } 38 | category["commands"] = commands 39 | end 40 | end 41 | 42 | def initialize_project 43 | name 44 | type 45 | database 46 | 47 | categories_with_commands.each do |category| 48 | category_name = category["name"] 49 | category_type = category["type"] 50 | category_command_list = create_command_list(category["commands"], category_type) 51 | 52 | @inputs[category_name.to_sym] = 53 | Prompt.new("Choose #{Utils.humanize(category_name)} gems: ", category_type.to_s, 54 | category_command_list).perform 55 | end 56 | 57 | create_project 58 | end 59 | 60 | def setup 61 | base = "rails new" 62 | cmd = "" 63 | 64 | @inputs.first(3).each { |_key, value| cmd += "#{value} " unless value.empty? } 65 | 66 | "#{base} #{cmd} -q --skip-hotwire" 67 | end 68 | 69 | def create_project 70 | # Install gems 71 | system("bin/setup") 72 | # Create project 73 | system(setup) 74 | # Install gems 75 | install_gems 76 | # Prepare project requirements and give instructions 77 | Utils.sign_project 78 | Message.prepare 79 | end 80 | 81 | def create_command_list(commands, category_type) 82 | return nil if commands.nil? || category_type.nil? 83 | 84 | list = category_type == "select" ? {} : [] 85 | 86 | commands.each do |command| 87 | if list.is_a?(Hash) 88 | list["None"] = nil 89 | list[command["name"]] = command["identifier"] 90 | else 91 | list << command["identifier"] 92 | end 93 | end 94 | 95 | list 96 | end 97 | 98 | def install_gems 99 | # Copy template files to project folder 100 | Utils.copy_templates_to_project(@inputs[:name]) 101 | 102 | @inputs.each do |key, value| 103 | next if %i[name type database].include?(key) || value.is_a?(Array) && value.empty? || value.nil? 104 | 105 | dependencies ||= @commands.dependencies(value) 106 | @handler.handle_multi_options(value, dependencies) if value.is_a?(Array) 107 | @handler.handle_option(value, dependencies) if value.is_a?(String) 108 | end 109 | 110 | # Prepare database for project everytime 111 | system("bin/rails db:prepare") 112 | 113 | # Remove templates folder from project folder 114 | Utils.remove_templates(@inputs[:name]) 115 | end 116 | 117 | def name 118 | @inputs[:name] = Prompt.new("Project name: ", "ask", required: true).perform 119 | end 120 | 121 | def type 122 | types = { "App" => "", "Api" => "--api" } 123 | @inputs[:type] = Prompt.new("Type: ", "select", types, required: true).perform 124 | end 125 | 126 | def database 127 | database_types = { "PostgreSQL" => "-d postgresql", "MySQL" => "-d mysql", "SQLite" => "" } 128 | 129 | @inputs[:database] = Prompt.new("Database: ", "select", database_types, required: true).perform 130 | end 131 | 132 | def admin_panel 133 | admin_panel = { "ActiveAdmin" => "active_admin" } 134 | 135 | @inputs[:admin_panel] = 136 | Prompt.new("Choose project admin panel: ", "select", admin_panel).perform 137 | end 138 | end 139 | end 140 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 8 | 9 | ## Our Standards 10 | 11 | Examples of behavior that contributes to a positive environment for our community include: 12 | 13 | * Demonstrating empathy and kindness toward other people 14 | * Being respectful of differing opinions, viewpoints, and experiences 15 | * Giving and gracefully accepting constructive feedback 16 | * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 17 | * Focusing on what is best not just for us as individuals, but for the overall community 18 | 19 | Examples of unacceptable behavior include: 20 | 21 | * The use of sexualized language or imagery, and sexual attention or 22 | advances of any kind 23 | * Trolling, insulting or derogatory comments, and personal or political attacks 24 | * Public or private harassment 25 | * Publishing others' private information, such as a physical or email 26 | address, without their explicit permission 27 | * Other conduct which could reasonably be considered inappropriate in a 28 | professional setting 29 | 30 | ## Enforcement Responsibilities 31 | 32 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 33 | 34 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 35 | 36 | ## Scope 37 | 38 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 39 | 40 | ## Enforcement 41 | 42 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at oguzhan824@gmail.com. All complaints will be reviewed and investigated promptly and fairly. 43 | 44 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 45 | 46 | ## Enforcement Guidelines 47 | 48 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 49 | 50 | ### 1. Correction 51 | 52 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 53 | 54 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 55 | 56 | ### 2. Warning 57 | 58 | **Community Impact**: A violation through a single incident or series of actions. 59 | 60 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 61 | 62 | ### 3. Temporary Ban 63 | 64 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 65 | 66 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 67 | 68 | ### 4. Permanent Ban 69 | 70 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 71 | 72 | **Consequence**: A permanent ban from any sort of public interaction within the community. 73 | 74 | ## Attribution 75 | 76 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, 77 | available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 78 | 79 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 80 | 81 | [homepage]: https://www.contributor-covenant.org 82 | 83 | For answers to common questions about this code of conduct, see the FAQ at 84 | https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 85 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | rails-interactive (2.1.3) 5 | tty-prompt 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | actioncable (7.0.3.1) 11 | actionpack (= 7.0.3.1) 12 | activesupport (= 7.0.3.1) 13 | nio4r (~> 2.0) 14 | websocket-driver (>= 0.6.1) 15 | actionmailbox (7.0.3.1) 16 | actionpack (= 7.0.3.1) 17 | activejob (= 7.0.3.1) 18 | activerecord (= 7.0.3.1) 19 | activestorage (= 7.0.3.1) 20 | activesupport (= 7.0.3.1) 21 | mail (>= 2.7.1) 22 | net-imap 23 | net-pop 24 | net-smtp 25 | actionmailer (7.0.3.1) 26 | actionpack (= 7.0.3.1) 27 | actionview (= 7.0.3.1) 28 | activejob (= 7.0.3.1) 29 | activesupport (= 7.0.3.1) 30 | mail (~> 2.5, >= 2.5.4) 31 | net-imap 32 | net-pop 33 | net-smtp 34 | rails-dom-testing (~> 2.0) 35 | actionpack (7.0.3.1) 36 | actionview (= 7.0.3.1) 37 | activesupport (= 7.0.3.1) 38 | rack (~> 2.0, >= 2.2.0) 39 | rack-test (>= 0.6.3) 40 | rails-dom-testing (~> 2.0) 41 | rails-html-sanitizer (~> 1.0, >= 1.2.0) 42 | actiontext (7.0.3.1) 43 | actionpack (= 7.0.3.1) 44 | activerecord (= 7.0.3.1) 45 | activestorage (= 7.0.3.1) 46 | activesupport (= 7.0.3.1) 47 | globalid (>= 0.6.0) 48 | nokogiri (>= 1.8.5) 49 | actionview (7.0.3.1) 50 | activesupport (= 7.0.3.1) 51 | builder (~> 3.1) 52 | erubi (~> 1.4) 53 | rails-dom-testing (~> 2.0) 54 | rails-html-sanitizer (~> 1.1, >= 1.2.0) 55 | activejob (7.0.3.1) 56 | activesupport (= 7.0.3.1) 57 | globalid (>= 0.3.6) 58 | activemodel (7.0.3.1) 59 | activesupport (= 7.0.3.1) 60 | activerecord (7.0.3.1) 61 | activemodel (= 7.0.3.1) 62 | activesupport (= 7.0.3.1) 63 | activestorage (7.0.3.1) 64 | actionpack (= 7.0.3.1) 65 | activejob (= 7.0.3.1) 66 | activerecord (= 7.0.3.1) 67 | activesupport (= 7.0.3.1) 68 | marcel (~> 1.0) 69 | mini_mime (>= 1.1.0) 70 | activesupport (7.0.3.1) 71 | concurrent-ruby (~> 1.0, >= 1.0.2) 72 | i18n (>= 1.6, < 2) 73 | minitest (>= 5.1) 74 | tzinfo (~> 2.0) 75 | ast (2.4.2) 76 | builder (3.2.4) 77 | byebug (11.1.3) 78 | coderay (1.1.3) 79 | colorize (0.8.1) 80 | concurrent-ruby (1.1.10) 81 | crass (1.0.6) 82 | diff-lcs (1.5.0) 83 | digest (3.1.0) 84 | erubi (1.10.0) 85 | globalid (1.0.1) 86 | activesupport (>= 5.0) 87 | i18n (1.12.0) 88 | concurrent-ruby (~> 1.0) 89 | json (2.6.2) 90 | loofah (2.19.1) 91 | crass (~> 1.0.2) 92 | nokogiri (>= 1.5.9) 93 | mail (2.7.1) 94 | mini_mime (>= 0.1.1) 95 | marcel (1.0.2) 96 | method_source (1.0.0) 97 | mini_mime (1.1.2) 98 | minitest (5.17.0) 99 | net-imap (0.2.3) 100 | digest 101 | net-protocol 102 | strscan 103 | net-pop (0.1.1) 104 | digest 105 | net-protocol 106 | timeout 107 | net-protocol (0.1.3) 108 | timeout 109 | net-smtp (0.3.1) 110 | digest 111 | net-protocol 112 | timeout 113 | nio4r (2.5.8) 114 | nokogiri (1.13.10-x86_64-darwin) 115 | racc (~> 1.4) 116 | nokogiri (1.13.10-x86_64-linux) 117 | racc (~> 1.4) 118 | parallel (1.22.1) 119 | parser (3.1.2.0) 120 | ast (~> 2.4.1) 121 | pastel (0.8.0) 122 | tty-color (~> 0.5) 123 | pry (0.14.1) 124 | coderay (~> 1.1) 125 | method_source (~> 1.0) 126 | racc (1.6.1) 127 | rack (2.2.6.3) 128 | rack-test (2.0.2) 129 | rack (>= 1.3) 130 | rails (7.0.3.1) 131 | actioncable (= 7.0.3.1) 132 | actionmailbox (= 7.0.3.1) 133 | actionmailer (= 7.0.3.1) 134 | actionpack (= 7.0.3.1) 135 | actiontext (= 7.0.3.1) 136 | actionview (= 7.0.3.1) 137 | activejob (= 7.0.3.1) 138 | activemodel (= 7.0.3.1) 139 | activerecord (= 7.0.3.1) 140 | activestorage (= 7.0.3.1) 141 | activesupport (= 7.0.3.1) 142 | bundler (>= 1.15.0) 143 | railties (= 7.0.3.1) 144 | rails-dom-testing (2.0.3) 145 | activesupport (>= 4.2.0) 146 | nokogiri (>= 1.6) 147 | rails-html-sanitizer (1.4.4) 148 | loofah (~> 2.19, >= 2.19.1) 149 | railties (7.0.3.1) 150 | actionpack (= 7.0.3.1) 151 | activesupport (= 7.0.3.1) 152 | method_source 153 | rake (>= 12.2) 154 | thor (~> 1.0) 155 | zeitwerk (~> 2.5) 156 | rainbow (3.1.1) 157 | rake (13.0.6) 158 | regexp_parser (2.5.0) 159 | rexml (3.2.5) 160 | rspec (3.11.0) 161 | rspec-core (~> 3.11.0) 162 | rspec-expectations (~> 3.11.0) 163 | rspec-mocks (~> 3.11.0) 164 | rspec-core (3.11.0) 165 | rspec-support (~> 3.11.0) 166 | rspec-expectations (3.11.0) 167 | diff-lcs (>= 1.2.0, < 2.0) 168 | rspec-support (~> 3.11.0) 169 | rspec-mocks (3.11.1) 170 | diff-lcs (>= 1.2.0, < 2.0) 171 | rspec-support (~> 3.11.0) 172 | rspec-support (3.11.0) 173 | rubocop (1.31.2) 174 | json (~> 2.3) 175 | parallel (~> 1.10) 176 | parser (>= 3.1.0.0) 177 | rainbow (>= 2.2.2, < 4.0) 178 | regexp_parser (>= 1.8, < 3.0) 179 | rexml (>= 3.2.5, < 4.0) 180 | rubocop-ast (>= 1.18.0, < 2.0) 181 | ruby-progressbar (~> 1.7) 182 | unicode-display_width (>= 1.4.0, < 3.0) 183 | rubocop-ast (1.19.1) 184 | parser (>= 3.1.1.0) 185 | ruby-progressbar (1.11.0) 186 | strscan (3.0.3) 187 | thor (1.2.1) 188 | timeout (0.3.0) 189 | tty-color (0.6.0) 190 | tty-cursor (0.7.1) 191 | tty-prompt (0.23.1) 192 | pastel (~> 0.8) 193 | tty-reader (~> 0.8) 194 | tty-reader (0.9.0) 195 | tty-cursor (~> 0.7) 196 | tty-screen (~> 0.8) 197 | wisper (~> 2.0) 198 | tty-screen (0.8.1) 199 | tzinfo (2.0.5) 200 | concurrent-ruby (~> 1.0) 201 | unicode-display_width (2.2.0) 202 | websocket-driver (0.7.5) 203 | websocket-extensions (>= 0.1.0) 204 | websocket-extensions (0.1.5) 205 | wisper (2.0.1) 206 | yaml (0.2.0) 207 | zeitwerk (2.6.0) 208 | 209 | PLATFORMS 210 | x86_64-darwin-20 211 | x86_64-linux 212 | 213 | DEPENDENCIES 214 | bundler 215 | byebug (~> 11.1.2) 216 | colorize 217 | pry 218 | rails 219 | rails-interactive! 220 | rake (~> 13.0) 221 | rspec (~> 3.0) 222 | rubocop (~> 1.7) 223 | tty-prompt 224 | yaml 225 | 226 | BUNDLED WITH 227 | 2.2.22 228 | -------------------------------------------------------------------------------- /lib/cli/config/commands.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - 3 | identifier: rubocop 4 | name: Rubocop 5 | category: code_quality 6 | description: "A Ruby static code analyzer and formatter, based on the community Ruby style guide. For details: https://github.com/rubocop/rubocop" 7 | dependencies: null 8 | - 9 | identifier: graphql 10 | name: GraphQL 11 | category: features 12 | description: "Ruby implementation of GraphQL. For details: https://github.com/rmosolgo/graphql-ruby" 13 | dependencies: null 14 | - 15 | identifier: avo 16 | name: Avo 17 | category: admin_panel 18 | description: "Configuration-based, no-maintenance, extendable Ruby on Rails admin. For details: https://github.com/avo-hq/avo" 19 | dependencies: null 20 | - 21 | identifier: awesome_print 22 | name: AwesomePrint 23 | category: development 24 | description: "Pretty print your Ruby objects with style. For details: https://github.com/awesome-print/awesome_print" 25 | dependencies: null 26 | - 27 | identifier: better_errors 28 | name: BetterErrors 29 | category: development 30 | description: "Better error page for Rack apps. For details: https://github.com/BetterErrors/better_errors" 31 | dependencies: null 32 | - 33 | identifier: brakeman 34 | name: Brakeman 35 | category: security 36 | description: "A static analysis security vulnerability scanner for Ruby on Rails applications. For details: https://github.com/presidentbeef/brakeman" 37 | dependencies: null 38 | - 39 | identifier: bullet 40 | name: Bullet 41 | category: development 42 | description: "Bullet helps to solve N+1 queries and unused eager loading. For details: https://github.com/flyerhzm/bullet" 43 | dependencies: null 44 | - 45 | identifier: cancancan 46 | name: CanCanCan 47 | category: authorization 48 | description: "CanCanCan is an authorization library for Ruby and Ruby on Rails which restricts what resources a given user is allowed to access. For details: https://github.com/CanCanCommunity/cancancan" 49 | dependencies: null 50 | - 51 | identifier: devise 52 | name: Devise 53 | category: authentication 54 | description: "Flexible authentication solution for Rails with Warden. For details: https://github.com/heartcombo/devise" 55 | dependencies: null 56 | - 57 | identifier: faker 58 | name: Faker 59 | category: development 60 | description: "A library for generating fake data such as names, addresses, and phone numbers. For details: https://github.com/faker-ruby/faker" 61 | dependencies: null 62 | - 63 | identifier: friendly_id 64 | name: FriendlyID 65 | category: development 66 | description: "FriendlyId is the 'Swiss Army bulldozer' of slugging and permalink plugins for Active Record. It lets you create pretty URLs and work with human-friendly strings as if they were numeric ids. For details: https://github.com/norman/friendly_id" 67 | dependencies: null 68 | - 69 | identifier: haml 70 | name: Haml 71 | category: template_engine 72 | description: "HTML Abstraction Markup Language. For details: https://github.com/haml/haml" 73 | dependencies: null 74 | - 75 | identifier: kaminari 76 | name: Kaminari 77 | category: features 78 | description: "A Scope & Engine based, clean, powerful, customizable and sophisticated paginator for Ruby webapps. For details: https://github.com/kaminari/kaminari" 79 | dependencies: null 80 | - 81 | identifier: letter_opener 82 | name: LetterOpener 83 | category: development 84 | description: "Preview email in the default browser instead of sending it on development mode. For details: https://github.com/ryanb/letter_opener" 85 | dependencies: null 86 | - 87 | identifier: omniauth 88 | name: OmniAuth 89 | category: authentication 90 | description: "OmniAuth is a flexible authentication system utilizing Rack middleware. For details: https://github.com/omniauth/omniauth" 91 | dependencies: 92 | - devise 93 | - 94 | identifier: pundit 95 | name: Pundit 96 | category: authorization 97 | description: "Minimal authorization through OO design and pure Ruby classes. For details: https://github.com/varvet/pundit" 98 | dependencies: null 99 | - 100 | identifier: rails_admin 101 | name: RailsAdmin 102 | category: admin_panel 103 | description: "RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data. For details: https://github.com/railsadminteam/rails_admin" 104 | dependencies: null 105 | - 106 | identifier: rspec 107 | name: RSpec 108 | category: testing 109 | description: "A unit test framework for the Ruby programming language. For details: https://github.com/rspec" 110 | dependencies: null 111 | - 112 | identifier: sidekiq 113 | name: Sidekiq 114 | category: background_job 115 | description: "Simple, efficient background processing for Ruby. For details: https://github.com/mperham/sidekiq" 116 | dependencies: null 117 | - 118 | identifier: slim 119 | name: Slim 120 | category: template_engine 121 | description: "Slim is a template language whose goal is to reduce the syntax to the essential parts without becoming cryptic. For details: https://github.com/slim-template/slim" 122 | dependencies: null 123 | - 124 | identifier: standart_rb 125 | name: StandartRB 126 | category: code_quality 127 | description: " Ruby Style Guide, with linter & automatic code fixer. For details: https://github.com/testdouble/standard" 128 | dependencies: null 129 | - 130 | identifier: sassc_rails 131 | name: Saasc Rails 132 | category: development 133 | description: "Integrate SassC-Ruby with Rails! For details: https://github.com/sass/sassc-rails" 134 | dependencies: null 135 | - 136 | identifier: active_admin 137 | name: ActiveAdmin 138 | category: admin_panel 139 | description: "The administration framework for Ruby on Rails applications. For details: https://github.com/activeadmin/activeadmin" 140 | dependencies: 141 | - sassc_rails 142 | - devise 143 | - 144 | identifier: minitest 145 | name: MiniTest ( Default ) 146 | category: testing 147 | description: "minitest provides a complete suite of testing facilities supporting TDD, BDD, mocking, and benchmarking. For details: https://github.com/minitest/minitest" 148 | dependencies: null 149 | - 150 | identifier: capybara 151 | name: Capybara 152 | category: end_to_end_testing 153 | description: "Acceptance test framework for web applications. For details: https://github.com/teamcapybara/capybara" 154 | dependencies: null 155 | - 156 | identifier: stimulus 157 | name: StimulusJS 158 | category: frontend 159 | description: "A modest JavaScript framework for the HTML you already have. For details: https://github.com/hotwired/stimulus" 160 | dependencies: null 161 | - 162 | identifier: react 163 | name: ReactJS 164 | category: frontend 165 | description: "A declarative, efficient, and flexible JavaScript library for building user interfaces. For details: https://github.com/facebook/react/" 166 | dependencies: null 167 | - 168 | identifier: tailwind 169 | name: Tailwind 170 | category: css_framework 171 | description: "A utility-first CSS framework for rapid UI development. For details: https://github.com/tailwindlabs/tailwindcss" 172 | dependencies: null --------------------------------------------------------------------------------