napa 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/LICENSE +4 -2
- data/README.md +25 -2
- data/docs/quickstart.md +27 -26
- data/lib/napa.rb +6 -2
- data/lib/napa/active_record_extensions/notifications_subscriber.rb +17 -0
- data/lib/napa/active_record_extensions/stats.rb +1 -14
- data/lib/napa/cli.rb +5 -2
- data/lib/napa/generators/api_generator.rb +5 -1
- data/lib/napa/generators/migration_generator.rb +6 -2
- data/lib/napa/generators/scaffold_generator.rb +4 -3
- data/lib/napa/generators/templates/api/app/apis/%name_tableize%_api.rb.tt +4 -5
- data/lib/napa/generators/templates/api/app/models/%name_underscore%.rb.tt +0 -1
- data/lib/napa/generators/templates/api/spec/apis/%name_tableize%_api_spec.rb.tt +16 -0
- data/lib/napa/generators/templates/api/spec/models/%name_underscore%_spec.rb.tt +9 -0
- data/lib/napa/generators/templates/migration/%migration_filename%.rb.tt +1 -1
- data/lib/napa/generators/templates/scaffold/.gitignore.tt +2 -0
- data/lib/napa/generators/templates/scaffold/Gemfile.tt +2 -2
- data/lib/napa/generators/templates/scaffold/app.rb +1 -1
- data/lib/napa/generators/templates/scaffold/config.ru.tt +1 -1
- data/lib/napa/generators/templates/scaffold/config/database.yml.tt +1 -0
- data/lib/napa/generators/templates/scaffold/spec/apis/hello_api_spec.rb.tt +1 -1
- data/lib/napa/generators/templates/scaffold/spec/spec_helper.rb +15 -2
- data/lib/napa/grape_extenders.rb +6 -2
- data/lib/napa/grape_extensions/error_formatter.rb +1 -1
- data/lib/napa/grape_extensions/grape_helpers.rb +8 -1
- data/lib/napa/logger/logger.rb +10 -0
- data/lib/napa/logger/parseable.rb +37 -0
- data/lib/napa/middleware/app_monitor.rb +1 -1
- data/lib/napa/middleware/database_stats.rb +15 -0
- data/lib/napa/middleware/logger.rb +6 -11
- data/lib/napa/middleware/request_stats.rb +7 -5
- data/lib/napa/{grape_extensions → output_formatters}/entity.rb +0 -0
- data/lib/napa/output_formatters/include_nil.rb +16 -0
- data/lib/napa/{grape_extensions → output_formatters}/representer.rb +2 -2
- data/lib/napa/rspec_extensions/response_helpers.rb +17 -0
- data/lib/napa/stats.rb +21 -1
- data/lib/napa/version.rb +1 -1
- data/lib/tasks/db.rake +7 -0
- data/lib/tasks/git.rake +3 -0
- data/napa.gemspec +0 -1
- data/spec/generators/api_generator_spec.rb +63 -0
- data/spec/generators/migration_generator_spec.rb +27 -0
- data/spec/generators/scaffold_generator_spec.rb +90 -0
- data/spec/grape_extensions/error_formatter_spec.rb +8 -0
- data/spec/grape_extensions/include_nil_spec.rb +23 -0
- data/spec/logger/logger_spec.rb +14 -0
- data/spec/logger/parseable_spec.rb +16 -0
- data/spec/middleware/database_stats_spec.rb +64 -0
- data/spec/middleware/request_stats_spec.rb +4 -5
- data/spec/spec_helper.rb +26 -0
- data/spec/stats_spec.rb +25 -1
- metadata +25 -20
- data/spec/active_record_extensions/stats_spec.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0eeeb8e92f9f844abe34b2a0545655227c5d493f
|
4
|
+
data.tar.gz: 2d38e5b45cab67654e24388746a3c46eb168739c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac876295c7e2f01d861766a12efe01302ae3b0bf816773cc34e2a99a41fd6698821b5fc86db54f1247383cae5e3656ffe56a472f8c44bae7c3c56ccf385a4ff0
|
7
|
+
data.tar.gz: 9bb036efa3d541e90c8aa20a3b6f088daa6d4f55d17d7acb22e7ffa4786b432aba6513974a2d0459081058b86fc5e70662ba3462a01947634dddfc53453fccb1
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
master
|
2
2
|
===
|
3
3
|
|
4
|
+
0.3.0
|
5
|
+
===
|
6
|
+
* Added `rake db:rollback` to rollback migrations just like Rails
|
7
|
+
* Fixed bug in migration generator causing constant not defined errors
|
8
|
+
* Fixed CORS config in scaffold generator
|
9
|
+
* Fixed logging bug in grape_extenders
|
10
|
+
* Set UTF-8 encoding in generated database.yml
|
11
|
+
* Removed unneeded gem dependencies (shotgun and unicorn)
|
12
|
+
* Fixed spec_helper that gets generated to ignore spec files and gems (on CI servers)
|
13
|
+
* Added spec response helpers `parsed_response`, `response_code` and `response_body` to make tests easier to DRY up
|
14
|
+
* Removed #filter and `include Napa::FilterByHash` from generated code.
|
15
|
+
* Fix when using IRB and napa console
|
16
|
+
* Added IncludeNil module for Representable/Roar output
|
17
|
+
* Template updates to include spec files for APIs
|
18
|
+
* Removing FilterByHash in the API template
|
19
|
+
* Fix when ErrorFormatter is passed a non-hash
|
20
|
+
* Added more descriptive messages on git based deploy errors
|
21
|
+
* Added RequestStats and DatabaseStats middlewares to report data to StatsD
|
22
|
+
* All String logs are now wrapped in a hash before being written to the log file
|
23
|
+
|
4
24
|
0.2.1
|
5
25
|
===
|
6
26
|
* Updated Napa console. It now takes an optional environment parameter, i.e. `napa console production`.
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2013
|
1
|
+
Copyright (c) 2013 Bellycard Inc.
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,6 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
“Napa”, and the Napa logo are registered trademarks of Bellycard Inc. All rights reserved.
|
data/README.md
CHANGED
@@ -36,7 +36,7 @@ Run `napa` terminal prompt to see available features:
|
|
36
36
|
```
|
37
37
|
Commands:
|
38
38
|
napa console # Start the Napa console
|
39
|
-
napa generate api <api_name> # Create a Grape API, Model and Representer
|
39
|
+
napa generate api <api_name> # Create a Grape API, Model and Representer, api_name should be singular i.e. user
|
40
40
|
napa generate migration <migration_name> # Create a Database Migration
|
41
41
|
napa help [COMMAND] # Describe available commands or one specific command
|
42
42
|
napa new <app_name> [app_path] # Create a scaffold for a new Napa service
|
@@ -94,7 +94,7 @@ The Health Check middleware will add an endpoint at `/health` that will return s
|
|
94
94
|
```
|
95
95
|
|
96
96
|
### Logger
|
97
|
-
The *Logger*
|
97
|
+
The *Logger* module is used to create a common log format across applications. The Logger is enable via a rack middleware by adding the line below to your `config.ru` file:
|
98
98
|
|
99
99
|
```ruby
|
100
100
|
use Napa::Middleware::Logger
|
@@ -111,6 +111,29 @@ ActiveRecord::Base.logger = Napa::Logger.logger
|
|
111
111
|
```ruby
|
112
112
|
Napa::Logger.logger.debug 'Some Debug Message'
|
113
113
|
```
|
114
|
+
### StatsD
|
115
|
+
There are two middlewares available to enable StatsD reporting, `RequestStats` and `DatabaseStats`. They can be enabled independently in your `config.ru` file:
|
116
|
+
|
117
|
+
```
|
118
|
+
use Napa::Middleware::RequestStats
|
119
|
+
use Napa::Middleware::DatabaseStats
|
120
|
+
```
|
121
|
+
|
122
|
+
**RequestStats** will emit information about your application's request count and response time.
|
123
|
+
|
124
|
+
**DatabaseStats** will emit information from ActiveRecord about query times.
|
125
|
+
|
126
|
+
##### Configuration
|
127
|
+
|
128
|
+
To configure StatsD in your application you will need to supply the `STATSD_HOST` and `STATSD_PORT` in your environment. Optionally, if your StatsD host requires an api token (i.e. hostedgraphite), you can configure that with the `STATSD_API_KEY` environment variable.
|
129
|
+
|
130
|
+
##### Logging
|
131
|
+
|
132
|
+
If you want to see the StatsD reporting in action you can hook up the logger to the Napa logger to see the requests in your logs.
|
133
|
+
|
134
|
+
```
|
135
|
+
Statsd.logger = Napa::Logger.logger
|
136
|
+
```
|
114
137
|
|
115
138
|
## Bugs & Feature Requests
|
116
139
|
Please add an issue in [Github](https://github.com/bellycard/napa/issues) if you discover a bug or have a feature request.
|
data/docs/quickstart.md
CHANGED
@@ -13,7 +13,7 @@ gem install napa
|
|
13
13
|
In this example we will create a new API to manage a directory of people. Each person will have a `name`, `job_title` and `email_address`. To get started, create a new scaffold by running:
|
14
14
|
|
15
15
|
```
|
16
|
-
napa new
|
16
|
+
napa new people-service
|
17
17
|
```
|
18
18
|
|
19
19
|
**Note:** by default, Napa will configure itself to use Mysql. If you prefer to use Postgres, simply pass in the `-d=pg` option to the `napa new` command.
|
@@ -22,33 +22,33 @@ You will see the following output:
|
|
22
22
|
|
23
23
|
```
|
24
24
|
Generating scaffold...
|
25
|
-
create
|
26
|
-
create
|
27
|
-
create
|
28
|
-
create
|
29
|
-
create
|
30
|
-
create
|
31
|
-
create
|
32
|
-
create
|
33
|
-
create
|
34
|
-
create
|
35
|
-
create
|
36
|
-
create
|
37
|
-
create
|
38
|
-
create
|
39
|
-
create
|
40
|
-
create
|
41
|
-
create
|
42
|
-
create
|
43
|
-
create
|
44
|
-
create
|
45
|
-
create
|
46
|
-
create
|
47
|
-
create
|
25
|
+
create people-service
|
26
|
+
create people-service/.env.test
|
27
|
+
create people-service/.env
|
28
|
+
create people-service/.gitignore
|
29
|
+
create people-service/.rubocop.yml
|
30
|
+
create people-service/.ruby-gemset
|
31
|
+
create people-service/.ruby-version
|
32
|
+
create people-service/Gemfile
|
33
|
+
create people-service/README.md
|
34
|
+
create people-service/Rakefile
|
35
|
+
create people-service/app.rb
|
36
|
+
create people-service/app/apis/application_api.rb
|
37
|
+
create people-service/app/apis/hello_api.rb
|
38
|
+
create people-service/config.ru
|
39
|
+
create people-service/config/database.yml
|
40
|
+
create people-service/config/initializers/active_record.rb
|
41
|
+
create people-service/config/middleware/honeybadger.rb
|
42
|
+
create people-service/db/schema.rb
|
43
|
+
create people-service/lib/.keep
|
44
|
+
create people-service/log/.gitkeep
|
45
|
+
create people-service/spec/apis/hello_api_spec.rb
|
46
|
+
create people-service/spec/factories/.gitkeep
|
47
|
+
create people-service/spec/spec_helper.rb
|
48
48
|
Done!
|
49
49
|
```
|
50
50
|
|
51
|
-
Now, change into the `
|
51
|
+
Now, change into the `people-service` directory and run Bundler to get all the gems you need:
|
52
52
|
|
53
53
|
```
|
54
54
|
bundle install
|
@@ -238,6 +238,7 @@ All response from Napa include the `data` key. In this case, we see an array con
|
|
238
238
|
{
|
239
239
|
"data": [
|
240
240
|
{
|
241
|
+
"object_type": "person",
|
241
242
|
"id": 1,
|
242
243
|
"name": "Darby Frey",
|
243
244
|
"job_title": "Software Engineer",
|
@@ -287,6 +288,6 @@ So, there you have it, a new API service in minutes. It's very basic, but you ca
|
|
287
288
|
|
288
289
|
## Resources
|
289
290
|
|
290
|
-
* [Code Example:
|
291
|
+
* [Code Example: people_service](https://github.com/darbyfrey/people_service)
|
291
292
|
* [Grape](http://intridea.github.io/grape/)
|
292
293
|
* [Roar](https://github.com/apotonick/roar)
|
data/lib/napa.rb
CHANGED
@@ -12,19 +12,23 @@ require 'napa/setup'
|
|
12
12
|
require 'napa/version'
|
13
13
|
require 'napa/logger/logger'
|
14
14
|
require 'napa/logger/log_transaction'
|
15
|
+
require 'napa/logger/parseable'
|
15
16
|
require 'napa/identity'
|
16
17
|
require 'napa/json_error'
|
17
18
|
require 'napa/stats'
|
18
19
|
require 'napa/active_record_extensions/filter_by_hash'
|
20
|
+
require 'napa/active_record_extensions/stats'
|
19
21
|
require 'napa/grape_extensions/error_formatter'
|
20
22
|
require 'napa/grape_extensions/grape_helpers'
|
21
|
-
require 'napa/
|
22
|
-
require 'napa/
|
23
|
+
require 'napa/output_formatters/entity'
|
24
|
+
require 'napa/output_formatters/include_nil'
|
25
|
+
require 'napa/output_formatters/representer'
|
23
26
|
require 'napa/grape_extenders'
|
24
27
|
require 'napa/middleware/logger'
|
25
28
|
require 'napa/middleware/app_monitor'
|
26
29
|
require 'napa/middleware/authentication'
|
27
30
|
require 'napa/middleware/request_stats'
|
31
|
+
require 'napa/middleware/database_stats'
|
28
32
|
require 'napa/authentication'
|
29
33
|
|
30
34
|
# load rake tasks if Rake installed
|
@@ -0,0 +1,17 @@
|
|
1
|
+
if defined?(ActiveRecord)
|
2
|
+
ActiveSupport::Notifications.subscribe 'sql.active_record' do |name, start, finish, id, payload|
|
3
|
+
if payload[:sql].downcase.match(/(select|update|insert|delete)(.+)/i)
|
4
|
+
table, action = Napa::ActiveRecordStats.extract_sql_content(payload[:sql])
|
5
|
+
end
|
6
|
+
|
7
|
+
if table
|
8
|
+
Napa::Stats.emitter.timing(
|
9
|
+
"sql.query_time",
|
10
|
+
(finish - start) * 1000)
|
11
|
+
|
12
|
+
Napa::Stats.emitter.timing(
|
13
|
+
"sql.table.#{table}.#{action.downcase}.query_time",
|
14
|
+
(finish - start) * 1000)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
if defined?(ActiveSupport)
|
1
|
+
if defined?(ActiveSupport) && defined?(ActiveRecord)
|
2
2
|
module Napa
|
3
3
|
module ActiveRecordStats
|
4
4
|
SQL_INSERT_DELETE_PARSER_REGEXP = /^(?<action>\w+)\s(\w+)\s\W*(?<table>\w+)/
|
@@ -32,19 +32,6 @@ if defined?(ActiveSupport)
|
|
32
32
|
end
|
33
33
|
[table, action]
|
34
34
|
end
|
35
|
-
|
36
|
-
ActiveSupport::Notifications.subscribe 'sql.active_record' do |name, start, finish, id, payload|
|
37
|
-
if payload[:sql].match(/(select|update|insert|delete)(.+)/i)
|
38
|
-
table, action = extract_sql_content(payload[:sql])
|
39
|
-
end
|
40
|
-
|
41
|
-
if table
|
42
|
-
stat_context = "#{Thread.current[:stats_context] || Napa::Identity.name + '.unknown'}"
|
43
|
-
Napa::Stats.emitter.timing(
|
44
|
-
"#{stat_context}.sql.#{table}.#{action.downcase}.query_time",
|
45
|
-
(finish - start) * 1000)
|
46
|
-
end
|
47
|
-
end
|
48
35
|
end
|
49
36
|
end
|
50
37
|
end
|
data/lib/napa/cli.rb
CHANGED
@@ -30,8 +30,8 @@ module Napa
|
|
30
30
|
|
31
31
|
desc 'console [environment]', 'Start the Napa console'
|
32
32
|
options aliases: 'c'
|
33
|
-
def console(environment =
|
34
|
-
ENV['RACK_ENV'] = environment
|
33
|
+
def console(environment = nil)
|
34
|
+
ENV['RACK_ENV'] = environment || 'development'
|
35
35
|
|
36
36
|
require 'racksh/init'
|
37
37
|
|
@@ -42,6 +42,9 @@ module Napa
|
|
42
42
|
require "irb"
|
43
43
|
require "irb/completion"
|
44
44
|
interpreter = IRB
|
45
|
+
# IRB uses ARGV and does not expect these arguments.
|
46
|
+
ARGV.delete('console')
|
47
|
+
ARGV.delete(environment) if environment
|
45
48
|
end
|
46
49
|
|
47
50
|
Rack::Shell.init
|
@@ -15,10 +15,14 @@ module Napa
|
|
15
15
|
name.tableize
|
16
16
|
end
|
17
17
|
|
18
|
+
def output_directory
|
19
|
+
'.'
|
20
|
+
end
|
21
|
+
|
18
22
|
def api
|
19
23
|
self.class.source_root "#{File.dirname(__FILE__)}/templates/api"
|
20
24
|
say 'Generating api...'
|
21
|
-
directory '.',
|
25
|
+
directory '.', output_directory
|
22
26
|
say 'Done!', :green
|
23
27
|
end
|
24
28
|
end
|
@@ -15,12 +15,16 @@ module Napa
|
|
15
15
|
"#{version}_#{migration_name.underscore}"
|
16
16
|
end
|
17
17
|
|
18
|
+
def output_directory
|
19
|
+
'./db/migrate'
|
20
|
+
end
|
21
|
+
|
18
22
|
def migration
|
19
23
|
self.class.source_root "#{File.dirname(__FILE__)}/templates/migration"
|
20
24
|
say 'Generating migration...'
|
21
|
-
directory '.',
|
25
|
+
directory '.', output_directory
|
22
26
|
say 'Done!', :green
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
26
|
-
end
|
30
|
+
end
|
@@ -15,9 +15,10 @@ module Napa
|
|
15
15
|
def generate
|
16
16
|
say 'Generating scaffold...'
|
17
17
|
|
18
|
-
@database_gem
|
19
|
-
@database_adapter
|
20
|
-
@
|
18
|
+
@database_gem = ['pg','postgres'].include?(options[:database]) ? 'pg' : 'mysql2'
|
19
|
+
@database_adapter = ['pg','postgres'].include?(options[:database]) ? 'postgresql' : 'mysql2'
|
20
|
+
@database_encoding = ['pg','postgres'].include?(options[:database]) ? 'unicode' : 'utf8'
|
21
|
+
@database_user = ['pg','postgres'].include?(options[:database]) ? '' : 'root'
|
21
22
|
|
22
23
|
directory ".", (app_path || app_name)
|
23
24
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class <%= name.classify.pluralize %>Api < Grape::API
|
2
2
|
desc 'Get a list of <%= name.underscore.tableize %>'
|
3
3
|
params do
|
4
|
-
optional :ids, type:
|
4
|
+
optional :ids, type: Array, desc: 'Array of <%= name.underscore %> ids'
|
5
5
|
end
|
6
6
|
get do
|
7
|
-
<%= name.underscore.tableize %> = <%= name.classify %>.
|
7
|
+
<%= name.underscore.tableize %> = params[:ids] ? <%= name.classify %>.where(id: params[:ids]) : <%= name.classify %>.all
|
8
8
|
represent <%= name.underscore.tableize %>, with: <%= name.classify %>Representer
|
9
9
|
end
|
10
10
|
|
@@ -13,8 +13,7 @@ class <%= name.classify.pluralize %>Api < Grape::API
|
|
13
13
|
end
|
14
14
|
|
15
15
|
post do
|
16
|
-
<%= name.underscore %> = <%= name.classify %>.create(
|
17
|
-
error!(present_error(:record_invalid, <%= name.underscore %>.errors.full_messages)) unless <%= name.underscore %>.errors.empty?
|
16
|
+
<%= name.underscore %> = <%= name.classify %>.create!(permitted_params)
|
18
17
|
represent <%= name.underscore %>, with: <%= name.classify %>Representer
|
19
18
|
end
|
20
19
|
|
@@ -34,7 +33,7 @@ class <%= name.classify.pluralize %>Api < Grape::API
|
|
34
33
|
put do
|
35
34
|
# fetch <%= name.underscore %> record and update attributes. exceptions caught in app.rb
|
36
35
|
<%= name.underscore %> = <%= name.classify %>.find(params[:id])
|
37
|
-
<%= name.underscore %>.update_attributes!(
|
36
|
+
<%= name.underscore %>.update_attributes!(permitted_params)
|
38
37
|
represent <%= name.underscore %>, with: <%= name.classify %>Representer
|
39
38
|
end
|
40
39
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def app
|
4
|
+
ApplicationApi
|
5
|
+
end
|
6
|
+
|
7
|
+
describe <%= name.classify.pluralize %>Api do
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
describe 'e.g. GET, POST, PUT, etc.' do
|
11
|
+
it 'needs tests to be written!' do
|
12
|
+
pending('write tests for <%= name.classify.pluralize %>Api!')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -6,7 +6,6 @@ gem '<%= @database_gem %>'
|
|
6
6
|
gem 'activerecord', '~> 4.0.0', :require => 'active_record'
|
7
7
|
gem 'honeybadger'
|
8
8
|
gem 'json'
|
9
|
-
gem 'shotgun'
|
10
9
|
gem 'napa'
|
11
10
|
gem 'roar'
|
12
11
|
gem 'grape-swagger'
|
@@ -16,7 +15,8 @@ group :development,:test do
|
|
16
15
|
end
|
17
16
|
|
18
17
|
group :development do
|
19
|
-
gem 'rubocop'
|
18
|
+
gem 'rubocop', require: false
|
19
|
+
gem 'shotgun', require: false
|
20
20
|
end
|
21
21
|
|
22
22
|
group :test do
|
@@ -15,5 +15,5 @@ Dir['./config/initializers/**/*.rb'].map { |file| require file }
|
|
15
15
|
Dir['./config/middleware/**/*.rb'].map { |file| require file }
|
16
16
|
|
17
17
|
# autoload app
|
18
|
-
relative_load_paths = %w
|
18
|
+
relative_load_paths = %w(app/apis app/representers app/models app/workers lib)
|
19
19
|
ActiveSupport::Dependencies.autoload_paths += relative_load_paths
|