senor_armando 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +49 -0
- data/.rspec +3 -0
- data/FEATURES.txt +20 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +112 -0
- data/LICENSE.txt +20 -0
- data/README.md +39 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/bin/armando_echo.rb +16 -0
- data/bin/armando_elsewhere.rb +41 -0
- data/bin/armando_gemfile_jail.rb +114 -0
- data/bin/armando_proxy.rb +17 -0
- data/config/app.example.yaml +8 -0
- data/config/app.rb +1 -0
- data/config/app.yaml +8 -0
- data/lib/boot.rb +13 -0
- data/lib/senor_armando.rb +20 -0
- data/lib/senor_armando/endpoint/echo.rb +21 -0
- data/lib/senor_armando/endpoint/proxy.rb +65 -0
- data/lib/senor_armando/error.rb +103 -0
- data/lib/senor_armando/plugins/statsd_plugin.rb +95 -0
- data/lib/senor_armando/rack/exception_handler.rb +75 -0
- data/lib/senor_armando/rack/statsd_logger.rb +35 -0
- data/lib/senor_armando/rack/tracer.rb +14 -0
- data/lib/senor_armando/spec/he_help_me_test.rb +35 -0
- data/lib/senor_armando/tasks.rb +3 -0
- data/lib/senor_armando/tasks/rspec.rake +20 -0
- data/lib/senor_armando/tasks/yard.rake +2 -0
- data/lib/senor_armando/use_gemfile_jail.rb +74 -0
- data/senor_armando.gemspec +175 -0
- data/senor_armando.jpeg +0 -0
- data/spec/armando_proxy_spec.rb +107 -0
- data/spec/spec_helper.rb +27 -0
- metadata +454 -0
data/.gitignore
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
## OS
|
2
|
+
.DS_Store
|
3
|
+
Icon?
|
4
|
+
nohup.out
|
5
|
+
.bak
|
6
|
+
|
7
|
+
## EDITORS
|
8
|
+
\#*
|
9
|
+
.#*
|
10
|
+
*~
|
11
|
+
*.swp
|
12
|
+
REVISION
|
13
|
+
TAGS*
|
14
|
+
tmtags
|
15
|
+
*_flymake.*
|
16
|
+
*_flymake
|
17
|
+
*.tmproj
|
18
|
+
.project
|
19
|
+
.settings
|
20
|
+
mkmf.log
|
21
|
+
|
22
|
+
## COMPILED
|
23
|
+
a.out
|
24
|
+
*.o
|
25
|
+
*.pyc
|
26
|
+
*.so
|
27
|
+
|
28
|
+
## OTHER SCM
|
29
|
+
.bzr
|
30
|
+
.hg
|
31
|
+
.svn
|
32
|
+
|
33
|
+
## PROJECT::GENERAL
|
34
|
+
coverage
|
35
|
+
rdoc
|
36
|
+
doc
|
37
|
+
pkg
|
38
|
+
.yardoc
|
39
|
+
*private.yaml
|
40
|
+
*private.rb
|
41
|
+
.bundle
|
42
|
+
db/*.sqlite3
|
43
|
+
log/*.log*
|
44
|
+
tmp/**/*
|
45
|
+
|
46
|
+
## PROJECT::SPECIFIC
|
47
|
+
|
48
|
+
.vendor
|
49
|
+
.bundle
|
data/.rspec
ADDED
data/FEATURES.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
ArmandoProxy
|
3
|
+
responds to requests by forwarding to a given responder
|
4
|
+
responds to requests
|
5
|
+
forwards to our API server
|
6
|
+
HTTP header handling
|
7
|
+
transforms back properly
|
8
|
+
query parameters
|
9
|
+
forwards the query parameters
|
10
|
+
request path
|
11
|
+
forwards the request path
|
12
|
+
headers
|
13
|
+
forwards the headers
|
14
|
+
request method
|
15
|
+
forwards GET requests
|
16
|
+
forwards POST requests
|
17
|
+
forwards POST requests
|
18
|
+
|
19
|
+
Finished in 0.03642 seconds
|
20
|
+
10 examples, 0 failures
|
data/Gemfile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'gorillib', "~> 0.1.0"
|
4
|
+
gem 'yajl-ruby', "~> 0.8.2"
|
5
|
+
gem 'configliere', "~> 0.4.7"
|
6
|
+
gem 'postrank-uri', "~> 1.0.9"
|
7
|
+
|
8
|
+
# you may want to link these two in ./lib if you're developing
|
9
|
+
gem 'goliath', :git => 'https://github.com/postrank-labs/goliath.git'
|
10
|
+
|
11
|
+
gem 'eventmachine', :git => 'https://github.com/eventmachine/eventmachine.git'
|
12
|
+
gem 'em-synchrony', :git => 'https://github.com/igrigorik/em-synchrony.git'
|
13
|
+
gem 'em-http-request', :git => 'https://github.com/igrigorik/em-http-request.git'
|
14
|
+
|
15
|
+
# Add dependencies to develop your gem here.
|
16
|
+
# Include everything needed to run rake, tests, features, etc.
|
17
|
+
group :development do
|
18
|
+
gem 'bundler', "~> 1.0.12"
|
19
|
+
gem 'yard', "~> 0.6.7"
|
20
|
+
gem 'jeweler', "~> 1.5.2"
|
21
|
+
gem 'rspec', "~> 2.5.0"
|
22
|
+
gem 'rcov', ">= 0.9.9"
|
23
|
+
end
|
24
|
+
|
25
|
+
group :test do
|
26
|
+
gem 'spork', "~> 0.9.0.rc5"
|
27
|
+
gem 'watchr'
|
28
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/eventmachine/eventmachine.git
|
3
|
+
revision: 1107730c338892c8281a14b6b2e0802f8d715fb4
|
4
|
+
specs:
|
5
|
+
eventmachine (1.0.0.beta.4)
|
6
|
+
|
7
|
+
GIT
|
8
|
+
remote: https://github.com/igrigorik/em-http-request.git
|
9
|
+
revision: 1b4e646c65ad33b9a04e18f6bc0fa0c2e54e81f2
|
10
|
+
specs:
|
11
|
+
em-http-request (1.0.0.beta.4)
|
12
|
+
addressable (>= 2.2.3)
|
13
|
+
em-socksify
|
14
|
+
eventmachine (>= 1.0.0.beta.3)
|
15
|
+
http_parser.rb (>= 0.5.1)
|
16
|
+
|
17
|
+
GIT
|
18
|
+
remote: https://github.com/igrigorik/em-synchrony.git
|
19
|
+
revision: 81af523ebad26a6cff2eb2842a4a1691c0c49374
|
20
|
+
specs:
|
21
|
+
em-synchrony (0.3.0.beta.1)
|
22
|
+
eventmachine (>= 1.0.0.beta.1)
|
23
|
+
|
24
|
+
GIT
|
25
|
+
remote: https://github.com/postrank-labs/goliath.git
|
26
|
+
revision: 3beab0f1e113f9d590d5c3d5dd6a1158a4756dba
|
27
|
+
specs:
|
28
|
+
goliath (0.9.2)
|
29
|
+
async-rack
|
30
|
+
em-synchrony (>= 0.3.0.beta.1)
|
31
|
+
eventmachine (>= 1.0.0.beta.3)
|
32
|
+
http_parser.rb
|
33
|
+
http_router (~> 0.9.0)
|
34
|
+
log4r
|
35
|
+
multi_json
|
36
|
+
rack (>= 1.2.2)
|
37
|
+
rack-contrib
|
38
|
+
rack-respond_to
|
39
|
+
|
40
|
+
GEM
|
41
|
+
remote: http://rubygems.org/
|
42
|
+
specs:
|
43
|
+
addressable (2.2.6)
|
44
|
+
async-rack (0.5.1)
|
45
|
+
rack (~> 1.1)
|
46
|
+
configliere (0.4.7)
|
47
|
+
json
|
48
|
+
diff-lcs (1.1.2)
|
49
|
+
domainatrix (0.0.10)
|
50
|
+
addressable
|
51
|
+
em-socksify (0.1.0)
|
52
|
+
eventmachine
|
53
|
+
git (1.2.5)
|
54
|
+
gorillib (0.1.4)
|
55
|
+
http_parser.rb (0.5.1)
|
56
|
+
http_router (0.9.1)
|
57
|
+
rack (>= 1.0.0)
|
58
|
+
url_mount (~> 0.2.1)
|
59
|
+
jeweler (1.5.2)
|
60
|
+
bundler (~> 1.0.0)
|
61
|
+
git (>= 1.2.5)
|
62
|
+
rake
|
63
|
+
json (1.5.3)
|
64
|
+
log4r (1.1.9)
|
65
|
+
multi_json (1.0.3)
|
66
|
+
nokogiri (1.5.0)
|
67
|
+
postrank-uri (1.0.15)
|
68
|
+
addressable (>= 2.2.3)
|
69
|
+
domainatrix
|
70
|
+
nokogiri
|
71
|
+
rack (1.3.1)
|
72
|
+
rack-accept-media-types (0.9)
|
73
|
+
rack-contrib (1.1.0)
|
74
|
+
rack (>= 0.9.1)
|
75
|
+
rack-respond_to (0.9.8)
|
76
|
+
rack-accept-media-types (>= 0.6)
|
77
|
+
rake (0.9.2)
|
78
|
+
rcov (0.9.9)
|
79
|
+
rspec (2.5.0)
|
80
|
+
rspec-core (~> 2.5.0)
|
81
|
+
rspec-expectations (~> 2.5.0)
|
82
|
+
rspec-mocks (~> 2.5.0)
|
83
|
+
rspec-core (2.5.2)
|
84
|
+
rspec-expectations (2.5.0)
|
85
|
+
diff-lcs (~> 1.1.2)
|
86
|
+
rspec-mocks (2.5.0)
|
87
|
+
spork (0.9.0.rc9)
|
88
|
+
url_mount (0.2.1)
|
89
|
+
rack
|
90
|
+
watchr (0.7)
|
91
|
+
yajl-ruby (0.8.2)
|
92
|
+
yard (0.6.8)
|
93
|
+
|
94
|
+
PLATFORMS
|
95
|
+
ruby
|
96
|
+
|
97
|
+
DEPENDENCIES
|
98
|
+
bundler (~> 1.0.12)
|
99
|
+
configliere (~> 0.4.7)
|
100
|
+
em-http-request!
|
101
|
+
em-synchrony!
|
102
|
+
eventmachine!
|
103
|
+
goliath!
|
104
|
+
gorillib (~> 0.1.0)
|
105
|
+
jeweler (~> 1.5.2)
|
106
|
+
postrank-uri (~> 1.0.9)
|
107
|
+
rcov (>= 0.9.9)
|
108
|
+
rspec (~> 2.5.0)
|
109
|
+
spork (~> 0.9.0.rc5)
|
110
|
+
watchr
|
111
|
+
yajl-ruby (~> 0.8.2)
|
112
|
+
yard (~> 0.6.7)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Philip (flip) Kromer for Infochimps
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Senor Armando - Goliath Helpers
|
2
|
+
|
3
|
+
In Planet of the Apes, Señor Armando is the owner of a circus, a human friend of Cornelius and Zira, and caregiver for Ceasar, teaching him human knowledge and introducing him to human habits.
|
4
|
+
|
5
|
+
On the Planet of the APIs, Señor Armando is a collection of helper methods that introduce human habits to your goliath app.
|
6
|
+
|
7
|
+
Both have an enthusiastic appreciation for rich Corinthian leather.
|
8
|
+
|
9
|
+
![Señor Armando photo](http://github.com/infochimps-labs/senor_armando/raw/master/senor_armando.jpeg)
|
10
|
+
|
11
|
+
## Setup
|
12
|
+
|
13
|
+
* run `armando_gemfile_jail`; this will run bundler install but cache the results locally for much quickness. **You MUST run it at least once explicitly**.
|
14
|
+
|
15
|
+
That should be it!
|
16
|
+
|
17
|
+
## Overview
|
18
|
+
|
19
|
+
|
20
|
+
## Code Organization
|
21
|
+
|
22
|
+
## Logging to Statsd
|
23
|
+
|
24
|
+
Start a graphite and statsd server:
|
25
|
+
|
26
|
+
```bash
|
27
|
+
python2.6 /usr/local/share/graphite/bin/carbon-cache.py start & sleep 1 ;
|
28
|
+
python2.6 /usr/local/share/graphite/bin/run-graphite-devel-server.py /usr/local/share/graphite & sleep 2 ;
|
29
|
+
node ~/ics/repos/statsd/stats.js /etc/graphite/statsd_config.js &
|
30
|
+
```
|
31
|
+
|
32
|
+
## PassthruProxy
|
33
|
+
|
34
|
+
## Colophon
|
35
|
+
|
36
|
+
Built with
|
37
|
+
* [Goliath](http://goliath.io)
|
38
|
+
* [Gorillib](http://github.com/infochimps-labs/gorillib)
|
39
|
+
* the [Señor Armando photo](http://www.flickr.com/photos/jonknutson/2176806164/sizes/o/in/photostream/) is courtesy Flickr user [jonknutson](http://www.flickr.com/photos/jonknutson).
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Goliath ; ROOT_DIR = File.expand_path(File.dirname(__FILE__)) ; end
|
2
|
+
require File.join(File.dirname(__FILE__), 'lib/senor_armando/use_gemfile_jail')
|
3
|
+
$LOAD_PATH.unshift(Goliath.root_path("lib")) unless $LOAD_PATH.include?(Goliath.root_path("lib"))
|
4
|
+
require 'rake'
|
5
|
+
require 'senor_armando/tasks'
|
6
|
+
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
10
|
+
gem.name = "senor_armando"
|
11
|
+
gem.homepage = "http://github.com/infochimps-labs/senor_armando"
|
12
|
+
gem.license = "MIT"
|
13
|
+
gem.summary = %Q{Helper middlewares for a Goliath (http://goliath.io/) app as used in Infochimps Planet of the APIs}
|
14
|
+
gem.description = %Q{Helper middlewares for a Goliath (http://goliath.io/) app as used in Infochimps Planet of the APIs}
|
15
|
+
gem.email = "coders@infochimps.org"
|
16
|
+
gem.authors = ["Infochimps team"]
|
17
|
+
|
18
|
+
Jeweler::RubygemsDotOrgTasks.new
|
19
|
+
|
20
|
+
gem.required_ruby_version = '>=1.9.2'
|
21
|
+
|
22
|
+
gem.add_dependency 'goliath', ">= 0.9.1"
|
23
|
+
gem.add_dependency 'eventmachine', ">= 1.0.0.beta.3"
|
24
|
+
gem.add_dependency 'em-synchrony', ">= 0.3.0.beta.1"
|
25
|
+
gem.add_dependency 'em-http-request', ">= 1.0.0.beta.3"
|
26
|
+
|
27
|
+
gem.add_dependency 'yajl-ruby', "~> 0.8.2"
|
28
|
+
gem.add_dependency 'gorillib', "~> 0.1.1"
|
29
|
+
gem.add_dependency 'addressable', "~> 2.2.5"
|
30
|
+
|
31
|
+
gem.add_dependency 'rack', ">=1.2.2"
|
32
|
+
gem.add_dependency 'rack-contrib'
|
33
|
+
gem.add_dependency 'rack-respond_to', "~> 0.9.8"
|
34
|
+
gem.add_dependency 'rack-abstract-format',"~> 0.9.9"
|
35
|
+
gem.add_dependency 'async-rack'
|
36
|
+
gem.add_dependency 'multi_json'
|
37
|
+
|
38
|
+
gem.add_development_dependency 'bundler', "~> 1.0.12"
|
39
|
+
gem.add_development_dependency 'yard', "~> 0.6.7"
|
40
|
+
gem.add_development_dependency 'jeweler', "~> 1.5.2"
|
41
|
+
gem.add_development_dependency 'rspec', "~> 2.5.0"
|
42
|
+
gem.add_development_dependency 'rcov', ">= 0.9.9"
|
43
|
+
gem.add_development_dependency 'spork', "~> 0.9.0.rc5"
|
44
|
+
gem.add_development_dependency 'watchr'
|
45
|
+
|
46
|
+
ignores = File.readlines(".gitignore").grep(/^[^#]\S+/).map{|s| s.chomp }
|
47
|
+
dotfiles = [".gemtest", ".gitignore", ".rspec", ".yardopts", ".bundle", ".vendor"]
|
48
|
+
gem.files = dotfiles + Dir["**/*"].
|
49
|
+
reject{|f| f =~ /^\.vendor\// }.
|
50
|
+
reject{|f| File.directory?(f) }.
|
51
|
+
reject{|f| ignores.any?{|i| File.fnmatch(i, f) || File.fnmatch(i+'/**/*', f) } }
|
52
|
+
gem.test_files = gem.files.grep(/^spec\//)
|
53
|
+
gem.require_paths = ['lib']
|
54
|
+
end
|
55
|
+
|
56
|
+
# App-specific tasks
|
57
|
+
Dir[File.dirname(__FILE__)+'/lib/tasks/**/*.rake'].sort.each{|f| load f }
|
58
|
+
|
59
|
+
task :default => :spec
|
60
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/armando_echo.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/boot')
|
3
|
+
|
4
|
+
# Usage:
|
5
|
+
# ruby -r ./lib/boot.rb ./bin/goliath_echo.rb -sv -p 9002
|
6
|
+
#
|
7
|
+
# curl -vv 'http://127.0.0.1:9002/this/that?the=other#yup'
|
8
|
+
#
|
9
|
+
# Summarizes the request back into the response header fields
|
10
|
+
#
|
11
|
+
class ArmandoEcho < SenorArmando::Endpoint::Echo
|
12
|
+
use Goliath::Rack::Heartbeat # respond to /status with 200, OK (monitoring, etc)
|
13
|
+
use Goliath::Rack::Tracer # log trace statistics
|
14
|
+
use Goliath::Rack::Params # parse & merge query and body parameters
|
15
|
+
use SenorArmando::Rack::ExceptionHandler # catch errors and present as non-200 responses
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/boot')
|
3
|
+
|
4
|
+
require 'goliath/endpoint/proxy'
|
5
|
+
|
6
|
+
# Usage:
|
7
|
+
#
|
8
|
+
# Start the server:
|
9
|
+
#
|
10
|
+
# ./app/passthru_proxy.rb -sv -p 9001 --config $PWD/config/app.rb
|
11
|
+
#
|
12
|
+
# curl -vv 'http://127.0.0.1:9001/unicodesnowmanforyou.com/'
|
13
|
+
#
|
14
|
+
# Takes all requests and forwards them to another server using EM-HTTP-Request.
|
15
|
+
#
|
16
|
+
# See http://everburning.com/news/stage-left-enter-goliath for more details --
|
17
|
+
#
|
18
|
+
class PassthruProxy < Goliath::Endpoint::Proxy
|
19
|
+
use Goliath::Rack::Heartbeat # respond to /status with 200, OK (monitoring, etc)
|
20
|
+
use Goliath::Rack::Tracer, 'X-Tracer' # log trace statistics
|
21
|
+
use Goliath::Rack::Params # parse & merge query and body parameters
|
22
|
+
use Goliath::Rack::ExceptionHandler # catch errors and present as non-200 responses
|
23
|
+
|
24
|
+
# use Goliath::Rack::StatsdLogger, Settings.statsd_logger_handle # send request logs to statsd
|
25
|
+
# plugin Goliath::Plugin::StatsdPlugin # send internal stats to statsd
|
26
|
+
|
27
|
+
# def dest_url_and_params(env)
|
28
|
+
# dest_params = {:head => env['client-headers'], :query => env.params}
|
29
|
+
#
|
30
|
+
# # Pull the base URI out of the path info
|
31
|
+
# env['PATH_INFO'] =~ %r{\A/([\w\.\-]+)/(.*)\z}o or raise Goliath::Validation::BadRequestError.new("Cannot forward to [#{env['PATH_INFO']}]")
|
32
|
+
# dest_host, dest_path = [$1, $2]
|
33
|
+
#
|
34
|
+
# # Set the target host correctly
|
35
|
+
# dest_params[:head]['Host'] = dest_host
|
36
|
+
# url = "http://#{dest_host}/#{dest_path}"
|
37
|
+
#
|
38
|
+
# [dest_url, dest_params]
|
39
|
+
# end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#/ Usage: config/bootstrap.rb [<options>]
|
3
|
+
#/ Bootstraps the gem environment.
|
4
|
+
#/
|
5
|
+
#/ Options are passed through to the bundle-install command. In most cases you
|
6
|
+
#/ won't need these. They're used primarily in production environments.
|
7
|
+
#/ --local use gems in .vendor/cache instead of rubygems.org
|
8
|
+
#/ --without=<groups> do not install gems in the groups specified
|
9
|
+
#
|
10
|
+
# =============================================================================
|
11
|
+
# Uses bundler to install all gems specified in the Gemfile under .vendor/gems,
|
12
|
+
# records the load path in config/loadpath, and generates bundler-free binstubs
|
13
|
+
# under bin.
|
14
|
+
#
|
15
|
+
# The basic idea is to use bundler to install necessary gems but not
|
16
|
+
# rely on it to manage the load path at runtime because it's slow. Requiring
|
17
|
+
# 'bundler/setup' takes ~500ms user CPU time in production and ~1500ms in
|
18
|
+
# development/test. This makes it unusable in scenarios that require a fast
|
19
|
+
# boot (e.g., script/gerve, proxymachine daemons, ernie/smoke, etc.). It's also
|
20
|
+
# a problem in development where it slows tools like rake command line
|
21
|
+
# completion to a crawl and adds at least a second to single-file test runs.
|
22
|
+
#
|
23
|
+
# There's very little reason to use bundler at runtime since everything
|
24
|
+
# is known at install time. We simply save off the result of the work done by
|
25
|
+
# bundle/setup and use it until bundle-install is run again.
|
26
|
+
|
27
|
+
# show usage message with --help
|
28
|
+
if ARGV.include?('--help')
|
29
|
+
system "grep '^#/' <'#{__FILE__}' |cut -c4-"
|
30
|
+
exit 2
|
31
|
+
end
|
32
|
+
|
33
|
+
# go into the project root because it makes everything easier
|
34
|
+
root = File.expand_path('../..', __FILE__)
|
35
|
+
Dir.chdir(root)
|
36
|
+
|
37
|
+
# point bundler to the right stuff
|
38
|
+
ENV['BUNDLE_GEMFILE'] = "#{root}/Gemfile"
|
39
|
+
ENV['BUNDLE_PATH'] = "#{root}/.vendor/gems"
|
40
|
+
|
41
|
+
# bring in rubygems and make sure bundler is installed.
|
42
|
+
require 'rubygems'
|
43
|
+
begin
|
44
|
+
require 'bundler'
|
45
|
+
rescue LoadError => boom
|
46
|
+
warn "Bundler not found. Install it with `gem install bundler' and try again."
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
50
|
+
# record the Gemfile checksum so we can tell if the Gemfile has changed
|
51
|
+
# since our loadpath was last generated. this is used in config/boot.rb
|
52
|
+
# to verify the environment is bootstrapped and up-to-date.
|
53
|
+
checksum = `cksum Gemfile`.to_i
|
54
|
+
installed = File.read('.bundle/checksum').to_i rescue nil
|
55
|
+
|
56
|
+
# run a quick check to see if everything's installed and up-to-date so we can
|
57
|
+
# skip the install and loadpath generation step if possible.
|
58
|
+
if checksum == installed && system('bundle check 1>/dev/null 2>&1')
|
59
|
+
puts "Gem environment up-to-date."
|
60
|
+
else
|
61
|
+
# run bundle-install to install any missing gems
|
62
|
+
argv = ['--no-color', 'install', '--path', '.vendor/gems'] + ARGV
|
63
|
+
system("bundle", *argv) || begin
|
64
|
+
warn "bundle executable not found. Ensure bundler is installed (`gem " +
|
65
|
+
"install bundler`) and that the gem bin path is in your PATH"
|
66
|
+
exit($?.exitstatus)
|
67
|
+
end
|
68
|
+
|
69
|
+
# load the Gemfile
|
70
|
+
bundle = Bundler.setup
|
71
|
+
|
72
|
+
# extract load paths for each gem and write to the config/loadpath file.
|
73
|
+
load_paths = []
|
74
|
+
bundle.gems.each do |gem|
|
75
|
+
next if gem.name == 'bundler'
|
76
|
+
gem.load_paths.each do |path|
|
77
|
+
if path[0, root.size] == root
|
78
|
+
path = path[(root.size + 1), path.size]
|
79
|
+
load_paths << path
|
80
|
+
else
|
81
|
+
warn "external load path directory detected: #{path}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# move the loadpath and checksum files into place if everything was installed
|
87
|
+
# okay and the load path file was written successfully.
|
88
|
+
File.open('.bundle/loadpath+', 'wb') { |fd| fd.write(load_paths.join("\n")) }
|
89
|
+
File.rename('.bundle/loadpath+', '.bundle/loadpath')
|
90
|
+
File.open('.bundle/checksum', 'wb') { |fd| fd.puts(checksum) }
|
91
|
+
|
92
|
+
# write binstubs for all executables. we can't use bundler's --binstubs option
|
93
|
+
# because the generated executables require 'bundler/setup'. the binstubs
|
94
|
+
# generated here require only config/boot.rb, which sets up the loadpath
|
95
|
+
# manually using the .bundle/loadpath file.
|
96
|
+
Dir.mkdir ".vendor/bin" unless File.directory?(".vendor/bin")
|
97
|
+
template = DATA.read
|
98
|
+
lineno = File.read(__FILE__).count("\n") - template.count("\n")
|
99
|
+
bundle.gems.each do |spec|
|
100
|
+
spec.executables.each do |executable|
|
101
|
+
script = eval('%Q{' + template + '}', binding, __FILE__, lineno)
|
102
|
+
File.open(".vendor/bin/#{executable}+", 'wb') { |fd| fd.write(script) }
|
103
|
+
File.chmod 0755, ".vendor/bin/#{executable}+"
|
104
|
+
File.rename(".vendor/bin/#{executable}+", ".vendor/bin/#{executable}")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
__END__
|
110
|
+
#!/usr/bin/env #{RbConfig::CONFIG['ruby_install_name']}
|
111
|
+
#
|
112
|
+
# This file was generated by config/bootstrap.
|
113
|
+
require '#{root}/lib/boot'
|
114
|
+
load File.join('#{spec.full_gem_path}', '.vendor', '#{spec.bindir}', '#{executable}')
|