'tree', 'file' => 'blob'); public function __construct($repo, $username='', $password='') { $this->repo = $repo; $this->username = $username; $this->password = $password; } /** * Returns the URL of the subversion repository. * * @param IDF_Project * @return string URL */ public static function getRemoteAccessUrl($project) { $conf = $project->getConf(); if (false !== ($url=$conf->getVal('svn_remote_url', false))) { // Remote repository return $url; } $url = Pluf::f('svn_remote_url'); if (Pluf::f('svn_repositories_unique', true)) { return $url; } return $url.'/'.$project->shortname; } /** * 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 if (false !== ($rep=$conf->getVal('svn_remote_url', false))) { // Remote repository return new IDF_Scm_Svn($rep, $conf->getVal('svn_username'), $conf->getVal('svn_password')); } else { $rep = Pluf::f('svn_repositories'); if (false == Pluf::f('svn_repositories_unique', false)) { $rep = $rep.'/'.$project->shortname; } return new IDF_Scm_Svn($rep); } } /** * 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 $cmd = sprintf('svn info --xml --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$path), escapeshellarg($rev)); $xmlInfo = shell_exec($cmd); // 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'; } /** * Given a commit hash returns an array of files in it. * * A file is a class with the following properties: * * 'perm', 'type', 'size', 'hash', 'file' * * @param string Commit ('HEAD') * @param string Base folder ('') * @return array */ public function filesAtCommit($rev='HEAD', $folder='') { $cmd = sprintf('svn ls --xml --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$folder), escapeshellarg($rev)); $xmlLs = shell_exec($cmd); $xml = simplexml_load_string($xmlLs); $res = array(); foreach ($xml->list->entry as $entry) { $file = array(); $file['type'] = $this->assoc[(string) $entry['kind']]; $file['file'] = (string) $entry->name; $file['fullpath'] = $folder.'/'.((string) $entry->name); $file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date)); $file['rev'] = (string) $entry->commit['revision']; // Get commit message $currentReposFile = $this->repo.'/'.$folder.'/'.$file['file']; $file['log'] = $this->getCommitMessage($currentReposFile, $rev); // Get the size if the type is blob if ($file['type'] == 'blob') { $file['size'] = (string) $entry->size; } $file['perm'] = ''; $res[] = (object) $file; } return $res; } /** * Get a commit message for given file and revision. * * @param string File * @param string Commit ('HEAD') * * @return String commit message */ private function getCommitMessage($file, $rev='HEAD') { $cmd = sprintf('svn log --xml --limit 1 --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($file), escapeshellarg($rev)); $xmlLog = shell_exec($cmd); $xml = simplexml_load_string($xmlLog); return (string) $xml->logentry->msg; } /** * Get the file info. * * @param string File * @param string Commit ('HEAD') * @return false Information */ public function getFileInfo($totest, $rev='HEAD') { $cmd = sprintf('svn info --xml --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$totest), escapeshellarg($rev)); $xmlInfo = shell_exec($cmd); $xml = simplexml_load_string($xmlInfo); $entry = $xml->entry; $file = array(); $file['fullpath'] = $totest; $file['hash'] = (string) $entry->repository->uuid; $file['type'] = $this->assoc[(string) $entry['kind']]; $file['file'] = $totest; $file['rev'] = (string) $entry->commit['revision']; $file['author'] = (string) $entry->author; $file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date)); $file['size'] = (string) $entry->size; $file['log'] = ''; return (object) $file; } /** * Get a blob. * * @param string Blob hash * @return string Raw blob */ public function getBlob($path, $rev) { $cmd = sprintf('svn cat --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$path), escapeshellarg($rev)); return shell_exec($cmd); } /** * Get the branches. * * @return array Branches. */ public function getBranches() { $res = array('HEAD'); return $res; } /** * Get commit details. * * @param string Commit ('HEAD'). * @return array Changes. */ public function getCommit($rev='HEAD') { $res = array(); $cmd = sprintf('svn log --xml -v --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo), escapeshellarg($rev)); $xmlRes = shell_exec($cmd); $xml = simplexml_load_string($xmlRes); $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']; $res['changes'] = $this->getDiff($rev); $res['tree'] = ''; return (object) $res; } private function getDiff($rev='HEAD') { $res = array(); $cmd = sprintf('svn diff -c %s --username=%s --password=%s %s', escapeshellarg($rev), escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo)); return shell_exec($cmd); } /** * Get latest changes. * * @param string Commit ('HEAD'). * @param int Number of changes (10). * * @return array Changes. */ public function getChangeLog($rev='HEAD', $n=10) { $res = array(); $cmd = sprintf('svn log --xml -v --limit %s --username=%s --password=%s %s@%s', escapeshellarg($n), escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo), escapeshellarg($rev)); $xmlRes = shell_exec($cmd); $xml = simplexml_load_string($xmlRes); $res = array(); foreach ($xml->logentry as $entry) { $log = array(); $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']; $log['full_message'] = ''; $res[] = (object) $log; } return $res; } /** * Generate the command to create a zip archive at a given commit. * Unsupported feature in subversion * * @param string dummy * @param string dummy * @return Exception */ public function getArchiveCommand($commit, $prefix='git-repo-dump/') { throw new Exception(('Unsupported feature.')); } /** * Get additionnals properties on path and revision * * @param string File * @param string Commit ('HEAD') * @return array */ public function getProperties($rev, $path='') { $res = array(); $cmd = sprintf('svn proplist --xml --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$path), escapeshellarg($rev)); $xmlProps = shell_exec($cmd); $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) { $key = (string) $prop['name']; $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(); $cmd = sprintf('svn propget --xml %s --username=%s --password=%s %s@%s', escapeshellarg($property), escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo.'/'.$path), escapeshellarg($rev)); $xmlProp = shell_exec($cmd); $prop = simplexml_load_string($xmlProp); return (string) $prop->target->property; } /** * 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 = ''; $cmd = sprintf('svn info --xml --username=%s --password=%s %s@%s', escapeshellarg($this->username), escapeshellarg($this->password), escapeshellarg($this->repo), escapeshellarg($rev)); $xmlInfo = shell_exec($cmd); $xml = simplexml_load_string($xmlInfo); return (string) $xml->entry->commit['revision']; } }