pliny 0.2.0 → 0.3.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 +14 -6
- data/README.md +59 -11
- data/bin/pliny-generate +2 -14
- data/bin/pliny-new +1 -1
- data/lib/pliny/commands/creator.rb +10 -11
- data/lib/pliny/commands/generator/base.rb +59 -0
- data/lib/pliny/commands/generator/endpoint.rb +44 -0
- data/lib/pliny/commands/generator/mediator.rb +21 -0
- data/lib/pliny/commands/generator/migration.rb +13 -0
- data/lib/pliny/commands/generator/model.rb +30 -0
- data/lib/pliny/commands/generator/schema.rb +24 -0
- data/lib/pliny/commands/generator/serializer.rb +21 -0
- data/lib/pliny/commands/generator.rb +50 -199
- data/lib/pliny/config_helpers.rb +52 -0
- data/lib/pliny/errors.rb +7 -4
- data/lib/pliny/helpers/encode.rb +7 -0
- data/lib/pliny/log.rb +18 -1
- data/lib/pliny/middleware/rescue_errors.rb +2 -8
- data/lib/pliny/middleware/versioning.rb +3 -3
- data/lib/pliny/tasks/db.rake +21 -7
- data/lib/pliny/tasks/schema.rake +2 -2
- data/lib/pliny/templates/endpoint.erb +5 -5
- data/lib/pliny/templates/endpoint_acceptance_test.erb +1 -1
- data/lib/pliny/templates/endpoint_scaffold.erb +5 -5
- data/lib/pliny/templates/endpoint_scaffold_acceptance_test.erb +1 -1
- data/lib/pliny/templates/endpoint_test.erb +1 -0
- data/lib/pliny/templates/migration.erb +0 -2
- data/lib/pliny/templates/model.erb +0 -2
- data/lib/pliny/templates/model_test.erb +0 -1
- data/lib/pliny/templates/serializer_test.erb +0 -1
- data/lib/pliny/version.rb +1 -1
- data/lib/pliny.rb +1 -2
- data/template/.env.sample +2 -1
- data/template/README.md +1 -1
- data/template/bin/console +1 -3
- data/template/bin/run +1 -3
- data/template/config/config.rb +19 -25
- data/template/config/initializers/rollbar.rb +1 -0
- data/template/config/puma.rb +2 -2
- data/template/config.ru +1 -4
- data/template/db/schema.sql +1 -2
- data/template/lib/application.rb +4 -0
- data/template/lib/endpoints/base.rb +5 -0
- data/template/lib/routes.rb +1 -1
- data/template/lib/serializers/base.rb +8 -1
- data/test/commands/creator_test.rb +1 -0
- data/test/commands/generator/base_test.rb +103 -0
- data/test/commands/generator/endpoint_test.rb +15 -0
- data/test/commands/generator_test.rb +95 -134
- data/test/extensions/instruments_test.rb +4 -0
- data/test/log_test.rb +16 -0
- metadata +116 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
Mjk3OWZlMTRiYjE4MmU4M2JkZDQzNjA5ODllZTNhNDQxYTBjZjRlZA==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
YjExMTc1Yzk3ZTNkODY1OTFiMWMzOGVhM2YzZTViNjk2ZGIwNDk3Mw==
|
|
7
|
+
!binary "U0hBNTEy":
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
Mzg5NWFkY2NlNzA0Y2U4MmQwYTExNTBmZGUwY2Y2YzJkMDRhNzY0ODVkM2Mz
|
|
10
|
+
NzVhM2JmN2U0ZTc0MmViYjEyM2NhZjhhYTVmOTVlNTRiNzMzMzhhMzRhN2Fj
|
|
11
|
+
MjBiMDQ0NjY3M2E1MTUwOTM3YjE2YWFkMDU3MzMzZTI3NWE0ZGI=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
YWQyMzBjMWEwNmMyOWU4ZDc5MTllOGZjM2U4NGNiZDNkMzBkOGE2NDMzNzIw
|
|
14
|
+
NGI4ZDFlMDk1OWJjNTQ2YzdjMmI3MTE5YThkMmQ5NTRiMjQwMjFmN2Q1MTU5
|
|
15
|
+
NzQyZjk4Y2I5NDlmMzdlYWM4NTEwNDBhOTNkMGUxYzc1M2NhNmY=
|
data/README.md
CHANGED
|
@@ -15,7 +15,7 @@ It bundles some of the patterns we like to develop these apps:
|
|
|
15
15
|
And gems/helpers to tie these together and support operations:
|
|
16
16
|
|
|
17
17
|
- [CORS middleware](lib/pliny/middleware/cors.rb) to allow JS developers to consume your API
|
|
18
|
-
- [
|
|
18
|
+
- [Rollbar](https://www.rollbar.com/) for tracking exceptions
|
|
19
19
|
- [Log helper](test/log_test.rb) that logs in [data format](https://www.youtube.com/watch?v=rpmc-wHFUBs) [to stdout](https://adam.heroku.com/past/2011/4/1/logs_are_streams_not_files)
|
|
20
20
|
- [Mediators](http://brandur.org/mediator) to help encapsulate more complex interactions
|
|
21
21
|
- [Rspec](https://github.com/rspec/rspec) for lean and fast testing
|
|
@@ -47,18 +47,17 @@ $ pliny-new myapp
|
|
|
47
47
|
$ cd myapp && bin/setup
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
Pliny also bundles some generators to help you get started:
|
|
50
|
+
Pliny also bundles [some generators](#generators) to help you get started:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
$ bundle exec pliny-generate model artist
|
|
54
54
|
created model file ./lib/models/artist.rb
|
|
55
|
-
created migration ./db/migrate/
|
|
56
|
-
created test ./
|
|
55
|
+
created migration ./db/migrate/1408995997_create_artists.rb
|
|
56
|
+
created test ./spec/models/artist_spec.rb
|
|
57
57
|
|
|
58
58
|
$ bundle exec pliny-generate mediator artists/creator
|
|
59
|
-
created base mediator ./lib/mediators/base.rb
|
|
60
59
|
created mediator file ./lib/mediators/artists/creator.rb
|
|
61
|
-
created test ./
|
|
60
|
+
created test ./spec/mediators/artists/creator_spec.rb
|
|
62
61
|
|
|
63
62
|
$ bundle exec pliny-generate endpoint artists
|
|
64
63
|
created endpoint file ./lib/endpoints/artists.rb
|
|
@@ -78,23 +77,72 @@ rebuilt ./docs/schema.json
|
|
|
78
77
|
To test your application:
|
|
79
78
|
|
|
80
79
|
```bash
|
|
81
|
-
bundle exec rake
|
|
80
|
+
$ bundle exec rake
|
|
82
81
|
```
|
|
83
82
|
|
|
84
83
|
Or to run a single test suite:
|
|
85
84
|
|
|
86
85
|
```bash
|
|
87
|
-
bundle exec rspec spec/acceptance/artists_spec.rb
|
|
86
|
+
$ bundle exec rspec spec/acceptance/artists_spec.rb
|
|
88
87
|
```
|
|
89
88
|
|
|
89
|
+
### Generators
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
$ bin/pliny-generate
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Commands:
|
|
97
|
+
pliny-generate endpoint NAME # Generates an endpoint
|
|
98
|
+
pliny-generate help [COMMAND] # Describe available commands or one specific command
|
|
99
|
+
pliny-generate mediator NAME # Generates a mediator
|
|
100
|
+
pliny-generate migration NAME # Generates a migration
|
|
101
|
+
pliny-generate model NAME # Generates a model
|
|
102
|
+
pliny-generate scaffold NAME # Generates a scaffold of endpoint, model, schema and serializer
|
|
103
|
+
pliny-generate schema NAME # Generates a schema
|
|
104
|
+
pliny-generate serializer NAME # Generates a serializer
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Rake tasks
|
|
108
|
+
|
|
109
|
+
Pliny comes with several rake tasks:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
rake db:create # Create the database
|
|
113
|
+
rake db:drop # Drop the database
|
|
114
|
+
rake db:migrate # Run database migrations
|
|
115
|
+
rake db:nuke # Nuke the database (drop all tables)
|
|
116
|
+
rake db:reset # Reset the database
|
|
117
|
+
rake db:rollback # Rollback the database
|
|
118
|
+
rake db:schema:dump # Dump the database schema
|
|
119
|
+
rake db:schema:load # Load the database schema
|
|
120
|
+
rake db:schema:merge # Merges migrations into schema and removes them
|
|
121
|
+
rake db:seed # Seed the database with data
|
|
122
|
+
rake db:setup # Setup the database
|
|
123
|
+
rake schema # Rebuild schema.json
|
|
124
|
+
rake test # Run tests
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Commands
|
|
128
|
+
|
|
129
|
+
And provides the following commands:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
$ foreman run bin/console # IRB/Pry console
|
|
133
|
+
$ foreman run bin/run 'puts "hello world"' # Run automated code
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
(hint: don't forget `foreman run` in development)
|
|
137
|
+
|
|
90
138
|
## Development
|
|
91
139
|
|
|
92
140
|
Run tests:
|
|
93
141
|
|
|
94
142
|
```
|
|
95
|
-
bundle install
|
|
96
|
-
git submodule update --init
|
|
97
|
-
rake
|
|
143
|
+
$ bundle install
|
|
144
|
+
$ git submodule update --init
|
|
145
|
+
$ rake
|
|
98
146
|
```
|
|
99
147
|
|
|
100
148
|
## Meta
|
data/bin/pliny-generate
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
ARGV.options do |options|
|
|
7
|
-
opts = {}
|
|
8
|
-
|
|
9
|
-
options.on("--paranoid", "Generate paranoid support in models") do
|
|
10
|
-
opts[:paranoid] = true
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
options.parse!
|
|
14
|
-
|
|
15
|
-
Pliny::Commands::Generator.run(ARGV.dup, opts)
|
|
16
|
-
end
|
|
3
|
+
require_relative '../lib/pliny/commands/generator'
|
|
4
|
+
Pliny::Commands::Generator.start
|
data/bin/pliny-new
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'pliny/version'
|
|
2
|
+
require 'fileutils'
|
|
2
3
|
|
|
3
4
|
module Pliny::Commands
|
|
4
5
|
class Creator
|
|
5
6
|
attr_accessor :args, :opts, :stream
|
|
6
7
|
|
|
7
|
-
def self.run(args, opts={}, stream
|
|
8
|
+
def self.run(args, opts = {}, stream = $stdout)
|
|
8
9
|
new(args, opts, stream).run!
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
def initialize(args={}, opts={}, stream
|
|
12
|
+
def initialize(args = {}, opts = {}, stream = $stdout)
|
|
12
13
|
@args = args
|
|
13
14
|
@opts = opts
|
|
14
15
|
@stream = stream
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def run!
|
|
18
|
-
if File.
|
|
19
|
-
abort("#{name} already exists")
|
|
20
|
-
end
|
|
19
|
+
abort("#{name} already exists") if File.exist?(app_dir)
|
|
21
20
|
|
|
22
21
|
FileUtils.copy_entry template_dir, app_dir
|
|
23
22
|
FileUtils.rm_rf("#{app_dir}/.git")
|
|
24
23
|
setup_database_urls
|
|
25
|
-
display
|
|
24
|
+
display 'Pliny app created. To start, run:'
|
|
26
25
|
display "cd #{app_dir} && bin/setup"
|
|
27
26
|
end
|
|
28
27
|
|
|
@@ -31,16 +30,16 @@ module Pliny::Commands
|
|
|
31
30
|
def setup_database_urls
|
|
32
31
|
db = URI.parse("postgres:///#{name}")
|
|
33
32
|
{
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
'.env.sample' => 'development',
|
|
34
|
+
'.env.test' => 'test'
|
|
36
35
|
}.each do |env_file, db_env_suffix|
|
|
37
36
|
env_path = "#{app_dir}/#{env_file}"
|
|
38
37
|
db.path = "/#{name}-#{db_env_suffix}"
|
|
39
38
|
env = File.read(env_path)
|
|
40
|
-
File.open(env_path,
|
|
39
|
+
File.open(env_path, 'w') do |f|
|
|
41
40
|
# ruby's URI#to_s renders foo:/bar when there's no host
|
|
42
41
|
# we want foo:///bar instead!
|
|
43
|
-
db_url = db.to_s.sub(
|
|
42
|
+
db_url = db.to_s.sub(':/', ':///')
|
|
44
43
|
f.puts env.sub(/DATABASE_URL=.*/, "DATABASE_URL=#{db_url}")
|
|
45
44
|
end
|
|
46
45
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'active_support/inflector'
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
require 'erb'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require 'pliny'
|
|
6
|
+
|
|
7
|
+
module Pliny::Commands
|
|
8
|
+
class Generator
|
|
9
|
+
class Base
|
|
10
|
+
attr_reader :name, :stream, :options
|
|
11
|
+
|
|
12
|
+
def initialize(name, options = {}, stream = $stdout)
|
|
13
|
+
@name = name
|
|
14
|
+
@options = options
|
|
15
|
+
@stream = stream
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def singular_class_name
|
|
19
|
+
name.gsub(/-/, '_').singularize.camelize
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def plural_class_name
|
|
23
|
+
name.gsub(/-/, '_').pluralize.camelize
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def field_name
|
|
27
|
+
name.tableize.singularize
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def pluralized_file_name
|
|
31
|
+
name.tableize
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def table_name
|
|
35
|
+
name.tableize.gsub('/', '_')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def display(msg)
|
|
39
|
+
stream.puts msg
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def render_template(template_file, destination_path, vars = {})
|
|
43
|
+
template_path = File.dirname(__FILE__) + "/../../templates/#{template_file}"
|
|
44
|
+
template = ERB.new(File.read(template_path), 0, '>')
|
|
45
|
+
context = OpenStruct.new(vars)
|
|
46
|
+
write_file(destination_path) do
|
|
47
|
+
template.result(context.instance_eval { binding })
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def write_file(destination_path)
|
|
52
|
+
FileUtils.mkdir_p(File.dirname(destination_path))
|
|
53
|
+
File.open(destination_path, 'w') do |f|
|
|
54
|
+
f.puts yield
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Pliny::Commands
|
|
4
|
+
class Generator
|
|
5
|
+
class Endpoint < Base
|
|
6
|
+
def create
|
|
7
|
+
endpoint = "./lib/endpoints/#{pluralized_file_name}.rb"
|
|
8
|
+
template = options[:scaffold] ? 'endpoint_scaffold.erb' : 'endpoint.erb'
|
|
9
|
+
render_template(template, endpoint,
|
|
10
|
+
plural_class_name: plural_class_name,
|
|
11
|
+
singular_class_name: singular_class_name,
|
|
12
|
+
field_name: field_name,
|
|
13
|
+
url_path: url_path)
|
|
14
|
+
display "created endpoint file #{endpoint}"
|
|
15
|
+
display 'add the following to lib/routes.rb:'
|
|
16
|
+
display " mount Endpoints::#{plural_class_name}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create_test
|
|
20
|
+
test = "./spec/endpoints/#{pluralized_file_name}_spec.rb"
|
|
21
|
+
render_template('endpoint_test.erb', test,
|
|
22
|
+
plural_class_name: plural_class_name,
|
|
23
|
+
singular_class_name: singular_class_name,
|
|
24
|
+
url_path: url_path)
|
|
25
|
+
display "created test #{test}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def create_acceptance_test
|
|
29
|
+
test = "./spec/acceptance/#{pluralized_file_name}_spec.rb"
|
|
30
|
+
template = options[:scaffold] ? 'endpoint_scaffold_acceptance_test.erb' : 'endpoint_acceptance_test.erb'
|
|
31
|
+
render_template(template, test,
|
|
32
|
+
plural_class_name: plural_class_name,
|
|
33
|
+
field_name: field_name,
|
|
34
|
+
singular_class_name: singular_class_name,
|
|
35
|
+
url_path: url_path)
|
|
36
|
+
display "created test #{test}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def url_path
|
|
40
|
+
'/' + name.pluralize.gsub(/_/, '-')
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Pliny::Commands
|
|
4
|
+
class Generator
|
|
5
|
+
class Mediator < Base
|
|
6
|
+
def create
|
|
7
|
+
mediator = "./lib/mediators/#{field_name}.rb"
|
|
8
|
+
render_template('mediator.erb', mediator,
|
|
9
|
+
singular_class_name: singular_class_name)
|
|
10
|
+
display "created mediator file #{mediator}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_test
|
|
14
|
+
test = "./spec/mediators/#{field_name}_spec.rb"
|
|
15
|
+
render_template('mediator_test.erb', test,
|
|
16
|
+
singular_class_name: singular_class_name)
|
|
17
|
+
display "created test #{test}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Pliny::Commands
|
|
4
|
+
class Generator
|
|
5
|
+
class Migration < Base
|
|
6
|
+
def create
|
|
7
|
+
migration = "./db/migrate/#{Time.now.to_i}_#{name}.rb"
|
|
8
|
+
render_template('migration.erb', migration)
|
|
9
|
+
display "created migration #{migration}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Pliny::Commands
|
|
4
|
+
class Generator
|
|
5
|
+
class Model < Base
|
|
6
|
+
def create
|
|
7
|
+
model = "./lib/models/#{field_name}.rb"
|
|
8
|
+
render_template('model.erb', model,
|
|
9
|
+
singular_class_name: singular_class_name,
|
|
10
|
+
paranoid: options[:paranoid])
|
|
11
|
+
display "created model file #{model}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_migration
|
|
15
|
+
migration = "./db/migrate/#{Time.now.to_i}_create_#{table_name}.rb"
|
|
16
|
+
render_template('model_migration.erb', migration,
|
|
17
|
+
table_name: table_name,
|
|
18
|
+
paranoid: options[:paranoid])
|
|
19
|
+
display "created migration #{migration}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def create_test
|
|
23
|
+
test = "./spec/models/#{field_name}_spec.rb"
|
|
24
|
+
render_template('model_test.erb', test,
|
|
25
|
+
singular_class_name: singular_class_name)
|
|
26
|
+
display "created test #{test}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
require 'prmd'
|
|
3
|
+
|
|
4
|
+
module Pliny::Commands
|
|
5
|
+
class Generator
|
|
6
|
+
class Schema < Base
|
|
7
|
+
def create
|
|
8
|
+
schema = "./docs/schema/schemata/#{field_name}.yaml"
|
|
9
|
+
write_file(schema) do
|
|
10
|
+
Prmd.init(name.singularize, yaml: true)
|
|
11
|
+
end
|
|
12
|
+
display "created schema file #{schema}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def rebuild
|
|
16
|
+
schemata = './docs/schema.json'
|
|
17
|
+
write_file(schemata) do
|
|
18
|
+
Prmd.combine('./docs/schema/schemata', meta: './docs/schema/meta.json')
|
|
19
|
+
end
|
|
20
|
+
display "rebuilt #{schemata}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'base'
|
|
2
|
+
|
|
3
|
+
module Pliny::Commands
|
|
4
|
+
class Generator
|
|
5
|
+
class Serializer < Base
|
|
6
|
+
def create
|
|
7
|
+
serializer = "./lib/serializers/#{name}.rb"
|
|
8
|
+
render_template('serializer.erb', serializer,
|
|
9
|
+
singular_class_name: singular_class_name)
|
|
10
|
+
display "created serializer file #{serializer}"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_test
|
|
14
|
+
test = "./spec/serializers/#{name}_spec.rb"
|
|
15
|
+
render_template('serializer_test.erb', test,
|
|
16
|
+
singular_class_name: singular_class_name)
|
|
17
|
+
display "created test #{test}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|