sickill-rack_revision_info 0.3

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.
@@ -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
+