dry-web-roda 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -1
  3. data/README.md +15 -1
  4. data/bin/dry-web-roda +6 -0
  5. data/dry-web-roda.gemspec +2 -0
  6. data/lib/dry/web/roda/cli/generate.rb +18 -0
  7. data/lib/dry/web/roda/cli.rb +19 -0
  8. data/lib/dry/web/roda/generate.rb +54 -0
  9. data/lib/dry/web/roda/generators/app.rb +36 -0
  10. data/lib/dry/web/roda/generators/umbrella.rb +38 -0
  11. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/application.rb.tt +33 -0
  12. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/container.rb.tt +19 -0
  13. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/import.rb.tt +5 -0
  14. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/page.rb.tt +6 -0
  15. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/transactions.rb.tt +12 -0
  16. data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/view.rb.tt +19 -0
  17. data/lib/dry/web/roda/skeletons/app/component/boot.rb.tt +10 -0
  18. data/lib/dry/web/roda/skeletons/app/lib/__underscored_app_name__/.keep +0 -0
  19. data/lib/dry/web/roda/skeletons/app/transactions/example.rb.tt +9 -0
  20. data/lib/dry/web/roda/skeletons/app/web/routes/example.rb.tt +7 -0
  21. data/lib/dry/web/roda/skeletons/app/web/templates/layouts/application.html.slim +3 -0
  22. data/lib/dry/web/roda/skeletons/umbrella/.gitignore +5 -0
  23. data/lib/dry/web/roda/skeletons/umbrella/Gemfile +39 -0
  24. data/lib/dry/web/roda/skeletons/umbrella/README.md.tt +12 -0
  25. data/lib/dry/web/roda/skeletons/umbrella/Rakefile.tt +81 -0
  26. data/lib/dry/web/roda/skeletons/umbrella/bin/console.tt +7 -0
  27. data/lib/dry/web/roda/skeletons/umbrella/bin/setup +7 -0
  28. data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/application.rb.tt +7 -0
  29. data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/container.rb.tt +17 -0
  30. data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/import.rb.tt +5 -0
  31. data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/settings.rb.tt +17 -0
  32. data/lib/dry/web/roda/skeletons/umbrella/component/boot/logger.rb.tt +5 -0
  33. data/lib/dry/web/roda/skeletons/umbrella/component/boot/rom.rb.tt +16 -0
  34. data/lib/dry/web/roda/skeletons/umbrella/component/boot.rb.tt +12 -0
  35. data/lib/dry/web/roda/skeletons/umbrella/config/settings.yml.tt +8 -0
  36. data/lib/dry/web/roda/skeletons/umbrella/config.ru.tt +2 -0
  37. data/lib/dry/web/roda/skeletons/umbrella/db/sample_data.rb +1 -0
  38. data/lib/dry/web/roda/skeletons/umbrella/db/seed.rb +1 -0
  39. data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/page.rb.tt +48 -0
  40. data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/repository.rb.tt +11 -0
  41. data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/transactions.rb.tt +33 -0
  42. data/lib/dry/web/roda/skeletons/umbrella/lib/persistence/commands/.keep +0 -0
  43. data/lib/dry/web/roda/skeletons/umbrella/lib/persistence/relations/.keep +0 -0
  44. data/lib/dry/web/roda/skeletons/umbrella/lib/roda_plugins.rb +34 -0
  45. data/lib/dry/web/roda/skeletons/umbrella/lib/types.rb +5 -0
  46. data/lib/dry/web/roda/skeletons/umbrella/log/.keep +0 -0
  47. data/lib/dry/web/roda/skeletons/umbrella/spec/app_helper.rb +35 -0
  48. data/lib/dry/web/roda/skeletons/umbrella/spec/db_helper.rb.tt +24 -0
  49. data/lib/dry/web/roda/skeletons/umbrella/spec/spec_helper.rb.tt +66 -0
  50. data/lib/dry/web/roda/skeletons/umbrella/spec/support/db/test_factories.rb +3 -0
  51. data/lib/dry/web/roda/skeletons/umbrella/spec/support/test_helpers.rb.tt +15 -0
  52. data/lib/dry/web/roda/version.rb +1 -1
  53. data/spec/dummy/apps/main/{core → component}/boot.rb +0 -0
  54. data/spec/dummy/apps/main/{core → component}/main/application.rb +0 -0
  55. data/spec/dummy/apps/main/{core → component}/main/container.rb +1 -0
  56. data/spec/dummy/apps/main/{core → component}/main/import.rb +0 -0
  57. data/spec/dummy/apps/main/{core → component}/main/requests.rb +0 -0
  58. data/spec/dummy/apps/main/{core → component}/main/view.rb +0 -0
  59. data/spec/dummy/bin/console +1 -1
  60. data/spec/dummy/{core → component}/boot.rb +1 -1
  61. data/spec/dummy/{core → component}/dummy/application.rb +0 -0
  62. data/spec/dummy/{core → component}/dummy/container.rb +1 -0
  63. data/spec/dummy/config.ru +1 -1
  64. data/spec/spec_helper.rb +1 -1
  65. metadata +97 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 726ea7f39f9d491d5e7681d9842ea0b0d466eb4f
4
- data.tar.gz: 288314be9441cb36682f5c863634013e5565fcc9
3
+ metadata.gz: 02425c79e7cb73bc2c6ba4828c849613926f4bd6
4
+ data.tar.gz: 45b4248b401fb991c9d9d6eee49379486c5a24d5
5
5
  SHA512:
6
- metadata.gz: 219b11b37b13bc7116425604ef6e98a9bf44e98c7e0e2ca362636cb4c880ecce42fec9fbd61a282d9b60563620cbba7b025f7d4fb0aeacff6b27a76359f47875
7
- data.tar.gz: dfd793d774f1528e0c3a8983c0f6d51dff8df1b133738a3644883323c4482970270d634cfe1889b4042c12c0fb1e5bcb6803b97f624db4e20a29fb1ef89a4d40
6
+ metadata.gz: 31397fe8d8dfcf700a5d567ff522addacc68f6e2c64b2b538c06848fdfb30a8e1fc0813c5c9dd55a9c4181dc33fb946aa5167956d776a0beb9e0e2de43eef110
7
+ data.tar.gz: 82928af236cdc3916ee453b91de9d4446c59ad9e5f0470e08266ca9473d0eaab06a15dd9fb02ed943971c0d377ac91313072cda8ef7a150a45a217c936f33024
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
- # 0.1.0, 2016-06-12
1
+ # 0.2.0 / 2016-06-22
2
+
3
+ ### Added
4
+
5
+ - Added a `dry-web-roda` executable CLI command, which can generate new dry-web-roda projects and apps within projects (timriley)
6
+
7
+ To generate a new project:
8
+
9
+ ```sh
10
+ dry-web-roda new my_new_project
11
+ ```
12
+
13
+ And to generate a new app within an existing project:
14
+
15
+ ```sh
16
+ dry-web-roda generate app my_sub_app --umbrella=my_new_project
17
+ ```
18
+ - Added the beginnings of a skeleton-based code generator, to support the above (timriley)
19
+
20
+ # 0.1.0 / 2016-06-12
2
21
 
3
22
  - Extracted from dry-web (timriley)
data/README.md CHANGED
@@ -1,9 +1,23 @@
1
1
  # dry-web-roda [![Join the chat at https://gitter.im/dry-rb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dry-rb/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2
2
 
3
+ Integration between dry-web and roda.
4
+
5
+ dry-web-roda offers a CLI for generating new projects:
6
+
7
+ ```sh
8
+ $ dry-web-roda new <project_name>
9
+ ```
10
+
11
+ And building apps within projects:
12
+
13
+ ```sh
14
+ $ dry-web-roda generate app <my_sub_app_name>
15
+ ```
16
+
3
17
  ## LICENSE
4
18
 
5
19
  See `LICENSE` file.
6
20
 
7
21
  ## Contributing
8
22
 
9
- Bug reports and pull requests are welcome on GitHub at https://github.com/dry-rb/dry-web.
23
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dry-rb/dry-web-roda.
data/bin/dry-web-roda ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dry/web/roda/cli"
5
+
6
+ Dry::Web::Roda::CLI.start ARGV
data/dry-web-roda.gemspec CHANGED
@@ -18,8 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ["lib"]
19
19
 
20
20
  spec.add_runtime_dependency "dry-configurable", "~> 0.1"
21
+ spec.add_runtime_dependency "inflecto", "~> 0.0"
21
22
  spec.add_runtime_dependency "roda", "~> 2.14"
22
23
  spec.add_runtime_dependency "roda-flow", "~> 0.3"
24
+ spec.add_runtime_dependency "thor", "~> 0.19"
23
25
 
24
26
  spec.add_development_dependency "bundler", "~> 1.7"
25
27
  spec.add_development_dependency "rake", "~> 11.0"
@@ -0,0 +1,18 @@
1
+ require "thor"
2
+
3
+ module Dry
4
+ module Web
5
+ module Roda
6
+ class CLI
7
+ class Generate < Thor
8
+ desc "generate app APP", "Generate an app within a dry-web umbrella"
9
+ option :umbrella, required: true, banner: "UMBRELLA_NAME", desc: "Provide the name of the umbrella app, e.g. my_project"
10
+ def app(app_name)
11
+ require "dry/web/roda/generators/app"
12
+ Dry::Web::Roda::Generators::App.new.(app_name, umbrella: options[:umbrella])
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require "thor"
2
+
3
+ module Dry
4
+ module Web
5
+ module Roda
6
+ class CLI < Thor
7
+ desc "new APP", "Generate a new dry-web-roda project"
8
+ def new(app_name)
9
+ require "dry/web/roda/generators/umbrella"
10
+ Generators::Umbrella.new.(app_name)
11
+ end
12
+
13
+ desc "generate GENERATOR", "Generate a new component for an existing dry-web-roda project"
14
+ require "dry/web/roda/cli/generate"
15
+ subcommand "generate", CLI::Generate
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,54 @@
1
+ require "pathname"
2
+ require "thor"
3
+
4
+ module Dry
5
+ module Web
6
+ module Roda
7
+ class Generate
8
+ SKELETONS_DIR = "skeletons".freeze
9
+
10
+ attr_reader :source_dir
11
+ attr_reader :processor
12
+
13
+ def initialize(skeleton_name)
14
+ @source_dir = Pathname(__FILE__).dirname.join(SKELETONS_DIR).join(skeleton_name)
15
+
16
+ @processor = Class.new(Thor) do
17
+ include Thor::Actions
18
+ end.new
19
+ @processor.class.source_root source_dir
20
+ end
21
+
22
+ def call(target_dir, scope = {})
23
+ target_dir = Pathname.getwd + target_dir
24
+ source_files = Dir[source_dir.join("**/{.,}*")]
25
+
26
+ source_files.select { |f| File.file?(f) }.each do |source_file|
27
+ source_file = Pathname(source_file)
28
+ relative_source_file = source_file.relative_path_from(source_dir)
29
+ target_file = target_dir + relative_source_file
30
+
31
+ if scope.any?
32
+ target_file = target_file.to_s.gsub(/__#{Regexp.union(scope.keys.map(&:to_s))}__/) { |match|
33
+ scope_key = match.gsub(/^__/, "").gsub(/__$/, "")
34
+ scope.fetch(scope_key.to_sym)
35
+ }
36
+ end
37
+
38
+ if relative_source_file.extname == Thor::TEMPLATE_EXTNAME
39
+ target_file = target_file.sub(/#{Thor::TEMPLATE_EXTNAME}$/, "")
40
+
41
+ processor.template relative_source_file, target_file, scope
42
+ else
43
+ processor.copy_file relative_source_file, target_file
44
+ end
45
+
46
+ if source_file.file? && source_file.executable?
47
+ FileUtils.chmod "a+x", target_file
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,36 @@
1
+ require "inflecto"
2
+ require "dry/web/roda/generate"
3
+
4
+ module Dry
5
+ module Web
6
+ module Roda
7
+ module Generators
8
+ class App
9
+ attr_reader :generate
10
+
11
+ def initialize
12
+ @generate = Dry::Web::Roda::Generate.new("app")
13
+ end
14
+
15
+ def call(target_dir, options = {})
16
+ umbrella_name = options.fetch(:umbrella)
17
+ generate_to = options.fetch(:to) { File.join("apps", target_dir) }
18
+
19
+ generate.(generate_to, prepare_scope(target_dir, umbrella_name))
20
+ end
21
+
22
+ private
23
+
24
+ def prepare_scope(target_dir, umbrella_name)
25
+ {
26
+ underscored_app_name: Inflecto.underscore(target_dir),
27
+ camel_cased_app_name: Inflecto.camelize(target_dir),
28
+ underscored_umbrella_name: Inflecto.underscore(umbrella_name),
29
+ camel_cased_umbrella_name: Inflecto.camelize(umbrella_name),
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require "inflecto"
2
+ require "securerandom"
3
+ require "dry/web/roda/generate"
4
+ require "dry/web/roda/generators/app"
5
+
6
+ module Dry
7
+ module Web
8
+ module Roda
9
+ module Generators
10
+ class Umbrella
11
+ attr_reader :generate, :app_generator
12
+
13
+ def initialize
14
+ @generate = Generate.new("umbrella")
15
+ @app_generator = Generators::App.new
16
+ end
17
+
18
+ def call(target_dir)
19
+ generate.(target_dir, prepare_scope(target_dir))
20
+
21
+ Dir.chdir(target_dir) do
22
+ app_generator.("main", umbrella: target_dir)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def prepare_scope(target_dir)
29
+ {
30
+ underscored_app_name: Inflecto.underscore(target_dir),
31
+ camel_cased_app_name: Inflecto.camelize(target_dir)
32
+ }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ require "rack/csrf"
2
+ require "dry/web/roda/application"
3
+ require_relative "container"
4
+ require "roda_plugins"
5
+
6
+ module <%= config[:camel_cased_app_name] %>
7
+ class Application < Dry::Web::Roda::Application
8
+ configure do |config|
9
+ config.routes = "web/routes".freeze
10
+ config.container = Container
11
+ end
12
+
13
+ opts[:root] = Pathname(__FILE__).join("../..").realpath.dirname
14
+
15
+ use Rack::Session::Cookie, key: "<%= config[:underscored_app_name] %>.session", secret: <%= config[:camel_cased_umbrella_name] %>::Container.settings.session_secret
16
+ use Rack::Csrf, raise: true
17
+
18
+ plugin :flash
19
+
20
+ plugin :view
21
+ plugin :page
22
+
23
+ def name
24
+ :<%= config[:underscored_app_name] %>
25
+ end
26
+
27
+ route do |r|
28
+ r.multi_route
29
+ end
30
+
31
+ load_routes!
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ require "pathname"
2
+ require "dry/web/container"
3
+
4
+ module <%= config[:camel_cased_app_name] %>
5
+ class Container < Dry::Web::Container
6
+ require root.join("component/<%= config[:underscored_umbrella_name] %>/container")
7
+ import <%= config[:camel_cased_umbrella_name] %>::Container
8
+
9
+ configure do |config|
10
+ config.root = Pathname(__FILE__).join("../..").realpath.dirname.freeze
11
+
12
+ config.auto_register = %w[
13
+ lib/<%= config[:underscored_app_name] %>
14
+ ]
15
+ end
16
+
17
+ load_paths! "lib", "component"
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "container"
2
+
3
+ module <%= config[:camel_cased_app_name] %>
4
+ Import = <%= config[:camel_cased_app_name] %>::Container::Inject
5
+ end
@@ -0,0 +1,6 @@
1
+ require "<%= config[:underscored_umbrella_name] %>/page"
2
+
3
+ module <%= config[:camel_cased_app_name] %>
4
+ class Page < <%= config[:camel_cased_umbrella_name] %>::Page
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+ require "dry-transaction"
2
+ require "<%= config[:underscored_umbrella_name] %>/transactions"
3
+ require "<%= config[:underscored_app_name] %>/container"
4
+ require "<%= config[:underscored_app_name] %>/import"
5
+
6
+ module <%= config[:camel_cased_app_name] %>
7
+ class Transactions < <%= config[:camel_cased_umbrella_name] %>::Transactions
8
+ configure do |config|
9
+ config.container = <%= config[:camel_cased_app_name] %>::Container
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require "slim"
2
+ require "dry-view"
3
+ require "<%= config[:underscored_app_name] %>/container"
4
+ require "<%= config[:underscored_app_name] %>/page"
5
+
6
+ module Main
7
+ Container.register "page", Page.new
8
+
9
+ class View < Dry::View::Layout
10
+ setting :root, Container.root.join("web/templates")
11
+ setting :scope, Container["page"]
12
+ setting :formats, {html: :slim}
13
+ setting :name, "application"
14
+
15
+ def locals(options)
16
+ super.merge(options[:scope].view_locals)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "main/container"
2
+
3
+ <%= config[:camel_cased_app_name] %>::Container.finalize! do |container|
4
+ end
5
+
6
+ require "<%= config[:underscored_app_name] %>/application"
7
+ require "<%= config[:underscored_app_name] %>/view"
8
+ require "<%= config[:underscored_app_name] %>/transactions"
9
+
10
+ <%= config[:camel_cased_app_name] %>::Container.require "transactions/**/*.rb"
@@ -0,0 +1,9 @@
1
+ require "<%= config[:underscored_app_name] %>/transactions"
2
+
3
+ <%= config[:camel_cased_app_name] %>::Transactions.define do |t|
4
+ # Define your dry-transaction objects here:
5
+ #
6
+ # t.define "<%= config[:underscored_app_name] %>.transactions.users.sign_up" do
7
+ # step :persist, with: "<%= config[:underscored_app_name] %>.users.operations.sign_up"
8
+ # end
9
+ end
@@ -0,0 +1,7 @@
1
+ # Define your routes like this:
2
+ #
3
+ # class <%= config[:camel_cased_app_name] %>::Application
4
+ # route "example" do |r|
5
+ # # Routes go here
6
+ # end
7
+ # end
@@ -0,0 +1,5 @@
1
+ # Ignore secrets in app settings (copy a version to settings.example.yml if you want to check one in)
2
+ /config/settings.yml
3
+
4
+ # RSpec
5
+ /spec/examples.txt
@@ -0,0 +1,39 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rake"
4
+
5
+ # Web framework
6
+ gem "dry-web", "~> 0.3.0"
7
+ gem "dry-web-roda", "~> 0.2.0"
8
+ gem "puma"
9
+ gem "rack_csrf"
10
+ gem "shotgun"
11
+
12
+ # Database persistence
13
+ gem "pg"
14
+ gem "rom", github: "rom-rb/rom"
15
+ gem "rom-mapper", github: "rom-rb/rom-mapper"
16
+ gem "rom-repository", github: "rom-rb/rom-repository"
17
+ gem "rom-sql", github: "rom-rb/rom-sql"
18
+ gem "rom-support", github: "rom-rb/rom-support"
19
+
20
+ # Application dependencies
21
+ gem "dry-result_matcher"
22
+ gem "dry-transaction"
23
+ gem "dry-types"
24
+ gem "dry-validation"
25
+ gem "dry-view"
26
+ gem "slim"
27
+
28
+ group :development, :test do
29
+ gem "guard-rspec"
30
+ gem "pry-byebug"
31
+ end
32
+
33
+ group :test do
34
+ gem "capybara"
35
+ gem "capybara-screenshot"
36
+ gem "database_cleaner"
37
+ gem "poltergeist"
38
+ gem "rspec"
39
+ end
@@ -0,0 +1,12 @@
1
+ # <%= config[:camel_cased_app_name] %>
2
+
3
+ Welcome! You’ve generated an app using dry-web-roda.
4
+
5
+ ## First steps
6
+
7
+ 1. Run `bundle`
8
+ 1. Review `config/settings.yml` (and make a copy at `config/settings.example.yml` if you want to keep example settings checked in)
9
+ 1. Create a `<%= config[:underscored_app_name] %>_development` database
10
+ 1. Add your own steps to `bin/setup`
11
+ 1. Run the app with `bundle exec shotgun -p 3000 -o 0.0.0.0 config.ru`
12
+ 1. Initialize git with `git init` and make your initial commit
@@ -0,0 +1,81 @@
1
+ require "bundler/setup"
2
+
3
+ require "byebug" unless ENV["RACK_ENV"] == "production"
4
+
5
+ begin
6
+ require "rspec/core/rake_task"
7
+ RSpec::Core::RakeTask.new :spec
8
+ task default: [:spec]
9
+ rescue LoadError
10
+ end
11
+
12
+ require_relative "component/<%= config[:underscored_app_name] %>/container"
13
+
14
+ require "rom/sql/rake_task"
15
+ require "sequel"
16
+ namespace :db do
17
+ task :setup do
18
+ <%= config[:camel_cased_app_name] %>::Container.boot! :rom
19
+ end
20
+
21
+ # The following migration tasks are adapted from https://gist.github.com/kalmbach/4471560
22
+ Sequel.extension :migration
23
+ DB = Sequel.connect(<%= config[:camel_cased_app_name] %>::Container.settings.database_url)
24
+
25
+ desc "Prints current schema version"
26
+ task :version do
27
+ version = if DB.tables.include?(:schema_migrations)
28
+ DB[:schema_migrations].order(:filename).last[:filename]
29
+ end || "not available"
30
+
31
+ puts "Current schema version: #{version}"
32
+ end
33
+
34
+ namespace :structure do
35
+ desc "Dump database structure to db/structure.sql"
36
+ task :dump do
37
+ require "uri"
38
+ uri = URI(DB.url)
39
+
40
+ dump = `pg_dump -h #{uri.hostname} -i -s -x -O #{uri.path.tr("/", "")}`
41
+ File.open "db/structure.sql", "w" do |file|
42
+ file.write dump
43
+ end
44
+ end
45
+ end
46
+
47
+ task :check_migrations_exist do
48
+ unless Dir["db/migrate/*.rb"].any?
49
+ puts "No migrations found"
50
+ exit 1
51
+ end
52
+ end
53
+
54
+ # Enhance the migration task provided by ROM
55
+ desc "Perform migration up to latest migration available"
56
+ task :migrate => [:check_migrations_exist] do
57
+ # Once db:migrate finishes, dump the db structure:
58
+ Rake::Task["db:structure:dump"].execute
59
+
60
+ # And print the current migration version:
61
+ Rake::Task["db:version"].execute
62
+ end
63
+
64
+ desc "Perform rollback to specified target"
65
+ task :rollback, :target do |t, args|
66
+ Sequel::Migrator.run(DB, "db/migrate", :target => args[:target].to_i)
67
+ Rake::Task["db:version"].execute
68
+ end
69
+
70
+ desc "Load seed data into the database"
71
+ task :seed do
72
+ seed_data = File.join("db", "seed.rb")
73
+ load(seed_data) if File.exist?(seed_data)
74
+ end
75
+
76
+ desc "Load a small, representative set of data so that the application can start in a useful state (for development)."
77
+ task :sample_data do
78
+ sample_data = File.join("db", "sample_data.rb")
79
+ load(sample_data) if File.exist?(sample_data)
80
+ end
81
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "dry/web/console"
5
+ require_relative "../component/boot"
6
+
7
+ Dry::Web::Console.start
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ APP_ROOT = File.expand_path("../../", __FILE__)
4
+
5
+ Dir.chdir(APP_ROOT) do
6
+ # Set up your app for development here
7
+ end
@@ -0,0 +1,7 @@
1
+ module <%= config[:camel_cased_app_name] %>
2
+ class Application < Roda
3
+ route do |r|
4
+ r.run Main::Application.freeze.app
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ require "dry/web/umbrella"
2
+ require_relative "settings"
3
+
4
+ module <%= config[:camel_cased_app_name] %>
5
+ class Container < Dry::Web::Umbrella
6
+ configure do
7
+ config.name = :core
8
+ config.settings_loader = <%= config[:camel_cased_app_name] %>::Settings
9
+ end
10
+
11
+ load_paths! "lib", "component"
12
+
13
+ def self.settings
14
+ config.settings
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "container"
2
+
3
+ module <%= config[:camel_cased_app_name] %>
4
+ Import = <%= config[:camel_cased_app_name] %>::Container::Inject
5
+ end
@@ -0,0 +1,17 @@
1
+ require "dry/web/settings"
2
+ require "dry-types"
3
+
4
+ module <%= config[:camel_cased_app_name] %>
5
+ class Settings < Dry::Web::Settings
6
+ module Types
7
+ include Dry::Types.module
8
+
9
+ module Required
10
+ String = Types::Strict::String.constrained(min_size: 1)
11
+ end
12
+ end
13
+
14
+ setting :database_url, Types::Required::String
15
+ setting :session_secret, Types::Required::String
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ require "logger"
2
+
3
+ <%= config[:camel_cased_app_name] %>::Container.finalize :logger do |container|
4
+ container.register "logger", Logger.new(container.root.join("log/#{container.config.env}.log"))
5
+ end
@@ -0,0 +1,16 @@
1
+ require "sequel"
2
+ require "rom"
3
+
4
+ Sequel.database_timezone = :utc
5
+ Sequel.application_timezone = :local
6
+
7
+ <%= config[:camel_cased_app_name] %>::Container.namespace "persistence" do |container|
8
+ config = ROM::Configuration.new(:sql, container.settings.database_url, extensions: [:error_sql])
9
+
10
+ container.register "config", config
11
+
12
+ container.finalize :rom do
13
+ config.auto_registration container.root.join("lib/persistence")
14
+ container.register "rom", ROM.container(config)
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require "byebug" if ENV["RACK_ENV"] == "development"
2
+ require "pry" if ENV["RACK_ENV"] == "development"
3
+
4
+ require_relative "<%= config[:underscored_app_name] %>/container"
5
+
6
+ <%= config[:camel_cased_app_name] %>::Container.finalize! do |container|
7
+ end
8
+
9
+ app_paths = Pathname(__FILE__).dirname.join("../apps").realpath.join("*")
10
+ Dir[app_paths].each { |f| require "#{f}/component/boot" }
11
+
12
+ require_relative "<%= config[:underscored_app_name] %>/application"
@@ -0,0 +1,8 @@
1
+ development: &base
2
+ database_url: 'postgres://localhost/<%= config[:underscored_app_name] %>_development'
3
+ session_secret: '<%= SecureRandom.hex %>'
4
+ test:
5
+ <<: *base
6
+ database_url: 'postgres://localhost/<%= config[:underscored_app_name] %>_test'
7
+ production:
8
+ <<: *base
@@ -0,0 +1,2 @@
1
+ require_relative "component/boot"
2
+ run <%= config[:camel_cased_app_name] %>::Application.freeze.app
@@ -0,0 +1 @@
1
+ # Build your sample data here