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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -1
- data/README.md +15 -1
- data/bin/dry-web-roda +6 -0
- data/dry-web-roda.gemspec +2 -0
- data/lib/dry/web/roda/cli/generate.rb +18 -0
- data/lib/dry/web/roda/cli.rb +19 -0
- data/lib/dry/web/roda/generate.rb +54 -0
- data/lib/dry/web/roda/generators/app.rb +36 -0
- data/lib/dry/web/roda/generators/umbrella.rb +38 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/application.rb.tt +33 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/container.rb.tt +19 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/import.rb.tt +5 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/page.rb.tt +6 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/transactions.rb.tt +12 -0
- data/lib/dry/web/roda/skeletons/app/component/__underscored_app_name__/view.rb.tt +19 -0
- data/lib/dry/web/roda/skeletons/app/component/boot.rb.tt +10 -0
- data/lib/dry/web/roda/skeletons/app/lib/__underscored_app_name__/.keep +0 -0
- data/lib/dry/web/roda/skeletons/app/transactions/example.rb.tt +9 -0
- data/lib/dry/web/roda/skeletons/app/web/routes/example.rb.tt +7 -0
- data/lib/dry/web/roda/skeletons/app/web/templates/layouts/application.html.slim +3 -0
- data/lib/dry/web/roda/skeletons/umbrella/.gitignore +5 -0
- data/lib/dry/web/roda/skeletons/umbrella/Gemfile +39 -0
- data/lib/dry/web/roda/skeletons/umbrella/README.md.tt +12 -0
- data/lib/dry/web/roda/skeletons/umbrella/Rakefile.tt +81 -0
- data/lib/dry/web/roda/skeletons/umbrella/bin/console.tt +7 -0
- data/lib/dry/web/roda/skeletons/umbrella/bin/setup +7 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/application.rb.tt +7 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/container.rb.tt +17 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/import.rb.tt +5 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/__underscored_app_name__/settings.rb.tt +17 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/boot/logger.rb.tt +5 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/boot/rom.rb.tt +16 -0
- data/lib/dry/web/roda/skeletons/umbrella/component/boot.rb.tt +12 -0
- data/lib/dry/web/roda/skeletons/umbrella/config/settings.yml.tt +8 -0
- data/lib/dry/web/roda/skeletons/umbrella/config.ru.tt +2 -0
- data/lib/dry/web/roda/skeletons/umbrella/db/sample_data.rb +1 -0
- data/lib/dry/web/roda/skeletons/umbrella/db/seed.rb +1 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/page.rb.tt +48 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/repository.rb.tt +11 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/__underscored_app_name__/transactions.rb.tt +33 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/persistence/commands/.keep +0 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/persistence/relations/.keep +0 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/roda_plugins.rb +34 -0
- data/lib/dry/web/roda/skeletons/umbrella/lib/types.rb +5 -0
- data/lib/dry/web/roda/skeletons/umbrella/log/.keep +0 -0
- data/lib/dry/web/roda/skeletons/umbrella/spec/app_helper.rb +35 -0
- data/lib/dry/web/roda/skeletons/umbrella/spec/db_helper.rb.tt +24 -0
- data/lib/dry/web/roda/skeletons/umbrella/spec/spec_helper.rb.tt +66 -0
- data/lib/dry/web/roda/skeletons/umbrella/spec/support/db/test_factories.rb +3 -0
- data/lib/dry/web/roda/skeletons/umbrella/spec/support/test_helpers.rb.tt +15 -0
- data/lib/dry/web/roda/version.rb +1 -1
- data/spec/dummy/apps/main/{core → component}/boot.rb +0 -0
- data/spec/dummy/apps/main/{core → component}/main/application.rb +0 -0
- data/spec/dummy/apps/main/{core → component}/main/container.rb +1 -0
- data/spec/dummy/apps/main/{core → component}/main/import.rb +0 -0
- data/spec/dummy/apps/main/{core → component}/main/requests.rb +0 -0
- data/spec/dummy/apps/main/{core → component}/main/view.rb +0 -0
- data/spec/dummy/bin/console +1 -1
- data/spec/dummy/{core → component}/boot.rb +1 -1
- data/spec/dummy/{core → component}/dummy/application.rb +0 -0
- data/spec/dummy/{core → component}/dummy/container.rb +1 -0
- data/spec/dummy/config.ru +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +97 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02425c79e7cb73bc2c6ba4828c849613926f4bd6
|
|
4
|
+
data.tar.gz: 45b4248b401fb991c9d9d6eee49379486c5a24d5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 31397fe8d8dfcf700a5d567ff522addacc68f6e2c64b2b538c06848fdfb30a8e1fc0813c5c9dd55a9c4181dc33fb946aa5167956d776a0beb9e0e2de43eef110
|
|
7
|
+
data.tar.gz: 82928af236cdc3916ee453b91de9d4446c59ad9e5f0470e08266ca9473d0eaab06a15dd9fb02ed943971c0d377ac91313072cda8ef7a150a45a217c936f33024
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
# 0.
|
|
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 [](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
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,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"
|
|
File without changes
|
|
@@ -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,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,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,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,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 @@
|
|
|
1
|
+
# Build your sample data here
|