<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2319,24 +2319,67 @@ class Mercurial(SourceBase):
 registerSlaveCommand(&quot;hg&quot;, Mercurial, command_version)
 
 
-class P4(SourceBase):
-    &quot;&quot;&quot;A P4 source-updater.
+class P4Base(SourceBase):
+    &quot;&quot;&quot;Base class for P4 source-updaters
 
     ['p4port'] (required): host:port for server to access
     ['p4user'] (optional): user to use for access
     ['p4passwd'] (optional): passwd to try for the user
     ['p4client'] (optional): client spec to use
-    ['p4extra_views'] (optional): additional client views to use
     &quot;&quot;&quot;
-
-    header = &quot;p4&quot;
-
     def setup(self, args):
         SourceBase.setup(self, args)
         self.p4port = args['p4port']
         self.p4client = args['p4client']
         self.p4user = args['p4user']
         self.p4passwd = args['p4passwd']
+
+    def parseGotRevision(self):
+        # Executes a p4 command that will give us the latest changelist number
+        # of any file under the current (or default) client:
+        command = ['p4']
+        if self.p4port:
+            command.extend(['-p', self.p4port])
+        if self.p4user:
+            command.extend(['-u', self.p4user])
+        if self.p4passwd:
+            command.extend(['-P', self.p4passwd])
+        if self.p4client:
+            command.extend(['-c', self.p4client])
+        command.extend(['changes', '-m', '1', '#have'])
+        c = ShellCommand(self.builder, command, self.builder.basedir,
+                         environ=self.env, timeout=self.timeout,
+                         sendStdout=True, sendStderr=False, sendRC=False,
+                         keepStdout=True)
+        self.command = c
+        d = c.start()
+
+        def _parse(res):
+            # 'p4 -c clien-name change -m 1 &quot;#have&quot;' will produce an output like:
+            # &quot;Change 28147 on 2008/04/07 by p4user@hostname...&quot;
+            # The number after &quot;Change&quot; is the one we want.
+            m = re.match('Change\s+(\d+)\s+', c.stdout)
+            if m:
+                return m.group(1)
+            return None
+        d.addCallback(_parse)
+        return d
+
+
+class P4(P4Base):
+    &quot;&quot;&quot;A P4 source-updater.
+
+    ['p4port'] (required): host:port for server to access
+    ['p4user'] (optional): user to use for access
+    ['p4passwd'] (optional): passwd to try for the user
+    ['p4client'] (optional): client spec to use
+    ['p4extra_views'] (optional): additional client views to use
+    &quot;&quot;&quot;
+
+    header = &quot;p4&quot;
+
+    def setup(self, args):
+        P4Base.setup(self, args)
         self.p4base = args['p4base']
         self.p4extra_views = args['p4extra_views']
         self.p4mode = args['mode']
@@ -2440,7 +2483,7 @@ class P4(SourceBase):
 registerSlaveCommand(&quot;p4&quot;, P4, command_version)
 
 
-class P4Sync(SourceBase):
+class P4Sync(P4Base):
     &quot;&quot;&quot;A partial P4 source-updater. Requires manual setup of a per-slave P4
     environment. The only thing which comes from the master is P4PORT.
     'mode' is required to be 'copy'.
@@ -2454,12 +2497,8 @@ class P4Sync(SourceBase):
     header = &quot;p4 sync&quot;
 
     def setup(self, args):
-        SourceBase.setup(self, args)
+        P4Base.setup(self, args)
         self.vcexe = getCommand(&quot;p4&quot;)
-        self.p4port = args['p4port']
-        self.p4user = args['p4user']
-        self.p4passwd = args['p4passwd']
-        self.p4client = args['p4client']
 
     def sourcedirIsUpdateable(self):
         return True</diff>
      <filename>buildbot/slave/commands.py</filename>
    </modified>
    <modified>
      <diff>@@ -1384,7 +1384,12 @@ class P4Helper(BaseHelper):
         def outReceived(self, data):
             # When it says starting, it has bound to the socket.
             if self.started:
-                if data.startswith('Perforce Server starting...'):
+                #
+                # Make sure p4d has started. Newer versions of p4d
+                # have more verbose messaging when db files don't exist, so
+                # we use re.search instead of startswith.
+                #
+                if re.search('Perforce Server starting...', data):
                     self.started.callback(None)
                 else:
                     print &quot;p4d said %r&quot; % data
@@ -1492,7 +1497,8 @@ class P4(VCBase, unittest.TestCase):
     metadir = None
     vctype = &quot;source.P4&quot;
     vc_name = &quot;p4&quot;
-
+    has_got_revision = True
+    
     def tearDownClass(self):
         if self.helper:
             return self.helper.shutdown_p4d()</diff>
      <filename>buildbot/test/test_vc.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a3c7af35410d2ed4aa4a238f653ebf51197f7760</id>
    </parent>
  </parents>
  <author>
    <name>gollum</name>
    <email>gollum@staticfoo-2.local</email>
  </author>
  <url>http://github.com/jgraff/buildbot/commit/ab61561c9bc98d69b64db2b3bdb5c05dce969264</url>
  <id>ab61561c9bc98d69b64db2b3bdb5c05dce969264</id>
  <committed-date>2009-01-22T13:09:43-08:00</committed-date>
  <authored-date>2009-01-22T13:09:43-08:00</authored-date>
  <message>Fix for issue #127. The &quot;got_revision&quot; property in perforce is now set after a P4 source
step. This fix consists of the patch in issue #229 (with cleanup) and adjustments to
the p4 tests (test_vc.py). p4 tests now support newer versions of p4d and check the
&quot;got_revision&quot; value via (has_got_revision = True)</message>
  <tree>0e1d2155d312865e0076f7a3af13334bd0d5113d</tree>
  <committer>
    <name>gollum</name>
    <email>gollum@staticfoo-2.local</email>
  </committer>
</commit>
