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

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

  • 相关阅读:
    jdk8 xp
    electron react
    electron install失败
    0511 Braft Editor和嵌套路由
    组播
    0427
    duilib自定义组件
    android 读写文件、列出根目录文件及新版本权限
    android Fragment使用RecyclerView
    Duilib 带xml的1
  • 原文地址:https://www.cnblogs.com/NewIdea/p/GITVersion.html
Copyright © 2011-2022 走看看