SVN上传时,同时将代码上传服务器——hook机制(多人WEB开发)

如果本文帮助到你,本人不胜荣幸,如果浪费了你的时间,本人深感抱歉。
希望用最简单的大白话来帮助那些像我一样的人。如果有什么错误,请一定指出,以免误导大家、也误导我。
本文来自:http://www.jianshu.com/users/320f9e8f7fc9/latest_articles
感谢您的关注。

这里是利用了 SVN 的一个功能——hook。

关于 SVN HOOK

HOOK 是干嘛的?

为了方便管理员控制提交的过程,Subversion 提供了 hook 机制。当特定的事件发生时,相应的 hook 会被调用, hook 其实就相当于特定事件的处理函数。每个 hook 会得到与它所处理的事件相关的参数,根据 hook 的返回值, Subversion 会决定是否继续当前的提交过程。

当前 Subversion 提 供了 5 种可以安装的 hook :


需求:

多人开发 WEB 项目时,如果用的 SVN ,都会遇到这么一种情况:我不仅要把代码提交到 SVN,还需要把代码反应到服务器。
怎么办呢?难道每次我改完代码要立马看效果,都必须去上传一次服务器吗?

由此,我们就来解决这个问题。利用的就是 SVN 的 hook 钩子机制。

我用的是 Windows ,开发语言是 PHP,用的 laravel 框架。

先来说步骤:

  1. 创建一个新的laravel项目,用来执行上传,添加自定义的上传命令;
  1. 创建一个 hook.bat,来执行命令;
  2. 设置 SVN 的 hook。

来,根据步骤,开始实现。


1. 创建一个新的laravel项目,用来执行上传,添加自定义的上传命令

我的是 laravel 4.2 的框架,
5.0以上的看这里:https://laravel-china.org/docs/5.0/commands
都是类似的。

在4.2的项目如下:

首先,在 app\config\remote.php 文件下做一些配置,设置所要上传服务器的必要信息。

    'connections' => array(

        'dev' => array(
            'host'      => '172.0.0.1',
            'username'  => 'dev-user',
            'password'  => '',
            'key'       => 'E:\PHPProject\test\app\config\pk\generate_dev-key.pem',
            'keyphrase' => '123456',
            'root'      => '/home/dev-user',
        ),

        'stage'=>array(
            'host'      => '172.0.0.2',
            'username'  => 'stage-user',
            'password'  => '',
            'key'       => 'E:\PHPProject\test\app\config\pk\generate_dev-key.pem',
            'keyphrase' => '123456',
            'root'      => '/home/stage-user',
        ),
        'prod'=>array(
            'host'      => '172.0.0.3',
            'username'  => 'root',
            'password'  => '123456',
            'key'       => '',
            'keyphrase' => '',
            'root'      => '/var/www/html/project_prod',
        ),

    ),

然后,自定义上传的命令,在 app\commands 目录下创建 synchronize.php 文件。

    <?php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class synchronize extends Command {

        /**
         * 第一个路径:是我们本地的路径,并不是全路径,会自动匹配。
         *
         * 第二个路径:是目标服务器的路径
         */
        private $app_path=[
                            'dev'=>["Trunk/Project_dev","/home/project_dev"],
                            'stage'=>["Trunk/Project_stage","/home/project_stage"],
                            'prod'=>["trunk/Project_prod","/var/www/html/project_prod"]
                          ];

        /**
         * The console command name.
         *
         * @var string
         */
        protected $name = 'synchronize';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'synchronize dev source with svn';

        /**
         * Create a new command instance.
         *
         * @return void
         */
        public function __construct()
        {
            parent::__construct();
        }

        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function fire()
        {
            //
            set_time_limit(0);
            $path=$this->argument("path");
            $fp=fopen($path,"r");
            while(!feof($fp) && $line=fgets($fp))
            {
                //去除换行符
                $line=str_replace(PHP_EOL,'',$line);
                //只对代码目录起效
                array_walk($this->app_path,function($v,$k) use ($line){
                    $path_array=explode($v[0],$line,2);
                    if(count($path_array)==2)
                    {
                        \Log::info($line);
                        \Log::info($k);
                        //获取远程路径
                        $temp_remote_path=$v[1].$path_array[1];
                        if(is_dir($line))
                        {
                            //文件夹
                            \Log::info('cd '.$v[1]);
                            \Log::info('mkdir -p '.trim($path_array[1],'/'));
                            \SSH::into($k)->run(
                                [
                                    'cd '.$v[1],
                                    'mkdir -p '.trim($path_array[1],'/'),
                                ]
                            );
                        }else
                        {
                            //获取需要删除或者新建的目录或者文件
                            $re_path=explode('/',$path_array[1]);
                            $re_path_length=count($re_path);
                            $work_path=$v[1];
                            array_walk($re_path,function($v,$k) use ($re_path_length,&$work_path){
                                if($k!=$re_path_length-1) $work_path.=$v.'/';
                            });
                            \Log::info(is_file($line));
                            if(is_file($line))
                            {
                                //创建文件夹
                                //文件夹
                                \Log::info('mkdir -p '.$work_path);
                                \SSH::into($k)->run(
                                    [
                                        'mkdir -p '.$work_path,
                                    ]
                                );
                                //上传文件
                                \SSH::into($k)->put($line,$temp_remote_path);
                            }else
                            {
                                //删除操作
                                \Log::info('cd '.$work_path);
                                \Log::info('rm -rf '.$re_path[$re_path_length-1]);
                                \SSH::into($k)->run(
                                    [
                                        'cd '.$work_path,
                                        'rm -rf '.$re_path[$re_path_length-1],
                                    ]
                                );
                            }
                        }
                    }
                });
            }
            fclose($fp);
        }

        /**
         * Get the console command arguments.
         *
         * @return array
         */
        protected function getArguments()
        {
            return array(
                array('path', InputArgument::REQUIRED, 'An example argument.'),
            );
        }

        /**
         * Get the console command options.
         *
         * @return array
         */
        protected function getOptions()
        {
            return array(
                array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null),
            );
        }

    }

这个做完之后,这个项目就可以往我们指定的服务器传文件了,但是怎么才能让它执行呢?我们继续。

<br />

2. 创建一个 hook.bat,来执行命令

因为我用的是 Windows,所以,创建一个 .bat 的执行文件。

首先,在一个目录创建一个 .txt 的文本文件,输入如下:

    cd E:\PHPProject\test
    D:\wamp\bin\php\php5.5.12\php.exe artisan synchronize %1

第一行的路径是我们上一步创建的项目的所在路径;
第二行是php的安装路径。

然后,再把这个 .txt 文件重命名,将其后缀名 改为 .bat。

这样,我们就建好了一个钩子(hook),最后就是将其配置到 SVN。

<br />

3. 设置 SVN 的 hook

如图,很明了。

点击 Setting
添加

<br />
大功告成。


<br />
这样,之后我们每次提交 SVN 的时候,就会自动同步到我们所配置的服务器。
这里需要提一下的是,在我们第一步所创建的项目,里面也会记录上传的 LOG,在 app\storage\logs\laravel.log 文件记录。

<br />
好了,文章到此结束。

如果有什么问题,请一定指出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • iOS 开发 SVN 版本控制器 更多技术交流请加群 iOS技术联盟 27512466 SVN是Subversio...
    Sunny_Fight阅读 8,726评论 7 63
  • 命令的使用 1、检出 svn cohttp://路径(目录或文件的全路径)[本地目录全路径] --username...
    小李龍彪阅读 4,398评论 0 9
  • 什么是SVN Hook SVN hook 脚本,大都译为SVN钩子,提供了一种非常强大而且灵活的方式把代码库的各种...
    浪尖儿阅读 8,401评论 4 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 无论你的头皮有任何需求, 我们都会完全满足您头皮的需要。 健康是根,科学是本。 认真对待每一寸头皮肌肤和每一个想长...
    泪湿的枕头阅读 1,239评论 0 0