结合ruby写的一个校验工具

背景:

每次发布detail这边一般都要发布多个js文件,然后同步到不同的CDN;现阶段CDN有提供一个平台,前端在发布js后可以根据js的文件名来逐个校验下每个js是否同步到每一个CDN节点,但在有多个js发布的时候,可能不能逐一校验,detail这边有出现发布js后同步到个别的CND节点同步失败,所以考虑用一个简便的方式来执行;

大致流程:

通过svn的命令拿到每次js发布的文件名,然后根据文件名在CDN同步校验平台上检测是否同步到每个CDN节点,如果同步失败返回信息;

具体步骤:

1、通过命令拿到每次要发布的js文件信息,这些信息包含 版本号、时间、提交者、文件名,将这些信息定向到一个XML文件

2、解读XML文件,根据提交者的名字查询该用户修改发布的文件名,将文件名转换成数组的元素

3、将数组中的每个文件名在CDN校验平台上逐一校验,并返回信息;

下面是具体实现方式:

本机调试:

运行CMD执行

svn log  --revision HEAD:{2012-11-24} http://svn.../malldetail/ 

如果执行上述的命令有输出相应的内容则请忽略下面的内容,如果提示SVN不是外部内部命令时请看下面:

Q1:

SVN 不是有内部或外部命令,也不是可运行的程序或批处理文件。

现场:

CMD内输入SVN显示:不是有内部或外部命令,也不是可运行的程序或批处理文件。、

本机已安装SVN

解决方案:

需要安装subversion,传送门:SubVersion,xp装32位  Win 7-64位 .

安装好对应的subversion后,重新执行运行输出结果;

由于需要拿到更新文件的文件名以及所在的路径信息,所以可以尝试使用SVN参数,在这里可以尝试下:

svn log  --quiet --verbose  --revision HEAD:{2012-11-24} http://svn.../malldetail/ 

 --quiet --verbose 参数加入后,输出信息将会输出更新文件的概要信息;

再将文件定向到一个XML文件(这里可以是其它后缀的文件,定义成XML是为了后面读取方便),继续加参数:

svn log  --quiet --verbose  --xml  --revision HEAD:{2012-11-24} http://svn.../malldetail/ 

在ruby中:

def svn_log(start_date)
    #reversion --{date}
    timespan = " --revision HEAD:{#{start_date}}"
    puts  timespan
    #URL中对应的目录是可更改的
    url="http://svn....../malldetail/assets/3.0b"
    root=url
    #将更新的文件重定向到一个文件中 可以csv 也可以xml
    #参数说明--quiet 查看程序的版本号不会打印日志信息正文本身;--verbose参数表示显示详细信息;
    `svn log #{timespan} #{root}  --quiet --verbose --xml >updatw_file.xml`
    # puts `svn log #{timespan} #{root}`
    puts 'done,已将修改的文件重定向到一个xml文件中'
  end

那么到这里,我们第一步通过svn拿到前端要发布的文件信息了;

{下面是svn log常用的几个参数

svn log [PATH]

svn log URL [PATH...]

它有几个参数:

--revision (-r) REV

--quiet (-q) 不打印信息,或只打印概要信息

--verbose (-v)  打印附加信息

--targets FILENAME 传递文件 ARG 内容为附件参数

--stop-on-copy 可以关闭这种行为,这可以用来找出分支点

--incremental 给予适合串联的输出

--xml  输出为 XML

全局配置项说明

--username USER 指定用户名称 ARG

--password PASS 指定密码 ARG

--no-auth-cache 不要缓存用户认证令牌

--non-interactive 不要交互提示

--config-dir DIR 从目录 DIR读取用户配置文件

}

第二步:读取XML文件,根据提交用户名字拿到该用户更新的文件,下面是具体的实现方式:

先附上一段xml内容:

<?xml version="1.0" encoding="UTF-8"?>

<log>

<logentry

   revision="7842">

<author>daqiu.lym</author>

<date>2012-12-27T09:49:13.386760Z</date>

<paths>

<path

   action="M"

   kind="">/trunk/malldetail/assets/4.0a/common/util.js</path>

<path

   action="M"

   kind="">/trunk/malldetail/assets/4.0a/other/ishare.js</path>

</paths>

</logentry>

</log>

def process()
    #可以更改时间,这里是从
    date_info = "2012-12-12"
    svn_log(date_info)
    # ********* 解析xml文件,根据提交的用户名拿到更新的文件名 *******
    #读取xml文件
    filename = "updatw_file.xml"
    doc = Document.new(File.open(filename))
    #根据author的值拿到更新的文件名称 在这里是可以更新author的值的
    #[author='daqiu.lym']作者名字可改
    path = "//logentry[author='daqiu.lym']/paths/path"
    #xpath根据提交代码用户的名字拿到他更新的文件
    v1 = XPath.match(doc,path).map{|uf| uf.text}
    #将文件转换成to_string的形式
    v3 = v1.to_s
    #将以js 或者css结尾时自动的换取行
    v4=v3.gsub(/js/,'js
').gsub(/\.css/,'.css
').gsub(/vm/,'vm
').gsub(/trunk/,"apps").gsub(/\/assets/,"")
#.gsub(/\.txt/,".txt
#")
    #将输出的文件名称转换成数组形式 然后去重
    arr =  v4.to_a.uniq
    puts " 文件更新列表:"

这里需要补充下,有将trunk替换为 apps,以及将assets去除,是为了方便第三步拼接URL校验;

感兴趣的还可以了解下sub或者gsub方法来进行替换的区别,他们两个方法第一个参数都是接受正则表达式。其中,sub方法替换掉第一个匹配的地方,而gsub方法替换掉左右匹配的地方,所以这里选择用gsub;

第二步实现方式就这么多了,在这过程中有遇到下面的两情况,最终通过查阅些资料和时间,选择了使用XPath.match

Q2:XPath

**不是直接的arr = IO.readlines(%%1)  #"myfile" 因为不需要太多的内容,我们只需要获取部分内容

Q3:

 # #  xml解析

    #没有选取

    #doc = Document.new(File.open("my.xml"))

    #doc.elements.each("log/logentry/paths"){  |elem|

    # puts elem.attributes["path"]

    #  puts "start"

    #}

第三步:将数组中的文件名放到CDN校验平台逐一校验

 校验平台: http://assets.f2e.taobao.net/ 

这里是直接的将文件名以及路径拼接到校验平台后的方式来实现:

#访问到查看页面
    url="http://a...../"
    ie = IEModel.start(url)
    #将更新的文件拼到URL中,然后检测更新的文件是否被同步到每个节点
    for $i in 0...(arr.size()-1) do
      # 拼接URL
      urla="http://a.cn"+arr[$i].to_s
      ie.goto(url+"?path="+urla)

然后校验页面的返回信息,根据返回信息作出相应的操作;

到这里为止,三部曲就完成了,这里还需要更多优化,目前这个需要依赖ruby的环境,我在这里抛砖引玉,希望大家有更好的更简洁方便的方法,然后一起来探讨。