napa 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +41 -8
- data/Rakefile +1 -0
- data/docs/grape_entity_to_roar.md +110 -0
- data/docs/quickstart.md +29 -3
- data/lib/napa/active_record_extensions/filter_by_hash.rb +1 -0
- data/lib/napa/active_record_extensions/seeder.rb +14 -0
- data/lib/napa/cli.rb +28 -2
- data/lib/napa/deploy.rb +98 -0
- data/lib/napa/deprecations/active_support_behavior.rb +8 -0
- data/lib/napa/deprecations/application_api.rb +9 -0
- data/lib/napa/deprecations/grape_entity.rb +5 -0
- data/lib/napa/deprecations/napa_setup.rb +38 -0
- data/lib/napa/deprecations.rb +13 -0
- data/lib/napa/gem_dependency.rb +37 -0
- data/lib/napa/generators/migration_generator.rb +199 -2
- data/lib/napa/generators/readme_generator.rb +47 -0
- data/lib/napa/generators/templates/create_table_migration/%migration_filename%.rb.tt +19 -0
- data/lib/napa/generators/templates/migration/%migration_filename%.rb.tt +36 -1
- data/lib/napa/generators/templates/readme/README.md.tt +55 -0
- data/lib/napa/generators/templates/readme/spec/docs/readme_spec.rb +7 -0
- data/lib/napa/generators/templates/scaffold/.env.test.tt +3 -0
- data/lib/napa/generators/templates/scaffold/.env.tt +3 -0
- data/lib/napa/generators/templates/scaffold/.gitignore.tt +1 -0
- data/lib/napa/generators/templates/scaffold/Rakefile +2 -1
- data/lib/napa/generators/templates/scaffold/app.rb +1 -1
- data/lib/napa/generators/templates/scaffold/config.ru.tt +3 -2
- data/lib/napa/generators/templates/scaffold/log/{.gitkeep → .keep} +0 -0
- data/lib/napa/generators.rb +1 -0
- data/lib/napa/middleware/logger.rb +1 -1
- data/lib/napa/middleware/request_stats.rb +0 -2
- data/lib/napa/output_formatters/entity.rb +4 -0
- data/lib/napa/rspec_extensions/response_helpers.rb +29 -0
- data/lib/napa/setup.rb +20 -0
- data/lib/napa/stats_d_timer.rb +1 -1
- data/lib/napa/version.rb +1 -1
- data/lib/napa.rb +19 -1
- data/lib/tasks/db.rake +7 -0
- data/lib/tasks/deploy.rake +2 -4
- data/lib/tasks/routes.rake +4 -3
- data/napa.gemspec +2 -1
- data/spec/active_record_extensions/filter_by_hash_spec.rb +5 -3
- data/spec/active_record_extensions/seeder_spec.rb +13 -0
- data/spec/authentication_spec.rb +3 -3
- data/spec/deprecations/application_api_spec.rb +19 -0
- data/spec/deprecations/entity_spec.rb +9 -0
- data/spec/deprecations/filter_by_hash_spec.rb +9 -0
- data/spec/deprecations/napa_setup_spec.rb +52 -0
- data/spec/generators/api_generator_spec.rb +1 -1
- data/spec/generators/migration_generator_spec.rb +86 -8
- data/spec/generators/readme_generator_spec.rb +35 -0
- data/spec/grape_extensions/error_formatter_spec.rb +6 -6
- data/spec/identity_spec.rb +13 -13
- data/spec/json_error_spec.rb +3 -3
- data/spec/logger/log_transaction_spec.rb +6 -6
- data/spec/middleware/authentication_spec.rb +8 -8
- data/spec/middleware/database_stats_spec.rb +8 -8
- data/spec/middleware/request_stats_spec.rb +2 -11
- data/spec/spec_helper.rb +11 -2
- data/spec/stats_d_timer_spec.rb +23 -0
- data/spec/stats_spec.rb +2 -2
- data/spec/version_spec.rb +6 -6
- metadata +35 -9
- data/lib/tasks/git.rake +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e880773f7d012f8c314fd0d58baf8b321cc0970d
|
4
|
+
data.tar.gz: 0610b2934b4e1edc1a72a0f60883b116240a1f3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15a72bf0f710f598bb027068fe1e9724fd8a21c5e11eae46e1656d4ac051b48dbe82aeae35b2725c1b3d1a4cf1a5692d5f92bc6732d3be3e34457ec563cce99b
|
7
|
+
data.tar.gz: bafddb18590875dc3439383d62fc2d1974aadef74c4debd94937add6e9786370c69b2c39d0d0ebb2b6df5318a8cf766aba94cb9de532b91c6a89aaf7f5c9ed98
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
master
|
2
2
|
===
|
3
3
|
|
4
|
+
0.4.0
|
5
|
+
===
|
6
|
+
* Added `Napa.cache` to wrap `ActiveSupport::Cache`
|
7
|
+
* Added README generator
|
8
|
+
* Update the HoneyBadger scaffolding
|
9
|
+
* Fixed a bug with Napa::StatsDTimer where time was being reported in seconds, not milliseconds
|
10
|
+
* Removed additional StatsD counter metric for request stats middleware
|
11
|
+
* Added new deploy CLI with `force` and `revision` options `napa deploy production`
|
12
|
+
* Added deprecation warnings
|
13
|
+
* Added initialization hook to run code when a Napa service boots
|
14
|
+
* Added Migration generators from Rails
|
15
|
+
* Added rake db:seed functionality
|
16
|
+
* Added some convinience methods to spec_helper
|
17
|
+
|
4
18
|
0.3.0
|
5
19
|
===
|
6
20
|
* Added `rake db:rollback` to rollback migrations just like Rails
|
data/README.md
CHANGED
@@ -35,12 +35,14 @@ Run `napa` terminal prompt to see available features:
|
|
35
35
|
|
36
36
|
```
|
37
37
|
Commands:
|
38
|
-
napa console
|
39
|
-
napa generate api <api_name>
|
40
|
-
napa generate migration <migration_name> # Create a Database Migration
|
41
|
-
napa
|
42
|
-
napa
|
43
|
-
napa
|
38
|
+
napa console [environment] # Start the Napa console
|
39
|
+
napa generate api <api_name> # Create a Grape API, Model and Representer
|
40
|
+
napa generate migration <migration_name> [field[:type][:index] field[:type][:index]] # Create a Database Migration
|
41
|
+
napa generate readme # Create a formatted README
|
42
|
+
napa deploy <environment> # Deploy to <environment> by setting a git tag
|
43
|
+
napa help [COMMAND] # Describe available commands or one specific command
|
44
|
+
napa new <app_name> [app_path] # Create a scaffold for a new Napa service
|
45
|
+
napa version # Shows the Napa version number
|
44
46
|
```
|
45
47
|
|
46
48
|
|
@@ -51,6 +53,21 @@ Similar to the Rails console, load an IRB sesson with your applications environm
|
|
51
53
|
napa console
|
52
54
|
```
|
53
55
|
|
56
|
+
### Deploy
|
57
|
+
Napa provides a CLI for deploying to a given environment by setting a git tag. This is useful for chef-based deploys where deploys are trigged when a git SHA changes.
|
58
|
+
|
59
|
+
```sh
|
60
|
+
napa deploy production
|
61
|
+
Are you sure you want to deploy this service? Y
|
62
|
+
#=> <git SHA> tagged as production by danielmackey at October 09, 2014 14:41
|
63
|
+
```
|
64
|
+
|
65
|
+
If you want to skip the 'Are you sure?' prompt, pass the `--confirm` flag to set the tag automatically
|
66
|
+
```sh
|
67
|
+
napa deploy production --confirm
|
68
|
+
#=> <git SHA> tagged as production by danielmackey at October 09, 2014 14:41
|
69
|
+
```
|
70
|
+
|
54
71
|
### Rake Tasks
|
55
72
|
|
56
73
|
`rake -T` will give you a list of all available rake tasks:
|
@@ -62,8 +79,7 @@ rake db:migrate # Migrate the database through scripts in db/migrate
|
|
62
79
|
rake db:reset # Create the test database
|
63
80
|
rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR
|
64
81
|
rake db:schema:load # Load a schema.rb file into the database
|
65
|
-
rake
|
66
|
-
rake deploy:staging # Deploy to staging
|
82
|
+
rake db:seed # Load the seed data from db/seeds.rb
|
67
83
|
rake git:set_tag[tag] # Set tag, which triggers deploy
|
68
84
|
rake git:verify # Verify git repository is in a good state for deployment
|
69
85
|
rake routes # display all routes for Grape
|
@@ -135,6 +151,23 @@ If you want to see the StatsD reporting in action you can hook up the logger to
|
|
135
151
|
Statsd.logger = Napa::Logger.logger
|
136
152
|
```
|
137
153
|
|
154
|
+
### Caching
|
155
|
+
|
156
|
+
Napa adds a simple wrapper around `ActiveSupport::Cache` that allows you to easily access it similar to how it works in Rails. `Napa.cache` will give you access to all of the methods available in `ActiveSupport::Cache::Store` [http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html](). So, for example:
|
157
|
+
|
158
|
+
```
|
159
|
+
Napa.cache.read
|
160
|
+
Napa.cache.write
|
161
|
+
Napa.cache.fetch
|
162
|
+
...
|
163
|
+
```
|
164
|
+
|
165
|
+
By default it will use `:memory_store`, but you can override it to use any other caching strategy, like Memcache by setting the store:
|
166
|
+
|
167
|
+
```
|
168
|
+
Napa.cache = :dalli_store
|
169
|
+
```
|
170
|
+
|
138
171
|
## Bugs & Feature Requests
|
139
172
|
Please add an issue in [Github](https://github.com/bellycard/napa/issues) if you discover a bug or have a feature request.
|
140
173
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
Converting from Napa::Entity to Napa::Representer
|
2
|
+
=====================================
|
3
|
+
|
4
|
+
The fastest way to figure this out is by example.
|
5
|
+
|
6
|
+
Here are two objects, an Entity and a Representer, that create the __exact same API response__:
|
7
|
+
|
8
|
+
### Entity
|
9
|
+
```ruby
|
10
|
+
class FooEntity < Napa::Entity
|
11
|
+
root :data, :data
|
12
|
+
|
13
|
+
expose :some_attr,
|
14
|
+
:other_attr
|
15
|
+
|
16
|
+
expose :weird_name, as: sane_name
|
17
|
+
|
18
|
+
expose :collection_of_things
|
19
|
+
|
20
|
+
expose :id, format_with: to_s, documentation:
|
21
|
+
{type: 'String', description: 'ID'}
|
22
|
+
|
23
|
+
expose :bar, using: BarEntity
|
24
|
+
expose :caz, using: CazEntity, if: lambda { |instance, opts| opts[:blah] == instance.blah }
|
25
|
+
|
26
|
+
expose :use_a_method do
|
27
|
+
some_property < 100
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
### Representer
|
33
|
+
```ruby
|
34
|
+
class FooRepresenter < Napa::Representer
|
35
|
+
property :some_attr
|
36
|
+
property :other_attr
|
37
|
+
|
38
|
+
property :weird_name, as: sane_name
|
39
|
+
|
40
|
+
collection :collection_of_things
|
41
|
+
|
42
|
+
property :id, type: String
|
43
|
+
|
44
|
+
property :bar, decorator: BarRepresenter
|
45
|
+
property :caz, decorator: CazEntity, if: lambda { |opts| opts[:blah] == @blah }
|
46
|
+
|
47
|
+
property :use_a_method, exec_context: :decorator
|
48
|
+
|
49
|
+
def use_a_method
|
50
|
+
represented.some_property < 100
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Check out the options on Representers if there are other cases:
|
57
|
+
|
58
|
+
https://github.com/apotonick/representable#available-options
|
59
|
+
|
60
|
+
### Some Gotchas
|
61
|
+
|
62
|
+
In your `Grape::API`, you'll something like this for Entities:
|
63
|
+
|
64
|
+
```
|
65
|
+
desc 'whatever', entity: FooEntity
|
66
|
+
get do
|
67
|
+
# code code
|
68
|
+
present foo, with: FooEntity
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
Do this instead:
|
73
|
+
|
74
|
+
```
|
75
|
+
desc 'whatever'
|
76
|
+
get do
|
77
|
+
# code code
|
78
|
+
represent foo, with: FooRepresenter
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
Change `present` to `represent`
|
83
|
+
|
84
|
+
---
|
85
|
+
|
86
|
+
`Napa::Entity` defines the following convenience methods
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
format_with :to_s do |val|
|
90
|
+
val.to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
def object_type
|
94
|
+
object.class.name.underscore
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
These may be defined inline for your Entities if they're not using Napa::Entity
|
99
|
+
|
100
|
+
---
|
101
|
+
|
102
|
+
There is no `Boolean` class in Ruby, but in `Napa:Entity` you can do `type: 'Boolean'`.
|
103
|
+
|
104
|
+
If it's a boolean in the database, you don't have to worry about it. If not, convert it in lambda method:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
class FooRepresenter < Napa::Representer
|
108
|
+
property :some_string, getter: lambda { |opts| @value == "weird" }
|
109
|
+
end
|
110
|
+
```
|
data/docs/quickstart.md
CHANGED
@@ -73,7 +73,7 @@ rspec spec
|
|
73
73
|
|
74
74
|
Now that we have our service scaffolded up, let's generate an API.
|
75
75
|
|
76
|
-
Napa
|
76
|
+
Napa includes an API generator which will create a Grape API, Model and Representer by running:
|
77
77
|
|
78
78
|
```
|
79
79
|
napa generate api person
|
@@ -96,7 +96,7 @@ Done!
|
|
96
96
|
From the output above, we can see that the generated create a `Person` model, so we should create a migration to actually build the table for that in our database. So, let's run:
|
97
97
|
|
98
98
|
```
|
99
|
-
napa generate migration CreatePerson
|
99
|
+
napa generate migration CreatePerson name job_title email
|
100
100
|
```
|
101
101
|
|
102
102
|
You will see the following output:
|
@@ -108,7 +108,7 @@ Generating migration...
|
|
108
108
|
Done!
|
109
109
|
```
|
110
110
|
|
111
|
-
Open up that migration file and
|
111
|
+
Open up that migration file and see the generated migration for the `people` table:
|
112
112
|
|
113
113
|
```ruby
|
114
114
|
class CreatePerson < ActiveRecord::Migration
|
@@ -284,6 +284,32 @@ curl -X PUT -d job_title="Doctor Pepper" http://localhost:9393/people/1
|
|
284
284
|
}
|
285
285
|
```
|
286
286
|
|
287
|
+
## README Generator
|
288
|
+
|
289
|
+
Now that you have an API service, time to document it!
|
290
|
+
|
291
|
+
```
|
292
|
+
napa generate readme
|
293
|
+
```
|
294
|
+
|
295
|
+
**Note:** Napa will have generated a README already, so you'll most likely see the conflict below
|
296
|
+
|
297
|
+
You will see the following output:
|
298
|
+
|
299
|
+
```
|
300
|
+
Generating readme...
|
301
|
+
exist
|
302
|
+
conflict README.md
|
303
|
+
Overwrite /Users/main/workspace/napa/README.md? (enter "h" for help) [Ynaqdh] y
|
304
|
+
force README.md
|
305
|
+
create spec/docs/readme_spec.rb
|
306
|
+
Done!
|
307
|
+
```
|
308
|
+
|
309
|
+
Go through the formatted README and fill out all of the sections that have a :bow:
|
310
|
+
|
311
|
+
- - -
|
312
|
+
|
287
313
|
So, there you have it, a new API service in minutes. It's very basic, but you can continue to build it out from here. One thing to note, we don't generate a `DELETE` request from the generator, but you can easily add that. The resources section below will link you to the Grape docs where you can find those instructions.
|
288
314
|
|
289
315
|
## Resources
|
@@ -0,0 +1,14 @@
|
|
1
|
+
if defined?(ActiveRecord)
|
2
|
+
module Napa
|
3
|
+
class ActiveRecordSeeder
|
4
|
+
def initialize(seed_file)
|
5
|
+
@seed_file = seed_file
|
6
|
+
end
|
7
|
+
|
8
|
+
def load_seed
|
9
|
+
raise "Seed file '#{@seed_file}' does not exist" unless File.file?(@seed_file)
|
10
|
+
load @seed_file
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/napa/cli.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'napa/generators'
|
3
|
+
require 'napa/deploy'
|
3
4
|
require 'napa/version'
|
4
5
|
|
6
|
+
Napa.load_environment if defined?(Dotenv)
|
7
|
+
|
5
8
|
module Napa
|
6
9
|
class CLI
|
7
10
|
class Generate < Thor
|
@@ -15,9 +18,16 @@ module Napa
|
|
15
18
|
register(
|
16
19
|
Generators::MigrationGenerator,
|
17
20
|
'migration',
|
18
|
-
'migration <migration_name>',
|
21
|
+
'migration <migration_name> [field[:type][:index] field[:type][:index]]',
|
19
22
|
'Create a Database Migration'
|
20
23
|
)
|
24
|
+
|
25
|
+
register(
|
26
|
+
Generators::ReadmeGenerator,
|
27
|
+
'readme',
|
28
|
+
'readme',
|
29
|
+
'Create a formatted README'
|
30
|
+
)
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
@@ -53,6 +63,19 @@ module Napa
|
|
53
63
|
interpreter.start
|
54
64
|
end
|
55
65
|
|
66
|
+
desc 'deploy [target]', 'Deploys A Service to a given target (i.e. production, staging, etc.)'
|
67
|
+
method_options :force => :boolean, :revision => :string, :confirm => :boolean
|
68
|
+
def deploy(environment)
|
69
|
+
if options[:confirm] || yes?('Are you sure you want to deploy this service?', Thor::Shell::Color::YELLOW)
|
70
|
+
deploy = Napa::Deploy.new(environment, force: options[:force], revision: options[:revision])
|
71
|
+
if deploy.deployable?
|
72
|
+
say(deploy.deploy!, Thor::Shell::Color::GREEN)
|
73
|
+
else
|
74
|
+
say("Deploy Failed:\n#{deploy.errors.join("\n")}", Thor::Shell::Color::RED)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
56
79
|
register(
|
57
80
|
Generators::ScaffoldGenerator,
|
58
81
|
'new',
|
@@ -63,8 +86,11 @@ module Napa
|
|
63
86
|
desc "generate api <api_name>", "Create a Grape API, Model and Representer"
|
64
87
|
subcommand "generate api", Napa::CLI::Generate
|
65
88
|
|
66
|
-
desc "generate migration <migration_name>", "Create a Database Migration"
|
89
|
+
desc "generate migration <migration_name> [field[:type][:index] field[:type][:index]]", "Create a Database Migration"
|
67
90
|
subcommand "generate", Napa::CLI::Generate
|
91
|
+
|
92
|
+
desc "generate readme", "Create a formatted README"
|
93
|
+
subcommand "generate readme", Napa::CLI::Generate
|
68
94
|
end
|
69
95
|
end
|
70
96
|
end
|
data/lib/napa/deploy.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'git'
|
2
|
+
require 'octokit'
|
3
|
+
|
4
|
+
module Napa
|
5
|
+
class Deploy
|
6
|
+
attr_reader :errors, :github_login
|
7
|
+
|
8
|
+
def initialize(environment, revision: nil, force: false, github_repo: nil, github_token: nil)
|
9
|
+
Napa.load_environment
|
10
|
+
|
11
|
+
@github_repo = github_repo || ENV['GITHUB_REPO']
|
12
|
+
@github_token = github_token || ENV['GITHUB_OAUTH_TOKEN']
|
13
|
+
@environment = environment
|
14
|
+
@revision = revision || local_head_revision
|
15
|
+
@force = force
|
16
|
+
|
17
|
+
@errors = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def deploy!
|
21
|
+
if deployable?
|
22
|
+
set_github_tag
|
23
|
+
"#{@revision} tagged as #{@environment} by #{@github_login} at #{Time.now.to_s(:long)}"
|
24
|
+
else
|
25
|
+
"Deploy error(s): #{@errors.join(' --- ')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_github_tag
|
30
|
+
begin
|
31
|
+
github_client.update_ref(
|
32
|
+
@github_repo,
|
33
|
+
"tags/#{@environment}",
|
34
|
+
@revision,
|
35
|
+
@force
|
36
|
+
)
|
37
|
+
rescue Octokit::UnprocessableEntity
|
38
|
+
github_client.create_ref(
|
39
|
+
@github_repo,
|
40
|
+
"tags/#{@environment}",
|
41
|
+
@revision
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def local_repo
|
47
|
+
@local_repo ||= Git.open('.')
|
48
|
+
end
|
49
|
+
|
50
|
+
def local_repo_status
|
51
|
+
@local_repo_status ||= local_repo.status
|
52
|
+
end
|
53
|
+
|
54
|
+
def github_client
|
55
|
+
return @github_client if @github_client
|
56
|
+
@errors << "ENV['GITHUB_REPO'] is not defined" if @github_repo.nil?
|
57
|
+
@errors << "ENV['GITHUB_OAUTH_TOKEN'] is not defined" if @github_token.nil?
|
58
|
+
|
59
|
+
client = Octokit::Client.new(access_token: @github_token)
|
60
|
+
begin
|
61
|
+
@github_login = client.login
|
62
|
+
return @github_client = client
|
63
|
+
rescue Octokit::Unauthorized
|
64
|
+
@errors << "Access denied for GITHUB_OAUTH_TOKEN"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def local_head_revision
|
69
|
+
local_repo.object('HEAD').sha
|
70
|
+
end
|
71
|
+
|
72
|
+
def deployable?
|
73
|
+
revision_exists_on_github?
|
74
|
+
any_local_uncommited_changes?
|
75
|
+
any_local_untracked_files?
|
76
|
+
|
77
|
+
@errors.empty? || @force
|
78
|
+
end
|
79
|
+
|
80
|
+
def revision_exists_on_github?
|
81
|
+
begin
|
82
|
+
github_client.commit(@github_repo, @revision)
|
83
|
+
rescue Octokit::NotFound
|
84
|
+
@errors << "Revision #{@revision} does not exist on #{@github_repo}, make sure you've merged your changes."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def any_local_uncommited_changes?
|
89
|
+
changes = local_repo_status.changed.collect{|change| change[0]}
|
90
|
+
@errors << "#{changes.to_sentence} have been changed and not committed." if changes.any?
|
91
|
+
end
|
92
|
+
|
93
|
+
def any_local_untracked_files?
|
94
|
+
changes = local_repo_status.untracked.collect{|change| change[0]}
|
95
|
+
@errors << "#{changes.to_sentence} file(s) have been added and are not tracked." if changes.any?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
if Napa.env.test?
|
2
|
+
ActiveSupport::Deprecation.behavior = :stderr
|
3
|
+
else
|
4
|
+
ActiveSupport::Deprecation.behavior = ->(message, callstack) {
|
5
|
+
# ignoring callstack for now because it's fairly noisy
|
6
|
+
Napa::Logger.logger.info(napa_deprecation_warning: message)
|
7
|
+
}
|
8
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Napa
|
2
|
+
class Deprecations
|
3
|
+
def self.application_api_check
|
4
|
+
unless File.exists?('./app/apis/application_api.rb')
|
5
|
+
ActiveSupport::Deprecation.warn 'no application_api.rb file found in app/apis, see https://github.com/bellycard/napa/blob/master/lib/napa/generators/templates/scaffold/app/apis/application_api.rb for an example', caller
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Napa
|
2
|
+
class Deprecations
|
3
|
+
REQUIRED_PATTERNS = [
|
4
|
+
/require 'bundler\/setup'/,
|
5
|
+
/Bundler.setup\(:default\)/,
|
6
|
+
/require 'napa\/setup'/,
|
7
|
+
/Bundler.require\(:default, Napa.env.to_sym\)/,
|
8
|
+
/require 'napa'/,
|
9
|
+
/Napa.load_environment/,
|
10
|
+
/Dir['.\/config\/initializers\/**\/*.rb'].map { |file| require file }/,
|
11
|
+
/Dir['.\/config\/middleware\/**\/*.rb'].map { |file| require file }/,
|
12
|
+
/relative_load_paths/,
|
13
|
+
/ActiveSupport::Dependencies.autoload_paths \+\= relative_load_paths/
|
14
|
+
]
|
15
|
+
|
16
|
+
EXPIRED_PATTERNS = [
|
17
|
+
/require 'dotenv'/,
|
18
|
+
"RACK_ENV = ENV['RACK_ENV']",
|
19
|
+
"if RACK_ENV == 'test'",
|
20
|
+
/Dotenv.load\(".env.test"\)/,
|
21
|
+
/Dotenv.load\(Napa.env.test\? \? '.env.test' : '.env'\)/,
|
22
|
+
/Bundler.require :default, RACK_ENV/,
|
23
|
+
/require 'will_paginate'/,
|
24
|
+
/require 'will_paginate\/active_record'/
|
25
|
+
]
|
26
|
+
|
27
|
+
def self.napa_setup_check
|
28
|
+
required_patterns_regex = Regexp.union(REQUIRED_PATTERNS)
|
29
|
+
expired_patterns_regex = Regexp.union(EXPIRED_PATTERNS)
|
30
|
+
|
31
|
+
if File.exists?('./app.rb')
|
32
|
+
if File.readlines('./app.rb').grep(expired_patterns_regex).any? || (File.readlines('./app.rb').grep(required_patterns_regex).count < REQUIRED_PATTERNS.count)
|
33
|
+
ActiveSupport::Deprecation.warn 'app.rb is out of date, please update your configuration', caller
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'napa/deprecations/active_support_behavior'
|
2
|
+
require 'napa/deprecations/application_api'
|
3
|
+
require 'napa/deprecations/napa_setup'
|
4
|
+
require 'napa/deprecations/grape_entity'
|
5
|
+
|
6
|
+
module Napa
|
7
|
+
class Deprecations
|
8
|
+
def self.initialization_checks
|
9
|
+
napa_setup_check
|
10
|
+
application_api_check
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support/json'
|
2
|
+
|
3
|
+
module Napa
|
4
|
+
class GemDependency
|
5
|
+
def self.log_all
|
6
|
+
Napa::Logger.logger.info(gems: list_all.as_json)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.list_all
|
10
|
+
Gem.loaded_specs.map { |spec| new(spec).to_hash }
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(spec)
|
14
|
+
@spec = spec[1]
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
@spec.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def version
|
22
|
+
@spec.version.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_version
|
26
|
+
@spec.git_version
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
{}.tap do |h|
|
31
|
+
h[:name] = name
|
32
|
+
h[:version] = version
|
33
|
+
h[:git_version] = git_version if git_version
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|