一、背景 软件打包发布并在机器部署后并生命周期没有结束,后续会随着使用发现各种各样的Bug,整个生命周期都与Bug为伴,发现Bug并解决Bug就是软件产品的一部分,通常软件出现异常会有日志记录,当问题出现后,如何知道一个软件库的版本,从而快速从源码库拉取对应版本的源码,调试并修复呢?这就需要记录下软件库的源码版本。 以.net程序为例,.net程序主要是有一系列的dll构成,为每一个dll标记源码库的版本号就很有必要,这将能指明dll对应源码的版本号,在实际使用中很有帮助。 .net程序集的版本号规则:主版本.次版本.生成号.修订号 希望每次发布的时候将修订号使用该项目对应的SVN版本号,假设项目的最初版本为1.0.0.0,当项目改动并提交到SVN后SVN版本号为100,则希望生成的dll中文件版本为:1.0.0.100,这样就能通过查看dll文件版本知道该dll对应的源码SVN版本号 二、通过SubWcRev.exe实现程序集信息包含SVN版本号 参考文档:https://tortoisesvn.net/docs/release/TortoiseSVN_zh_CN/tsvn-subwcrev.html 方案简要概述: (1)创建一个程序集模板文件:AssemblyInfo.tmpl (2)将该文件中的[assembly: AssemblyFileVersion("1.0.0.0")]改为[assembly: AssemblyFileVersion("1.0.0.$WCREV$")] (3)在预编译命令时执行SubWcRev.exe,将AssemblyInfo.tmpl模板文件生成AssemblyInfo.cs,步骤2中的程序集版本就会被自动替换为SVN最新版本号 以上最终实现编译后的dll文件版本包含SVN版本号 三、实际使用问题 But,实际使用中存在一些问题:SubWcRev.exe正确执行要求操作的目录必须为SVN Working Copy,否则无法编译通过,实际使用中有些机器并未预装SVN环境,结果就是编译报错。 显然,该方案源码编译是依赖于SVN环境的,是一种耦合问题 四、解决方案 那么,对于无SVN环境的机器,如何顺利编译通过? 1、方案一:为需要编译的项目源码提供SVN环境 在该机器安装VisualSVN Server Manager,将源码上传本地后再拉取副本,这样确保源码在新机器上是SVN Working Copy 虽然可行,但是这种方案比较繁琐,效率低下 问题根源在于SubWcRev.exe命令执行的源码目录是SVN Working Copy!!! 因此需要解决当源码目录不是SVN Woring Copy的情况下,依然能成功编译的问题,该问题的卡点在于如何判定指定源码目录是否为SVN Working Copy? 一旦能判断出指定源码目录不是 SVN Woring Copy,不执行SubWcRev.exe命令,就不会导致编译报错问题。 通过查阅资料,找到svn info命令可担此重任 : (1)当源码目录是SVN Working Copy,会打印出详细信息 (2)当源码目录不是SVN Working Copy,会提示错误信息:XXX is not working copy 创建一个解决方案,命名为SVNVersion,该解决方案包含两个项目:
打开命令行,定位到上述源码目录,试验验证如下,执行成功:E:\SvnVersion>svn info
Path: . Working Copy Root Path: E:\SvnVersion URL: https://xxx/svn/SvnVersion Relative URL: /SvnVersion Repository Root: https://xxx/svn/SvnVersion Repository UUID: ccdf0fd3-632d-c745-82a6-d8dcb4201352 Revision: 120 Node Kind: directory Schedule: normal Last Changed Author: xxx Last Changed Rev: 120 Last Changed Date: 2023-04-29 15:54:26 +0800
将.svn目录命名为.svn2,再次执行svn info,执行错误:
E:\SvnVersion>svn info以上试验说明svn info命令可以有效的检查一个指定目录是否为SVN Working Copy 如何判断svn info命令是否执行成功? CMD命令执行成功返回0,可以通过判断ERRORLEVEL变量是否等于0,来确定svn info 是否执行成功 至此,构思完成,解决了最初遇到的问题,优雅的解除了源码编译对SVN环境的依赖 最终给出解决方案:通过svn info 判断要编译的源码目录是否为SVN Working Copy,若是执行SubWcRev.exe,若不是则不执行,这样无论源码是否为SVN Working Copy都能正确编译 2、方案二:摆脱项目编译对SVN环境的依赖 具体实施步骤: (1)将SubWcRev.exe、SVN.exe文件拷贝到源码中,与解决方案文件(*.sln文件一个目录),这样可以确保没有SVN环境的机器同样可以执行SubWcRev、svn Info命令 (2)编写CMD代码:
svn: E155007: 'E:\SvnVersion' is not a working copy
cd /d $(SolutionDir) svn info if %ERRORLEVEL%==0 ( SubWcRev "$(ProjectDir)\" "$(ProjectDir)Properties\AssemblyInfo.tmpl" "$(ProjectDir)Properties\AssemblyInfo.cs" )(3)将上述代码放到项目的生成前事件命令中,分别在源码是SVN Working Copy和不是SVN Working Copy两种场景中编译试验,均能通过测试,只是后一种情况编译的dll无SVN版本号 至此,已解决编译项目对SVN环境依赖问题,即便没有SVN环境,源码不是SVN Working Copy,依然能编译通过。 更近一步,对于实际项目中,通常有N多项目,每个项目都写这一段代码必然重复,违反了DRY原则,故重构上述代码,使之更整洁。 思路是将其提取到一个名为GenerateAssemblyInfo.bat文件中(与*.sln文件同一目录),将需要的目录作为变量传递:
set ProjectDir=%1 svn info if %ERRORLEVEL%==0 ( SubWcRev %ProjectDir% %ProjectDir%Properties\AssemblyInfo.tmpl %ProjectDir%Properties\AssemblyInfo.cs )
项目属性中生成前事件命令行,改为调用bat文件:
cd /d $(SolutionDir) call GenerateAssemblyInfo.bat $(ProjectDir)
总结: (1)本文从实际需求出发,给出软件dll版本号与SVN版本号产生关联的方案:通过SubWcRev.exe实现 (2)在实际使用中上述方案存在编译依赖SVN环境的问题,导致无SVN环境的机器在编译项目时报错,无法编译通过 (3)通过分析问题症结,找出问题卡点在于能否有效判定源码目录是否为SVN Working Copy,并通过执行svn info命令给出判定依据 (4)综合需求及实际问题,给出优化方案,最终解决项目编译对SVN环境的依赖:当源码目录被检测出是SVN Working Copy时,执行SubWcRev.exe,否则不予执行 (5)通过重构批处理命令,提取到一个文件中,项目统一调用该文件,便于多个项目复用,保持了方案的整洁性 标签:SVN,svn,依赖,Working,编译,源码,Copy From: https://www.cnblogs.com/maomu/p/17364657.html