VisualSvn Server通过Hooks自动更新到FTP
2013-6-4 18:33 Tuesday  

分类: PHP 标签: function file path result private 评论(79) 浏览(26023)

post-commit.cmd内容如下

@echo off  
:: Stops commits that don't include a log message of at least 6 characters.        
@echo off  

setlocal  

rem Subversion sends through the repository path and transaction id  
set REPOS=%1
set TXN=%2   

"C:\Program Files (x86)\phpStudy\PHP5\php.exe" -q D:\Repositories\wwwphpecorg\hooks\handle.php %1 %2  1>&2
::err  
exit 1

 

 

 

handle.php文件内容如下,我将svn和ftp类放在一起了

<?php
	class SVN
	{
		const DEFAULT_PATH = "C:\windows\Temp\\";
		// 
		static private function console ($str) {
			$arr = array();
			$result = exec($str, $arr);
			return $arr;
		}
		// svn changed
		static private function getChangedList($revision, $respos) {
			$arr = array();
			$result = self::console("\"C:\Program Files (x86)\VisualSVN Server\bin\svnlook.exe\" changed -r $revision $respos");
			log_local(implode('\r\n', $result));
			return $result;
		}
		// svn cat 
		static private function getContent($revision, $respos, $path) {
			$arr = array();
			$basename = pathinfo($path, PATHINFO_BASENAME);
			// Ensure the path is unique
			do {
				$tempPath = self::DEFAULT_PATH.substr(md5(rand(1,100) % rand(1, 1000)), 0, 10).$basename;
			} while (file_exists($tempPath));
			// write into a local file
			self::console("\"C:\Program Files (x86)\VisualSVN Server\bin\svnlook.exe\" cat -r $revision $respos $path >$tempPath");
			$result = array();
			if (exec("echo %ERRORLEVEL%") != 0) 
				die("Fail to create file");
			return $tempPath;
		}
		// 
		static private function analyse($str) {
			// $value : EXAMPLE , U  program/list.txt
			$result = explode(" ", $str);
			// get the operation status
			$status = $result[0];
			$path = $result[3];
			$type = 'f';
			// directory or file
			if (substr($path, strlen($path) - 1) == "/") {
				$type = 'd';
			}
			return array(
				'status' 	=> $status,
				'path' 		=> $path,
				'type' 		=> $type,
			);
		}

		// 
		public static function getList($revision, $respos) {
			$list = self::getChangedList($revision, $respos);
			$result = array();
			foreach ($list as $key => $value) {
				$tempArr = self::analyse($value);
				if ($tempArr['type'] == 'f' && in_array($tempArr['status'], array('A', 'U'))) {
					$tempArr['local_file'] = self::getContent($revision, $respos, $tempArr['path']);
				}
				$result[$key] = $tempArr;
			}
			return $result;
		}

	}


	class FTP
	{
		private $server;
		private $user;
		private $passwd;
		private $connect_id;
		private $remote_root = "/phpecorg/";
		private $local_root = "";

		public function __construct($config) {
			$this->server 	= $config['server'];
			$this->user 	= $config['user'];
			$this->passwd 	= $config['passwd'];

			$connect_id = ftp_connect($config['server']);
			$connect_id === false && die("Can't connect the server");
			$result = ftp_login($connect_id, $this->user, $this->passwd);
			$result === false && die("Fail to login");
			ftp_pasv($connect_id, true); // 开启被动模式

			$this->connect_id = $connect_id;
		}

		public function handle($arr) {
			if ($arr['type'] == 'f') {
				switch ($arr['status']) {
					case 'A':
					case 'U':
						$this->update($arr['path'], $arr['local_file']);
						break;
					case 'D':
						$this->delete($arr['path']);
						break;
					default:
						die("No such status!");
						break;
				}
			} else if($arr['type'] == 'd') {
				switch ($arr['status']) {
					case 'A':
						$this->mkdir($arr['path']);
						break;
					case 'U':
						$this->update($arr['path']);
						break;
					case 'D':
						$this->rmdir($arr['path']);
						break;
					default:
						die("No such status!");
						break;
				}
			}
		}
		private function mkdir($pathname) {
			$result = ftp_mkdir($this->connect_id, $this->getDir($pathname));
			if ($result) 
				$str = "Successfully created directory $pathname\n";
			else 
				$str = "There was a problem while creating directory $pathname\n";
			log_local($str);
		}
		private function rmdir($pathname) {
			$result = ftp_rmdir($this->connect_id, $this->getDir($pathname));
			if ($result) 
				$str = "Successfully deleted directory $pathname\n";
			else 
				$str = "There was a problem while deleting directory $pathname\n";
			log_local($str);
		}

		private function update($file, $local_file) {
			$result = ftp_put($this->connect_id, $this->getDir($file), $local_file, FTP_BINARY);
			if ($result) 
				$str = "Successfully uploaded file $file\n";
			else 
				$str = "There was a problem while uploading file $file\n";
			log_local($str);
		}
		private function delete($file) {
			$result = ftp_delete($this->connect_id, $this->getDir($file));
			if ($result) 
				$str = "Successfully deleted file $file\n";
			else 
				$str = "There was a problem while deleting file $file\n";
			log_local($str);
		}

		private function get_mode($path) {
			$number = getimagesize($path);
			if ($number) 
				$mode = FTP_IMAGE;
			else 
				$mode = FTP_BINARY;
			return $mode;
		}

		private function getDir($dir) {
			// validate the dir 
			//echo $dir.'------'.$this->local_root.'    ';
			//strpos($dir, $this->local_root) === 0 || die("The local_root does not match the dir!");
			return $this->remote_root.substr($dir, strlen($this->local_root));
		}

		public function __destruct() {
			ftp_close($this->connect_id);
		}
	}

	$revision = 0;
	$respos = "";
	//log_local("\r\n ".serialize($_SERVER)."\r\n");
	if (!empty($_SERVER['argv']) && $_SERVER['argc'] >= 3) {
		$respos 	= $_SERVER['argv'][1];
		$revision 	= $_SERVER['argv'][2];
	} else {
		echo "Missing param";
		exit;
	}


	$config = array(
			'server' 	=> 'www.phpec.org',
			'user'		=> 'aboc',
			'passwd' 	=> 'abocpassword',
		);

	$changeList = SVN::getList($revision, $respos);
	$FTP = new FTP($config);

	foreach ($changeList as $key => $value) {
		$FTP->handle($value);
	}

	function log_local($message) {
		echo "\r\n".$message;
		$default_path = "D:\Repositories\wwwphpecorg\hooks\s.log";
		$fp = fopen($default_path, 'a+');
		if (flock($fp, LOCK_EX)) {
			fwrite($fp, $message."\r\n");
		    flock($fp, LOCK_UN);
		} else {
			echo "Couldn't lock the file !";
		}
		fclose($fp);
	}

 

就是如此简单

 

+1 7

留下你的看法: