zoukankan      html  css  js  c++  java
  • 在VS项目中通过GIT生成版本号作为编译版本号

    上一篇博客写了如何在 .Net 项目使用 SVN 作为版本控制工具时生成与代码对应的组件版本号。虽然在公司一直使用 SVN ,但我却对 GIT 情有独钟(可能要归功于那段捣鼓 ROM 的时光),但少有文章提及如何具体在 Windows 平台来获得版本号。这让我有了迫切得到方法的希望。

    上篇博客《在VS项目中使用SVN版本号作为编译版本号

    经过测试,该方法是可行的,以前验证失败的原因主要是打开了 AssemblyInfo.cs  文件,造成占用不可替换!

    本文提供的方法还不完善,写出来的目的是为了得到更多人的关注,也希望有大牛能指点一二。

    将 GIT 的 commit 作为 . Net 项目编译后生成dll的文件版本号主要有以下几个困难。

    1GIT 没有一个数字的序号,而是一个SHA散列码;

    2GIT 提供的命令在 linux 十分方便,在 Windows 下需要额外的工具。

    第一个问题好解决,我们取当前文件夹 commit 的次数加上截取一段 SHA 码就可以作为文件版本号的最后一位。第二个问题目前想到的方法是调用 msysgit 提供的 Git Bash 来执行命令。

    好了,首先我们依旧得找到 msysgit 的安装目录,一查之下头就大了,各个地方的路径都感觉不靠谱,最后还是选用了

    HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstallGit_is1InstallLocation 

    (本来是想通过 temp 环境变量来取值的,查看 GIT 源代码好像也有写入,后来在自己电脑里却找不到)

    注:经验证,与安装选项有关,如果希望简单的话在安装时选择一下可以省很多事情!

    然后参照 Git Bash 的快捷方式拼接了下 call 的语句。

    然后写了一个 sh 文件来获得版本号,并保存到文件:

    1 # file name: git_ver.sh
    2 #!/bin/bash 
    3 VER_FILE=git_version.tmp
    4 LOCALVER=`git rev-list HEAD | wc -l | awk '{print $1}'`
    5 VER=r$LOCALVER
    6 VER="$VER $(git rev-list HEAD -n 1 | cut -c 1-7)"
    7 GIT_VERSION=$VER
    8 echo $GIT_VERSION>$VER_FILE
    View Code

     

    在批处理里取出刚保存文件的值,接下来的工作就和使用 SVN 里的差不多了,唯一的区别是我们要自己实现关键字的替换。

    上篇博客《在VS项目中使用SVN版本号作为编译版本号

    我们建立以一个 AssemblyInfo.tpl 作为替换使用的模板,由于 AssemblyInfo.cs 中除了固定的值外还有类似 GUID 变化的值,所以我们不能全部替换,因此仅将需要修改的部分放在 tpl 中,内容如下:

    [assembly: AssemblyVersion("1.0.0.0")]

    [assembly: AssemblyFileVersion("1.0.0.GITVERSION")]

    自己替换 GITVERSION 字段为前面取到的版本号。

    接下来使用批处理替换原来的 AssemblyInfo.cs 文件,为了在每次编译时都自动替换,我们把调用批处理的命令卸载项目生成事件的生成前事件中:

    "$(TargetDir)BeforeBuildProject.bat" $(ProjectDir) $(TargetDir)

    批处理代码:

     1 ::-------------------------------------------------
     2 :: <sunmary>
     3 :: 根据指定工作目录信息和模板生成目标文件
     4 :: </sunmary>
     5 :: <param name="WorkDir">工作目录路径</param>
     6 :: <param name="Template">模板文件路径</param>
     7 :: <param name="target">生成目标文件的路径</param>
     8 :: <returns>执行结果</returns>
     9 ::=================================================
    10 
    11 ::-------------------------------------------------
    12 :: * Initialize *
    13 @ECHO OFF
    14 ::SetLocal EnableExtensions
    15 setlocal enabledelayedexpansion
    16 
    17 Rem Initialize Script arguments
    18 SET WorkDir=%1
    19 SET target=%2
    20 
    21 Rem Initialize Constants
    22 SET AssemblyInfo=ASSEMBLY_INFO.tmp
    23 
    24 Rem GoTo Main Entry
    25 GOTO Main
    26 ::=================================================
    27 
    28 ::-------------------------------------------------
    29 :: * Main Entry *
    30 :Main
    31 Rem Check arguments
    32 IF %WorkDir%=="" GOTO ARGUNENT_ERROR
    33 IF %target%=="" GOTO ARGUNENT_ERROR
    34 PushD %WorkDir%
    35 
    36 Rem Search TSVN Path
    37 
    38 For /f "tokens=1* delims=_" %%1 in ('reg query "HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstallGit_is1" /v "InstallLocation"^| findstr /i "InstallLocation"') Do (
    39   For /f "tokens=1*" %%3  in ("%%~2") Do (
    40     SET GIT_PATH=%%4
    41   )
    42 )
    43 
    44 COPY /y "%target%git_ver" "%WorkDir%git_ver"
    45 
    46 SET GIT_PATH="%GIT_PATH%binsh.exe" --login -i
    47 call %GIT_PATH% %WorkDir%git_ver
    48 
    49 for /f "delims=" %%i in (%WorkDir%git_version.tmp) do (set VERSION=%%i)&(goto :next)
    50 :next
    51 DEL /Q "%WorkDir%git_ver">NUL
    52 DEL /Q "%WorkDir%git_version.tmp">NUL
    53 
    54 Rem Generate a template file
    55 
    56 COPY /y "%WorkDir%PropertiesAssemblyInfo.cs" "%WorkDir%PropertiesAssemblyInfo.cs.bak">NUL
    57 SET FILESTR="%WorkDir%PropertiesAssemblyInfo.cs"
    58 FindStr /v "AssemblyVersion AssemblyFileVersion" %FILESTR%>%AssemblyInfo%
    59 
    60 For /f "delims=" %%k In (%target%AssemblyInfo.tpl) do (
    61   set str=%%k
    62   set str=!str:GITVERSION=%VERSION%!
    63   echo !str! >> "%AssemblyInfo%"
    64 )
    65 
    66 COPY /y "%AssemblyInfo%" "%WorkDir%PropertiesAssemblyInfo.cs"
    67 GOTO SUCCESS
    68 ::=================================================
    69 
    70 ::-------------------------------------------------
    71 :: * Error Handlers *
    72 :ARGUNENT_ERROR
    73 ECHO 传入的参数无效。
    74 GOTO FAIL
    75 
    76 :UNKNOE_ERROR
    77 ECHO 未知错误。
    78 GOTO FAIL
    79 ::=================================================
    80 
    81 ::-------------------------------------------------
    82 :: * Program Exit *
    83 :FAIL
    84 DEL /Q "%AssemblyInfo%">NUL
    85 ::IF EXIST "%WorkDir%PropertiesAssemblyInfo.cs.bak" (COPY /y "%WorkDir%PropertiesAssemblyInfo.cs.bak" "%WorkDir%PropertiesAssemblyInfo.cs"&DEL /q "%WorkDir%PropertiesAssemblyInfo.cs.bak")>NUL
    86 ECHO "error"
    87 popd
    88 EXIT 1
    89 
    90 :SUCCESS
    91 DEL /Q "%AssemblyInfo%">NUL
    92 ECHO "success"
    93 popd
    94 EXIT 0
    95 ::=================================================
    View Code

     

    如果一切顺利的话,应该就可以得到想要的结果了,可是……

    替换文件竟然发生在生成后,也就是说 VS 在批处理执行结束前就已经编译生成了,这样文件版本号就只能在下次生成才会生效。上篇文章说的每次版本号都会增加的缺陷就无法那样解决了。

    当然你也可以为每个 AssemblyInfo.cs 文件生成备份,批处理通过备份文件产生 AssemblyInfo.cs ,这样可以把 AssemblyInfo.cs 排除到项目外。版本号也就不会因此迭代增加了。

    对于疑问的一个猜想是:因为我在批处理中调用了 Git Bash ,导致 VS 以为批处理执行结束而继续了生成。

    希望大家能提出其它想法或者验证我的猜想,有解决方案那就再好不过了。

    惯例附上所有代码:点击下载

     

    本文来自 NewIdea 的博客,作者 Carey Tzou 。

    原文地址:http://www.cnblogs.com/NewIdea/p/GITVersion.html

    转载请注明出处,否则拒绝转载!

  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/NewIdea/p/GITVersion.html
Copyright © 2011-2022 走看看