public
Fork of chris/cruisecontrolrb_perforce
Description: Perforce support for CruiseControl.rb
Homepage: http://cobaltedge.com/2008/06/perforce-support-for-cruise-co.html
Clone URL: git://github.com/bcurren/cruisecontrolrb_perforce.git
Updated the perforce driver to work with cruisecontrolrb 1.3.

Correctly build the ChangeSetEntry for a Revision.
bcurren (author)
Tue Jun 17 21:19:25 -0700 2008
commit  d3f764c1e6fc92075b7c77f1eb96decb129fd300
tree    ec45248c1bb323eea6f9f9ab1c80e3ae765a168e
parent  9294a37b07417f8e01482a97a51e0167cd852b51
0
...
26
27
28
29
 
30
31
32
...
26
27
28
 
29
30
31
32
0
@@ -26,7 +26,7 @@ in order to use Perforce:
0
       :clientspec => 'clientspec-for-cruisecontrol',
0
       :user => 'buildusername',
0
       :password => 'builduserpassword',
0
- :path => '//depot/path/to/your/rails/app/...')
0
+ :p4path => '//depot/path/to/your/rails/app/...')
0
   end
0
   
0
 * Sync your code once.
...
5
6
7
8
 
9
10
11
 
 
12
13
 
14
15
16
 
 
 
17
18
19
20
21
22
 
23
24
25
26
27
28
29
30
 
 
 
31
32
33
 
34
35
36
37
38
39
40
41
42
43
 
 
 
 
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 
 
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
76
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
79
80
 
 
81
82
83
84
85
86
87
88
89
90
91
92
93
 
 
 
 
 
 
 
 
 
 
 
 
 
94
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
97
98
...
5
6
7
 
8
9
 
 
10
11
12
 
13
14
 
 
15
16
17
18
19
20
21
22
 
23
24
25
 
 
 
 
 
 
26
27
28
29
30
 
31
32
 
 
 
 
 
 
 
 
 
33
34
35
36
37
38
 
 
 
 
 
 
 
 
 
 
 
 
 
39
40
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 
 
80
81
82
 
 
 
 
 
 
 
 
 
 
 
 
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
0
@@ -5,94 +5,125 @@ require 'builder_error'
0
 class Perforce
0
   include CommandLine
0
 
0
- attr_accessor :port, :client_spec, :username, :password, :path
0
+ attr_accessor :port, :client_spec, :username, :password, :path, :p4path
0
 
0
- MAX_CHANGELISTS_TO_FETCH = 25
0
-
0
+ MAX_CHANGELISTS_TO_FETCH = 25
0
+
0
   def initialize(options = {})
0
- @port, @clientspec, @username, @password, @path, @interactive =
0
+ @port, @clientspec, @username, @password, @path, @p4path, @interactive =
0
           options.delete(:port), options.delete(:clientspec),
0
- options.delete(:user), options.delete(:password),
0
- options.delete(:path), options.delete(:interactive)
0
+ options.delete(:user), options.delete(:password),
0
+ options.delete(:path), options.delete(:p4path),
0
+ options.delete(:interactive)
0
     raise "don't know how to handle '#{options.keys.first}'" if options.length > 0
0
     @clientspec or raise 'P4 Clientspec not specified'
0
     @port or raise 'P4 Port not specified'
0
     @username or raise 'P4 username not specified'
0
     @password or raise 'P4 password not specified'
0
- @path or raise 'P4 depot path not specified'
0
+ @p4path or raise 'P4 depot path not specified'
0
   end
0
 
0
- def checkout(target_directory, revision = nil)
0
- # No need for target_directory with Perforce, since this is controlled by
0
- # the clientspec.
0
-
0
- options = ""
0
- options << "#{@path}##{revision_number(revision)}" unless revision.nil?
0
+ def checkout(revision = nil, stdout = $stdout)
0
+ options = ""
0
+ options << "#{@p4path}@#{revision_number(revision)}" unless revision.nil?
0
 
0
     # need to read from command output, because otherwise tests break
0
- p4(:sync, options).each {|line| puts line.to_s }
0
+ p4(:sync, options).each {|line| stdout.puts line.to_s }
0
   end
0
-
0
- def latest_revision(project)
0
- # Get the latest changelist for this project
0
- change = p4(:changes, "-m 1 #{@path}").first
0
-
0
- # TODO: This isn't right - changesets I believe is supposed to be the set
0
- # of files that were changed as part of this changelist.
0
- changesets = [ ChangesetEntry.new(change['status'], change['desc']) ]
0
- Revision.new(change['change'].to_i, change['user'], Time.at(change['time'].to_i), change['desc'], changesets)
0
+
0
+ def clean_checkout(revision = nil, stdout = $stdout)
0
+ FileUtils.rm_rf(path)
0
+ checkout(revision, stdout)
0
   end
0
 
0
- def revisions_since(project, revision_number)
0
- # This should get all changelists since the last one we used, but when using
0
- # the -R flag with P4 it only seems to get the latest one.
0
- changelists = p4(:changes, "-m #{MAX_CHANGELISTS_TO_FETCH} #{@path}@#{revision_number},#head")
0
-
0
- changes = Array.new
0
- changelists.each do |cl|
0
- changeset = [ ChangesetEntry.new(cl['status'], cl['desc']) ]
0
- changes << Revision.new(cl['change'].to_i, cl['user'], Time.at(cl['time'].to_i), cl['desc'], changeset)
0
- end
0
- changes.delete_if { |r| r.number == revision_number }
0
-
0
- changes
0
+ def latest_revision
0
+ build_revision_from(p4(:changes, "-m 1 #{@p4path}").first)
0
   end
0
-
0
- SYNC_PATTERN = /^(\/\/.+#\d+) - (\w+) .+$/
0
- def update(project, revision = nil)
0
- sync_output = p4(:sync, revision.nil? ? "" : "#{@path}@#{revision_number(revision)}")
0
- synced_files = Array.new
0
-
0
- sync_output.each do |line|
0
- match = SYNC_PATTERN.match(line['data'])
0
- if match
0
- file, operation = match[1..2]
0
- synced_files << ChangesetEntry.new(operation, file)
0
- end
0
- end.compact
0
-
0
- synced_files
0
+
0
+ def last_locally_known_revision
0
+ return Revision.new(0) unless File.exist?(path)
0
+ Revision.new(info.revision)
0
+ end
0
+
0
+ def up_to_date?(reasons = [], revision_number = last_locally_known_revision.number)
0
+ result = true
0
+
0
+ latest_revision = self.latest_revision()
0
+ if latest_revision > Revision.new(revision_number)
0
+ reasons << "New revision #{latest_revision.number} detected"
0
+ reasons << revisions_since(revision_number)
0
+ result = false
0
+ end
0
+
0
+ return result
0
   end
0
   
0
- private
0
+ # SYNC_PATTERN = /^(\/\/.+#\d+) - (\w+) .+$/
0
+ def update(revision = nil)
0
+ checkout(revision)
0
+ # sync_output = p4(:sync, revision.nil? ? "" : "#{@path}@#{revision_number(revision)}")
0
+ # synced_files = Array.new
0
+ #
0
+ # sync_output.each do |line|
0
+ # match = SYNC_PATTERN.match(line['data'])
0
+ # if match
0
+ # file, operation = match[1..2]
0
+ # synced_files << ChangesetEntry.new(operation, file)
0
+ # end
0
+ # end.compact
0
+ #
0
+ # synced_files
0
+ end
0
+
0
+private
0
   
0
- # Execute a P4 command, and return an array of the resulting output lines
0
- # The array will contain a hash for each line out output
0
+ # Execute a P4 command, and return an array of the resulting output lines
0
+ # The array will contain a hash for each line out output
0
   def p4(operation, options = nil)
0
- p4cmd = "p4 -R -p #{@port} -c #{@clientspec} -u #{@username} -P #{@password} "
0
- p4cmd << "#{operation.to_s}"
0
- p4cmd << " " << options if options
0
-
0
- p4_output = Array.new
0
- IO.popen(p4cmd, "rb") do |file|
0
- while not file.eof
0
- p4_output << Marshal.load(file)
0
- end
0
- end
0
-
0
- p4_output
0
+ p4cmd = "p4 -R -p #{@port} -c #{@clientspec} -u #{@username} -P #{@password} "
0
+ p4cmd << "#{operation.to_s}"
0
+ p4cmd << " " << options if options
0
+
0
+ p4_output = Array.new
0
+ # puts p4cmd
0
+ IO.popen(p4cmd, "rb") do |file|
0
+ while not file.eof
0
+ p4_output << Marshal.load(file)
0
+ end
0
+ end
0
+
0
+ p4_output
0
   end
0
-
0
+
0
+ def info
0
+ change1 = p4(:changes, "-m 1 #{@p4path}#have").first
0
+ change2 = p4(:changes, "-m 1 #{@p4path}#head").first
0
+ Perforce::Info.new(change1['change'].to_i, change2['change'].to_i, change2['user'])
0
+ end
0
+
0
+ def build_revision_from(change)
0
+ return nil unless change
0
+
0
+ changeset = change['change'].to_i
0
+
0
+ # Build the array of changes
0
+ changed_files = p4(:describe, "-s #{changeset}").first
0
+ i = 0
0
+ changesets = []
0
+ while (changed_files["action#{i}"])
0
+ changesets << ChangesetEntry.new(changed_files["action#{i}"], changed_files["depotFile#{i}"])
0
+ i = i + 1
0
+ end
0
+
0
+ Revision.new(changeset, change['user'], Time.at(change['time'].to_i), change['desc'], changesets)
0
+ end
0
+
0
+ def revisions_since(revision_number)
0
+ p4(:changes, "-m #{MAX_CHANGELISTS_TO_FETCH} #{@p4path}@#{revision_number},#head").collect do |change|
0
+ build_revision_from(change)
0
+ end
0
+ end
0
+
0
   def revision_number(revision)
0
     revision.respond_to?(:number) ? revision.number : revision.to_i
0
   end

Comments

    No one has commented yet.