sickill-rack_revision_info 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ module Rack
2
+ class RevisionInfo
3
+ INJECT_ACTIONS = [:after, :before, :append, :prepend, :swap, :inner_html]
4
+ DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S %Z"
5
+
6
+ def initialize(app, opts={})
7
+ @app = app
8
+ path = opts[:path] or raise ArgumentError, "You must specify directory of your local repository!"
9
+ revision, date = get_revision_info(path)
10
+ @revision_info = "Revision #{revision || 'unknown'}"
11
+ @revision_info << " (#{date.strftime(DATETIME_FORMAT)})" if date
12
+ @action = (opts.keys & INJECT_ACTIONS).first
13
+ if @action
14
+ require 'hpricot'
15
+ @selector = opts[@action]
16
+ end
17
+ end
18
+
19
+ def call(env)
20
+ status, headers, body = @app.call(env)
21
+ if headers['Content-Type'].include?('text/html') && !Rack::Request.new(env).xhr?
22
+ begin
23
+ if @action
24
+ doc = Hpricot(body.to_s)
25
+ elements = doc.search(@selector).compact
26
+ if elements.size > 0
27
+ elements = elements.first if @action == :swap
28
+ elements.send(@action, @revision_info)
29
+ body = doc.to_s
30
+ end
31
+ end
32
+ rescue => e
33
+ puts e
34
+ puts e.backtrace
35
+ end
36
+ body << %(\n<!-- #{@revision_info} -->\n)
37
+ end
38
+ [status, headers, body]
39
+ end
40
+
41
+ protected
42
+
43
+ def get_revision_info(path)
44
+ case detect_type(path)
45
+ when :git
46
+ info = `cd #{path}; LC_ALL=C git log -1 --pretty=medium`
47
+ revision = info[/commit\s([a-z0-9]+)/, 1]
48
+ date = (d = info[/Date:\s+(.+)$/, 1]) && (DateTime.parse(d) rescue nil)
49
+ when :svn
50
+ info = `cd #{path}; LC_ALL=C svn info`
51
+ revision = info[/Revision:\s(\d+)$/, 1]
52
+ date = (d = info[/Last Changed Date:\s([^\(]+)/, 1]) && (DateTime.parse(d.strip) rescue nil)
53
+ else
54
+ revision, date = nil, nil
55
+ end
56
+ [revision, date]
57
+ end
58
+
59
+ def detect_type(path)
60
+ return :git if ::File.directory?(::File.join(path, ".git"))
61
+ return :svn if ::File.directory?(::File.join(path, ".svn"))
62
+ :unknown
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec'
2
+ require 'rack/builder'
3
+ require 'rack/mock'
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'rack_revision_info.rb')
5
+
6
+ class Rack::RevisionInfo
7
+ def get_revision_info(path)
8
+ [REV, DATE]
9
+ end
10
+ end
11
+
12
+ describe "Rack::RevisionInfo" do
13
+ REV = "a4jf64jf4hff"
14
+ DATE = DateTime.now
15
+
16
+ it "should append revision info in html comment" do
17
+ app = Rack::Builder.new do
18
+ use Rack::RevisionInfo, :path => "/some/path/to/repo"
19
+ run lambda { |env| [200, { 'Content-Type' => 'text/html' }, ["<html><head></head><body>Hello, World!</body></html>"]] }
20
+ end
21
+ response = Rack::MockRequest.new(app).get('/')
22
+ response.body.should match(/#{Regexp.escape("<!-- Revision #{REV} (#{DATE.strftime(Rack::RevisionInfo::DATETIME_FORMAT)}) -->")}/)
23
+ end
24
+
25
+ it "shouldn't append revision info for non-html content-types" do
26
+ app = Rack::Builder.new do
27
+ use Rack::RevisionInfo, :path => "/some/path/to/repo"
28
+ run lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ["Hello, World!"]] }
29
+ end
30
+ response = Rack::MockRequest.new(app).get('/')
31
+ response.body.should_not match(/#{Regexp.escape('<!-- Revision ')}/)
32
+ end
33
+
34
+ it "shouldn't append revision info for xhr requests" do
35
+ app = Rack::Builder.new do
36
+ use Rack::RevisionInfo, :path => "/some/path/to/repo"
37
+ run lambda { |env| [200, { 'Content-Type' => 'text/html' }, ["<html><head></head><body>Hello, World!</body></html>"]] }
38
+ end
39
+ response = Rack::MockRequest.new(app).get('/', "HTTP_X_REQUESTED_WITH" => "XMLHttpRequest")
40
+ response.body.should_not match(/#{Regexp.escape('<!-- Revision ')}/)
41
+ end
42
+
43
+ it "should raise exeption when no path given" do
44
+ app = Rack::Builder.new do
45
+ use Rack::RevisionInfo
46
+ run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
47
+ end
48
+ lambda do
49
+ response = Rack::MockRequest.new(app).get('/')
50
+ end.should raise_error(ArgumentError)
51
+ end
52
+
53
+ it "should inject revision info into DOM" do
54
+ Rack::RevisionInfo::INJECT_ACTIONS.each do |action|
55
+ app = Rack::Builder.new do
56
+ use Rack::RevisionInfo, :path => "/some/path/to/repo", action => "#footer"
57
+ run lambda { |env| [200, { 'Content-Type' => 'text/html' }, ["<html><head></head><body>Hello, World!<div id='footer'>Foota</div></body></html>"]] }
58
+ end
59
+ response = Rack::MockRequest.new(app).get('/')
60
+ response.body.should match(/#{Regexp.escape("Revision #{REV} (#{DATE.strftime(Rack::RevisionInfo::DATETIME_FORMAT)})")}.*#{Regexp.escape("</body>")}/)
61
+ end
62
+ end
63
+
64
+ it "shouldn't inject revision info into DOM if unknown action" do
65
+ app = Rack::Builder.new do
66
+ use Rack::RevisionInfo, :path => "/some/path/to/repo", :what_what => "#footer"
67
+ run lambda { |env| [200, { 'Content-Type' => 'text/html' }, ["<html><head></head><body>Hello, World!<div id='footer'>Foota</div></body></html>"]] }
68
+ end
69
+ response = Rack::MockRequest.new(app).get('/')
70
+ response.body.should_not match(/#{Regexp.escape("Revision #{REV} (#{DATE.strftime(Rack::RevisionInfo::DATETIME_FORMAT)})")}.*#{Regexp.escape("</body>")}/)
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sickill-rack_revision_info
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.3"
5
+ platform: ruby
6
+ authors:
7
+ - Marcin Kulik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-31 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: marcin.kulik@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/rack_revision_info.rb
26
+ - spec/spec_rack_revision_info.rb
27
+ has_rdoc: false
28
+ homepage: http://sickill.net
29
+ post_install_message:
30
+ rdoc_options: []
31
+
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: "0"
39
+ version:
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ requirements: []
47
+
48
+ rubyforge_project:
49
+ rubygems_version: 1.2.0
50
+ signing_key:
51
+ specification_version: 2
52
+ summary: Rack middleware showing current git (or svn) revision number of application
53
+ test_files: []
54
+