roda-project 0.1.6 → 0.1.7
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/lib/roda/project/bin/generator.rb +11 -0
- data/lib/roda/project/bin/generators/migration.rb +49 -0
- data/lib/roda/project/bin/generators/routes.rb +105 -0
- data/lib/roda/project/bin/generators.rb +36 -0
- data/lib/roda/project/cli.rb +15 -30
- data/lib/roda/project/generator.rb +19 -0
- data/lib/roda/project/helpers/ids.rb +34 -1
- data/lib/roda/project/helpers/{input.rb → interactive_input.rb} +14 -2
- data/lib/roda/project/helpers/template.rb +9 -5
- data/lib/roda/project/{context.rb → main_context.rb} +25 -10
- data/lib/roda/{templates → project/templates}/base/app/app.rb.erb +10 -7
- data/lib/roda/{templates → project/templates}/base/minimal/Gemfile.erb +1 -1
- data/lib/roda/{templates → project/templates}/base/minimal/app.rb +4 -1
- data/lib/roda/project/templates/base/minimal/bin/roda.erb +47 -0
- data/lib/roda/{templates → project/templates}/base/scaffold/Gemfile.erb +8 -7
- data/lib/roda/{templates → project/templates}/base/scaffold/app/config/config.rb.erb +2 -13
- data/lib/roda/project/templates/base/scaffold/bin/roda.erb +88 -0
- data/lib/roda/project/templates/front-end/app/views/layout.erb +23 -0
- data/lib/roda/{templates → project/templates}/front-end/esbuild.js +6 -6
- data/lib/roda/project/version.rb +2 -2
- data/lib/roda/project.rb +23 -12
- metadata +79 -62
- data/lib/roda/templates/base/minimal/Rakefile.erb +0 -51
- data/lib/roda/templates/base/scaffold/Rakefile.erb +0 -210
- data/lib/roda/templates/front-end/app/views/foo/html.rb +0 -6
- data/lib/roda/templates/front-end/app/views/html.rb +0 -38
- data/lib/roda/templates/front-end/app/views/layout.erb +0 -15
- /data/lib/roda/{templates → project/templates}/base/minimal/AGENTS.md +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/Gemfile.lock +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/Guardfile +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/README.md +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/boot.rb +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/config.ru +0 -0
- /data/lib/roda/{templates → project/templates}/base/minimal/public/exception_page.css +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/AGENTS.md +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/Guardfile +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/README.md +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/en.yml +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/foo/en.yml +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/foo/pt-br.yml +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/pt-br.yml +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/providers/logger.rb +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/providers/mailer.rb +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/app/routes/foo.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/boot.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/config.ru.erb +0 -0
- /data/lib/roda/{templates → project/templates}/base/scaffold/public/exception_page.css +0 -0
- /data/lib/roda/{templates → project/templates}/database/app/config/providers/db/conn.rb +0 -0
- /data/lib/roda/{templates → project/templates}/database/db/seeds.rb +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/app/assets/css/app.css +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/app/assets/js/app.js +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/app/assets/js/some/foo.js +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/app/views/foo/bar.erb +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/app/views/index.erb +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/package.json +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/public/assets/app.css +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/public/assets/app.js +0 -0
- /data/lib/roda/{templates → project/templates}/front-end/public/images/roda-project.png +0 -0
- /data/lib/roda/{templates → project/templates}/rodauth/app/models/account.rb +0 -0
- /data/lib/roda/{templates → project/templates}/rodauth/app/views/create-account.erb +0 -0
- /data/lib/roda/{templates → project/templates}/rodauth/db/migrations/001_add_rodauth.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minimal/minitest/spec/app_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minimal/minitest/spec/spec_helper.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minimal/rspec/spec/app_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minimal/rspec/spec/spec_helper.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/app_spec.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/routes/foo_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/routes/test_branch_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/views/html_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/minitest/spec/spec_helper.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/app_spec.rb.erb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/routes/foo_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/routes/test_branch_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/views/html_spec.rb +0 -0
- /data/lib/roda/{templates → project/templates}/tests/rspec/spec/spec_helper.rb.erb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 235c82e6d3bae7eebc1b331a1d74272222f3e5a6a0957536a68b4d766f82a34c
|
|
4
|
+
data.tar.gz: e8ee5c63d19ad043c2f0c55647b6534b6bc0186d2a92e67335ec9319e9a7c93a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d371e15403ffec2a67ff2577a2044d671334380af4188b3b2cd828ef61f181a48ba30e30d2640042c6d534d41e4fba9acaa5aa553e27d1e50de7946f054c2762
|
|
7
|
+
data.tar.gz: 9413055aab700d47ecf17442ab7e2fff22d6db8d0fb7a3a94e9237b16a2b718763a14453f1b1eb36230561068e9c66c10c556478ee3f46e909d8177241028034
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
class Roda
|
|
2
|
+
module Project
|
|
3
|
+
module Bin
|
|
4
|
+
class Generators < ::Thor
|
|
5
|
+
class Migration < Roda::Project::Bin::Generator
|
|
6
|
+
def call
|
|
7
|
+
if migration_name.nil? || migration_name.empty?
|
|
8
|
+
puts "Usage: bin/roda g migration your_migration_name"
|
|
9
|
+
exit 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
FileUtils.mkdir_p(migrations_path) unless File.directory?(migrations_path)
|
|
13
|
+
|
|
14
|
+
existing_migrations = Dir.glob(File.join(migrations_path, "*.rb"))
|
|
15
|
+
max_number = existing_migrations.map do |file|
|
|
16
|
+
File.basename(file).match(/^(\d+)/)&.captures&.first.to_i
|
|
17
|
+
end.max || 0
|
|
18
|
+
next_number = (max_number + 1).to_s.rjust(3, "0")
|
|
19
|
+
|
|
20
|
+
filename = File.join(migrations_path, "#{next_number}_#{migration_name}.rb")
|
|
21
|
+
|
|
22
|
+
content = <<~RUBY
|
|
23
|
+
Sequel.migration do
|
|
24
|
+
up do
|
|
25
|
+
# add your migration here
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
down do
|
|
29
|
+
# remove your migration here
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
RUBY
|
|
33
|
+
|
|
34
|
+
File.write(filename, content)
|
|
35
|
+
puts "* created migration: #{filename}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def migrations_path
|
|
39
|
+
"db/migrations"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def migration_name
|
|
43
|
+
@migration_name ||= @args[0]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
class Roda
|
|
2
|
+
module Project
|
|
3
|
+
module Bin
|
|
4
|
+
class Generators < ::Thor
|
|
5
|
+
class Routes < Roda::Project::Bin::Generator
|
|
6
|
+
def call
|
|
7
|
+
if branch_name.nil? || branch_name.empty? || routes_list.nil? || routes_list.empty?
|
|
8
|
+
puts "Usage: bin/roda g routes branch_name route1 route2:method"
|
|
9
|
+
exit 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
generate_routes
|
|
13
|
+
generate_views
|
|
14
|
+
generate_tests
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def generate_routes
|
|
20
|
+
filename = File.join(ensure_and_get_path("app/routes"), "#{branch_name}.rb")
|
|
21
|
+
route_definitions = routes_list.map do |route_str|
|
|
22
|
+
method, name = parse_route_string(route_str)
|
|
23
|
+
view_line = (method == "get" && must_generate_views?) ? "\n view('#{name}')" : ""
|
|
24
|
+
" r.#{method} \"#{name}\" do#{view_line}\n end"
|
|
25
|
+
end.join("\n\n")
|
|
26
|
+
|
|
27
|
+
content = <<~RUBY
|
|
28
|
+
class #{@context.const_project_name}
|
|
29
|
+
hash_branch "#{branch_name}" do |r|
|
|
30
|
+
#{route_definitions}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
RUBY
|
|
34
|
+
File.write(filename, content)
|
|
35
|
+
puts "* created routes file: #{filename}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def generate_views
|
|
39
|
+
if must_generate_views?
|
|
40
|
+
branch_views_dir = File.join("app/views", branch_name)
|
|
41
|
+
FileUtils.mkdir_p(branch_views_dir)
|
|
42
|
+
routes_list.each do |route_str|
|
|
43
|
+
method, name = parse_route_string(route_str)
|
|
44
|
+
if method == "get"
|
|
45
|
+
view_filename = File.join(branch_views_dir, "#{name}.erb")
|
|
46
|
+
File.write(view_filename, "")
|
|
47
|
+
puts "* created view file: #{view_filename}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def generate_tests
|
|
54
|
+
test_filename = File.join(ensure_and_get_path("spec/app/routes"), "#{branch_name}_spec.rb")
|
|
55
|
+
nesting_level = branch_name.count("/")
|
|
56
|
+
relative_spec_helper_path = "../" * (2 + nesting_level) + "spec_helper"
|
|
57
|
+
|
|
58
|
+
test_route_definitions = routes_list.map do |route_str|
|
|
59
|
+
method, name = parse_route_string(route_str)
|
|
60
|
+
" it \"responds to #{method.upcase} /#{branch_name}/#{name}\" do\n" \
|
|
61
|
+
" #{method} \"/#{branch_name}/#{name}\"\n" \
|
|
62
|
+
" expect(last_response.status).to eq(200)\n" \
|
|
63
|
+
" end"
|
|
64
|
+
end.join("\n")
|
|
65
|
+
|
|
66
|
+
test_content = <<~RUBY
|
|
67
|
+
require_relative "#{relative_spec_helper_path}"
|
|
68
|
+
|
|
69
|
+
describe "Routes for #{branch_name}" do
|
|
70
|
+
#{test_route_definitions}
|
|
71
|
+
end
|
|
72
|
+
RUBY
|
|
73
|
+
File.write(test_filename, test_content)
|
|
74
|
+
puts "* created test file: #{test_filename}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def must_generate_views?
|
|
78
|
+
@options[:views] && Dir.exist?("app/views")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def parse_route_string(route_str)
|
|
82
|
+
name, method = route_str.split(":", 2)
|
|
83
|
+
method ||= "get"
|
|
84
|
+
[method, name]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def ensure_and_get_path(path)
|
|
88
|
+
full_path_dir = File.join(path, File.dirname(branch_name))
|
|
89
|
+
FileUtils.mkdir_p(full_path_dir) unless File.directory?(full_path_dir)
|
|
90
|
+
|
|
91
|
+
path
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def routes_list
|
|
95
|
+
@routes_list ||= @args[1..-1]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def branch_name
|
|
99
|
+
@branch_name ||= @args[0]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require_relative "../../project"
|
|
2
|
+
|
|
3
|
+
class Roda
|
|
4
|
+
module Project
|
|
5
|
+
module Bin
|
|
6
|
+
class Generators < ::Thor
|
|
7
|
+
desc "migration", "Create a database migration"
|
|
8
|
+
def migration(*args)
|
|
9
|
+
Migration.new(context:, args:, options:).call
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "routes", "Create routes inside hash_branches, views and tests"
|
|
13
|
+
option :views, type: :boolean, default: true
|
|
14
|
+
def routes(*args)
|
|
15
|
+
Routes.new(context:, args:, options:).call
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def context
|
|
21
|
+
return @context if @context
|
|
22
|
+
|
|
23
|
+
@context = Roda::Project::MainContext.new
|
|
24
|
+
@context.project_name = options[:main_context][:project_name]
|
|
25
|
+
@context.base = options[:main_context][:base]
|
|
26
|
+
@context.database = options[:main_context][:database]
|
|
27
|
+
@context.database_type = options[:main_context][:database_type]
|
|
28
|
+
@context.rodauth = options[:main_context][:rodauth]
|
|
29
|
+
@context.tests = options[:main_context][:tests]
|
|
30
|
+
|
|
31
|
+
@context
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/roda/project/cli.rb
CHANGED
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class Roda
|
|
4
4
|
module Project
|
|
5
|
-
class CLI
|
|
6
|
-
include Helpers::
|
|
7
|
-
include Helpers::Input
|
|
8
|
-
include Helpers::Ids
|
|
9
|
-
|
|
10
|
-
def initialize(context: Context.new, pastel: Pastel.new, dir: nil)
|
|
11
|
-
@context = context
|
|
12
|
-
@pastel = pastel
|
|
13
|
-
@dir = dir
|
|
14
|
-
end
|
|
5
|
+
class CLI < Generator
|
|
6
|
+
include Helpers::InteractiveInput
|
|
15
7
|
|
|
16
8
|
def call
|
|
17
|
-
puts
|
|
18
|
-
puts
|
|
9
|
+
puts pastel.bright_black("[roda-project v#{Roda::Project::VERSION}]\n")
|
|
10
|
+
puts pastel.italic("#{Roda::Project.messages.sample.first}\n")
|
|
19
11
|
|
|
20
12
|
get_user_context
|
|
21
13
|
|
|
22
|
-
puts
|
|
14
|
+
puts pastel.bright_black("\n[project: #{@context.project_name}]\n")
|
|
23
15
|
|
|
24
16
|
create_base_project
|
|
25
17
|
add_front_end
|
|
@@ -34,15 +26,15 @@ module Roda
|
|
|
34
26
|
puts "\n* put your dev database credentials in app/config/config.rb\n"
|
|
35
27
|
end
|
|
36
28
|
puts "\nmigrate the database (use RACK_ENV to migrate 'test' or 'production' environments):\n\n"
|
|
37
|
-
puts "$
|
|
29
|
+
puts "$ bin/roda db migrate"
|
|
38
30
|
end
|
|
39
31
|
puts "\nrun and watch the project in dev mode:\n"
|
|
40
|
-
puts "\n$
|
|
32
|
+
puts "\n$ bin/roda dev"
|
|
41
33
|
if @context.fullstack?
|
|
42
34
|
puts "\ncompile and watch assets:\n"
|
|
43
|
-
puts "\n$
|
|
35
|
+
puts "\n$ bin/roda assets:dev"
|
|
44
36
|
end
|
|
45
|
-
puts "\nrun '
|
|
37
|
+
puts "\nrun 'bin/roda' inside #{@context.project_name} to see all available tasks\n\n"
|
|
46
38
|
rescue TTY::Reader::InputInterrupt
|
|
47
39
|
puts "\n\nGoodbye"
|
|
48
40
|
end
|
|
@@ -70,19 +62,11 @@ module Roda
|
|
|
70
62
|
end
|
|
71
63
|
end
|
|
72
64
|
|
|
73
|
-
def retry_on_error
|
|
74
|
-
yield
|
|
75
|
-
rescue Roda::Project::Context::InvalidValue => e
|
|
76
|
-
puts "\n #{@pastel.red(e.message)} \n\n"
|
|
77
|
-
|
|
78
|
-
yield
|
|
79
|
-
end
|
|
80
|
-
|
|
81
65
|
def create_base_project
|
|
82
66
|
puts "* creating base project"
|
|
83
67
|
if @context.minimal?
|
|
84
68
|
TTY::File.copy_directory(
|
|
85
|
-
File.expand_path("
|
|
69
|
+
File.expand_path("templates/base/minimal", __dir__),
|
|
86
70
|
"#{@dir}#{@context.project_name}",
|
|
87
71
|
context: @context
|
|
88
72
|
)
|
|
@@ -91,16 +75,18 @@ module Roda
|
|
|
91
75
|
end
|
|
92
76
|
|
|
93
77
|
TTY::File.copy_directory(
|
|
94
|
-
File.expand_path("
|
|
78
|
+
File.expand_path("templates/base/scaffold", __dir__),
|
|
95
79
|
"#{@dir}#{@context.project_name}",
|
|
96
80
|
context: @context
|
|
97
81
|
)
|
|
98
82
|
|
|
99
83
|
TTY::File.copy_file(
|
|
100
|
-
File.expand_path("
|
|
84
|
+
File.expand_path("templates/base/app/app.rb.erb", __dir__),
|
|
101
85
|
"#{@dir}#{@context.project_name}/app/#{@context.project_name}.rb",
|
|
102
86
|
context: @context
|
|
103
87
|
)
|
|
88
|
+
|
|
89
|
+
TTY::File.chmod("#{@dir}#{@context.project_name}/bin/roda", "+x")
|
|
104
90
|
end
|
|
105
91
|
|
|
106
92
|
def add_front_end
|
|
@@ -110,7 +96,6 @@ module Roda
|
|
|
110
96
|
erb_cp_file("front-end", "esbuild.js")
|
|
111
97
|
erb_cp_file("front-end", "package.json")
|
|
112
98
|
cp_dir("front-end", "app/views")
|
|
113
|
-
cp_dir("front-end", "app/views")
|
|
114
99
|
cp_dir("front-end", "public/assets")
|
|
115
100
|
cp_dir("front-end", "public/images")
|
|
116
101
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Roda
|
|
2
|
+
module Project
|
|
3
|
+
class Generator
|
|
4
|
+
include Helpers::Template
|
|
5
|
+
include Helpers::Ids
|
|
6
|
+
|
|
7
|
+
def initialize(context: MainContext.new, args: [], options: {}, dir: nil)
|
|
8
|
+
@context = context
|
|
9
|
+
@args = args
|
|
10
|
+
@options = options
|
|
11
|
+
@dir = dir
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
false
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class Roda
|
|
2
2
|
module Project
|
|
3
3
|
module Helpers
|
|
4
4
|
module Ids
|
|
@@ -10,6 +10,39 @@ module Roda
|
|
|
10
10
|
def postgresql_id = Roda::Project::POSTGRESQL
|
|
11
11
|
def rspec_id = Roda::Project::RSPEC
|
|
12
12
|
def minitest_id = Roda::Project::MINITEST
|
|
13
|
+
|
|
14
|
+
def id_to_string(id, type)
|
|
15
|
+
const =
|
|
16
|
+
case type
|
|
17
|
+
when :base
|
|
18
|
+
case id
|
|
19
|
+
when fullstack_id
|
|
20
|
+
"FULLSTACK"
|
|
21
|
+
when api_id
|
|
22
|
+
"API"
|
|
23
|
+
when minimal_id
|
|
24
|
+
"MINIMAL"
|
|
25
|
+
end
|
|
26
|
+
when :database
|
|
27
|
+
case id
|
|
28
|
+
when mysql_id
|
|
29
|
+
"MYSQL"
|
|
30
|
+
when sqlite_id
|
|
31
|
+
"SQLITE"
|
|
32
|
+
when postgresql_id
|
|
33
|
+
"POSTGRESQL"
|
|
34
|
+
end
|
|
35
|
+
when :tests
|
|
36
|
+
case id
|
|
37
|
+
when rspec_id
|
|
38
|
+
"RSPEC"
|
|
39
|
+
when minitest_id
|
|
40
|
+
"MINITEST"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
"Roda::Project::" << const
|
|
45
|
+
end
|
|
13
46
|
end
|
|
14
47
|
end
|
|
15
48
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
class Roda
|
|
2
2
|
module Project
|
|
3
3
|
module Helpers
|
|
4
|
-
module
|
|
4
|
+
module InteractiveInput
|
|
5
5
|
def read_line(prompt, default)
|
|
6
6
|
val = reader.read_line(prompt).chomp
|
|
7
7
|
return default if val == ""
|
|
@@ -14,6 +14,18 @@ module Roda
|
|
|
14
14
|
def reader
|
|
15
15
|
@reader ||= TTY::Reader.new
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
def retry_on_error
|
|
19
|
+
yield
|
|
20
|
+
rescue Roda::Project::Error => e
|
|
21
|
+
puts "\n #{pastel.red(e.message)} \n\n"
|
|
22
|
+
|
|
23
|
+
yield
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def pastel
|
|
27
|
+
@pastel ||= Pastel.new
|
|
28
|
+
end
|
|
17
29
|
end
|
|
18
30
|
end
|
|
19
31
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
class Roda
|
|
2
2
|
module Project
|
|
3
3
|
module Helpers
|
|
4
4
|
module Template
|
|
5
5
|
def erb_cp_dir(type, path)
|
|
6
6
|
TTY::File.copy_directory(
|
|
7
|
-
File.expand_path("
|
|
7
|
+
File.expand_path("#{templates_root}/#{type}/#{path}", __dir__),
|
|
8
8
|
"#{@dir}#{@context.project_name}/#{path}",
|
|
9
9
|
context: @context
|
|
10
10
|
)
|
|
@@ -12,7 +12,7 @@ module Roda
|
|
|
12
12
|
|
|
13
13
|
def erb_cp_file(type, path)
|
|
14
14
|
TTY::File.copy_file(
|
|
15
|
-
File.expand_path("
|
|
15
|
+
File.expand_path("#{templates_root}/#{type}/#{path}", __dir__),
|
|
16
16
|
"#{@dir}#{@context.project_name}/#{path}",
|
|
17
17
|
context: @context
|
|
18
18
|
)
|
|
@@ -21,7 +21,7 @@ module Roda
|
|
|
21
21
|
# For copy without parse ERB files
|
|
22
22
|
def cp_dir(type, path)
|
|
23
23
|
FileUtils.cp_r(
|
|
24
|
-
File.expand_path("
|
|
24
|
+
File.expand_path("#{templates_root}/#{type}/#{path}", __dir__),
|
|
25
25
|
"#{@dir}#{@context.project_name}/#{path}"
|
|
26
26
|
)
|
|
27
27
|
end
|
|
@@ -30,9 +30,13 @@ module Roda
|
|
|
30
30
|
def cp_file(type, path)
|
|
31
31
|
File.write(
|
|
32
32
|
"#{@dir}#{@context.project_name}/#{path}",
|
|
33
|
-
File.read(File.expand_path("
|
|
33
|
+
File.read(File.expand_path("#{templates_root}/#{type}/#{path}", __dir__))
|
|
34
34
|
)
|
|
35
35
|
end
|
|
36
|
+
|
|
37
|
+
def templates_root
|
|
38
|
+
@templates_root ||= "../templates"
|
|
39
|
+
end
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
42
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
class Roda
|
|
2
2
|
module Project
|
|
3
|
-
class
|
|
3
|
+
class MainContext
|
|
4
4
|
include Helpers::Ids
|
|
5
5
|
|
|
6
|
-
class InvalidValue <
|
|
6
|
+
class InvalidValue < Roda::Project::Error; end
|
|
7
7
|
VALID_PROJECT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9_]*$/
|
|
8
8
|
|
|
9
9
|
attr_reader(
|
|
@@ -11,15 +11,30 @@ module Roda
|
|
|
11
11
|
:rodauth,
|
|
12
12
|
:database,
|
|
13
13
|
:database_type,
|
|
14
|
-
:
|
|
14
|
+
:default_db_url,
|
|
15
15
|
:db_gem,
|
|
16
16
|
:project_name,
|
|
17
17
|
:base
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
+
def to_thor_option
|
|
21
|
+
option = <<~RUBY
|
|
22
|
+
option :main_context, type: :hash, default: {
|
|
23
|
+
project_name: "#{project_name}",
|
|
24
|
+
base: #{id_to_string(base, :base)},
|
|
25
|
+
rodauth: #{rodauth},
|
|
26
|
+
tests: #{id_to_string(tests, :tests)},
|
|
27
|
+
database: #{database},
|
|
28
|
+
RUBY
|
|
29
|
+
if database?
|
|
30
|
+
option << " database_type: #{id_to_string(database_type, :database)},"
|
|
31
|
+
end
|
|
32
|
+
option << "\n }"
|
|
33
|
+
end
|
|
34
|
+
|
|
20
35
|
def tests=(val)
|
|
21
36
|
if ![minitest_id, rspec_id].include?(val)
|
|
22
|
-
raise InvalidValue, "Invalid test framework option"
|
|
37
|
+
raise InvalidValue, "Invalid test framework option: #{val}"
|
|
23
38
|
end
|
|
24
39
|
|
|
25
40
|
@tests = val
|
|
@@ -27,7 +42,7 @@ module Roda
|
|
|
27
42
|
|
|
28
43
|
def base=(val)
|
|
29
44
|
if ![fullstack_id, api_id, minimal_id].include?(val)
|
|
30
|
-
raise InvalidValue, "Invalid project option"
|
|
45
|
+
raise InvalidValue, "Invalid project base option: #{val}"
|
|
31
46
|
end
|
|
32
47
|
|
|
33
48
|
@base = val
|
|
@@ -48,19 +63,19 @@ module Roda
|
|
|
48
63
|
# rubocop:disable Lint/InterpolationCheck
|
|
49
64
|
def database_type=(val)
|
|
50
65
|
if ![mysql_id, postgresql_id, sqlite_id].include?(val)
|
|
51
|
-
raise InvalidValue, "Invalid database option"
|
|
66
|
+
raise InvalidValue, "Invalid database type option: #{val}"
|
|
52
67
|
end
|
|
53
68
|
|
|
54
69
|
@database_type = val
|
|
55
70
|
|
|
56
71
|
if mysql?
|
|
57
|
-
@
|
|
72
|
+
@default_db_url = '"mysql2://user:password@localhost/app_#{environment}"'
|
|
58
73
|
@db_gem = "mysql2"
|
|
59
74
|
elsif postgresql?
|
|
60
|
-
@
|
|
75
|
+
@default_db_url = '"postgres://user:password@localhost:5432/app_#{environment}"'
|
|
61
76
|
@db_gem = "pg"
|
|
62
77
|
else
|
|
63
|
-
@
|
|
78
|
+
@default_db_url = '"sqlite://db/#{environment}.db"'
|
|
64
79
|
@db_gem = "sqlite3"
|
|
65
80
|
end
|
|
66
81
|
end
|
|
@@ -11,6 +11,7 @@ class <%= context.const_project_name %> < Roda
|
|
|
11
11
|
plugin :render, layout: "./layout"
|
|
12
12
|
plugin :content_for, append: false
|
|
13
13
|
plugin :flash
|
|
14
|
+
plugin :assets_manifest
|
|
14
15
|
<% end %>
|
|
15
16
|
# Request / Response
|
|
16
17
|
plugin :halt
|
|
@@ -37,8 +38,8 @@ class <%= context.const_project_name %> < Roda
|
|
|
37
38
|
# Other
|
|
38
39
|
plugin :common_logger, Providers::Logger.get
|
|
39
40
|
plugin :json_parser
|
|
40
|
-
plugin :sessions, secret: Config.get[:secret]
|
|
41
|
-
plugin :i18n, **Config.get[:i18n]
|
|
41
|
+
plugin :sessions, secret: Config.get[:secret]<% if context.fullstack? %>
|
|
42
|
+
plugin :i18n, **Config.get[:i18n]<% end %>
|
|
42
43
|
<% if context.rodauth? %><% if context.api? %>
|
|
43
44
|
# Authentication
|
|
44
45
|
plugin :rodauth, json: :only do
|
|
@@ -60,13 +61,12 @@ class <%= context.const_project_name %> < Roda
|
|
|
60
61
|
hmac_secret Config.get[:hmac_secret]
|
|
61
62
|
end
|
|
62
63
|
<% end %>
|
|
63
|
-
def config = @config ||= Config.get
|
|
64
|
-
def html = @html ||= Views::Html.new(t)<% end %>
|
|
64
|
+
def config = @config ||= Config.get
|
|
65
65
|
|
|
66
66
|
route do |r|
|
|
67
|
-
r.hash_branches
|
|
67
|
+
r.hash_branches<% if context.fullstack? %>
|
|
68
68
|
# session[:locale] = 'pt-br'
|
|
69
|
-
# r.i18n_set_locale_from(:session)
|
|
69
|
+
# r.i18n_set_locale_from(:session)<% end %>
|
|
70
70
|
<% if context.rodauth? %>
|
|
71
71
|
r.rodauth
|
|
72
72
|
rodauth.require_authentication
|
|
@@ -77,7 +77,10 @@ class <%= context.const_project_name %> < Roda
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
error do |e|
|
|
80
|
-
|
|
80
|
+
if Config.not_production?
|
|
81
|
+
puts e
|
|
82
|
+
next exception_page(e, css_file: "/public/exception_page.css")
|
|
83
|
+
end
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
not_found do
|
|
@@ -23,6 +23,7 @@ gem "oj"
|
|
|
23
23
|
gem "bcrypt"
|
|
24
24
|
|
|
25
25
|
group :development do
|
|
26
|
+
gem "thor"
|
|
26
27
|
gem "guard-puma"
|
|
27
28
|
gem "rack-test"
|
|
28
29
|
gem "debug"
|
|
@@ -30,7 +31,6 @@ group :development do
|
|
|
30
31
|
gem "standard"<% if context.minitest? %>
|
|
31
32
|
gem "minitest"
|
|
32
33
|
gem "minitest-hooks"
|
|
33
|
-
gem "rake"
|
|
34
34
|
<% else %>
|
|
35
35
|
gem "rspec"<% end %>
|
|
36
36
|
end
|
|
@@ -19,7 +19,10 @@ class App < Roda
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
error do |e|
|
|
22
|
-
|
|
22
|
+
if NOT_PRODUCTION
|
|
23
|
+
puts e
|
|
24
|
+
next exception_page(e, css_file: "/public/exception_page.css")
|
|
25
|
+
end
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
not_found do
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require "thor"
|
|
3
|
+
|
|
4
|
+
class CLI < Thor
|
|
5
|
+
desc "console", "Open a console with application context, alias: roda c"
|
|
6
|
+
def console
|
|
7
|
+
system("irb -r ./boot.rb")
|
|
8
|
+
end
|
|
9
|
+
map "c" => "console"
|
|
10
|
+
|
|
11
|
+
desc "lint", "Run lint"
|
|
12
|
+
option :fix, type: :boolean, aliases: "-w", desc: "Auto fix lint warnings"
|
|
13
|
+
def lint
|
|
14
|
+
if options[:fix]
|
|
15
|
+
system("bundle exec standardrb --fix")
|
|
16
|
+
else
|
|
17
|
+
system("bundle exec standardrb")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc "test", "Run tests"
|
|
22
|
+
def test<% if context.rspec? %>
|
|
23
|
+
system("RACK_ENV=test bundle exec rspec")<% else %>
|
|
24
|
+
system("RACK_ENV=test bundle exec minitest spec/")<% end %>
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc "dev", "Exec development server watching for changes"
|
|
28
|
+
def dev
|
|
29
|
+
system("RACK_ENV=development bundle exec guard")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
desc "server", "Runs the project, alias roda s"
|
|
33
|
+
def server
|
|
34
|
+
if ENV["RACK_ENV"] == "production"
|
|
35
|
+
if ENV["SESSION_SECRET"].nil?
|
|
36
|
+
puts("SESSION_SECRET is empty")
|
|
37
|
+
exit 1
|
|
38
|
+
end
|
|
39
|
+
system("RUBYOPT=--yjit RUBY_YJIT_ENABLE=1 RACK_ENV=production bundle exec puma --port 4000")
|
|
40
|
+
else
|
|
41
|
+
system("RACK_ENV=development bundle exec puma --port 4000")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
map "s" => "server"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
CLI.start(ARGV)
|