revision_plate 0.1.1
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 +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +21 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +10 -0
- data/lib/revision_plate.rb +3 -0
- data/lib/revision_plate/app.rb +43 -0
- data/lib/revision_plate/middleware.rb +19 -0
- data/lib/revision_plate/rails.rb +11 -0
- data/lib/revision_plate/version.rb +3 -0
- data/revision_plate.gemspec +27 -0
- data/test/app_test.rb +121 -0
- data/test/middleware_test.rb +75 -0
- data/test/test_helper.rb +4 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0b7a681b78b1521300089eec60a31ddf500e2497
|
4
|
+
data.tar.gz: 00b444374ae5a0364fcee8fa9b9dfada64bc30a0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2d0a4f7068344548015eceb82d7c8273683be979cb85726f8445514a3a2e62ba9c0548737d4128b75ae57d378b4febc82a3e33bf764dbddef0b21beba3b2be4d
|
7
|
+
data.tar.gz: b0b47299856a9c9373a3c468c7e65d799050e2d88622fb5e59cb57c8b01059429fd485b5dc21fb5687756dc91cef43a0d6687cccc61d98b3eb49c0fc01f474a0
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
sudo: false
|
4
|
+
|
5
|
+
rvm:
|
6
|
+
- 2.0.0
|
7
|
+
- 2.1
|
8
|
+
- 2.2
|
9
|
+
- ruby-head
|
10
|
+
|
11
|
+
matrix:
|
12
|
+
fast_finish: true
|
13
|
+
allow_failures:
|
14
|
+
- rvm: "ruby-head"
|
15
|
+
|
16
|
+
before_install:
|
17
|
+
- gem i bundler -v 1.8.4
|
18
|
+
|
19
|
+
script:
|
20
|
+
- bundle exec rake
|
21
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Shota Fukumori (sora_h)
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# RevisionPlate
|
2
|
+
|
3
|
+
Rack application and middleware that serves endpoint returns application's `REVISION`.
|
4
|
+
|
5
|
+
## Detail
|
6
|
+
|
7
|
+
The endpoint returns content of `REVISION`
|
8
|
+
|
9
|
+
Content of the endpoint wouldn't be changed even if `REVISION` file has changed. But it'll return 404 when it has removed.
|
10
|
+
|
11
|
+
This can be used for health check + remove from service by hand.
|
12
|
+
|
13
|
+
This gem is used in [Cookpad](https://info.cookpad.com/).
|
14
|
+
And seems several companies runs similar thing (e.g. [GitHub](https://github.com/blog/609-tracking-deploys-with-compare-view)).
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
### typical Rails app
|
19
|
+
|
20
|
+
``` ruby
|
21
|
+
# Gemfile
|
22
|
+
gem 'revision_plate', require: 'revision_plate/rails'
|
23
|
+
```
|
24
|
+
|
25
|
+
then your Rails application will handle `/site/sha`.
|
26
|
+
|
27
|
+
### rack application
|
28
|
+
|
29
|
+
``` ruby
|
30
|
+
# Gemfile
|
31
|
+
gem 'revision_plate'
|
32
|
+
|
33
|
+
# config.ru (middleware)
|
34
|
+
use RevisionPlate::Middleware, '/site/sha', "#{__dir__}/REVISION"
|
35
|
+
|
36
|
+
# config.ru (mount)
|
37
|
+
map '/site/sha' do
|
38
|
+
run RevisionPlate::App.new("#{__dir__}/REVISION")
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
## Test
|
43
|
+
|
44
|
+
```
|
45
|
+
$ echo 'deadbeef' > REVISION
|
46
|
+
$ (... start your app ...)
|
47
|
+
$ curl localhost:3000/site/sha
|
48
|
+
deadbeef
|
49
|
+
$ rm REVISION
|
50
|
+
$ curl localhost:3000/site/sha
|
51
|
+
REVISION_FILE_REMOVED
|
52
|
+
```
|
53
|
+
|
54
|
+
## Advanced
|
55
|
+
|
56
|
+
### I want to customize (Rails app)
|
57
|
+
|
58
|
+
remove `require: 'revision_plate/rails'` from Gemfile, then initialize `RevisionPlate::App` on routes:
|
59
|
+
|
60
|
+
```
|
61
|
+
# routes.rb
|
62
|
+
get '/site/sha' => RevisionPlate::App.new
|
63
|
+
get '/site/sha' => RevisionPlate::App.new("/path/to/my/favorite/REVISION")
|
64
|
+
```
|
65
|
+
|
66
|
+
## Development
|
67
|
+
|
68
|
+
### Testing
|
69
|
+
|
70
|
+
```
|
71
|
+
$ rake test
|
72
|
+
```
|
73
|
+
|
74
|
+
## License
|
75
|
+
|
76
|
+
MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module RevisionPlate
|
4
|
+
class App
|
5
|
+
def initialize(file = nil, path: nil)
|
6
|
+
@file = file
|
7
|
+
@path = path
|
8
|
+
if @file
|
9
|
+
unless @file.kind_of?(Pathname)
|
10
|
+
@file = Pathname.new(@file)
|
11
|
+
end
|
12
|
+
else
|
13
|
+
if defined? Rails
|
14
|
+
@file = Rails.root.join('REVISION')
|
15
|
+
else
|
16
|
+
raise ArgumentError, "couldn't locate REVISION file"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if @file.exist?
|
21
|
+
@revision = @file.read.chomp
|
22
|
+
else
|
23
|
+
@revision = nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
unless env['REQUEST_METHOD'] == 'GET' && (@path ? env['PATH_INFO'] == @path : true)
|
29
|
+
return [404, {'Content-Type' => 'text/plain'}, []]
|
30
|
+
end
|
31
|
+
|
32
|
+
if @revision
|
33
|
+
if @file.exist?
|
34
|
+
[200, {'Content-Type' => 'text/plain'}, [@revision, ?\n]]
|
35
|
+
else
|
36
|
+
[404, {'Content-Type' => 'text/plain'}, ["REVISION_FILE_REMOVED\n"]]
|
37
|
+
end
|
38
|
+
else
|
39
|
+
[404, {'Content-Type' => 'text/plain'}, ["REVISION_FILE_NOT_FOUND\n"]]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'revision_plate/app'
|
2
|
+
|
3
|
+
module RevisionPlate
|
4
|
+
class Middleware
|
5
|
+
def initialize(app, path, file = nil, options={})
|
6
|
+
@path = path
|
7
|
+
@app = app
|
8
|
+
@revision_app = App.new(file, **options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
if env['PATH_INFO'] == @path && env['REQUEST_METHOD'] == 'GET'
|
13
|
+
@revision_app.call(env)
|
14
|
+
else
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'revision_plate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "revision_plate"
|
8
|
+
spec.version = RevisionPlate::VERSION
|
9
|
+
spec.authors = ["Shota Fukumori (sora_h)"]
|
10
|
+
spec.email = ["sorah@cookpad.com"]
|
11
|
+
spec.summary = %q{Rack middleware and application to show deployed application's revision (commit)}
|
12
|
+
spec.description = nil
|
13
|
+
spec.homepage = "https://github.com/sorah/revision_plate"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", ">= 1.7.8"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "minitest", "~> 5.5.1"
|
24
|
+
spec.add_development_dependency "rack-test", "~> 0.6.3"
|
25
|
+
|
26
|
+
spec.add_dependency "rack"
|
27
|
+
end
|
data/test/app_test.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require_relative './test_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
require 'revision_plate/app'
|
5
|
+
|
6
|
+
class AppTest < Minitest::Spec
|
7
|
+
include Rack::Test::Methods
|
8
|
+
alias_method :response, :last_response
|
9
|
+
|
10
|
+
describe 'app' do
|
11
|
+
let(:app) { RevisionPlate::App.new(file) }
|
12
|
+
let(:tmpdir) { Dir.mktmpdir('revision_plate_app_test') }
|
13
|
+
let(:file) { Pathname.new(tmpdir).join('REVISION') }
|
14
|
+
|
15
|
+
before do
|
16
|
+
File.write file.to_s, "a"
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'with default' do
|
20
|
+
let(:app) { RevisionPlate::App.new }
|
21
|
+
|
22
|
+
describe 'with Rails' do
|
23
|
+
before do
|
24
|
+
RevisionPlate.const_set :Rails, Class.new {
|
25
|
+
def self.root
|
26
|
+
@root
|
27
|
+
end
|
28
|
+
def self.root=(o)
|
29
|
+
@root = Pathname.new(o)
|
30
|
+
end
|
31
|
+
}.tap { |klass|
|
32
|
+
klass.root = tmpdir
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
RevisionPlate.send :remove_const, :Rails
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns RAILS_ROOT/REVISION' do
|
41
|
+
get '/'
|
42
|
+
assert_equal 200, response.status
|
43
|
+
assert_equal "a\n", response.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'without Rails' do
|
48
|
+
it "raises error" do
|
49
|
+
assert_raises(ArgumentError) { app }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'with path' do
|
55
|
+
let(:app) { RevisionPlate::App.new(file, path: '/site/sha') }
|
56
|
+
|
57
|
+
it "won't respond to request to invalid path" do
|
58
|
+
get '/site/sha'
|
59
|
+
assert_equal 200, response.status
|
60
|
+
assert_equal "a\n", response.body
|
61
|
+
|
62
|
+
post '/site/sha'
|
63
|
+
assert_equal 404, response.status
|
64
|
+
|
65
|
+
get '/site/sha/a'
|
66
|
+
assert_equal 404, response.status
|
67
|
+
|
68
|
+
get '/'
|
69
|
+
assert_equal 404, response.status
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns specified file' do
|
74
|
+
get '/'
|
75
|
+
assert_equal 200, response.status
|
76
|
+
assert_equal "a\n", response.body
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns same revision even if updated' do
|
80
|
+
app # ensure to instantiate
|
81
|
+
File.write file.to_s, "b\n"
|
82
|
+
|
83
|
+
get '/'
|
84
|
+
assert_equal 200, response.status
|
85
|
+
assert_equal "a\n", response.body
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns 404 for POST request' do
|
89
|
+
post '/'
|
90
|
+
assert_equal 404, response.status
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns 404 if removed' do
|
94
|
+
app # ensure to instantiate
|
95
|
+
file.unlink
|
96
|
+
|
97
|
+
get '/'
|
98
|
+
assert_equal 404, response.status
|
99
|
+
assert_equal "REVISION_FILE_REMOVED\n", response.body
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns 404 if not exists' do
|
103
|
+
file.unlink
|
104
|
+
app # instantiate
|
105
|
+
|
106
|
+
get '/'
|
107
|
+
assert_equal 404, response.status
|
108
|
+
assert_equal "REVISION_FILE_NOT_FOUND\n", response.body
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'returns 404 if created but it was not existed' do
|
112
|
+
file.unlink
|
113
|
+
app # instantiate
|
114
|
+
File.write file.to_s, "b\n"
|
115
|
+
|
116
|
+
get '/'
|
117
|
+
assert_equal 404, response.status
|
118
|
+
assert_equal "REVISION_FILE_NOT_FOUND\n", response.body
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative './test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
require 'revision_plate/middleware'
|
5
|
+
|
6
|
+
module RevisionPlate
|
7
|
+
AppOriginal = App
|
8
|
+
end
|
9
|
+
|
10
|
+
class AppTest < Minitest::Spec
|
11
|
+
include Rack::Test::Methods
|
12
|
+
alias_method :response, :last_response
|
13
|
+
|
14
|
+
describe 'middleware' do
|
15
|
+
let(:tempfile) { Tempfile.new('revision_plate-middielware-test') }
|
16
|
+
|
17
|
+
let(:nextapp) { -> (env) { [200, {'Content-Type' => 'text/plain'}, ['hi']] } }
|
18
|
+
let(:mockapp) do
|
19
|
+
Class.new do
|
20
|
+
def self.instances
|
21
|
+
@instances ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(file, **options)
|
25
|
+
@file = file
|
26
|
+
@options = options
|
27
|
+
self.class.instances << self
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :file, :options
|
31
|
+
|
32
|
+
def call(env)
|
33
|
+
[200, {'Content-Type' => 'text/plain'}, "deadbeef"]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:app) { RevisionPlate::Middleware.new(nextapp, '/site/sha', tempfile.path, opt: :option) }
|
39
|
+
|
40
|
+
before do
|
41
|
+
RevisionPlate.send(:remove_const, :App)
|
42
|
+
RevisionPlate.const_set(:App, mockapp)
|
43
|
+
end
|
44
|
+
|
45
|
+
after do
|
46
|
+
RevisionPlate.send(:remove_const, :App)
|
47
|
+
RevisionPlate.const_set(:App, RevisionPlate::AppOriginal)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'instantiates App with proper argument' do
|
51
|
+
app
|
52
|
+
|
53
|
+
assert_equal 1, mockapp.instances.size
|
54
|
+
assert_equal({opt: :option}, mockapp.instances.first.options)
|
55
|
+
assert_equal tempfile.path, mockapp.instances.first.file
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'pass-through requests to nextapp' do
|
59
|
+
get '/'
|
60
|
+
assert_equal response.body, 'hi'
|
61
|
+
post '/'
|
62
|
+
assert_equal response.body, 'hi'
|
63
|
+
get '/site'
|
64
|
+
assert_equal response.body, 'hi'
|
65
|
+
post '/site/sha'
|
66
|
+
assert_equal response.body, 'hi'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'pass requests to RevisionPlate::App on specific path' do
|
70
|
+
get '/site/sha'
|
71
|
+
assert_equal response.body, 'deadbeef'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: revision_plate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shota Fukumori (sora_h)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.7.8
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.7.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.5.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.5.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.6.3
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.6.3
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: ''
|
84
|
+
email:
|
85
|
+
- sorah@cookpad.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- lib/revision_plate.rb
|
97
|
+
- lib/revision_plate/app.rb
|
98
|
+
- lib/revision_plate/middleware.rb
|
99
|
+
- lib/revision_plate/rails.rb
|
100
|
+
- lib/revision_plate/version.rb
|
101
|
+
- revision_plate.gemspec
|
102
|
+
- test/app_test.rb
|
103
|
+
- test/middleware_test.rb
|
104
|
+
- test/test_helper.rb
|
105
|
+
homepage: https://github.com/sorah/revision_plate
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.4.5
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Rack middleware and application to show deployed application's revision (commit)
|
129
|
+
test_files:
|
130
|
+
- test/app_test.rb
|
131
|
+
- test/middleware_test.rb
|
132
|
+
- test/test_helper.rb
|