dry-web-roda 0.1.0 → 0.2.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.
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