rscm 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +198 -0
- data/Rakefile +118 -0
- data/ext/rscm.jar +0 -0
- data/lib/rscm.rb +10 -0
- data/lib/rscm/abstract_log_parser.rb +49 -0
- data/lib/rscm/abstract_scm.rb +229 -0
- data/lib/rscm/changes.rb +271 -0
- data/lib/rscm/cvs/cvs.rb +363 -0
- data/lib/rscm/cvs/cvs_log_parser.rb +161 -0
- data/lib/rscm/darcs/darcs.rb +69 -0
- data/lib/rscm/line_editor.rb +46 -0
- data/lib/rscm/logging.rb +5 -0
- data/lib/rscm/monotone/monotone.rb +107 -0
- data/lib/rscm/mooky/mooky.rb +13 -0
- data/lib/rscm/parser.rb +39 -0
- data/lib/rscm/path_converter.rb +92 -0
- data/lib/rscm/perforce/perforce.rb +415 -0
- data/lib/rscm/starteam/starteam.rb +99 -0
- data/lib/rscm/svn/svn.rb +337 -0
- data/lib/rscm/svn/svn_log_parser.rb +134 -0
- data/lib/rscm/time_ext.rb +125 -0
- data/test/rscm/apply_label_scm_tests.rb +26 -0
- data/test/rscm/changes_fixture.rb +20 -0
- data/test/rscm/changes_test.rb +129 -0
- data/test/rscm/cvs/cvs_log_parser_test.rb +575 -0
- data/test/rscm/cvs/cvs_test.rb +22 -0
- data/test/rscm/darcs/darcs_test.rb +14 -0
- data/test/rscm/difftool_test.rb +40 -0
- data/test/rscm/file_ext.rb +12 -0
- data/test/rscm/generic_scm_tests.rb +282 -0
- data/test/rscm/line_editor_test.rb +76 -0
- data/test/rscm/mockit.rb +130 -0
- data/test/rscm/mockit_test.rb +117 -0
- data/test/rscm/monotone/monotone_test.rb +19 -0
- data/test/rscm/mooky/mooky_test.rb +14 -0
- data/test/rscm/parser_test.rb +47 -0
- data/test/rscm/path_converter_test.rb +52 -0
- data/test/rscm/perforce/perforce_test.rb +14 -0
- data/test/rscm/starteam/starteam_test.rb +36 -0
- data/test/rscm/svn/svn_log_parser_test.rb +111 -0
- data/test/rscm/svn/svn_test.rb +28 -0
- data/test/rscm/tempdir.rb +12 -0
- metadata +81 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
module RSCM
|
2
|
+
module TimeExt
|
3
|
+
SECOND = 1
|
4
|
+
MINUTE = 60
|
5
|
+
HOUR = 60 * MINUTE
|
6
|
+
DAY = 24 * HOUR
|
7
|
+
WEEK = 7 * DAY
|
8
|
+
MONTH = 30 * DAY
|
9
|
+
YEAR = 365 * DAY
|
10
|
+
YEARS = 2 * YEAR
|
11
|
+
|
12
|
+
def duration_as_text(duration_secs)
|
13
|
+
case duration_secs
|
14
|
+
when 0 then "0 seconds"
|
15
|
+
when SECOND then "#{duration_secs/SECOND} second"
|
16
|
+
when SECOND+1..MINUTE-1 then "#{duration_secs/SECOND} seconds"
|
17
|
+
when MINUTE..2*MINUTE-1 then "#{duration_secs/MINUTE} minute"
|
18
|
+
when 2*MINUTE..HOUR-1 then "#{duration_secs/MINUTE} minutes"
|
19
|
+
when HOUR..2*HOUR-1 then "#{duration_secs/HOUR} hour"
|
20
|
+
when 2*HOUR..DAY-1 then "#{duration_secs/HOUR} hours"
|
21
|
+
when DAY..2*DAY-1 then "#{duration_secs/DAY} day"
|
22
|
+
when 2*DAY..WEEK-1 then "#{duration_secs/DAY} days"
|
23
|
+
when WEEK..2*WEEK-1 then "#{duration_secs/WEEK} week"
|
24
|
+
when 2*WEEK..MONTH-1 then "#{duration_secs/WEEK} weeks"
|
25
|
+
when MONTH..2*MONTH-1 then "#{duration_secs/MONTH} month"
|
26
|
+
when 2*MONTH..YEAR-1 then "#{duration_secs/MONTH} months"
|
27
|
+
when YEAR..2*YEAR-1 then "#{duration_secs/YEAR} year"
|
28
|
+
else "#{duration_secs/YEAR} years"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
module_function :duration_as_text
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Time mixin that adds some additional utility methods
|
36
|
+
class Time
|
37
|
+
include RSCM::TimeExt
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def epoch
|
41
|
+
Time.utc(1970)
|
42
|
+
end
|
43
|
+
|
44
|
+
def infinity
|
45
|
+
Time.utc(2038)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def Time.parse_ymdHMS(timestamp_as_ymdHMS)
|
50
|
+
Time.utc(
|
51
|
+
timestamp_as_ymdHMS[0..3], # year
|
52
|
+
timestamp_as_ymdHMS[4..5], # month
|
53
|
+
timestamp_as_ymdHMS[6..7], # day
|
54
|
+
timestamp_as_ymdHMS[8..9], # hour
|
55
|
+
timestamp_as_ymdHMS[10..11], # minute
|
56
|
+
timestamp_as_ymdHMS[12..13] # second
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_rfc2822
|
61
|
+
utc.strftime("%a, %d %b %Y %H:%M:%S +0000")
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_human
|
65
|
+
utc.strftime("%d %b %Y %H:%M:%S")
|
66
|
+
end
|
67
|
+
|
68
|
+
def ymdHMS
|
69
|
+
utc.strftime("%Y%m%d%H%M%S")
|
70
|
+
end
|
71
|
+
|
72
|
+
def ==(o)
|
73
|
+
return false unless o.is_a?(Time)
|
74
|
+
ymdHMS == o.ymdHMS
|
75
|
+
end
|
76
|
+
|
77
|
+
# In many cases (for example when drawing a graph with
|
78
|
+
# dates along the x-axis) it can be useful to know what
|
79
|
+
# month, week or day a certain timestamp is within.
|
80
|
+
#
|
81
|
+
# This lets you do that. Call with :day, :week or :month
|
82
|
+
# returns period_number, period_start
|
83
|
+
#
|
84
|
+
# period_number is an int representing the day, week or month number of the year.
|
85
|
+
# period_start is a utc time of the start of the period.
|
86
|
+
def get_period_info(interval)
|
87
|
+
case interval
|
88
|
+
when :week then get_week_info
|
89
|
+
when :month then get_month_info
|
90
|
+
when :day then get_day_info
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# week_number, week_start_date = get_info(time, :week)
|
95
|
+
def get_week_info
|
96
|
+
first_day_of_year = Time.utc(utc.year, 1, 1)
|
97
|
+
week_day_of_first_day_of_year = first_day_of_year.wday
|
98
|
+
# Sunday = 0, .. Monday = 6
|
99
|
+
first_monday_of_year = Time.utc(utc.year, 1, ((week_day_of_first_day_of_year % 7) + 1))
|
100
|
+
|
101
|
+
week_number = nil
|
102
|
+
week_start_date = nil
|
103
|
+
days = (utc.yday - first_monday_of_year.yday)
|
104
|
+
week_number = (days / 7) + 1
|
105
|
+
week_start_date = first_monday_of_year + ((week_number-1) * 7) * 60 * 60 * 24
|
106
|
+
return week_number, week_start_date
|
107
|
+
end
|
108
|
+
|
109
|
+
# month_number, month_start_date = get_info(time, :month)
|
110
|
+
def get_month_info
|
111
|
+
return month, Time.utc(utc.year, utc.month, 1)
|
112
|
+
end
|
113
|
+
|
114
|
+
# day_number, day_date = get_info(time, :day)
|
115
|
+
def get_day_info
|
116
|
+
return yday, Time.utc(utc.year, utc.month, utc.day)
|
117
|
+
end
|
118
|
+
|
119
|
+
def difference_as_text(t)
|
120
|
+
raise "t must be a time" unless t.is_a?(Time)
|
121
|
+
diff = (self - t).to_i
|
122
|
+
duration_as_text(diff)
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module RSCM
|
4
|
+
module GenericSCMTests
|
5
|
+
include FileUtils
|
6
|
+
|
7
|
+
def test_apply_label
|
8
|
+
work_dir = new_temp_dir
|
9
|
+
checkout_dir = "#{work_dir}/checkout"
|
10
|
+
repository_dir = "#{work_dir}/repository"
|
11
|
+
scm = create_scm(repository_dir, "damagecontrolled")
|
12
|
+
scm.create
|
13
|
+
|
14
|
+
import_damagecontrolled(scm, "#{work_dir}/damagecontrolled")
|
15
|
+
scm.checkout(checkout_dir)
|
16
|
+
|
17
|
+
add_or_edit_and_commit_file(scm, checkout_dir, "before.txt", "Before label")
|
18
|
+
scm.apply_label(checkout_dir, "MY_LABEL")
|
19
|
+
add_or_edit_and_commit_file(scm, checkout_dir, "after.txt", "After label")
|
20
|
+
scm.checkout(checkout_dir, "MY_LABEL")
|
21
|
+
assert(File.exist?("#{checkout_dir}/before.txt"))
|
22
|
+
assert(!File.exist?("#{checkout_dir}/after.txt"))
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rscm/changes'
|
3
|
+
|
4
|
+
module RSCM
|
5
|
+
module ChangesFixture
|
6
|
+
def setup_changes
|
7
|
+
#1
|
8
|
+
@change1 = RSCM::Change.new("path/one", "jon", "Fixed CATCH-22", nil, Time.utc(2004,7,5,12,0,2))
|
9
|
+
@change2 = RSCM::Change.new("path/two", "jon", "Fixed CATCH-22", nil, Time.utc(2004,7,5,12,0,4))
|
10
|
+
#2
|
11
|
+
@change3 = RSCM::Change.new("path/three", "jon", "hipp hurra", nil, Time.utc(2004,7,5,12,0,6))
|
12
|
+
#3
|
13
|
+
@change4 = RSCM::Change.new("path/four", "aslak", "hipp hurraX", nil, Time.utc(2004,7,5,12,0,8))
|
14
|
+
#4
|
15
|
+
@change5 = RSCM::Change.new("path/five", "aslak", "hipp hurra", nil, Time.utc(2004,7,5,12,0,10))
|
16
|
+
@change6 = RSCM::Change.new("path/six", "aslak", "hipp hurra", nil, Time.utc(2004,7,5,12,0,12))
|
17
|
+
@change7 = RSCM::Change.new("path/seven", "aslak", "hipp hurra", nil, Time.utc(2004,7,5,12,0,14))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rscm/changes_fixture'
|
3
|
+
|
4
|
+
module RSCM
|
5
|
+
class ChangesTest < Test::Unit::TestCase
|
6
|
+
include ChangesFixture
|
7
|
+
|
8
|
+
def setup
|
9
|
+
setup_changes
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_convert_changes_to_changesets_should_match_user_message_and_timestamp_
|
13
|
+
changesets = ChangeSets.new
|
14
|
+
changesets.add(@change1)
|
15
|
+
changesets.add(@change2)
|
16
|
+
changesets.add(@change3)
|
17
|
+
changesets.add(@change4)
|
18
|
+
changesets.add(@change5)
|
19
|
+
changesets.add(@change6)
|
20
|
+
changesets.add(@change7)
|
21
|
+
|
22
|
+
changeset_0 = ChangeSet.new
|
23
|
+
changeset_0 << @change1
|
24
|
+
changeset_0 << @change2
|
25
|
+
|
26
|
+
changeset_1 = ChangeSet.new
|
27
|
+
changeset_1 << @change3
|
28
|
+
|
29
|
+
changeset_2 = ChangeSet.new
|
30
|
+
changeset_2 << @change4
|
31
|
+
|
32
|
+
changeset_3 = ChangeSet.new
|
33
|
+
changeset_3 << @change5
|
34
|
+
changeset_3 << @change6
|
35
|
+
changeset_3 << @change7
|
36
|
+
|
37
|
+
assert_equal(4, changesets.length)
|
38
|
+
|
39
|
+
expected_changesets = ChangeSets.new
|
40
|
+
expected_changesets.add(changeset_0)
|
41
|
+
expected_changesets.add(changeset_1)
|
42
|
+
expected_changesets.add(changeset_2)
|
43
|
+
expected_changesets.add(changeset_3)
|
44
|
+
|
45
|
+
assert_equal(expected_changesets, changesets)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_changesets_can_add_individual_changes_and_group_in_changeset_instances
|
49
|
+
changesets = ChangeSets.new
|
50
|
+
assert(0, changesets.length)
|
51
|
+
|
52
|
+
changesets.add(@change1)
|
53
|
+
changesets.add(@change2)
|
54
|
+
changesets.add(@change3)
|
55
|
+
changesets.add(@change4)
|
56
|
+
assert(3, changesets.length)
|
57
|
+
|
58
|
+
tjo_bing_changeset = changesets[0]
|
59
|
+
hipp_hurra_changeset = changesets[1]
|
60
|
+
hipp_hurraX_changeset = changesets[2]
|
61
|
+
assert(2, tjo_bing_changeset.length)
|
62
|
+
assert(1, hipp_hurra_changeset.length)
|
63
|
+
assert(1, hipp_hurraX_changeset.length)
|
64
|
+
|
65
|
+
assert_same(@change1, tjo_bing_changeset[0])
|
66
|
+
assert_same(@change2, tjo_bing_changeset[1])
|
67
|
+
assert_same(@change3, hipp_hurra_changeset[0])
|
68
|
+
assert_same(@change4, hipp_hurraX_changeset[0])
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_sort_by_time
|
72
|
+
changesets = ChangeSets.new
|
73
|
+
changesets.add(@change1)
|
74
|
+
changesets.add(@change4)
|
75
|
+
changesets.add(@change2)
|
76
|
+
changesets.add(@change7)
|
77
|
+
changesets.add(@change5)
|
78
|
+
changesets.add(@change3)
|
79
|
+
changesets.add(@change6)
|
80
|
+
|
81
|
+
changesets = changesets.sort do |a,b|
|
82
|
+
a.time <=> b.time
|
83
|
+
end
|
84
|
+
assert_equal(4, changesets.length)
|
85
|
+
|
86
|
+
assert_equal(@change2.time, changesets[0].time)
|
87
|
+
assert_equal(@change7.time, changesets[-1].time)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_can_parse_changesets_from_yaml
|
91
|
+
changesets = File.open(File.dirname(__FILE__) + "/changesets.yaml") do |io|
|
92
|
+
YAML::load(io)
|
93
|
+
end
|
94
|
+
assert_equal("rinkrank", changesets[0][1].developer)
|
95
|
+
assert_equal("En to\ntre buksa \nned\n", changesets[0][1].message)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_reports_timestamp_of_latest_change
|
99
|
+
changeset = ChangeSet.new
|
100
|
+
changeset << Change.new(nil, nil, nil, nil, Time.utc(2004))
|
101
|
+
changeset << Change.new(nil, nil, nil, nil, Time.utc(2005))
|
102
|
+
changeset << Change.new(nil, nil, nil, nil, Time.utc(2003))
|
103
|
+
assert_equal(Time.utc(2005), changeset.time)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_should_sort_changesets
|
107
|
+
changesets = ChangeSets.new
|
108
|
+
changesets.add(@change1)
|
109
|
+
changesets.add(@change4)
|
110
|
+
changesets.add(@change2)
|
111
|
+
changesets.add(@change7)
|
112
|
+
changesets.add(@change5)
|
113
|
+
changesets.add(@change3)
|
114
|
+
changesets.add(@change6)
|
115
|
+
|
116
|
+
cs0 = changesets[0]
|
117
|
+
cs1 = changesets[1]
|
118
|
+
cs2 = changesets[2]
|
119
|
+
cs3 = changesets[3]
|
120
|
+
|
121
|
+
reversed = changesets.reverse
|
122
|
+
assert_equal(cs0, reversed[3])
|
123
|
+
assert_equal(cs1, reversed[2])
|
124
|
+
assert_equal(cs2, reversed[1])
|
125
|
+
assert_equal(cs3, reversed[0])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
@@ -0,0 +1,575 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'stringio'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'rscm/changes'
|
5
|
+
require 'rscm/cvs/cvs_log_parser'
|
6
|
+
|
7
|
+
module RSCM
|
8
|
+
class CVSLogParserTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
include FileUtils
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@parser = CVSLogParser.new(nil)
|
14
|
+
@parser.cvspath = "/scm/damagecontrol"
|
15
|
+
@parser.cvsmodule = "damagecontrol"
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
assert(!@parser.had_error?, "parser had errors") unless @parser.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_read_log_entry
|
23
|
+
assert_equal(nil, CVSLogParser.new(StringIO.new("")).next_log_entry)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_parses_entire_log_into_changesets
|
27
|
+
File.open(File.dirname(__FILE__) + "/cvs-test.log") do |io|
|
28
|
+
@parser = CVSLogParser.new(io)
|
29
|
+
changesets = @parser.parse_changesets
|
30
|
+
|
31
|
+
assert_equal(24, changesets.length)
|
32
|
+
assert_match(/o YAML config \(BuildBootstrapper\)/, changesets[1].message)
|
33
|
+
assert_match(/failure/, changesets[8].message)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# http://jira.codehaus.org/browse/DC-312
|
38
|
+
def test_jira_dc_312
|
39
|
+
File.open(File.dirname(__FILE__) + "/cvs-dataforge.log") do |io|
|
40
|
+
@parser = CVSLogParser.new(io)
|
41
|
+
changesets = @parser.parse_changesets
|
42
|
+
|
43
|
+
assert_equal(271, changesets.length)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_parse_changes
|
48
|
+
changesets = ChangeSets.new
|
49
|
+
@parser.parse_changes(LOG_ENTRY, changesets)
|
50
|
+
changesets.sort!
|
51
|
+
assert_equal(4, changesets.length)
|
52
|
+
assert_equal("src/ruby/damagecontrol/BuildExecutorTest.rb", changesets[0][0].path)
|
53
|
+
assert_match(/linux-windows galore/, changesets[1][0].message)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_sets_previous_revision_to_one_before_the_current
|
57
|
+
change = @parser.parse_change(CHANGE_ENTRY)
|
58
|
+
assert_equal("1.20", change.revision)
|
59
|
+
assert_equal("1.19", change.previous_revision)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_can_determine_previous_revisions_from_tricky_input
|
63
|
+
assert_equal("2.2.1.1", @parser.determine_previous_revision("2.2.1.2"))
|
64
|
+
assert_equal(nil, @parser.determine_previous_revision("2.2.1.1"))
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_parse_change
|
68
|
+
change = @parser.parse_change(CHANGE_ENTRY)
|
69
|
+
assert_equal("1.20", change.revision)
|
70
|
+
assert_equal(Time.utc(2003,11,9,17,53,37), change.time)
|
71
|
+
assert_equal("tirsen", change.developer)
|
72
|
+
assert_match(/Quiet period is configurable for each project/, change.message)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_can_split_entries_separated_by_line_of_dashes
|
76
|
+
entries = @parser.split_entries(LOG_ENTRY)
|
77
|
+
assert_equal(5, entries.length)
|
78
|
+
assert_equal(CHANGE_ENTRY, entries[1])
|
79
|
+
end
|
80
|
+
|
81
|
+
CHANGE_ENTRY = <<-EOF
|
82
|
+
revision 1.20
|
83
|
+
date: 2003/11/09 17:53:37; author: tirsen; state: Exp; lines: +3 -4
|
84
|
+
Quiet period is configurable for each project
|
85
|
+
EOF
|
86
|
+
|
87
|
+
LOG_ENTRY_WITH_DELETED_FILE = <<EOF
|
88
|
+
RCS file: /scm/damagecontrol/damagecontrol/server/damagecontrol/Attic/codehaus.rb,v
|
89
|
+
Working file: server/damagecontrol/codehaus.rb
|
90
|
+
head: 1.23
|
91
|
+
branch:
|
92
|
+
locks: strict
|
93
|
+
access list:
|
94
|
+
keyword substitution: kv
|
95
|
+
total revisions: 23; selected revisions: 1
|
96
|
+
description:
|
97
|
+
----------------------------
|
98
|
+
revision 1.23
|
99
|
+
date: 2004/07/13 07:56:26; author: tirsen; state: dead; lines: +0 -0
|
100
|
+
remove username check (doesn't work on beaver)
|
101
|
+
I do really want to see the url in irc, it's very, very convenient. thank you very much ;-)
|
102
|
+
EOF
|
103
|
+
|
104
|
+
def test_can_parse_changes_with_deleted_file
|
105
|
+
changesets = ChangeSets.new
|
106
|
+
@parser.parse_changes(LOG_ENTRY_WITH_DELETED_FILE, changesets)
|
107
|
+
assert_equal(1, changesets.length)
|
108
|
+
assert_equal("server/damagecontrol/codehaus.rb", changesets[0][0].path)
|
109
|
+
assert_equal(Change::DELETED, changesets[0][0].status)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_log_from_e2e_test
|
113
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_FROM_E2E_TEST))
|
114
|
+
changesets = @parser.parse_changesets
|
115
|
+
assert_equal(2, changesets.length)
|
116
|
+
assert_match(/foo/, changesets[1].message)
|
117
|
+
assert_match(/bar/, changesets[0].message)
|
118
|
+
end
|
119
|
+
|
120
|
+
LOG_FROM_E2E_TEST = <<-EOF
|
121
|
+
=============================================================================
|
122
|
+
|
123
|
+
RCS file: C:\projects\damagecontrol\target\temp_e2e_1081547757\repository/e2eproject/build.bat,v
|
124
|
+
Working file: build.bat
|
125
|
+
head: 1.2
|
126
|
+
branch:
|
127
|
+
locks: strict
|
128
|
+
access list:
|
129
|
+
symbolic names:
|
130
|
+
keyword substitution: kv
|
131
|
+
total revisions: 2; selected revisions: 2
|
132
|
+
description:
|
133
|
+
----------------------------
|
134
|
+
revision 1.2
|
135
|
+
date: 2004/04/09 21:56:47; author: jtirsen; state: Exp; lines: +1 -1
|
136
|
+
foo
|
137
|
+
----------------------------
|
138
|
+
revision 1.1
|
139
|
+
date: 2004/04/09 21:56:12; author: jtirsen; state: Exp;
|
140
|
+
bar
|
141
|
+
=============================================================================EOF
|
142
|
+
EOF
|
143
|
+
|
144
|
+
LOG_ENTRY = <<-EOF
|
145
|
+
=============================================================================
|
146
|
+
|
147
|
+
RCS file: /scm/damagecontrol/damagecontrol/src/ruby/damagecontrol/BuildExecutorTest.rb,v
|
148
|
+
Working file: src/ruby/damagecontrol/BuildExecutorTest.rb
|
149
|
+
head: 1.20
|
150
|
+
branch:
|
151
|
+
locks: strict
|
152
|
+
access list:
|
153
|
+
symbolic names:
|
154
|
+
keyword substitution: kv
|
155
|
+
total revisions: 20; selected revisions: 4
|
156
|
+
description:
|
157
|
+
----------------------------
|
158
|
+
revision 1.20
|
159
|
+
date: 2003/11/09 17:53:37; author: tirsen; state: Exp; lines: +3 -4
|
160
|
+
Quiet period is configurable for each project
|
161
|
+
----------------------------
|
162
|
+
revision 1.19
|
163
|
+
date: 2003/11/09 17:04:18; author: tirsen; state: Exp; lines: +32 -2
|
164
|
+
Quiet period implemented for BuildExecutor, but does not yet handle multiple projects (builds are not queued as before)
|
165
|
+
----------------------------
|
166
|
+
revision 1.18
|
167
|
+
date: 2003/11/09 15:51:50; author: rinkrank; state: Exp; lines: +1 -2
|
168
|
+
linux-windows galore
|
169
|
+
----------------------------
|
170
|
+
revision 1.17
|
171
|
+
date: 2003/11/09 15:00:06; author: rinkrank; state: Exp; lines: +6 -8
|
172
|
+
o YAML config (BuildBootstrapper)
|
173
|
+
o EmailPublisher
|
174
|
+
=============================================================================
|
175
|
+
EOF
|
176
|
+
|
177
|
+
def test_can_parse_path
|
178
|
+
assert_equal("testdata/damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java",
|
179
|
+
@parser.parse_path(LOG_ENTRY_FROM_05_07_2004_19_42))
|
180
|
+
end
|
181
|
+
|
182
|
+
LOG_ENTRY_FROM_05_07_2004_19_42 = <<-EOF
|
183
|
+
RCS file: /scm/damagecontrol/damagecontrol/testdata/damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java,v
|
184
|
+
Working file: testdata/damagecontrolled/src/java/com/thoughtworks/damagecontrolled/Thingy.java
|
185
|
+
head: 1.1
|
186
|
+
branch:
|
187
|
+
locks: strict
|
188
|
+
access list:
|
189
|
+
symbolic names:
|
190
|
+
BEFORE_CENTRAL_REFACTORING: 1.1
|
191
|
+
RELEASE_0_1: 1.1
|
192
|
+
keyword substitution: kv
|
193
|
+
total revisions: 1; selected revisions: 1
|
194
|
+
description:
|
195
|
+
EOF
|
196
|
+
|
197
|
+
def test_can_parse_LOG_FROM_05_07_2004_19_41
|
198
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_FROM_05_07_2004_19_41))
|
199
|
+
assert_equal(11, @parser.split_entries(LOG_FROM_05_07_2004_19_41).size)
|
200
|
+
assert_equal("server/damagecontrol/scm/CVS.rb", @parser.parse_path(@parser.split_entries(LOG_FROM_05_07_2004_19_41)[0]))
|
201
|
+
changesets = @parser.parse_changesets
|
202
|
+
|
203
|
+
assert_equal(10, changesets.length)
|
204
|
+
expected_change = Change.new
|
205
|
+
expected_change.path = "server/damagecontrol/scm/CVS.rb"
|
206
|
+
expected_change.developer = "tirsen"
|
207
|
+
expected_change.message = "fixed some stuff in the log parser"
|
208
|
+
expected_change.revision = "1.19"
|
209
|
+
expected_change.time = Time.utc(2004, 7, 5, 9, 41, 51)
|
210
|
+
|
211
|
+
assert_equal(expected_change, changesets[9][0])
|
212
|
+
end
|
213
|
+
|
214
|
+
LOG_FROM_05_07_2004_19_41 = <<-EOF
|
215
|
+
|
216
|
+
RCS file: /scm/damagecontrol/damagecontrol/server/damagecontrol/scm/CVS.rb,v
|
217
|
+
Working file: server/damagecontrol/scm/CVS.rb
|
218
|
+
head: 1.19
|
219
|
+
branch:
|
220
|
+
locks: strict
|
221
|
+
access list:
|
222
|
+
symbolic names:
|
223
|
+
BEFORE_CENTRAL_REFACTORING: 1.1
|
224
|
+
keyword substitution: kv
|
225
|
+
total revisions: 19; selected revisions: 19
|
226
|
+
description:
|
227
|
+
----------------------------
|
228
|
+
revision 1.19
|
229
|
+
date: 2004/07/05 09:41:51; author: tirsen; state: Exp; lines: +1 -1
|
230
|
+
fixed some stuff in the log parser
|
231
|
+
----------------------------
|
232
|
+
revision 1.18
|
233
|
+
date: 2004/07/05 09:38:21; author: tirsen; state: Exp; lines: +7 -6
|
234
|
+
fixed some stuff in the log parser
|
235
|
+
----------------------------
|
236
|
+
revision 1.17
|
237
|
+
date: 2004/07/05 09:09:44; author: tirsen; state: Exp; lines: +2 -0
|
238
|
+
oops.... log parser can't actually log apparently, well, it can now...
|
239
|
+
----------------------------
|
240
|
+
revision 1.16
|
241
|
+
date: 2004/07/05 08:52:39; author: tirsen; state: Exp; lines: +23 -26
|
242
|
+
refactorings in the web
|
243
|
+
fixed footer with css
|
244
|
+
some other cssing around
|
245
|
+
fixed cvs output so my irc client actually gives me a proper link I can click on
|
246
|
+
----------------------------
|
247
|
+
revision 1.15
|
248
|
+
date: 2004/07/04 18:04:38; author: rinkrank; state: Exp; lines: +1 -1
|
249
|
+
debug debug
|
250
|
+
----------------------------
|
251
|
+
revision 1.14
|
252
|
+
date: 2004/07/04 17:44:36; author: rinkrank; state: Exp; lines: +23 -8
|
253
|
+
improved error logging
|
254
|
+
----------------------------
|
255
|
+
revision 1.13
|
256
|
+
date: 2004/07/04 15:59:16; author: rinkrank; state: Exp; lines: +1 -0
|
257
|
+
debugging cvs timestamps
|
258
|
+
----------------------------
|
259
|
+
revision 1.12
|
260
|
+
date: 2004/07/03 19:25:19; author: rinkrank; state: Exp; lines: +20 -3
|
261
|
+
support for previous_revision in modifications
|
262
|
+
----------------------------
|
263
|
+
revision 1.11
|
264
|
+
date: 2004/07/02
|
265
|
+
CVS and CC refactorings. Improved parsing of trigger command line and bootstrapping
|
266
|
+
----------------------------
|
267
|
+
revision 1.1
|
268
|
+
date: 2003/10/04 12:04:14; author: tirsen; state: Exp;
|
269
|
+
Cleaned up the end-to-end test, did some more work on the CCLogPoller
|
270
|
+
EOF
|
271
|
+
|
272
|
+
LOG_ENTRY_FROM_06_07_2004_19_25_1 = <<EOF
|
273
|
+
RCS file: /home/projects/jmock/scm/jmock/core/src/test/jmock/core/testsupport/MockInvocationMat
|
274
|
+
V1_0_1: 1.4
|
275
|
+
V1_0_0: 1.4
|
276
|
+
V1_0_0_RC1: 1.4
|
277
|
+
v1_0_0_RC1: 1.4
|
278
|
+
before_removing_features_deprecated_pre_1_0_0: 1.1
|
279
|
+
keyword substitution: kv
|
280
|
+
total revisions: 4; selected revisions: 0
|
281
|
+
description:
|
282
|
+
|
283
|
+
EOF
|
284
|
+
|
285
|
+
def test_can_parse_LOG_ENTRY_FROM_06_07_2004_19_25_1
|
286
|
+
@parser.cvspath = "/home/projects/jmock/scm/jmock"
|
287
|
+
@parser.cvsmodule = "core"
|
288
|
+
assert_equal("src/test/jmock/core/testsupport/MockInvocationMat", @parser.parse_path(LOG_ENTRY_FROM_06_07_2004_19_25_1))
|
289
|
+
end
|
290
|
+
|
291
|
+
LOG_ENTRY_FROM_06_07_2004_19_19 = <<EOF
|
292
|
+
Working file: lib/xmlrpc/datetime.rb
|
293
|
+
head: 1.1
|
294
|
+
branch:
|
295
|
+
locks: strict
|
296
|
+
access list:
|
297
|
+
symbolic names:
|
298
|
+
BEFORE_CENTRAL_REFACTORING: 1.1
|
299
|
+
keyword substitution: kv
|
300
|
+
total revisions: 1; selected revisions: 0
|
301
|
+
description:
|
302
|
+
|
303
|
+
EOF
|
304
|
+
|
305
|
+
def test_can_parse_LOG_ENTRY_FROM_06_07_2004_19_19
|
306
|
+
assert_equal("lib/xmlrpc/datetime.rb", @parser.parse_path(LOG_ENTRY_FROM_06_07_2004_19_19))
|
307
|
+
end
|
308
|
+
|
309
|
+
LOG_ENTRY_FROM_06_07_2004_19_25_2 = <<EOF
|
310
|
+
RC
|
311
|
+
Working file: website/templates/logo.gif
|
312
|
+
head: 1.2
|
313
|
+
branch:
|
314
|
+
locks: strict
|
315
|
+
access list:
|
316
|
+
symbolic names:
|
317
|
+
steves_easymock: 1.2.0.2
|
318
|
+
Root_steves_easymock: 1.2
|
319
|
+
V1_0_1: 1.2
|
320
|
+
V1_0_0: 1.2
|
321
|
+
V1_0_0_RC1: 1.2
|
322
|
+
before_removing_features_deprecated_pre_1_0_0: 1.2
|
323
|
+
pre-hotmock-syntax-change: 1.2
|
324
|
+
keyword substitution: b
|
325
|
+
total revisions: 2; selected revisions: 0
|
326
|
+
description:
|
327
|
+
|
328
|
+
EOF
|
329
|
+
|
330
|
+
def test_can_parse_LOG_ENTRY_FROM_06_07_2004_19_25_2
|
331
|
+
assert_equal("website/templates/logo.gif", @parser.parse_path(LOG_ENTRY_FROM_06_07_2004_19_25_2))
|
332
|
+
end
|
333
|
+
|
334
|
+
# stand in picocontainer's java folder
|
335
|
+
# cvs log -d"2003/07/25 12:38:41<=2004/07/08 12:38:41" build.xml
|
336
|
+
LOG_WITH_DELETIONS= <<EOF
|
337
|
+
RCS file: /home/projects/picocontainer/scm/java/Attic/build.xml,v
|
338
|
+
Working file: build.xml
|
339
|
+
head: 1.11
|
340
|
+
branch:
|
341
|
+
locks: strict
|
342
|
+
access list:
|
343
|
+
symbolic names:
|
344
|
+
MERGE_CONTAINER_AND_REGISTRY_REFACTORING_BRANCH: 1.10.0.2
|
345
|
+
BEFORE_MERGE_CONTAINER_AND_REGISTRY_REFACTORING_TAG: 1.10
|
346
|
+
BEFORE_MULTIPLE_CONSTRUCTORS: 1.10
|
347
|
+
keyword substitution: kv
|
348
|
+
total revisions: 11; selected revisions: 2
|
349
|
+
description:
|
350
|
+
----------------------------
|
351
|
+
revision 1.11
|
352
|
+
date: 2003/10/13 00:04:54; author: rinkrank; state: dead; lines: +0 -0
|
353
|
+
Obsolete
|
354
|
+
----------------------------
|
355
|
+
revision 1.10
|
356
|
+
date: 2003/07/25 16:32:39; author: rinkrank; state: Exp; lines: +1 -1
|
357
|
+
fixed broken url (NANO-8)
|
358
|
+
=============================================================================
|
359
|
+
EOF
|
360
|
+
|
361
|
+
def test_can_parse_LOG_WITH_DELETIONS
|
362
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_WITH_DELETIONS))
|
363
|
+
changesets = @parser.parse_changesets
|
364
|
+
assert_equal(2, changesets.length)
|
365
|
+
|
366
|
+
changeset_delete = changesets[1]
|
367
|
+
# assert_equal("MAIN:rinkrank:20031013000454", changeset_delete.revision)
|
368
|
+
assert_equal(Time.utc(2003,10,13,00,04,54,0), changeset_delete.time)
|
369
|
+
assert_equal("Obsolete", changeset_delete.message)
|
370
|
+
assert_equal("rinkrank", changeset_delete.developer)
|
371
|
+
assert_equal(1, changeset_delete.length)
|
372
|
+
assert_equal("build.xml", changeset_delete[0].path)
|
373
|
+
assert_equal("1.11", changeset_delete[0].revision)
|
374
|
+
assert_equal("1.10", changeset_delete[0].previous_revision)
|
375
|
+
assert(Change::DELETED, changeset_delete[0].status)
|
376
|
+
|
377
|
+
changeset_fix_url = changesets[0]
|
378
|
+
# assert_equal("MAIN:rinkrank:20030725163239", changeset_fix_url.revision)
|
379
|
+
assert_equal(Time.utc(2003,07,25,16,32,39,0), changeset_fix_url.time)
|
380
|
+
assert_equal("fixed broken url (NANO-8)", changeset_fix_url.message)
|
381
|
+
assert_equal("rinkrank", changeset_fix_url.developer)
|
382
|
+
assert_equal(1, changeset_fix_url.length)
|
383
|
+
assert_equal("build.xml", changeset_fix_url[0].path)
|
384
|
+
assert_equal("1.10", changeset_fix_url[0].revision)
|
385
|
+
assert_equal("1.9", changeset_fix_url[0].previous_revision)
|
386
|
+
assert_equal(Change::MODIFIED, changeset_fix_url[0].status)
|
387
|
+
end
|
388
|
+
|
389
|
+
LOG_WITH_MISSING_ENTRIES = <<EOF
|
390
|
+
RCS file: /cvsroot/damagecontrol/damagecontrol/Attic/build.xml,v
|
391
|
+
Working file: build.xml
|
392
|
+
head: 1.2
|
393
|
+
branch:
|
394
|
+
locks: strict
|
395
|
+
access list:
|
396
|
+
symbolic names:
|
397
|
+
initial-import: 1.1.1.1
|
398
|
+
mgm: 1.1.1
|
399
|
+
keyword substitution: kv
|
400
|
+
total revisions: 3; selected revisions: 0
|
401
|
+
description:
|
402
|
+
=============================================================================
|
403
|
+
|
404
|
+
RCS file: /cvsroot/damagecontrol/damagecontrol/maven.xml,v
|
405
|
+
Working file: maven.xml
|
406
|
+
head: 1.2
|
407
|
+
branch:
|
408
|
+
locks: strict
|
409
|
+
access list:
|
410
|
+
symbolic names:
|
411
|
+
keyword substitution: kv
|
412
|
+
total revisions: 2; selected revisions: 0
|
413
|
+
description:
|
414
|
+
=============================================================================
|
415
|
+
EOF
|
416
|
+
|
417
|
+
def test_can_parse_LOG_WITH_MISSING_ENTRIES
|
418
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_WITH_MISSING_ENTRIES))
|
419
|
+
changesets = @parser.parse_changesets
|
420
|
+
assert_equal(0, changesets.length)
|
421
|
+
end
|
422
|
+
|
423
|
+
LOG_WITH_NEW_AND_OLD_FILE = <<EOF
|
424
|
+
RCS file: /home/projects/damagecontrol/scm/damagecontrol/dummy.txt,v
|
425
|
+
Working file: dummy.txt
|
426
|
+
head: 1.1
|
427
|
+
branch:
|
428
|
+
locks: strict
|
429
|
+
access list:
|
430
|
+
keyword substitution: kv
|
431
|
+
total revisions: 1; selected revisions: 1
|
432
|
+
description:
|
433
|
+
----------------------------
|
434
|
+
revision 1.1
|
435
|
+
date: 2004/07/13 21:50:59; author: rinkrank; state: Exp;
|
436
|
+
Debug. Need to see what the log looks like for a new file.
|
437
|
+
=============================================================================
|
438
|
+
|
439
|
+
RCS file: /home/projects/damagecontrol/scm/damagecontrol/license.txt,v
|
440
|
+
Working file: license.txt
|
441
|
+
head: 1.4
|
442
|
+
branch:
|
443
|
+
locks: strict
|
444
|
+
access list:
|
445
|
+
keyword substitution: kv
|
446
|
+
total revisions: 4; selected revisions: 4
|
447
|
+
description:
|
448
|
+
----------------------------
|
449
|
+
revision 1.101
|
450
|
+
date: 2004/07/10 17:41:14; author: rinkrank; state: Exp; lines: +2 -2
|
451
|
+
typo
|
452
|
+
----------------------------
|
453
|
+
revision 1.11
|
454
|
+
date: 2004/07/10 17:38:22; author: rinkrank; state: Exp; lines: +2 -2
|
455
|
+
fixed http://jira.codehaus.org/browse/DC-123
|
456
|
+
----------------------------
|
457
|
+
revision 1.1
|
458
|
+
date: 2004/07/02 08:42:51; author: tirsen; state: Exp;
|
459
|
+
installer!!!!!! it's getting close to release!!!
|
460
|
+
=============================================================================
|
461
|
+
EOF
|
462
|
+
|
463
|
+
def test_can_distinguish_new_file_from_old_file
|
464
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_WITH_NEW_AND_OLD_FILE))
|
465
|
+
changesets = @parser.parse_changesets
|
466
|
+
|
467
|
+
assert_equal(Change::ADDED, changesets[0][0].status)
|
468
|
+
assert_equal(Change::MODIFIED, changesets[1][0].status)
|
469
|
+
assert_equal(Change::MODIFIED, changesets[2][0].status)
|
470
|
+
assert_equal(Change::ADDED, changesets[3][0].status)
|
471
|
+
end
|
472
|
+
|
473
|
+
# https://sitemesh.dev.java.net/source/browse/sitemesh/.cvsignore
|
474
|
+
# The default commit message probably showed up in vi, and the committer
|
475
|
+
# probably just left it there. Not sure why CVS kept it this way
|
476
|
+
# (lines starting with CVS: should be ignored in commit message afik).
|
477
|
+
# Anyway, the parser nw knows how to deal with this. (AH)
|
478
|
+
LOG_WITH_WEIRD_CVS_AND_MANY_DASHES = <<EOF
|
479
|
+
? log.txt
|
480
|
+
|
481
|
+
RCS file: /cvs/sitemesh/.cvsignore,v
|
482
|
+
Working file: .cvsignore
|
483
|
+
head: 1.3
|
484
|
+
branch:
|
485
|
+
locks: strict
|
486
|
+
access list:
|
487
|
+
keyword substitution: kv
|
488
|
+
total revisions: 3; selected revisions: 3
|
489
|
+
description:
|
490
|
+
----------------------------
|
491
|
+
revision 1.3
|
492
|
+
date: 2004/05/03 09:03:56; author: rhallier; state: Exp; lines: +2 -0
|
493
|
+
Issue number: SIM-90
|
494
|
+
|
495
|
+
Obtained from: JIRA
|
496
|
+
|
497
|
+
Submitted by: rhallier
|
498
|
+
|
499
|
+
Reviewed by:
|
500
|
+
|
501
|
+
CVS: ----------------------------------------------------------------------
|
502
|
+
|
503
|
+
CVS: Issue number:
|
504
|
+
|
505
|
+
CVS: If this change addresses one or more issues,
|
506
|
+
|
507
|
+
CVS: then enter the issue number(s) here.
|
508
|
+
|
509
|
+
CVS: Obtained from:
|
510
|
+
|
511
|
+
CVS: If this change has been taken from another system,
|
512
|
+
|
513
|
+
CVS: then name the system in this line, otherwise delete it.
|
514
|
+
|
515
|
+
CVS: Submitted by:
|
516
|
+
|
517
|
+
CVS: If this code has been contributed to the project by someone else; i.e.,
|
518
|
+
|
519
|
+
CVS: they sent us a patch or a set of diffs, then include their name/email
|
520
|
+
|
521
|
+
CVS: address here. If this is your work then delete this line.
|
522
|
+
|
523
|
+
CVS: Reviewed by:
|
524
|
+
|
525
|
+
CVS: If we are doing pre-commit code reviews and someone else has
|
526
|
+
|
527
|
+
CVS: reviewed your changes, include their name(s) here.
|
528
|
+
|
529
|
+
CVS: If you have not had it reviewed then delete this line.
|
530
|
+
----------------------------
|
531
|
+
revision 1.2
|
532
|
+
date: 2003/11/22 07:56:51; author: hani; state: Exp; lines: +2 -1
|
533
|
+
Ignore IDEA files
|
534
|
+
----------------------------
|
535
|
+
revision 1.1
|
536
|
+
date: 2003/11/03 16:27:37; author: mbogaert; state: Exp;
|
537
|
+
Moved from SF.
|
538
|
+
=============================================================================
|
539
|
+
|
540
|
+
RCS file: /cvs/sitemesh/CHANGES.txt,v
|
541
|
+
Working file: CHANGES.txt
|
542
|
+
head: 1.3
|
543
|
+
branch:
|
544
|
+
locks: strict
|
545
|
+
access list:
|
546
|
+
keyword substitution: kv
|
547
|
+
total revisions: 3; selected revisions: 3
|
548
|
+
description:
|
549
|
+
----------------------------
|
550
|
+
revision 1.3
|
551
|
+
date: 2004/10/08 07:18:38; author: hani; state: Exp; lines: +18 -0
|
552
|
+
More files not updated for release
|
553
|
+
----------------------------
|
554
|
+
revision 1.2
|
555
|
+
date: 2004/09/24 14:04:12; author: jwalnes1; state: Exp; lines: +19 -0
|
556
|
+
Preparing for 2.2 release.
|
557
|
+
Issue number:
|
558
|
+
Obtained from:
|
559
|
+
Submitted by:
|
560
|
+
Reviewed by:
|
561
|
+
----------------------------
|
562
|
+
revision 1.1
|
563
|
+
date: 2004/07/22 01:30:27; author: farkas; state: Exp;
|
564
|
+
Final changes for 2.1 release
|
565
|
+
=============================================================================
|
566
|
+
EOF
|
567
|
+
|
568
|
+
def test_can_parse_logs_with_cvs_and_dashes_in_commit_message
|
569
|
+
@parser = CVSLogParser.new(StringIO.new(LOG_WITH_WEIRD_CVS_AND_MANY_DASHES))
|
570
|
+
changesets = @parser.parse_changesets
|
571
|
+
assert_equal(6, changesets.length)
|
572
|
+
end
|
573
|
+
|
574
|
+
end
|
575
|
+
end
|