rails-new-app 0.0.3 → 0.1.0
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/.github/workflows/tests.yml +28 -0
- data/.gitignore +2 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +60 -0
- data/README.md +60 -20
- data/Rakefile +9 -0
- data/lib/rails-new-app.rb +1 -1
- data/lib/rails-new-app/processors/authentication_processor.rb +16 -0
- data/lib/rails-new-app/processors/authorization_processor.rb +18 -0
- data/lib/rails-new-app/runner.rb +97 -146
- data/lib/rails-new-app/screens.rb +8 -0
- data/lib/rails-new-app/screens/app_name_screen.rb +28 -0
- data/lib/rails-new-app/screens/auth_screen.rb +26 -0
- data/lib/rails-new-app/screens/authentication_screen.rb +27 -0
- data/lib/rails-new-app/screens/authorization_screen.rb +27 -0
- data/lib/rails-new-app/screens/choice_screen.rb +52 -0
- data/lib/rails-new-app/{steps/code_coverage_step.rb → screens/code_coverage_screen.rb} +3 -3
- data/lib/rails-new-app/{steps/database_step.rb → screens/database_screen.rb} +7 -5
- data/lib/rails-new-app/{steps/form_builder_step.rb → screens/form_builder_screen.rb} +2 -2
- data/lib/rails-new-app/{steps/java_script_framework_step.rb → screens/java_script_framework_screen.rb} +2 -2
- data/lib/rails-new-app/screens/menu_screen.rb +61 -0
- data/lib/rails-new-app/{steps/pagination_step.rb → screens/pagination_screen.rb} +2 -2
- data/lib/rails-new-app/screens/review_and_confirm_screen.rb +59 -0
- data/lib/rails-new-app/{steps/ruby_linter_step.rb → screens/ruby_linter_screen.rb} +2 -2
- data/lib/rails-new-app/screens/screen.rb +66 -0
- data/lib/rails-new-app/{steps/template_engine_step.rb → screens/template_engine_screen.rb} +2 -2
- data/lib/rails-new-app/{steps/test_factory_step.rb → screens/test_factory_screen.rb} +3 -3
- data/lib/rails-new-app/{steps/test_fake_data.rb → screens/test_fake_data_screen.rb} +3 -3
- data/lib/rails-new-app/{steps/test_runner_step.rb → screens/test_runner_screen.rb} +3 -3
- data/lib/rails-new-app/{steps/yes_no_choice_step.rb → screens/yes_no_choice_screen.rb} +1 -1
- data/lib/rails-new-app/templates/cancancan-config.rb +1 -0
- data/lib/rails-new-app/templates/cancancan-gemfile.rb +1 -0
- data/lib/rails-new-app/templates/devise-config.rb +1 -0
- data/lib/rails-new-app/templates/devise-gemfile.rb +1 -0
- data/lib/rails-new-app/templates/pagy-config.rb +1 -1
- data/lib/rails-new-app/templates/pundit-config.rb +7 -0
- data/lib/rails-new-app/templates/pundit-gemfile.rb +1 -0
- data/lib/rails-new-app/version.rb +1 -1
- metadata +34 -18
- data/lib/rails-new-app/steps.rb +0 -7
- data/lib/rails-new-app/steps/app_name_step.rb +0 -20
- data/lib/rails-new-app/steps/choice_step.rb +0 -45
- data/lib/rails-new-app/steps/rails_version_step.rb +0 -34
- data/lib/rails-new-app/steps/step.rb +0 -75
@@ -0,0 +1,8 @@
|
|
1
|
+
# require generic screens first
|
2
|
+
path = File.expand_path("../screens", __FILE__)
|
3
|
+
require "#{path}/screen"
|
4
|
+
require "#{path}/choice_screen"
|
5
|
+
require "#{path}/yes_no_choice_screen"
|
6
|
+
require "#{path}/menu_screen"
|
7
|
+
# require the rest
|
8
|
+
Dir.glob("#{path}/*").sort.each { |f| require f }
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class AppNameScreen < Screen
|
3
|
+
def screen_text
|
4
|
+
[].tap do |ls|
|
5
|
+
ls << "The selected name is invalid." if @error
|
6
|
+
ls << "Type the name of the app:"
|
7
|
+
end.join("\n")
|
8
|
+
end
|
9
|
+
|
10
|
+
def after_valid
|
11
|
+
puts "Your app is: #{@input}\n"
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?(input)
|
15
|
+
if /\A[a-z_]+\z/i.match?(input.strip)
|
16
|
+
@error = false
|
17
|
+
true
|
18
|
+
else
|
19
|
+
@error = true
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def next_step
|
25
|
+
@input != "" ? :menu : :rerender
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class AuthScreen < ChoiceScreen
|
3
|
+
def options
|
4
|
+
["Authentication", "Authorization"]
|
5
|
+
end
|
6
|
+
|
7
|
+
def step_question
|
8
|
+
"Type the option to go to a submenu:"
|
9
|
+
end
|
10
|
+
|
11
|
+
def return_value
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.default
|
16
|
+
{}
|
17
|
+
end
|
18
|
+
|
19
|
+
def next_step
|
20
|
+
case @input
|
21
|
+
when 1 then :authentication
|
22
|
+
when 2 then :authorization
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class AuthenticationScreen < ChoiceScreen
|
3
|
+
def step_question
|
4
|
+
"Type the option number of the Authentication gem to use:"
|
5
|
+
end
|
6
|
+
|
7
|
+
def options
|
8
|
+
["None", "Devise"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def lowercase_keys
|
12
|
+
["", "devise"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_valid
|
16
|
+
puts "Selected authentication gem is: #{option}\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.default
|
20
|
+
{
|
21
|
+
option_number: 1,
|
22
|
+
name: "None",
|
23
|
+
key: ""
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class AuthorizationScreen < ChoiceScreen
|
3
|
+
def step_question
|
4
|
+
"Type the option number of the Authorization gem to use:"
|
5
|
+
end
|
6
|
+
|
7
|
+
def options
|
8
|
+
["None", "Pundit", "Can Can Can"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def lowercase_keys
|
12
|
+
["", "pundit", "cancancan"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_valid
|
16
|
+
puts "Selected authorization gem is: #{option}\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.default
|
20
|
+
{
|
21
|
+
option_number: 1,
|
22
|
+
name: "None",
|
23
|
+
key: ""
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class ChoiceScreen < Screen
|
3
|
+
def options
|
4
|
+
[]
|
5
|
+
end
|
6
|
+
|
7
|
+
def option
|
8
|
+
options[@input - 1]
|
9
|
+
end
|
10
|
+
|
11
|
+
def screen_text
|
12
|
+
[].tap do |ls|
|
13
|
+
ls << @error if @error
|
14
|
+
ls << step_question
|
15
|
+
ls << ""
|
16
|
+
|
17
|
+
current = config[self.class.key] ? config[self.class.key][:option_number] : nil
|
18
|
+
options.each_with_index do |op, idx|
|
19
|
+
aux = idx + 1
|
20
|
+
is_current = aux == current ? " (current)" : ""
|
21
|
+
ls << "#{aux} ) #{op}#{is_current}"
|
22
|
+
end
|
23
|
+
ls << ""
|
24
|
+
ls << "0 ) Back to menu"
|
25
|
+
end.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def clean_input(input)
|
29
|
+
input.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?(input)
|
33
|
+
if options[input - 1]
|
34
|
+
@error = false
|
35
|
+
true
|
36
|
+
else
|
37
|
+
@error = "Invalid option, choose again:"
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def return_value
|
43
|
+
lower = lowercase_keys[@input - 1]
|
44
|
+
|
45
|
+
{
|
46
|
+
option_number: @input,
|
47
|
+
name: option,
|
48
|
+
key: lower
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class CodeCoverageScreen < ChoiceScreen
|
3
3
|
def step_question
|
4
4
|
warning =
|
5
5
|
if config[:test_runner][:key] == ""
|
@@ -24,8 +24,8 @@ module RailsNewApp
|
|
24
24
|
|
25
25
|
def self.default
|
26
26
|
{
|
27
|
-
option_number:
|
28
|
-
name: "None
|
27
|
+
option_number: 1,
|
28
|
+
name: "None",
|
29
29
|
key: ""
|
30
30
|
}
|
31
31
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class DatabaseScreen < ChoiceScreen
|
3
3
|
def rails_new_options
|
4
4
|
%W[mysql postgresql sqlite3 oracle sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc]
|
5
5
|
end
|
6
6
|
|
7
7
|
def options
|
8
|
-
["
|
8
|
+
["SQLite", "MySQL / MariaDB", "PostgreSQL"]
|
9
9
|
end
|
10
10
|
|
11
11
|
def lowercase_keys
|
12
|
-
["
|
12
|
+
["sqlite3", "mysql", "postgresql"]
|
13
13
|
end
|
14
14
|
|
15
15
|
def step_question
|
@@ -23,15 +23,17 @@ module RailsNewApp
|
|
23
23
|
def return_value
|
24
24
|
super.tap do |h|
|
25
25
|
h[:in_rails_new] = rails_new_options.include?(h[:key])
|
26
|
+
h[:is_default] = h[:key] == :sqlite3
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
30
|
def self.default
|
30
31
|
{
|
31
|
-
option_number:
|
32
|
+
option_number: 1,
|
32
33
|
name: "SQLite",
|
33
34
|
key: "sqlite3",
|
34
|
-
in_rails_new: true
|
35
|
+
in_rails_new: true,
|
36
|
+
is_default: true
|
35
37
|
}
|
36
38
|
end
|
37
39
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class FormBuilderScreen < ChoiceScreen
|
3
3
|
def step_question
|
4
4
|
"Type the option number of the Form Builder gem to use:"
|
5
5
|
end
|
@@ -18,7 +18,7 @@ module RailsNewApp
|
|
18
18
|
|
19
19
|
def self.default
|
20
20
|
{
|
21
|
-
option_number:
|
21
|
+
option_number: 1,
|
22
22
|
name: "None",
|
23
23
|
key: ""
|
24
24
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class JavaScriptFrameworkScreen < ChoiceScreen
|
3
3
|
def rails_new_options
|
4
4
|
%W[react vue angular elm stimulus]
|
5
5
|
end
|
@@ -28,7 +28,7 @@ module RailsNewApp
|
|
28
28
|
|
29
29
|
def self.default
|
30
30
|
{
|
31
|
-
option_number:
|
31
|
+
option_number: 1,
|
32
32
|
name: "None",
|
33
33
|
key: "",
|
34
34
|
in_rails_new: false
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class MenuScreen < Screen
|
3
|
+
def initialize(screens)
|
4
|
+
@screens = screens
|
5
|
+
@current_page = 1
|
6
|
+
end
|
7
|
+
|
8
|
+
def get_screen(option)
|
9
|
+
SCREENS.find { |x| x[:option] == option.to_s && x[:page] == @current_page }
|
10
|
+
end
|
11
|
+
|
12
|
+
def screen_text
|
13
|
+
[].tap do |ls|
|
14
|
+
@screens.each do |s|
|
15
|
+
next if s[:option].nil?
|
16
|
+
next if s[:page] != @current_page
|
17
|
+
|
18
|
+
screen_name = s[:class].clean_name
|
19
|
+
ls << "#{s[:option]} : #{screen_name}"
|
20
|
+
end
|
21
|
+
ls << ""
|
22
|
+
ls << "n : Next menu" if @current_page == 1
|
23
|
+
ls << "p : Previous menu" if @current_page == 2
|
24
|
+
ls << "0 : Review and confirm"
|
25
|
+
ls << ""
|
26
|
+
ls << "Type the number of the menu and press enter:"
|
27
|
+
end.join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid?(input)
|
31
|
+
case input
|
32
|
+
when "0" then true
|
33
|
+
when "n" then @current_page == 1
|
34
|
+
when "p" then @current_page == 2
|
35
|
+
when /\A\d\z/ then get_screen(input)
|
36
|
+
else false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def go_to_next_page
|
41
|
+
@current_page += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
def go_to_previous_page
|
45
|
+
@current_page -= 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def next_step
|
49
|
+
case @input
|
50
|
+
when "0" then :review_and_confirm
|
51
|
+
when "n"
|
52
|
+
go_to_next_page
|
53
|
+
:rerender
|
54
|
+
when "p"
|
55
|
+
go_to_previous_page
|
56
|
+
:rerender
|
57
|
+
else get_screen(@input)[:class].key
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class PaginationScreen < ChoiceScreen
|
3
3
|
def step_question
|
4
4
|
"Type the option number of the Pagination gem to use:"
|
5
5
|
end
|
@@ -18,7 +18,7 @@ module RailsNewApp
|
|
18
18
|
|
19
19
|
def self.default
|
20
20
|
{
|
21
|
-
option_number:
|
21
|
+
option_number: 1,
|
22
22
|
name: "None",
|
23
23
|
key: ""
|
24
24
|
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class ReviewAndConfirmScreen < Screen
|
3
|
+
def screen_text
|
4
|
+
[].tap do |ls|
|
5
|
+
ls << <<~REVIEW
|
6
|
+
===== New Rails app config =====
|
7
|
+
|
8
|
+
App name: #{config[:app_name]}
|
9
|
+
Ruby version: #{RUBY_VERSION}
|
10
|
+
Database: #{config[:database]}
|
11
|
+
Test runner: #{config[:test_runner]}
|
12
|
+
Code coverage: #{config[:code_coverage]}
|
13
|
+
Test factories: #{config[:test_factory]}
|
14
|
+
Test fake data: #{config[:test_fake_data]}
|
15
|
+
JS framework: #{config[:java_script_framework]}
|
16
|
+
Ruby Linter: #{config[:ruby_linter]}
|
17
|
+
Template engine: #{config[:template_engine]}
|
18
|
+
Form builder: #{config[:form_builder]}
|
19
|
+
Pagination: #{config[:pagination]}
|
20
|
+
Authorization: #{config[:authorization]}
|
21
|
+
Authentication: #{config[:authentication]}
|
22
|
+
|
23
|
+
REVIEW
|
24
|
+
|
25
|
+
message = "Type 'Y(es)' to confirm, 'B(ack) to go back, or 'N(o)' to abort"
|
26
|
+
if config[:app_name] == ""
|
27
|
+
ls << <<~WARNING
|
28
|
+
=====================================
|
29
|
+
App name is required
|
30
|
+
=====================================
|
31
|
+
|
32
|
+
WARNING
|
33
|
+
message.gsub!("Type 'Y(es)' to confirm, ", "Type ")
|
34
|
+
end
|
35
|
+
|
36
|
+
ls << message
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def valid?(input)
|
41
|
+
if /\A*Y(es)?\z|\A*B(ack)?\z|\A*N(o)?\z/i.match?(input)
|
42
|
+
@error = false
|
43
|
+
true
|
44
|
+
else
|
45
|
+
@error = "Invalid option"
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def next_step
|
51
|
+
case @input
|
52
|
+
when /\A*B(ack)?\z/i then :menu
|
53
|
+
when /\A*Y(es)?\z/i then :finish
|
54
|
+
when /\A*N(o)?\z/i then :abort
|
55
|
+
else :rerender
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RailsNewApp
|
2
|
-
class
|
2
|
+
class RubyLinterScreen < ChoiceScreen
|
3
3
|
def step_question
|
4
4
|
"Type the option number of the Ruby Linter gem to use:"
|
5
5
|
end
|
@@ -18,7 +18,7 @@ module RailsNewApp
|
|
18
18
|
|
19
19
|
def self.default
|
20
20
|
{
|
21
|
-
option_number:
|
21
|
+
option_number: 1,
|
22
22
|
name: "None",
|
23
23
|
key: ""
|
24
24
|
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module RailsNewApp
|
2
|
+
class Screen
|
3
|
+
attr_reader :config
|
4
|
+
|
5
|
+
def initialize(config)
|
6
|
+
@config = config
|
7
|
+
@input = ""
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.clean_name
|
11
|
+
to_s.gsub("Screen", "").gsub("RailsNewApp::", "")
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.key
|
15
|
+
clean_name.underscore.to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
def screen_text
|
19
|
+
raise "screen text must be re-defined"
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_user_input(input)
|
23
|
+
if validate_user_input(input)
|
24
|
+
[next_step, return_value]
|
25
|
+
else
|
26
|
+
[:rerender, nil]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_user_input(input)
|
31
|
+
input = clean_input(input)
|
32
|
+
if valid?(input)
|
33
|
+
@input = input
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# clean the input if needed before validations
|
39
|
+
def clean_input(input)
|
40
|
+
input.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
# validate the input
|
44
|
+
def valid?(input)
|
45
|
+
@error = false
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
# after valid message
|
50
|
+
def after_valid
|
51
|
+
end
|
52
|
+
|
53
|
+
# process @input to return a different value
|
54
|
+
def return_value
|
55
|
+
@input
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.default
|
59
|
+
""
|
60
|
+
end
|
61
|
+
|
62
|
+
def next_step
|
63
|
+
:menu
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|