| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | <?php | 
					
						
							|  |  |  | /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | # ***** BEGIN LICENSE BLOCK *****
 | 
					
						
							|  |  |  | # This file is part of InDefero, an open source project management application.
 | 
					
						
							|  |  |  | # Copyright (C) 2008 Céondo Ltd and contributors.
 | 
					
						
							|  |  |  | #
 | 
					
						
							|  |  |  | # InDefero is free software; you can redistribute it and/or modify
 | 
					
						
							|  |  |  | # it under the terms of the GNU General Public License as published by
 | 
					
						
							|  |  |  | # the Free Software Foundation; either version 2 of the License, or
 | 
					
						
							|  |  |  | # (at your option) any later version.
 | 
					
						
							|  |  |  | #
 | 
					
						
							|  |  |  | # InDefero is distributed in the hope that it will be useful,
 | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | # GNU General Public License for more details.
 | 
					
						
							|  |  |  | #
 | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License
 | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software
 | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
					
						
							|  |  |  | #
 | 
					
						
							|  |  |  | # ***** END LICENSE BLOCK ***** */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |  * Subversion backend. | 
					
						
							|  |  |  |  * When a branch is not a branch. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Contrary to most other SCMs, Subversion is using folders to manage | 
					
						
							|  |  |  |  * the branches and so what is either the commit or the branch in | 
					
						
							|  |  |  |  * other SCMs is the revision number with Subversion. So, do not be | 
					
						
							|  |  |  |  * surprised if you have the feeling that the methods are not really | 
					
						
							|  |  |  |  * returning what could be expected from their names. | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  | class IDF_Scm_Svn extends IDF_Scm | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     public $repo = ''; | 
					
						
							|  |  |  |     public $username = ''; | 
					
						
							|  |  |  |     public $password = ''; | 
					
						
							|  |  |  |     private $assoc = array('dir' => 'tree', | 
					
						
							|  |  |  |                            'file' => 'blob'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-20 15:05:34 +02:00
										 |  |  |     private $commit=array(); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-27 23:08:55 +02:00
										 |  |  |     public function __construct($repo, $project=null, $username='', $password='') | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->repo = $repo; | 
					
						
							| 
									
										
										
										
											2009-05-27 23:08:55 +02:00
										 |  |  |         $this->project = $project; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $this->username = $username; | 
					
						
							|  |  |  |         $this->password = $password; | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         $this->cache['commitmess'] = array(); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public function isAvailable() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-05 11:34:02 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Given the string describing the author from the log find the | 
					
						
							|  |  |  |      * author in the database. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string Author | 
					
						
							|  |  |  |      * @return mixed Pluf_User or null | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function findAuthor($author) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $sql = new Pluf_SQL('login=%s', array(trim($author))); | 
					
						
							|  |  |  |         $users = Pluf::factory('Pluf_User')->getList(array('filter'=>$sql->gen())); | 
					
						
							|  |  |  |         return ($users->count() > 0) ? $users[0] : null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns the URL of the subversion repository. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param IDF_Project | 
					
						
							|  |  |  |      * @return string URL | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public static function getAnonymousAccessUrl($project) | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         $conf = $project->getConf(); | 
					
						
							| 
									
										
										
										
											2008-11-18 11:23:09 +01:00
										 |  |  |         if (false !== ($url=$conf->getVal('svn_remote_url', false))  | 
					
						
							|  |  |  |             && !empty($url)) { | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |             // Remote repository
 | 
					
						
							|  |  |  |             return $url; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-11-24 20:27:03 +01:00
										 |  |  |         return sprintf(Pluf::f('svn_remote_url'), $project->shortname); | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-27 22:54:26 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns the URL of the subversion repository. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param IDF_Project | 
					
						
							|  |  |  |      * @return string URL | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function getAuthAccessUrl($project, $user) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $conf = $project->getConf(); | 
					
						
							|  |  |  |         if (false !== ($url=$conf->getVal('svn_remote_url', false))  | 
					
						
							|  |  |  |             && !empty($url)) { | 
					
						
							|  |  |  |             // Remote repository
 | 
					
						
							|  |  |  |             return $url; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return sprintf(Pluf::f('svn_remote_url'), $project->shortname); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns this object correctly initialized for the project. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param IDF_Project | 
					
						
							|  |  |  |      * @return IDF_Scm_Svn | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public static function factory($project) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $conf = $project->getConf(); | 
					
						
							|  |  |  |         // Find the repository
 | 
					
						
							| 
									
										
										
										
											2008-11-18 11:23:09 +01:00
										 |  |  |         if (false !== ($rep=$conf->getVal('svn_remote_url', false))  | 
					
						
							|  |  |  |             && !empty($rep)) { | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |             // Remote repository
 | 
					
						
							| 
									
										
										
										
											2009-05-27 23:08:55 +02:00
										 |  |  |             return new IDF_Scm_Svn($rep, $project, | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |                                    $conf->getVal('svn_username'), | 
					
						
							|  |  |  |                                    $conf->getVal('svn_password')); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2008-11-24 20:27:03 +01:00
										 |  |  |             $rep = sprintf(Pluf::f('svn_repositories'), $project->shortname); | 
					
						
							| 
									
										
										
										
											2009-05-27 23:08:55 +02:00
										 |  |  |             return new IDF_Scm_Svn($rep, $project); | 
					
						
							| 
									
										
										
										
											2008-09-02 15:51:57 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Subversion revisions are either a number or 'HEAD'. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function isValidRevision($rev) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($rev == 'HEAD') { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@%s', | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							|  |  |  |         exec($cmd, $out, $ret); | 
					
						
							|  |  |  |         return (0 == $ret); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Test a given object hash. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string Object hash. | 
					
						
							|  |  |  |      * @return mixed false if not valid or 'blob', 'tree', 'commit' | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function testHash($rev, $path='') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // OK if HEAD on /
 | 
					
						
							|  |  |  |         if ($rev === 'HEAD' && $path === '') { | 
					
						
							|  |  |  |             return 'commit'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Else, test the path on revision
 | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/'.$path), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlInfo = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // If exception is thrown, return false
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             $xml = simplexml_load_string($xmlInfo); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         catch (Exception $e) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // If the entry node does exists, params are wrong
 | 
					
						
							|  |  |  |         if (!isset($xml->entry)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Else, enjoy it :)
 | 
					
						
							|  |  |  |         return 'commit'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public function getTree($rev='HEAD', $folder='') | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --xml --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/'.$folder), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         $xml = simplexml_load_string(shell_exec($cmd)); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2008-12-03 20:58:06 +01:00
										 |  |  |         $folder = (strlen($folder)) ? $folder.'/' : ''; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         foreach ($xml->list->entry as $entry) { | 
					
						
							|  |  |  |             $file = array(); | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |             $file['type'] = $this->assoc[(string) $entry['kind']]; | 
					
						
							|  |  |  |             $file['file'] = (string) $entry->name; | 
					
						
							| 
									
										
										
										
											2008-12-03 20:58:06 +01:00
										 |  |  |             $file['fullpath'] = $folder.((string) $entry->name); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             $file['date'] = gmdate('Y-m-d H:i:s', | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |                                    strtotime((string) $entry->commit->date)); | 
					
						
							|  |  |  |             $file['rev'] = (string) $entry->commit['revision']; | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |             $file['log'] = $this->getCommitMessage($file['rev']); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             // Get the size if the type is blob
 | 
					
						
							|  |  |  |             if ($file['type'] == 'blob') { | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |                 $file['size'] = (string) $entry->size; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-01-21 19:25:49 +01:00
										 |  |  |             $file['author'] = (string) $entry->commit->author; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             $file['perm'] = ''; | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |             $res[] = (object) $file; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         return $res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |      * Get the commit message of a revision revision. | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @param string Commit ('HEAD') | 
					
						
							|  |  |  |      * @return String commit message | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |     private function getCommitMessage($rev='HEAD') | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         if (isset($this->cache['commitmess'][$rev])) { | 
					
						
							|  |  |  |             return $this->cache['commitmess'][$rev]; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |                        escapeshellarg($this->repo), | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         $xml = simplexml_load_string(shell_exec($cmd)); | 
					
						
							|  |  |  |         $this->cache['commitmess'][$rev] = (string) $xml->logentry->msg; | 
					
						
							|  |  |  |         return $this->cache['commitmess'][$rev]; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |      * FIXME: Need to check the case of an inexisting file. | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public function getPathInfo($totest, $rev='HEAD') | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/'.$totest), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         $xml = simplexml_load_string(shell_exec($cmd)); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $entry = $xml->entry; | 
					
						
							|  |  |  |         $file = array(); | 
					
						
							|  |  |  |         $file['fullpath'] = $totest; | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         $file['hash'] = (string) $entry->repository->uuid; | 
					
						
							|  |  |  |         $file['type'] = $this->assoc[(string) $entry['kind']]; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $file['file'] = $totest; | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |         $file['rev'] = $rev;  | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         $file['author'] = (string) $entry->author; | 
					
						
							|  |  |  |         $file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date)); | 
					
						
							|  |  |  |         $file['size'] = (string) $entry->size; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $file['log'] = ''; | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         return (object) $file; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public function getFile($def) | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' cat --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |                        escapeshellarg($this->repo.'/'.$def->fullpath), | 
					
						
							|  |  |  |                        escapeshellarg($def->rev)); | 
					
						
							|  |  |  |         return shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |      * Subversion branches are repository based.  | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |      * One need to list the folder to know them. | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function getBranches() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         if (isset($this->cache['branches'])) { | 
					
						
							|  |  |  |             return $this->cache['branches']; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-05-26 21:20:10 +02:00
										 |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --username=%s --password=%s %s@HEAD', | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/branches')); | 
					
						
							|  |  |  |         exec($cmd, $out, $ret); | 
					
						
							|  |  |  |         if ($ret == 0) { | 
					
						
							|  |  |  |             foreach ($out as $entry) { | 
					
						
							|  |  |  |                 if (substr(trim($entry), -1) == '/') { | 
					
						
							|  |  |  |                     $branch = substr(trim($entry), 0, -1); | 
					
						
							|  |  |  |                     $res[$branch] = 'branches/'.$branch; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ksort($res); | 
					
						
							|  |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@HEAD', | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/trunk')); | 
					
						
							|  |  |  |         exec($cmd, $out, $ret); | 
					
						
							|  |  |  |         if ($ret == 0) { | 
					
						
							| 
									
										
										
										
											2009-04-27 11:39:19 +02:00
										 |  |  |             $res = array('trunk' => 'trunk') + $res; | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         $this->cache['branches'] = $res; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         return $res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |     public function getMainBranch() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return 'HEAD'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function inBranches($commit, $path) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         foreach ($this->getBranches() as $branch => $bpath) { | 
					
						
							|  |  |  |             if ($bpath and 0 === strpos($path, $bpath)) { | 
					
						
							|  |  |  |                 return array($branch); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return array(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get commit details. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2009-01-20 13:12:17 +01:00
										 |  |  |      * @param string Commit ('HEAD') | 
					
						
							|  |  |  |      * @param bool Get commit diff (false) | 
					
						
							|  |  |  |      * @return array Changes | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-01-20 13:12:17 +01:00
										 |  |  |     public function getCommit($rev='HEAD', $getdiff=false) | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-04-20 15:05:34 +02:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 -v --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlRes = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $xml = simplexml_load_string($xmlRes); | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         $res['author'] = (string) $xml->logentry->author; | 
					
						
							|  |  |  |         $res['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $xml->logentry->date)); | 
					
						
							|  |  |  |         $res['title'] = (string) $xml->logentry->msg; | 
					
						
							|  |  |  |         $res['commit'] = (string) $xml->logentry['revision']; | 
					
						
							| 
									
										
										
										
											2009-01-20 13:12:17 +01:00
										 |  |  |         $res['changes'] = ($getdiff) ? $this->getDiff($rev) : ''; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $res['tree'] = ''; | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         return (object) $res; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-17 18:46:26 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |      * Check if a commit is big. | 
					
						
							| 
									
										
										
										
											2009-01-17 18:46:26 +01:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @param string Commit ('HEAD') | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |      * @return bool The commit is big | 
					
						
							| 
									
										
										
										
											2009-01-17 18:46:26 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |     public function isCommitLarge($commit='HEAD') | 
					
						
							| 
									
										
										
										
											2009-01-17 18:46:26 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |         if (substr($this->repo, 0, 7) != 'file://') { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // We have a locally hosted repository, we can query it with
 | 
					
						
							|  |  |  |         // svnlook
 | 
					
						
							|  |  |  |         $repo = substr($this->repo, 7); | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svnlook_path', 'svnlook').' changed -r %s %s', | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |                        escapeshellarg($commit), | 
					
						
							|  |  |  |                        escapeshellarg($repo)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $out = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2009-01-20 16:26:36 +01:00
										 |  |  |         $lines = preg_split("/\015\012|\015|\012/", $out); | 
					
						
							|  |  |  |         return (count($lines) > 100); | 
					
						
							| 
									
										
										
										
											2009-01-17 18:46:26 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     private function getDiff($rev='HEAD') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' diff -c %s --username=%s --password=%s %s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($rev), | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         return shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get latest changes. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2009-05-26 21:20:10 +02:00
										 |  |  |      * @param string Revision or ('HEAD'). | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |      * @param int Number of changes (10). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array Changes. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getChangeLog($rev='HEAD', $n=10) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-05-26 21:20:10 +02:00
										 |  |  |         if ($rev != 'HEAD' and !preg_match('/^\d+$/', $rev)) { | 
					
						
							|  |  |  |             // we accept only revisions or HEAD
 | 
					
						
							|  |  |  |             $rev = 'HEAD'; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --limit %s --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($n), | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlRes = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $xml = simplexml_load_string($xmlRes); | 
					
						
							|  |  |  |         foreach ($xml->logentry as $entry) { | 
					
						
							|  |  |  |             $log = array(); | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |             $log['author'] = (string) $entry->author; | 
					
						
							|  |  |  |             $log['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->date)); | 
					
						
							|  |  |  |             $log['title'] = (string) $entry->msg; | 
					
						
							|  |  |  |             $log['commit'] = (string) $entry['revision']; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             $log['full_message'] = ''; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |             $res[] = (object) $log; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         return $res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get additionnals properties on path and revision | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string File | 
					
						
							|  |  |  |      * @param string Commit ('HEAD') | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getProperties($rev, $path='') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' proplist --xml --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/'.$path), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlProps = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $props = simplexml_load_string($xmlProps); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // No properties, returns an empty array
 | 
					
						
							|  |  |  |         if (!isset($props->target)) { | 
					
						
							|  |  |  |             return $res; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Get the value of each property
 | 
					
						
							|  |  |  |         foreach ($props->target->property as $prop) { | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |             $key = (string) $prop['name']; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |             $res[$key] = $this->getProperty($key, $rev, $path); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a specific additionnal property on path and revision | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string Property | 
					
						
							|  |  |  |      * @param string File | 
					
						
							|  |  |  |      * @param string Commit ('HEAD') | 
					
						
							|  |  |  |      * @return string the property value | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function getProperty($property, $rev, $path='') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $res = array(); | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' propget --xml %s --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($property), | 
					
						
							|  |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo.'/'.$path), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlProp = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |         $prop = simplexml_load_string($xmlProp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         return (string) $prop->target->property; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the number of the last commit in the repository. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string Commit ('HEAD'). | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return String last number commit | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getLastCommit($rev='HEAD') | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $xmlInfo = ''; | 
					
						
							| 
									
										
										
										
											2009-02-25 14:28:14 +01:00
										 |  |  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s', | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |                        escapeshellarg($this->username), | 
					
						
							|  |  |  |                        escapeshellarg($this->password), | 
					
						
							|  |  |  |                        escapeshellarg($this->repo), | 
					
						
							|  |  |  |                        escapeshellarg($rev)); | 
					
						
							| 
									
										
										
										
											2009-04-26 11:57:21 +02:00
										 |  |  |         $xmlInfo = shell_exec($cmd); | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $xml = simplexml_load_string($xmlInfo); | 
					
						
							| 
									
										
										
										
											2008-08-29 20:38:13 +02:00
										 |  |  |         return (string) $xml->entry->commit['revision']; | 
					
						
							| 
									
										
										
										
											2008-08-29 19:50:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |