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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/lib/roda/project/bin/generator.rb +11 -0
  3. data/lib/roda/project/bin/generators/migration.rb +49 -0
  4. data/lib/roda/project/bin/generators/routes.rb +105 -0
  5. data/lib/roda/project/bin/generators.rb +36 -0
  6. data/lib/roda/project/cli.rb +15 -30
  7. data/lib/roda/project/generator.rb +19 -0
  8. data/lib/roda/project/helpers/ids.rb +34 -1
  9. data/lib/roda/project/helpers/{input.rb → interactive_input.rb} +14 -2
  10. data/lib/roda/project/helpers/template.rb +9 -5
  11. data/lib/roda/project/{context.rb → main_context.rb} +25 -10
  12. data/lib/roda/{templates → project/templates}/base/app/app.rb.erb +10 -7
  13. data/lib/roda/{templates → project/templates}/base/minimal/Gemfile.erb +1 -1
  14. data/lib/roda/{templates → project/templates}/base/minimal/app.rb +4 -1
  15. data/lib/roda/project/templates/base/minimal/bin/roda.erb +47 -0
  16. data/lib/roda/{templates → project/templates}/base/scaffold/Gemfile.erb +8 -7
  17. data/lib/roda/{templates → project/templates}/base/scaffold/app/config/config.rb.erb +2 -13
  18. data/lib/roda/project/templates/base/scaffold/bin/roda.erb +88 -0
  19. data/lib/roda/project/templates/front-end/app/views/layout.erb +23 -0
  20. data/lib/roda/{templates → project/templates}/front-end/esbuild.js +6 -6
  21. data/lib/roda/project/version.rb +2 -2
  22. data/lib/roda/project.rb +23 -12
  23. metadata +79 -62
  24. data/lib/roda/templates/base/minimal/Rakefile.erb +0 -51
  25. data/lib/roda/templates/base/scaffold/Rakefile.erb +0 -210
  26. data/lib/roda/templates/front-end/app/views/foo/html.rb +0 -6
  27. data/lib/roda/templates/front-end/app/views/html.rb +0 -38
  28. data/lib/roda/templates/front-end/app/views/layout.erb +0 -15
  29. /data/lib/roda/{templates → project/templates}/base/minimal/AGENTS.md +0 -0
  30. /data/lib/roda/{templates → project/templates}/base/minimal/Gemfile.lock +0 -0
  31. /data/lib/roda/{templates → project/templates}/base/minimal/Guardfile +0 -0
  32. /data/lib/roda/{templates → project/templates}/base/minimal/README.md +0 -0
  33. /data/lib/roda/{templates → project/templates}/base/minimal/boot.rb +0 -0
  34. /data/lib/roda/{templates → project/templates}/base/minimal/config.ru +0 -0
  35. /data/lib/roda/{templates → project/templates}/base/minimal/public/exception_page.css +0 -0
  36. /data/lib/roda/{templates → project/templates}/base/scaffold/AGENTS.md +0 -0
  37. /data/lib/roda/{templates → project/templates}/base/scaffold/Guardfile +0 -0
  38. /data/lib/roda/{templates → project/templates}/base/scaffold/README.md +0 -0
  39. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/en.yml +0 -0
  40. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/foo/en.yml +0 -0
  41. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/foo/pt-br.yml +0 -0
  42. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/locales/pt-br.yml +0 -0
  43. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/providers/logger.rb +0 -0
  44. /data/lib/roda/{templates → project/templates}/base/scaffold/app/config/providers/mailer.rb +0 -0
  45. /data/lib/roda/{templates → project/templates}/base/scaffold/app/routes/foo.rb.erb +0 -0
  46. /data/lib/roda/{templates → project/templates}/base/scaffold/boot.rb.erb +0 -0
  47. /data/lib/roda/{templates → project/templates}/base/scaffold/config.ru.erb +0 -0
  48. /data/lib/roda/{templates → project/templates}/base/scaffold/public/exception_page.css +0 -0
  49. /data/lib/roda/{templates → project/templates}/database/app/config/providers/db/conn.rb +0 -0
  50. /data/lib/roda/{templates → project/templates}/database/db/seeds.rb +0 -0
  51. /data/lib/roda/{templates → project/templates}/front-end/app/assets/css/app.css +0 -0
  52. /data/lib/roda/{templates → project/templates}/front-end/app/assets/js/app.js +0 -0
  53. /data/lib/roda/{templates → project/templates}/front-end/app/assets/js/some/foo.js +0 -0
  54. /data/lib/roda/{templates → project/templates}/front-end/app/views/foo/bar.erb +0 -0
  55. /data/lib/roda/{templates → project/templates}/front-end/app/views/index.erb +0 -0
  56. /data/lib/roda/{templates → project/templates}/front-end/package.json +0 -0
  57. /data/lib/roda/{templates → project/templates}/front-end/public/assets/app.css +0 -0
  58. /data/lib/roda/{templates → project/templates}/front-end/public/assets/app.js +0 -0
  59. /data/lib/roda/{templates → project/templates}/front-end/public/images/roda-project.png +0 -0
  60. /data/lib/roda/{templates → project/templates}/rodauth/app/models/account.rb +0 -0
  61. /data/lib/roda/{templates → project/templates}/rodauth/app/views/create-account.erb +0 -0
  62. /data/lib/roda/{templates → project/templates}/rodauth/db/migrations/001_add_rodauth.rb +0 -0
  63. /data/lib/roda/{templates → project/templates}/tests/minimal/minitest/spec/app_spec.rb +0 -0
  64. /data/lib/roda/{templates → project/templates}/tests/minimal/minitest/spec/spec_helper.rb.erb +0 -0
  65. /data/lib/roda/{templates → project/templates}/tests/minimal/rspec/spec/app_spec.rb +0 -0
  66. /data/lib/roda/{templates → project/templates}/tests/minimal/rspec/spec/spec_helper.rb +0 -0
  67. /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/app_spec.rb.erb +0 -0
  68. /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/routes/foo_spec.rb +0 -0
  69. /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/routes/test_branch_spec.rb +0 -0
  70. /data/lib/roda/{templates → project/templates}/tests/minitest/spec/app/views/html_spec.rb +0 -0
  71. /data/lib/roda/{templates → project/templates}/tests/minitest/spec/spec_helper.rb.erb +0 -0
  72. /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/app_spec.rb.erb +0 -0
  73. /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/routes/foo_spec.rb +0 -0
  74. /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/routes/test_branch_spec.rb +0 -0
  75. /data/lib/roda/{templates → project/templates}/tests/rspec/spec/app/views/html_spec.rb +0 -0
  76. /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: a0848c0ffefb79c9a29e0f914ade9409ed3da6f94523afa9fd686647eb49c401
4
- data.tar.gz: 9a100a0a6781bdd0c9d0a005f473db621f4f28749e95523186bddf338b0acd10
3
+ metadata.gz: 235c82e6d3bae7eebc1b331a1d74272222f3e5a6a0957536a68b4d766f82a34c
4
+ data.tar.gz: e8ee5c63d19ad043c2f0c55647b6534b6bc0186d2a92e67335ec9319e9a7c93a
5
5
  SHA512:
6
- metadata.gz: 883ecbdc87121a984469a003ab1f2350ef3aa998bdda14efb6443d151b9378adf56f0704b66eb40c8e9765d193a2b3fdce521fc3cae4b3faf0de0039a8822136
7
- data.tar.gz: 06b3aeba438bb755926afff42b68a66303f42332c97fcb9bca23f96e47399a16cda090e42d6835837ee091bcefb135d6f5f2a6ba54d2070164616be113e4e3be
6
+ metadata.gz: d371e15403ffec2a67ff2577a2044d671334380af4188b3b2cd828ef61f181a48ba30e30d2640042c6d534d41e4fba9acaa5aa553e27d1e50de7946f054c2762
7
+ data.tar.gz: 9413055aab700d47ecf17442ab7e2fff22d6db8d0fb7a3a94e9237b16a2b718763a14453f1b1eb36230561068e9c66c10c556478ee3f46e909d8177241028034
@@ -0,0 +1,11 @@
1
+ class Roda
2
+ module Project
3
+ module Bin
4
+ class Generator < Roda::Project::Generator
5
+ def templates_root
6
+ @templates_root ||= "../bin/generators/templates"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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
@@ -1,25 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Roda
3
+ class Roda
4
4
  module Project
5
- class CLI
6
- include Helpers::Template
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 @pastel.bright_black("[roda-project v#{Roda::Project::VERSION}]\n")
18
- puts @pastel.italic("#{Roda::Project.messages.sample.first}\n")
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 @pastel.bright_black("\n[project: #{@context.project_name}]\n")
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 "$ rake db:migrate"
29
+ puts "$ bin/roda db migrate"
38
30
  end
39
31
  puts "\nrun and watch the project in dev mode:\n"
40
- puts "\n$ rake dev"
32
+ puts "\n$ bin/roda dev"
41
33
  if @context.fullstack?
42
34
  puts "\ncompile and watch assets:\n"
43
- puts "\n$ rake dev:assets"
35
+ puts "\n$ bin/roda assets:dev"
44
36
  end
45
- puts "\nrun 'rake' inside #{@context.project_name} to see all available tasks\n\n"
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("../templates/base/minimal", __dir__),
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("../templates/base/scaffold", __dir__),
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("../templates/base/app/app.rb.erb", __dir__),
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
- module Roda
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
- module Roda
1
+ class Roda
2
2
  module Project
3
3
  module Helpers
4
- module Input
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
- module Roda
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("../../templates/#{type}/#{path}", __dir__),
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("../../templates/#{type}/#{path}", __dir__),
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("../../templates/#{type}/#{path}", __dir__),
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("../../templates/#{type}/#{path}", __dir__))
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
- module Roda
1
+ class Roda
2
2
  module Project
3
- class Context
3
+ class MainContext
4
4
  include Helpers::Ids
5
5
 
6
- class InvalidValue < StandardError; end
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
- :dev_db_url,
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
- @dev_db_url = '"mysql2://user:password@localhost/app_#{environment}"'
72
+ @default_db_url = '"mysql2://user:password@localhost/app_#{environment}"'
58
73
  @db_gem = "mysql2"
59
74
  elsif postgresql?
60
- @dev_db_url = '"postgres://user:password@localhost:5432/app_#{environment}"'
75
+ @default_db_url = '"postgres://user:password@localhost:5432/app_#{environment}"'
61
76
  @db_gem = "pg"
62
77
  else
63
- @dev_db_url = '"sqlite://db/#{environment}.db"'
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<% if context.fullstack? %>
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
- next exception_page(e, css_file: "/public/exception_page.css") if Config.not_production?
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
- next exception_page(e, css_file: "/public/exception_page.css") if NOT_PRODUCTION
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)