rscm 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README +198 -0
  2. data/Rakefile +118 -0
  3. data/ext/rscm.jar +0 -0
  4. data/lib/rscm.rb +10 -0
  5. data/lib/rscm/abstract_log_parser.rb +49 -0
  6. data/lib/rscm/abstract_scm.rb +229 -0
  7. data/lib/rscm/changes.rb +271 -0
  8. data/lib/rscm/cvs/cvs.rb +363 -0
  9. data/lib/rscm/cvs/cvs_log_parser.rb +161 -0
  10. data/lib/rscm/darcs/darcs.rb +69 -0
  11. data/lib/rscm/line_editor.rb +46 -0
  12. data/lib/rscm/logging.rb +5 -0
  13. data/lib/rscm/monotone/monotone.rb +107 -0
  14. data/lib/rscm/mooky/mooky.rb +13 -0
  15. data/lib/rscm/parser.rb +39 -0
  16. data/lib/rscm/path_converter.rb +92 -0
  17. data/lib/rscm/perforce/perforce.rb +415 -0
  18. data/lib/rscm/starteam/starteam.rb +99 -0
  19. data/lib/rscm/svn/svn.rb +337 -0
  20. data/lib/rscm/svn/svn_log_parser.rb +134 -0
  21. data/lib/rscm/time_ext.rb +125 -0
  22. data/test/rscm/apply_label_scm_tests.rb +26 -0
  23. data/test/rscm/changes_fixture.rb +20 -0
  24. data/test/rscm/changes_test.rb +129 -0
  25. data/test/rscm/cvs/cvs_log_parser_test.rb +575 -0
  26. data/test/rscm/cvs/cvs_test.rb +22 -0
  27. data/test/rscm/darcs/darcs_test.rb +14 -0
  28. data/test/rscm/difftool_test.rb +40 -0
  29. data/test/rscm/file_ext.rb +12 -0
  30. data/test/rscm/generic_scm_tests.rb +282 -0
  31. data/test/rscm/line_editor_test.rb +76 -0
  32. data/test/rscm/mockit.rb +130 -0
  33. data/test/rscm/mockit_test.rb +117 -0
  34. data/test/rscm/monotone/monotone_test.rb +19 -0
  35. data/test/rscm/mooky/mooky_test.rb +14 -0
  36. data/test/rscm/parser_test.rb +47 -0
  37. data/test/rscm/path_converter_test.rb +52 -0
  38. data/test/rscm/perforce/perforce_test.rb +14 -0
  39. data/test/rscm/starteam/starteam_test.rb +36 -0
  40. data/test/rscm/svn/svn_log_parser_test.rb +111 -0
  41. data/test/rscm/svn/svn_test.rb +28 -0
  42. data/test/rscm/tempdir.rb +12 -0
  43. 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