rails-interactive 1.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +9 -0
- data/Gemfile.lock +77 -72
- data/README.md +1 -1
- data/bin/console +2 -9
- data/lib/cli/category.rb +18 -0
- data/lib/cli/command.rb +29 -0
- data/lib/cli/command_handler.rb +50 -0
- data/lib/cli/config/categories.yml +51 -0
- data/lib/cli/config/commands.yml +142 -0
- data/lib/cli/message.rb +55 -0
- data/lib/cli/prompt.rb +42 -0
- data/lib/cli/templates/setup_active_admin.rb +8 -0
- data/lib/cli/templates/setup_avo.rb +10 -0
- data/lib/cli/templates/setup_awesome_print.rb +4 -0
- data/lib/cli/templates/setup_better_errors.rb +8 -0
- data/lib/cli/templates/setup_brakeman.rb +6 -0
- data/lib/cli/templates/setup_bullet.rb +7 -0
- data/lib/cli/templates/setup_cancancan.rb +7 -0
- data/lib/cli/templates/setup_devise.rb +10 -0
- data/lib/cli/templates/setup_faker.rb +5 -0
- data/lib/cli/templates/setup_friendly_id.rb +5 -0
- data/lib/cli/templates/setup_graphql.rb +10 -0
- data/lib/cli/templates/setup_haml.rb +18 -0
- data/lib/cli/templates/setup_kaminari.rb +7 -0
- data/lib/cli/templates/setup_letter_opener.rb +15 -0
- data/lib/cli/templates/setup_omniauth.rb +61 -0
- data/lib/cli/templates/setup_pundit.rb +15 -0
- data/lib/cli/templates/setup_rails_admin.rb +10 -0
- data/lib/cli/templates/setup_rspec.rb +13 -0
- data/lib/cli/templates/setup_rubocop.rb +10 -0
- data/lib/cli/templates/setup_sassc_rails.rb +4 -0
- data/lib/cli/templates/setup_sidekiq.rb +32 -0
- data/lib/cli/templates/setup_slim.rb +19 -0
- data/lib/cli/templates/setup_standardrb.rb +10 -0
- data/lib/cli/utils.rb +38 -0
- data/lib/{rails_interactive → cli}/version.rb +3 -1
- data/lib/rails_interactive.rb +80 -32
- data/rails-interactive.gemspec +4 -2
- metadata +62 -5
- data/lib/rails_interactive/message.rb +0 -54
- data/lib/rails_interactive/prompt.rb +0 -40
data/lib/cli/prompt.rb
ADDED
@@ -0,0 +1,42 @@
|
|
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
|
@@ -0,0 +1,10 @@
|
|
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"
|
@@ -0,0 +1,18 @@
|
|
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
|
@@ -0,0 +1,15 @@
|
|
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!"
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
run "bundle add omniauth"
|
4
|
+
|
5
|
+
run "bundle install"
|
6
|
+
|
7
|
+
# rubocop:disable Layout/LineLength
|
8
|
+
rails_command "generate model identity user:references provider:string:index uid:string:index token:string:index refresh_token:string:index"
|
9
|
+
# rubocop:enable Layout/LineLength
|
10
|
+
|
11
|
+
rails_command "generate migration AddIdentityToUsers identities_count:integer"
|
12
|
+
|
13
|
+
rails_command "db:migrate"
|
14
|
+
|
15
|
+
inject_into_file "config/routes.rb", after: "devise_for :users\n" do
|
16
|
+
" # devise_for :users, controllers: { omniauth_callbacks: 'omniauth' }"
|
17
|
+
end
|
18
|
+
|
19
|
+
inject_into_file "app/models/user.rb", after: ":database_authenticatable, " do
|
20
|
+
":omniauthable, "
|
21
|
+
end
|
22
|
+
|
23
|
+
inject_into_file "app/models/identity.rb", after: "belongs_to :user" do
|
24
|
+
", counter_cache: true"
|
25
|
+
end
|
26
|
+
|
27
|
+
inject_into_file "app/models/user.rb", after: "class User < ApplicationRecord\n" do
|
28
|
+
# rubocop:disable Naming/HeredocDelimiterNaming
|
29
|
+
<<-EOF
|
30
|
+
has_many :identities, dependent: :destroy
|
31
|
+
|
32
|
+
def self.from_omniauth(auth)
|
33
|
+
if auth.present? && auth.provider.present? && auth.uid.present?
|
34
|
+
identity = Identity.where(provider: auth.provider, uid: auth.uid).first_or_initialize
|
35
|
+
if auth.credentials.present?
|
36
|
+
identity.token = auth.credentials.token
|
37
|
+
identity.refresh_token = auth.credentials.refresh_token
|
38
|
+
end
|
39
|
+
if identity.user.nil? && auth.info.email.present?
|
40
|
+
user = User.where(email: auth.info.email).first_or_initialize
|
41
|
+
user.name = auth.info.name
|
42
|
+
user.password = Devise.friendly_token if user.new_record?
|
43
|
+
user.save!
|
44
|
+
identity.user = user
|
45
|
+
end
|
46
|
+
identity.save!
|
47
|
+
identity.user
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
EOF
|
52
|
+
# rubocop:enable Naming/HeredocDelimiterNaming
|
53
|
+
end
|
54
|
+
|
55
|
+
file "app/controllers/omniauth_controller.rb", <<~CODE
|
56
|
+
class OmniauthController < Devise::OmniauthCallbacksController
|
57
|
+
|
58
|
+
end
|
59
|
+
CODE
|
60
|
+
|
61
|
+
puts "IMPORTANT: Add devise_for :users, controllers: { omniauth_callbacks: 'omniauth' } to your routes.rb"
|
@@ -0,0 +1,15 @@
|
|
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")
|
@@ -0,0 +1,10 @@
|
|
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"
|
@@ -0,0 +1,32 @@
|
|
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"'
|
@@ -0,0 +1,19 @@
|
|
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
|
data/lib/cli/utils.rb
ADDED
@@ -0,0 +1,38 @@
|
|
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
|
data/lib/rails_interactive.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "
|
5
|
-
require "
|
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"
|
6
9
|
|
7
10
|
module RailsInteractive
|
8
11
|
# CLI class for the interactive CLI module
|
9
12
|
class CLI
|
10
13
|
def initialize
|
11
14
|
@inputs = {}
|
15
|
+
@commands = Command.new
|
16
|
+
@categories = Category.new
|
17
|
+
@handler = CommandHandler.new
|
12
18
|
end
|
13
19
|
|
14
20
|
def perform(key)
|
@@ -23,67 +29,109 @@ module RailsInteractive
|
|
23
29
|
end
|
24
30
|
end
|
25
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
|
+
|
26
42
|
def initialize_project
|
27
43
|
name
|
28
44
|
type
|
29
45
|
database
|
30
|
-
css_frameworks
|
31
46
|
|
32
|
-
|
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
|
33
58
|
end
|
34
59
|
|
35
|
-
def
|
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"
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_project
|
36
70
|
# Install gems
|
37
71
|
system("bin/setup")
|
38
|
-
|
39
72
|
# Create project
|
40
73
|
system(setup)
|
41
|
-
|
74
|
+
# Install gems
|
75
|
+
intall_gems
|
42
76
|
# Prepare project requirements and give instructions
|
43
|
-
|
44
|
-
system("rails db:create")
|
45
|
-
|
46
|
-
sign_project
|
77
|
+
Utils.sign_project
|
47
78
|
Message.prepare
|
48
79
|
end
|
49
80
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
81
|
+
def create_command_list(commands, category_type)
|
82
|
+
return nil if commands.nil? || category_type.nil?
|
83
|
+
|
84
|
+
list = category_type == "select" ? {} : []
|
53
85
|
|
54
|
-
|
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
|
55
94
|
|
56
|
-
|
95
|
+
list
|
57
96
|
end
|
58
97
|
|
59
|
-
|
98
|
+
def intall_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
|
+
|
107
|
+
@handler.handle_multi_options(value, dependencies) if value.is_a?(Array)
|
108
|
+
@handler.handle_option(value, dependencies) if value.is_a?(String)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Remove templates folder from project folder
|
112
|
+
Utils.remove_templates(@inputs[:name])
|
113
|
+
end
|
60
114
|
|
61
115
|
def name
|
62
|
-
@inputs[:name] = Prompt.new("
|
116
|
+
@inputs[:name] = Prompt.new("Project name: ", "ask", required: true).perform
|
63
117
|
end
|
64
118
|
|
65
119
|
def type
|
66
|
-
types = { "App" => "", "
|
67
|
-
@inputs[:type] = Prompt.new("
|
120
|
+
types = { "App" => "", "Api" => "--api" }
|
121
|
+
@inputs[:type] = Prompt.new("Type: ", "select", types, required: true).perform
|
68
122
|
end
|
69
123
|
|
70
124
|
def database
|
71
125
|
database_types = { "PostgreSQL" => "-d postgresql", "MySQL" => "-d mysql", "SQLite" => "" }
|
72
126
|
|
73
|
-
@inputs[:database] = Prompt.new("
|
127
|
+
@inputs[:database] = Prompt.new("Database: ", "select", database_types, required: true).perform
|
74
128
|
end
|
75
129
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
@inputs[:css_framework] =
|
80
|
-
Prompt.new("Choose project's CSS framework: ", "select", css_frameworks, required: true).perform
|
81
|
-
end
|
130
|
+
def admin_panel
|
131
|
+
admin_panel = { "ActiveAdmin" => "active_admin" }
|
82
132
|
|
83
|
-
|
84
|
-
|
85
|
-
msg = "\n> This project was generated by [Rails Interactive CLI](https://github.com/oguzsh/rails-interactive)"
|
86
|
-
File.write(file, msg, mode: "a+")
|
133
|
+
@inputs[:admin_panel] =
|
134
|
+
Prompt.new("Choose project admin panel: ", "select", admin_panel).perform
|
87
135
|
end
|
88
136
|
end
|
89
137
|
end
|
data/rails-interactive.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "lib/
|
3
|
+
require_relative "lib/cli/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "rails-interactive"
|
7
|
-
spec.version = RailsInteractive::VERSION
|
7
|
+
spec.version = RailsInteractive::CLI::VERSION
|
8
8
|
spec.authors = ["Oguzhan Ince"]
|
9
9
|
spec.email = ["oguzhan824@gmail.com"]
|
10
10
|
|
@@ -29,9 +29,11 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency "bundler"
|
30
30
|
spec.add_development_dependency "byebug", "~> 11.1.2"
|
31
31
|
spec.add_development_dependency "colorize"
|
32
|
+
spec.add_development_dependency "pry"
|
32
33
|
spec.add_development_dependency "rake"
|
33
34
|
spec.add_development_dependency "rspec"
|
34
35
|
spec.add_development_dependency "rubocop"
|
36
|
+
spec.add_development_dependency "yaml"
|
35
37
|
|
36
38
|
spec.add_dependency "tty-prompt"
|
37
39
|
|