pliny 0.2.1 → 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.
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