pliny 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +14 -6
  2. data/README.md +59 -11
  3. data/bin/pliny-generate +2 -14
  4. data/bin/pliny-new +1 -1
  5. data/lib/pliny.rb +1 -2
  6. data/lib/pliny/commands/creator.rb +10 -11
  7. data/lib/pliny/commands/generator.rb +50 -199
  8. data/lib/pliny/commands/generator/base.rb +59 -0
  9. data/lib/pliny/commands/generator/endpoint.rb +44 -0
  10. data/lib/pliny/commands/generator/mediator.rb +21 -0
  11. data/lib/pliny/commands/generator/migration.rb +13 -0
  12. data/lib/pliny/commands/generator/model.rb +30 -0
  13. data/lib/pliny/commands/generator/schema.rb +24 -0
  14. data/lib/pliny/commands/generator/serializer.rb +21 -0
  15. data/lib/pliny/config_helpers.rb +52 -0
  16. data/lib/pliny/helpers/encode.rb +7 -0
  17. data/lib/pliny/log.rb +18 -1
  18. data/lib/pliny/middleware/versioning.rb +3 -3
  19. data/lib/pliny/tasks/db.rake +21 -7
  20. data/lib/pliny/tasks/schema.rake +2 -2
  21. data/lib/pliny/templates/endpoint.erb +5 -5
  22. data/lib/pliny/templates/endpoint_acceptance_test.erb +1 -1
  23. data/lib/pliny/templates/endpoint_scaffold.erb +5 -5
  24. data/lib/pliny/templates/endpoint_scaffold_acceptance_test.erb +1 -1
  25. data/lib/pliny/templates/endpoint_test.erb +1 -0
  26. data/lib/pliny/templates/migration.erb +0 -2
  27. data/lib/pliny/templates/model.erb +0 -2
  28. data/lib/pliny/templates/model_test.erb +0 -1
  29. data/lib/pliny/templates/serializer_test.erb +0 -1
  30. data/lib/pliny/version.rb +1 -1
  31. data/template/.env.sample +2 -1
  32. data/template/README.md +1 -1
  33. data/template/bin/console +1 -3
  34. data/template/bin/run +1 -3
  35. data/template/config.ru +1 -4
  36. data/template/config/config.rb +19 -25
  37. data/template/config/initializers/rollbar.rb +1 -0
  38. data/template/config/puma.rb +2 -2
  39. data/template/db/schema.sql +1 -2
  40. data/template/lib/application.rb +4 -0
  41. data/template/lib/endpoints/base.rb +1 -0
  42. data/template/lib/routes.rb +1 -1
  43. data/template/lib/serializers/base.rb +8 -1
  44. data/test/commands/creator_test.rb +1 -0
  45. data/test/commands/generator/base_test.rb +103 -0
  46. data/test/commands/generator/endpoint_test.rb +15 -0
  47. data/test/commands/generator_test.rb +95 -134
  48. data/test/log_test.rb +16 -0
  49. metadata +100 -69
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 59e9993f316b4360e09b0e9e60c9227daad19a00
4
- data.tar.gz: 4de44f2103e728082c0c611d97d5e4a43695588e
5
- SHA512:
6
- metadata.gz: 4361dee922785399136ce3a3a76e3ac6ec6d075700a4eb485fe6f6536bd9535676bee13424d41e7593110d8ef55843d9de23cce7da8c0ee155645f1ea1951fbf
7
- data.tar.gz: 1a72822bb718edb5d5c5918b18b8b032272cc4c19c25c415cfb50a0cd1fa19700822bb1a01683034bd4f73922e8c3756f2b6ea09b1a134e4f58a764170d6540f
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
- - [Honeybadger](https://www.honeybadger.io/) for tracking exceptions
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/1395873224_create_artist.rb
56
- created test ./test/models/artist_test.rb
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 ./test/mediators/artists/creator_test.rb
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
@@ -1,16 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "optparse"
4
- require_relative "../lib/pliny"
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "optparse"
4
- require_relative "../lib/pliny"
4
+ require_relative '../lib/pliny/commands/creator'
5
5
 
6
6
  ARGV.options do |options|
7
7
  opts = {}
@@ -2,10 +2,9 @@ require "multi_json"
2
2
  require "sinatra/base"
3
3
 
4
4
  require_relative "pliny/version"
5
- require_relative "pliny/commands/creator"
6
- require_relative "pliny/commands/generator"
7
5
  require_relative "pliny/errors"
8
6
  require_relative "pliny/extensions/instruments"
7
+ require_relative "pliny/helpers/encode"
9
8
  require_relative "pliny/helpers/params"
10
9
  require_relative "pliny/log"
11
10
  require_relative "pliny/request_store"
@@ -1,28 +1,27 @@
1
- require "fileutils"
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=$stdout)
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=$stdout)
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.exists?(app_dir)
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 "Pliny app created. To start, run:"
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
- ".env.sample" => "development",
35
- ".env.test" => "test"
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, "w") do |f|
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
@@ -1,222 +1,73 @@
1
- require "erb"
2
- require "fileutils"
3
- require "ostruct"
4
- require "active_support/inflector"
5
- require "prmd"
1
+ require 'pliny/version'
2
+ require 'thor'
6
3
 
7
4
  module Pliny::Commands
8
- class Generator
9
- attr_accessor :args, :opts, :stream
5
+ class Generator < Thor
6
+ desc 'endpoint NAME', 'Generates an endpoint'
7
+ method_option :scaffold, type: :boolean, default: false, hide: true
8
+ def endpoint(name)
9
+ require_relative 'generator/endpoint'
10
10
 
11
- def self.run(args, opts={}, stream=$stdout)
12
- new(args, opts).run!
11
+ ep = Endpoint.new(name, options)
12
+ ep.create
13
+ ep.create_test
14
+ ep.create_acceptance_test
13
15
  end
14
16
 
15
- def initialize(args={}, opts={}, stream=$stdout)
16
- @args = args
17
- @opts = opts
18
- @stream = stream
19
- end
20
-
21
- def run!
22
- unless type
23
- raise "Missing type of object to generate"
24
- end
25
- unless name
26
- raise "Missing #{type} name"
27
- end
28
-
29
- case type
30
- when "endpoint"
31
- create_endpoint(scaffold: false)
32
- create_endpoint_test
33
- create_endpoint_acceptance_test(scaffold: false)
34
- when "mediator"
35
- create_mediator
36
- create_mediator_test
37
- when "migration"
38
- create_migration
39
- when "model"
40
- create_model
41
- create_model_migration
42
- create_model_test
43
- when "scaffold"
44
- create_endpoint(scaffold: true)
45
- create_endpoint_test
46
- create_endpoint_acceptance_test(scaffold: true)
47
- create_model
48
- create_model_migration
49
- create_model_test
50
- create_schema
51
- rebuild_schema
52
- create_serializer
53
- create_serializer_test
54
- when "schema"
55
- create_schema
56
- rebuild_schema
57
- when "serializer"
58
- create_serializer
59
- create_serializer_test
60
- else
61
- abort("Don't know how to generate '#{type}'.")
62
- end
63
- end
64
-
65
- def type
66
- args.first
67
- end
68
-
69
- def name
70
- args[1]
71
- end
72
-
73
- def paranoid
74
- opts[:paranoid]
75
- end
76
-
77
- def singular_class_name
78
- name.gsub(/-/, '_').singularize.camelize
79
- end
80
-
81
- def plural_class_name
82
- name.gsub(/-/, '_').pluralize.camelize
83
- end
84
-
85
- def field_name
86
- name.tableize.singularize
87
- end
88
-
89
- def table_name
90
- name.tableize
91
- end
17
+ desc 'mediator NAME', 'Generates a mediator'
18
+ def mediator(name)
19
+ require_relative 'generator/mediator'
92
20
 
93
- def display(msg)
94
- stream.puts msg
21
+ md = Mediator.new(name, options)
22
+ md.create
23
+ md.create_test
95
24
  end
96
25
 
97
- def create_endpoint(options = {})
98
- endpoint = "./lib/endpoints/#{table_name}.rb"
99
- template = options[:scaffold] ? "endpoint_scaffold.erb" : "endpoint.erb"
100
- render_template(template, endpoint, {
101
- plural_class_name: plural_class_name,
102
- singular_class_name: singular_class_name,
103
- field_name: field_name,
104
- url_path: url_path,
105
- })
106
- display "created endpoint file #{endpoint}"
107
- display "add the following to lib/routes.rb:"
108
- display " mount Endpoints::#{plural_class_name}"
109
- end
110
-
111
- def create_endpoint_test
112
- test = "./spec/endpoints/#{table_name}_spec.rb"
113
- render_template("endpoint_test.erb", test, {
114
- plural_class_name: plural_class_name,
115
- singular_class_name: singular_class_name,
116
- url_path: url_path,
117
- })
118
- display "created test #{test}"
119
- end
120
-
121
- def create_endpoint_acceptance_test(options = {})
122
- test = "./spec/acceptance/#{table_name}_spec.rb"
123
- template = options[:scaffold] ? "endpoint_scaffold_acceptance_test.erb" :
124
- "endpoint_acceptance_test.erb"
125
- render_template(template, test, {
126
- plural_class_name: plural_class_name,
127
- field_name: field_name,
128
- singular_class_name: singular_class_name,
129
- url_path: url_path,
130
- })
131
- display "created test #{test}"
132
- end
133
-
134
- def create_mediator
135
- mediator = "./lib/mediators/#{field_name}.rb"
136
- render_template("mediator.erb", mediator, singular_class_name: singular_class_name)
137
- display "created mediator file #{mediator}"
138
- end
139
-
140
- def create_mediator_test
141
- test = "./spec/mediators/#{field_name}_spec.rb"
142
- render_template("mediator_test.erb", test, singular_class_name: singular_class_name)
143
- display "created test #{test}"
144
- end
26
+ desc 'migration NAME', 'Generates a migration'
27
+ def migration(name)
28
+ require_relative 'generator/migration'
145
29
 
146
- def create_migration
147
- migration = "./db/migrate/#{Time.now.to_i}_#{name}.rb"
148
- render_template("migration.erb", migration)
149
- display "created migration #{migration}"
30
+ mg = Migration.new(name, options)
31
+ mg.create
150
32
  end
151
33
 
152
- def create_model
153
- model = "./lib/models/#{field_name}.rb"
154
- render_template("model.erb", model,
155
- singular_class_name: singular_class_name,
156
- paranoid: paranoid)
157
- display "created model file #{model}"
158
- end
34
+ desc 'model NAME', 'Generates a model'
35
+ method_option :paranoid, type: :boolean, default: false, desc: 'adds paranoid support to model'
36
+ def model(name)
37
+ require_relative 'generator/model'
159
38
 
160
- def create_model_migration
161
- migration = "./db/migrate/#{Time.now.to_i}_create_#{table_name}.rb"
162
- render_template("model_migration.erb", migration,
163
- table_name: table_name,
164
- paranoid: paranoid)
165
- display "created migration #{migration}"
39
+ md = Model.new(name, options)
40
+ md.create
41
+ md.create_migration
42
+ md.create_test
166
43
  end
167
44
 
168
- def create_model_test
169
- test = "./spec/models/#{field_name}_spec.rb"
170
- render_template("model_test.erb", test, singular_class_name: singular_class_name)
171
- display "created test #{test}"
45
+ desc 'scaffold NAME', 'Generates a scaffold of endpoint, model, schema and serializer'
46
+ method_option :paranoid, type: :boolean, default: false, desc: 'adds paranoid support to model'
47
+ method_option :scaffold, type: :boolean, default: true, hide: true
48
+ def scaffold(name)
49
+ endpoint(name)
50
+ model(name)
51
+ schema(name)
52
+ serializer(name)
172
53
  end
173
54
 
174
- def create_schema
175
- schema = "./docs/schema/schemata/#{field_name}.yaml"
176
- write_file(schema) do
177
- Prmd.init(name.singularize, yaml: true)
178
- end
179
- display "created schema file #{schema}"
180
- end
55
+ desc 'schema NAME', 'Generates a schema'
56
+ def schema(name)
57
+ require_relative 'generator/schema'
181
58
 
182
- def rebuild_schema
183
- schemata = "./docs/schema.json"
184
- write_file(schemata) do
185
- Prmd.combine("./docs/schema/schemata", meta: "./docs/schema/meta.json")
186
- end
187
- display "rebuilt #{schemata}"
59
+ sc = Schema.new(name, options)
60
+ sc.create
61
+ sc.rebuild
188
62
  end
189
63
 
190
- def create_serializer
191
- serializer = "./lib/serializers/#{name}_serializer.rb"
192
- render_template("serializer.erb", serializer, singular_class_name: singular_class_name)
193
- display "created serializer file #{serializer}"
194
- end
195
-
196
- def create_serializer_test
197
- test = "./spec/serializers/#{name}_serializer_spec.rb"
198
- render_template("serializer_test.erb", test, singular_class_name: singular_class_name)
199
- display "created test #{test}"
200
- end
201
-
202
- def render_template(template_file, destination_path, vars={})
203
- template_path = File.dirname(__FILE__) + "/../templates/#{template_file}"
204
- template = ERB.new(File.read(template_path), 0, ">")
205
- context = OpenStruct.new(vars)
206
- write_file(destination_path) do
207
- template.result(context.instance_eval { binding })
208
- end
209
- end
210
-
211
- def url_path
212
- "/" + name.pluralize.gsub(/_/, '-')
213
- end
64
+ desc 'serializer NAME', 'Generates a serializer'
65
+ def serializer(name)
66
+ require_relative 'generator/serializer'
214
67
 
215
- def write_file(destination_path)
216
- FileUtils.mkdir_p(File.dirname(destination_path))
217
- File.open(destination_path, "w") do |f|
218
- f.puts yield
219
- end
68
+ se = Serializer.new(name, options)
69
+ se.create
70
+ se.create_test
220
71
  end
221
72
  end
222
73
  end