【问题标题】:Getting SVN revision number into a program automatically自动将 SVN 修订号导入程序
【发布时间】:2010-11-29 19:31:16
【问题描述】:

我在 SVN 下有一个 python 项目,我想在它运行时显示版本号。有没有办法做到这一点(例如在提交时自动运行一个可以更新版本文件的短脚本,或者在 Python 中查询 SVN 存储库?)

【问题讨论】:

    标签: python svn revision


    【解决方案1】:

    我不确定 Python 的细节,但如果将字符串 $Revision$ 放入文件中的某个位置,并且在 SVN 配置中启用了 enable-auto-props=true,它将被重写为 $Revision : 144 美元。然后你可以在你的脚本中解析它。

    a number of property keywords you can use in this way

    这不会有任何开销,例如查询 SVN 存储库,因为该字符串在提交或更新时被硬编码到您的文件中。

    我不确定你会如何在 Python 中解析它,但我会在 PHP 中解析:

    $revString = '$Revision: 144$';
    if(preg_match('/: ([0-9]+)\$/', $revString, $matches) {
        echo 'Revision is ' . $matches[1];
    }
    

    【讨论】:

    • 这是正确答案!此外,请记住在要执行此操作的每个文件上设置属性“keywords=Revision”。
    • Drew - 我想如果设置了enable-auto-props=true,那么默认关键字都设置好了?
    • +1 太棒了!但是,就我而言,如果它是在此修订中更改的不同文件,是否有办法让 SVN 编辑修订号?例如,如果我在 version.py 中有修订号关键字,但我不更改修订 nnn 中的 version.py,它不会更新它,是吗?如果没有,有没有办法以这种方式使用这种方法?
    • @Smashery 恐怕您必须编写自己的提交钩子才能做到这一点,我怀疑您可以使用 svn:keywords 属性,但可以通过设置自己的关键字并让 SVN 进行替换给你。
    • 这只适用于正在提交的文件。我们在构建脚本中处理它,很容易做到。
    【解决方案2】:

    类似于,但比 PHP 答案更 Pythonic;把它放在你模块的__init__.py:

    __version__ = filter(str.isdigit, "$Revision: 13 $")
    

    并确保添加 Revision 属性:

    svn propset svn:keywords Revision __init__.py
    

    【讨论】:

    • 或 ''.join(c for c in "$LastChangedRevision: 1546 $" if c.isdigit()) 如果你不喜欢过滤器。
    【解决方案3】:

    或者你可以这样做:

    import re,subprocess
    
    svn_info = subprocess.check_output("svn info")
    
    print (re.search(ur"Revision:\s\d+", svn_info)).group()
    

    它在我的项目中打印"Revision: 2874"

    或者像这样:

    print (subprocess.check_output("svnversion")).split(":")[0]
    

    它在我的项目中打印"2874"

    编辑

    对于较新的 python 版本 (>=3.4) 和明确的文件路径:

    import re,subprocess
    
    file_path = 'c:/foo'
    
    svn_info = subprocess.check_output('svn info ' + file_path)
    
    revision_string = re.search(r"Revision:\s\d+", str(svn_info)).group()
    revision = revision_string.split(': ')[1]
    print(revision)
    

    例如打印

    '8623'

    【讨论】:

    • 不仅仅是工作副本。您可以首先从“svn info”中检索 svn 远程 URL,例如执行“svn info”,然后从输出中获取“URL”参数值并执行相同的代码,但使用“svn info value_of_URL_param”所以,更新的代码是:import re ,subprocess svn_info = subprocess.check_output("svn info svn.you_remote_repo_url") print (re.search(ur"Revision:\s\d+", svn_info)).group()
    • 您的打印语句出现无效语法错误。 print (re.search(ur"Revision:\s\d+", svn_info)).group()
    • a) 从 python 3.4 开始,在字符串之前使用 r 而不是 ur:stackoverflow.com/questions/26063899/… b) 在 str() 中包装二进制字符串
    【解决方案4】:

    您的存储库中的文件hooks/pre-commit 是一个脚本或程序,它将在成功提交之前执行。只需将此脚本设为在提交时使用正确的版本号更新您的文件(修订号在运行时传递给您的脚本)。这是一个编写预提交钩子示例的教程:http://wordaligned.org/articles/a-subversion-pre-commit-hook

    【讨论】:

    • 哎哟。让预提交挂钩修改文件通常是个坏主意。 repo 中的版本将与工作副本中的版本不同,这可能会导致一些混乱。提交者必须恢复到文件的早期版本,然后获取新版本,这可能会导致某种冲突,因为 svn 已将原始版本存储在工作副本的文本库中。
    • 我同意这是危险的,通常不是理想的行为,但如果你适当地限制自己,那么我看不出问题。例如,如果您有一个“svn_version.txt”文件,其中只包含当前的修订号,那么它将是非常安全的;您的本地副本将始终具有您已签出的版本,并且存储库将始终具有最新版本(通常与您的工作副本相同)。
    【解决方案5】:

    在 Django 中有一个 sn-p 代码可以让你做到这一点,我建议你看看它。 http://code.djangoproject.com/browser/django/trunk/django/utils/version.py

    【讨论】:

    • 此功能仅在您从 subversion checkout 中运行时才有效。如果这是 OP 想要的,那么问题就解决了。但是,我怀疑他可能希望脚本包含在其自身或配置文件或其颠覆修订​​版中,即使该脚本不再处于颠覆之下,在这种情况下该链接将无用。
    • 是的,这是一个很好的后备选项,但是将版本号也置于源代码控制之下会更好。谢谢! +1
    【解决方案6】:

    查看pysvn。它在 Python 中公开了 Subversion 运行时功能的扩展。

    【讨论】:

      【解决方案7】:

      我通过在构建我的项目时运行一个小脚本来做到这一点。该脚本只是结合 sed 调用 svn info 来获取裸修订数据并将该数字注入到 revision.txt 文件中。

      Hudson 构建服务器使它变得更加容易,因为它在调用构建脚本之前将 SVN 修订号设置为环境变量。

      【讨论】:

        【解决方案8】:

        我发现运行时间部分有点模棱两可 - 当它从哪里运行时?来自 SVN 结帐还是来自已发布的代码?所有解决方案都以某种方式将 SVN 版本注入 Python 源代码或存储库中某个单独版本文件的位置。

        版本文件在新签出时会更改,因此需要在分发之前进行干净签出。所以我关于程序在哪里运行的问题仍然存在。

        【讨论】:

          【解决方案9】:

          重新回答,因为我找不到 python 3 的所有信息。 在 python 3 中,您可以使用以下内容:

          import re
          
          revstring = '$Revision: 123 $'
          revnumber = re.sub(r'\D', '', revstring)
          

          要让 SVN 替换数字,必须设置文件关键字“Revision”。您可以通过在终端中输入以下命令来实现:

          svn propset svn:keywords Revision YOURFILE.py
          

          此外,在 subversion 配置文件中,属性enable-auto-props 必须设置为yes。应该已经是这样了。在 Tortoise SVN 中,可以通过单击常规设置选项卡中“颠覆配置文件”旁边的“编辑”按钮访问此配置文件。

          【讨论】:

            【解决方案10】:

            这在 Python 中对我有用:

            获取所有svn信息:

            svn_info = subprocess.check_output('svn info').decode("utf-8") 
            print(svn_info)
            

            进行搜索并拆分号码:

            revisionNum = re.search("Revision:\s\d+", svn_info)
            print(revisionNum.group().split(":")[1])
            

            【讨论】:

            • 我会添加一个 'strip()' 以避免意外空格
            【解决方案11】:

            您可以通过将 'svn info --xml' 的输出解析为 xml 元素来以编程方式执行此操作:

            def get_svn_rev(dir: Union[str, Path]) -> str:
                """Get the svn revision of the given directory"""
                dir = str(dir)
                svn_info_cmd = ['svn', 'info', '--xml', dir]
                print(' '.join(svn_info_cmd))
                svn_info_process = subprocess.run(svn_info_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                if svn_info_process.returncode:
                    eprint(svn_info_process.stderr.decode().strip())
                    raise subprocess.CalledProcessError(returncode=svn_info_process.returncode, cmd=svn_info_cmd,
                                                        output=svn_info_process.stdout,
                                                        stderr=svn_info_process.stderr)
                else:
                    info = ElementTree.fromstring(svn_info_process.stdout.decode().strip())
                    entry = info.find('entry')
                    revision = entry.get('revision')
            
                return revision
            

            【讨论】:

              猜你喜欢
              • 2015-12-30
              • 2011-04-24
              • 1970-01-01
              • 2013-07-16
              • 2010-09-14
              • 1970-01-01
              • 1970-01-01
              • 2010-09-05
              • 1970-01-01
              相关资源
              最近更新 更多