request-log-analyzer 1.0.2
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.
- data/DESIGN +14 -0
- data/HACKING +7 -0
- data/LICENSE +20 -0
- data/README.textile +36 -0
- data/Rakefile +5 -0
- data/bin/request-log-analyzer +123 -0
- data/lib/cli/bashcolorizer.rb +60 -0
- data/lib/cli/command_line_arguments.rb +301 -0
- data/lib/cli/progressbar.rb +236 -0
- data/lib/request_log_analyzer.rb +14 -0
- data/lib/request_log_analyzer/aggregator/base.rb +45 -0
- data/lib/request_log_analyzer/aggregator/database.rb +148 -0
- data/lib/request_log_analyzer/aggregator/echo.rb +25 -0
- data/lib/request_log_analyzer/aggregator/summarizer.rb +116 -0
- data/lib/request_log_analyzer/controller.rb +201 -0
- data/lib/request_log_analyzer/file_format.rb +81 -0
- data/lib/request_log_analyzer/file_format/merb.rb +33 -0
- data/lib/request_log_analyzer/file_format/rails.rb +90 -0
- data/lib/request_log_analyzer/filter/base.rb +29 -0
- data/lib/request_log_analyzer/filter/field.rb +36 -0
- data/lib/request_log_analyzer/filter/timespan.rb +32 -0
- data/lib/request_log_analyzer/line_definition.rb +159 -0
- data/lib/request_log_analyzer/log_parser.rb +173 -0
- data/lib/request_log_analyzer/log_processor.rb +121 -0
- data/lib/request_log_analyzer/request.rb +95 -0
- data/lib/request_log_analyzer/source/base.rb +42 -0
- data/lib/request_log_analyzer/source/log_file.rb +170 -0
- data/lib/request_log_analyzer/tracker/base.rb +54 -0
- data/lib/request_log_analyzer/tracker/category.rb +71 -0
- data/lib/request_log_analyzer/tracker/duration.rb +81 -0
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +80 -0
- data/lib/request_log_analyzer/tracker/timespan.rb +54 -0
- data/spec/controller_spec.rb +40 -0
- data/spec/database_inserter_spec.rb +101 -0
- data/spec/file_format_spec.rb +78 -0
- data/spec/file_formats/spec_format.rb +26 -0
- data/spec/filter_spec.rb +137 -0
- data/spec/fixtures/merb.log +84 -0
- data/spec/fixtures/multiple_files_1.log +5 -0
- data/spec/fixtures/multiple_files_2.log +2 -0
- data/spec/fixtures/rails_1x.log +59 -0
- data/spec/fixtures/rails_22.log +12 -0
- data/spec/fixtures/rails_22_cached.log +10 -0
- data/spec/fixtures/rails_unordered.log +24 -0
- data/spec/fixtures/syslog_1x.log +5 -0
- data/spec/fixtures/test_file_format.log +13 -0
- data/spec/fixtures/test_language_combined.log +14 -0
- data/spec/fixtures/test_order.log +16 -0
- data/spec/line_definition_spec.rb +124 -0
- data/spec/log_parser_spec.rb +68 -0
- data/spec/log_processor_spec.rb +57 -0
- data/spec/merb_format_spec.rb +38 -0
- data/spec/rails_format_spec.rb +76 -0
- data/spec/request_spec.rb +72 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/summarizer_spec.rb +9 -0
- data/tasks/github-gem.rake +177 -0
- data/tasks/request_log_analyzer.rake +10 -0
- data/tasks/rspec.rake +6 -0
- metadata +135 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'request_log_analyzer/log_processor'
|
3
|
+
|
4
|
+
describe RequestLogAnalyzer::LogProcessor, 'anonymization' do
|
5
|
+
|
6
|
+
include RequestLogAnalyzerSpecHelper
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@log_anonymizer = RequestLogAnalyzer::LogProcessor.new(spec_format, :anonymize, {})
|
10
|
+
@alternate_log_anonymizer = RequestLogAnalyzer::LogProcessor.new(spec_format, :anonymize, {:keep_junk_lines => true, :discard_teaser_lines => true})
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should keep a junk line if :keep_junk_lines is true" do
|
14
|
+
@alternate_log_anonymizer.anonymize_line("junk line\n").should == "junk line\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should remove a junk line" do
|
18
|
+
@log_anonymizer.anonymize_line("junk line\n").should be_empty
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should keep a teaser line intact" do
|
22
|
+
@log_anonymizer.anonymize_line("processing 1234\n").should == "processing 1234\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should discard a teaser line if discard_teaser_line is true" do
|
26
|
+
@alternate_log_anonymizer.anonymize_line("processing 1234\n").should be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should keep a matching line intact if no anonymizing is declared" do
|
30
|
+
@alternate_log_anonymizer.anonymize_line("finishing request 130\n").should == "finishing request 130\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should anonymize values completely if requested" do
|
34
|
+
@alternate_log_anonymizer.anonymize_line("testing is great\n").should == "testing is ***\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should anonymize values slightly if requested" do
|
38
|
+
@alternate_log_anonymizer.anonymize_line("finishing request 130\n").should =~ /^finishing request 1\d\d\n$/
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe RequestLogAnalyzer::LogProcessor, 'stripping log files' do
|
43
|
+
|
44
|
+
include RequestLogAnalyzerSpecHelper
|
45
|
+
|
46
|
+
before(:each) do
|
47
|
+
@log_stripper = RequestLogAnalyzer::LogProcessor.new(spec_format, :strip, {})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should remove a junk line" do
|
51
|
+
@log_stripper.strip_line("junk line\n").should be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should keep a teaser line intact" do
|
55
|
+
@log_stripper.strip_line("processing 1234\n").should be_empty
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
#
|
3
|
+
# describe RequestLogAnalyzer::LogParser, "Merb" do
|
4
|
+
# include RequestLogAnalyzerSpecHelper
|
5
|
+
#
|
6
|
+
# before(:each) do
|
7
|
+
# @log_parser = RequestLogAnalyzer::LogParser.new(:merb)
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# it "should have a valid language definitions" do
|
11
|
+
# @log_parser.file_format.should be_valid
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# it "should parse a stream and find valid requests" do
|
15
|
+
# File.open(log_fixture(:merb), 'r') do |io|
|
16
|
+
# @log_parser.parse_io(io) do |request|
|
17
|
+
# request.should be_kind_of(RequestLogAnalyzer::Request)
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# it "should find 11 completed requests" do
|
23
|
+
# @log_parser.should_receive(:handle_request).exactly(11).times
|
24
|
+
# @log_parser.parse_file(log_fixture(:merb))
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# it "should parse all details from a request correctly" do
|
28
|
+
# request = nil
|
29
|
+
# @log_parser.parse_file(log_fixture(:merb)) { |found_request| request ||= found_request }
|
30
|
+
#
|
31
|
+
# request.should be_completed
|
32
|
+
# request[:timestamp].should == DateTime.parse('Fri Aug 29 11:10:23 +0200 2008')
|
33
|
+
# request[:dispatch_time].should == 0.243424
|
34
|
+
# request[:after_filters_time].should == 6.9e-05
|
35
|
+
# request[:before_filters_time].should == 0.213213
|
36
|
+
# request[:action_time].should == 0.241652
|
37
|
+
# end
|
38
|
+
# end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::LogParser, "Rails" do
|
4
|
+
include RequestLogAnalyzerSpecHelper
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
@log_parser = RequestLogAnalyzer::LogParser.new(RequestLogAnalyzer::FileFormat.load(:rails))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have a valid language definitions" do
|
11
|
+
@log_parser.file_format.should be_valid
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should parse a stream and find valid requests" do
|
15
|
+
io = File.new(log_fixture(:rails_1x), 'r')
|
16
|
+
@log_parser.parse_io(io) do |request|
|
17
|
+
request.should be_kind_of(RequestLogAnalyzer::Request)
|
18
|
+
end
|
19
|
+
io.close
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should find 4 completed requests" do
|
23
|
+
@log_parser.should_not_receive(:warn)
|
24
|
+
@log_parser.should_receive(:handle_request).exactly(4).times
|
25
|
+
@log_parser.parse_file(log_fixture(:rails_1x))
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse a Rails 2.2 request properly" do
|
29
|
+
@log_parser.should_not_receive(:warn)
|
30
|
+
@log_parser.parse_file(log_fixture(:rails_22)) do |request|
|
31
|
+
request.should =~ :processing
|
32
|
+
request.should =~ :completed
|
33
|
+
|
34
|
+
request[:controller].should == 'PageController'
|
35
|
+
request[:action].should == 'demo'
|
36
|
+
request[:url].should == 'http://www.example.coml/demo'
|
37
|
+
request[:status].should == 200
|
38
|
+
request[:duration].should == 0.614
|
39
|
+
request[:db].should == 0.031
|
40
|
+
request[:view].should == 0.120
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should parse a syslog file with prefix correctly" do
|
45
|
+
@log_parser.should_not_receive(:warn)
|
46
|
+
@log_parser.parse_file(log_fixture(:syslog_1x)) do |request|
|
47
|
+
|
48
|
+
request.should be_completed
|
49
|
+
|
50
|
+
request[:controller].should == 'EmployeeController'
|
51
|
+
request[:action].should == 'index'
|
52
|
+
request[:url].should == 'http://example.com/employee.xml'
|
53
|
+
request[:status].should == 200
|
54
|
+
request[:duration].should == 0.21665
|
55
|
+
request[:db].should == 0.0
|
56
|
+
request[:view].should == 0.00926
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should parse cached requests" do
|
61
|
+
@log_parser.should_not_receive(:warn)
|
62
|
+
@log_parser.parse_file(log_fixture(:rails_22_cached)) do |request|
|
63
|
+
request.should be_completed
|
64
|
+
request =~ :cache_hit
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should detect unordered requests in the logs" do
|
69
|
+
@log_parser.should_not_receive(:handle_request)
|
70
|
+
# the first Processing-line will not give a warning, but the next one will
|
71
|
+
@log_parser.should_receive(:warn).with(:unclosed_request, anything).once
|
72
|
+
# Both Completed ;ines will give a warning
|
73
|
+
@log_parser.should_receive(:warn).with(:no_current_request, anything).twice
|
74
|
+
@log_parser.parse_file(log_fixture(:rails_unordered))
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::Request, :incomplete_request do
|
4
|
+
|
5
|
+
include RequestLogAnalyzerSpecHelper
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@incomplete_request = RequestLogAnalyzer::Request.new(spec_format)
|
9
|
+
@incomplete_request << { :line_type => :test, :lineno => 1, :test_capture => 'awesome!' }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be single if only one line has been added" do
|
13
|
+
@incomplete_request.should_not be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should not be a completed request" do
|
17
|
+
@incomplete_request.should_not be_completed
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should take the line type of the first line as global line_type" do
|
21
|
+
@incomplete_request.lines[0][:line_type].should == :test
|
22
|
+
@incomplete_request.should =~ :test
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return the first field value" do
|
26
|
+
@incomplete_request[:test_capture].should == 'awesome!'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return nil if no such field is present" do
|
30
|
+
@incomplete_request[:nonexisting].should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe RequestLogAnalyzer::Request, :completed_request do
|
36
|
+
|
37
|
+
include RequestLogAnalyzerSpecHelper
|
38
|
+
|
39
|
+
before(:each) do
|
40
|
+
@completed_request = RequestLogAnalyzer::Request.new(spec_format)
|
41
|
+
@completed_request << { :line_type => :first, :lineno => 1, :name => 'first line!' }
|
42
|
+
@completed_request << { :line_type => :test, :lineno => 4, :test_capture => 'testing' }
|
43
|
+
@completed_request << { :line_type => :test, :lineno => 7, :test_capture => 'testing some more' }
|
44
|
+
@completed_request << { :line_type => :last, :lineno => 10, :time => 0.03 }
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not be empty when multiple liness are added" do
|
48
|
+
@completed_request.should_not be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be a completed request" do
|
52
|
+
@completed_request.should be_completed
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should recognize all line types" do
|
56
|
+
[:first, :test, :last].each { |type| @completed_request.should =~ type }
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should detect the correct field value" do
|
60
|
+
@completed_request[:name].should == 'first line!'
|
61
|
+
@completed_request[:time].should == 0.03
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should detect the first matching field value" do
|
65
|
+
@completed_request.first(:test_capture).should == 'testing'
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should detect the every matching field value" do
|
69
|
+
@completed_request.every(:test_capture).should == ['testing', "testing some more"]
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'spec'
|
5
|
+
require 'request_log_analyzer'
|
6
|
+
|
7
|
+
module RequestLogAnalyzerSpecHelper
|
8
|
+
|
9
|
+
def format_file(format)
|
10
|
+
File.dirname(__FILE__) + "/file_formats/#{format}.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
def spec_format
|
14
|
+
@spec_format ||= begin
|
15
|
+
require format_file(:spec_format)
|
16
|
+
SpecFormat.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def log_fixture(name)
|
21
|
+
File.dirname(__FILE__) + "/fixtures/#{name}.log"
|
22
|
+
end
|
23
|
+
|
24
|
+
def request(fields, format = TestFileFormat)
|
25
|
+
if fields.kind_of?(Array)
|
26
|
+
RequestLogAnalyzer::Request.create(format, *fields)
|
27
|
+
else
|
28
|
+
RequestLogAnalyzer::Request.create(format, fields)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module TestFileFormat
|
35
|
+
|
36
|
+
module Summarizer
|
37
|
+
def self.included(base)
|
38
|
+
# monkey patching for summarizer here :-)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module LogParser
|
43
|
+
def self.included(base)
|
44
|
+
# monkey patching for log parser here :-)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
LINE_DEFINITIONS = {
|
49
|
+
:first => {
|
50
|
+
:header => true,
|
51
|
+
:teaser => /processing /,
|
52
|
+
:regexp => /processing request (\d+)/,
|
53
|
+
:captures => [{ :name => :request_no, :type => :integer, :anonymize => :slightly }]
|
54
|
+
},
|
55
|
+
:test => {
|
56
|
+
:teaser => /testing /,
|
57
|
+
:regexp => /testing is (\w+)/,
|
58
|
+
:captures => [{ :name => :test_capture, :type => :string, :anonymize => true}]
|
59
|
+
},
|
60
|
+
:last => {
|
61
|
+
:footer => true,
|
62
|
+
:teaser => /finishing /,
|
63
|
+
:regexp => /finishing request (\d+)/,
|
64
|
+
:captures => [{ :name => :request_no, :type => :integer}]
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/tasklib'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module Rake
|
7
|
+
|
8
|
+
class GithubGem < TaskLib
|
9
|
+
|
10
|
+
attr_accessor :name
|
11
|
+
attr_accessor :specification
|
12
|
+
|
13
|
+
def self.define_tasks!
|
14
|
+
gem_task_builder = Rake::GithubGem.new
|
15
|
+
gem_task_builder.register_all_tasks!
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
reload_gemspec!
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_all_tasks!
|
24
|
+
namespace(:gem) do
|
25
|
+
desc "Updates the file lists for this gem"
|
26
|
+
task(:manifest) { manifest_task }
|
27
|
+
|
28
|
+
desc "Builds a ruby gem for #{@name}"
|
29
|
+
task(:build => [:manifest]) { build_task }
|
30
|
+
|
31
|
+
desc "Installs the ruby gem for #{@name} locally"
|
32
|
+
task(:install => [:build]) { install_task }
|
33
|
+
|
34
|
+
desc "Uninstalls the ruby gem for #{@name} locally"
|
35
|
+
task(:uninstall) { uninstall_task }
|
36
|
+
|
37
|
+
desc "Releases a new version of #{@name}"
|
38
|
+
task(:release) { release_task }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def reload_gemspec!
|
47
|
+
raise "No gemspec file found!" if gemspec_file.nil?
|
48
|
+
spec = File.read(gemspec_file)
|
49
|
+
@specification = eval(spec)
|
50
|
+
@name = specification.name
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_command(command)
|
54
|
+
lines = []
|
55
|
+
IO.popen(command) { |f| lines = f.readlines }
|
56
|
+
return lines
|
57
|
+
end
|
58
|
+
|
59
|
+
def git_modified?(file)
|
60
|
+
return !run_command('git status').detect { |line| Regexp.new(Regexp.quote(file)) =~ line }.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
def git_commit_file(file, message, branch = nil)
|
64
|
+
verify_current_branch(branch) unless branch.nil?
|
65
|
+
if git_modified?(file)
|
66
|
+
sh "git add #{file}"
|
67
|
+
sh "git commit -m \"#{message}\""
|
68
|
+
else
|
69
|
+
raise "#{file} is not modified and cannot be committed!"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def git_create_tag(tag_name, message)
|
74
|
+
sh "git tag -a \"#{tag_name}\" -m \"#{message}\""
|
75
|
+
end
|
76
|
+
|
77
|
+
def git_push(remote = 'origin', branch = 'master', options = [])
|
78
|
+
verify_clean_status(branch)
|
79
|
+
options_str = options.map { |o| "--#{o}"}.join(' ')
|
80
|
+
sh "git push #{options_str} #{remote} #{branch}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def gemspec_version=(new_version)
|
84
|
+
spec = File.read(gemspec_file)
|
85
|
+
spec.gsub!(/^(\s*s\.version\s*=\s*)('|")(.+)('|")(\s*)$/) { "#{$1}'#{new_version}'#{$5}" }
|
86
|
+
spec.gsub!(/^(\s*s\.date\s*=\s*)('|")(.+)('|")(\s*)$/) { "#{$1}'#{Date.today.strftime('%Y-%m-%d')}'#{$5}" }
|
87
|
+
File.open(gemspec_file, 'w') { |f| f << spec }
|
88
|
+
reload_gemspec!
|
89
|
+
end
|
90
|
+
|
91
|
+
def gemspec_date=(new_date)
|
92
|
+
spec = File.read(gemspec_file)
|
93
|
+
spec.gsub!(/^(\s*s\.date\s*=\s*)('|")(.+)('|")(\s*)$/) { "#{$1}'#{new_date.strftime('%Y-%m-%d')}'#{$5}" }
|
94
|
+
File.open(gemspec_file, 'w') { |f| f << spec }
|
95
|
+
reload_gemspec!
|
96
|
+
end
|
97
|
+
|
98
|
+
def gemspec_file
|
99
|
+
@gemspec_file ||= Dir['*.gemspec'].first
|
100
|
+
end
|
101
|
+
|
102
|
+
def verify_current_branch(branch)
|
103
|
+
run_command('git branch').detect { |line| /^\* (.+)/ =~ line }
|
104
|
+
raise "You are currently not working in the master branch!" unless branch == $1
|
105
|
+
end
|
106
|
+
|
107
|
+
def verify_clean_status(on_branch = nil)
|
108
|
+
sh "git fetch"
|
109
|
+
lines = run_command('git status')
|
110
|
+
raise "You don't have the most recent version available. Run git pull first." if /^\# Your branch is behind/ =~ lines[1]
|
111
|
+
raise "You are currently not working in the #{on_branch} branch!" unless on_branch.nil? || (/^\# On branch (.+)/ =~ lines.first && $1 == on_branch)
|
112
|
+
raise "Your master branch contains modifications!" unless /^nothing to commit \(working directory clean\)/ =~ lines.last
|
113
|
+
end
|
114
|
+
|
115
|
+
def verify_version(new_version)
|
116
|
+
newest_version = run_command('git tag').map { |tag| tag.split(name + '-').last }.compact.map { |v| Gem::Version.new(v) }.max
|
117
|
+
raise "This version number (#{new_version}) is not higher than the highest tagged version (#{newest_version})" if !newest_version.nil? && newest_version >= Gem::Version.new(new_version.to_s)
|
118
|
+
end
|
119
|
+
|
120
|
+
def manifest_task
|
121
|
+
verify_current_branch('master')
|
122
|
+
|
123
|
+
list = Dir['**/*'].sort
|
124
|
+
list -= [gemspec_file]
|
125
|
+
|
126
|
+
if File.exist?('.gitignore')
|
127
|
+
File.read('.gitignore').each_line do |glob|
|
128
|
+
glob = glob.chomp.sub(/^\//, '')
|
129
|
+
list -= Dir[glob]
|
130
|
+
list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# update the spec file
|
135
|
+
spec = File.read(gemspec_file)
|
136
|
+
spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
|
137
|
+
assignment = $1
|
138
|
+
bunch = $2 ? list.grep(/^(test.*_test\.rb|spec.*_spec.rb)$/) : list
|
139
|
+
'%s%%w(%s)' % [assignment, bunch.join(' ')]
|
140
|
+
end
|
141
|
+
|
142
|
+
File.open(gemspec_file, 'w') { |f| f << spec }
|
143
|
+
reload_gemspec!
|
144
|
+
end
|
145
|
+
|
146
|
+
def build_task
|
147
|
+
sh "gem build #{gemspec_file}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def install_task
|
151
|
+
raise "#{name} .gem file not found" unless File.exist?("#{name}-#{specification.version}.gem")
|
152
|
+
sh "gem install #{name}-#{specification.version}.gem"
|
153
|
+
end
|
154
|
+
|
155
|
+
def uninstall_task
|
156
|
+
raise "#{name} .gem file not found" unless File.exist?("#{name}-#{specification.version}.gem")
|
157
|
+
sh "gem uninstall #{name}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def release_task
|
161
|
+
verify_clean_status('master')
|
162
|
+
verify_version(ENV['VERSION'] || @specification.version)
|
163
|
+
|
164
|
+
# update gemspec file
|
165
|
+
self.gemspec_version = ENV['VERSION'] if Gem::Version.correct?(ENV['VERSION'])
|
166
|
+
self.gemspec_date = Date.today
|
167
|
+
manifest_task
|
168
|
+
git_commit_file(gemspec_file, "Updated #{gemspec_file} for release of version #{@specification.version}") if git_modified?(gemspec_file)
|
169
|
+
|
170
|
+
# create tag and push changes
|
171
|
+
git_create_tag("#{@name}-#{@specification.version}", "Tagged version #{@specification.version}")
|
172
|
+
git_push('origin', 'master', [:tags])
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
Rake::GithubGem.define_tasks!
|