【问题标题】:How does one add a svn repository build number to Python code?如何将 svn 存储库内部版本号添加到 Python 代码?
【发布时间】:2008-10-28 05:10:33
【问题描述】:

编辑:这个问题重复了How to access the current Subversion build number?(感谢您的提醒,Charles!)

你好,

这个问题类似于Getting the subversion repository number into code

区别在于:

  1. 我想给 Python 添加修订号

  2. 我想要存储库的修订版(不是签出的文件)

即我想从'svn info'的返回中提取修订号,就像这样:

$ svn 信息

Path: .
URL: svn://localhost/B/trunk
Repository Root: svn://localhost/B
Revision: 375
Node Kind: directory
Schedule: normal
Last Changed Author: bmh
Last Changed Rev: 375
Last Changed Date: 2008-10-27 12:09:00 -0400 (Mon, 27 Oct 2008)

我想要一个 375(修订版)的变量。将 $Rev$ 放入变量中以跟踪文件的更改很容易。但是,我想跟踪存储库的版本,并且我理解(并且似乎基于我的测试)$Rev$ 仅在文件更改时更新。

我最初的想法是使用 Python 内置的 svn/libsvn 模块,但我找不到任何关于如何使用它们的文档或示例。

另外,我考虑过调用“svn info”并正则表达式将代码输出,尽管这看起来相当残酷。 :)

我们将不胜感激。

感谢和干杯。

【问题讨论】:

  • 这个问题有很多很多重复项——我几乎看不出这是一个特定于 python 的问题(或有一个特定于 python 的答案),除非你想绑定到基于 setuptools 的构建过程之类的。

标签: python svn


【解决方案1】:

有一个名为svnversion 的命令,它是subversion 附带的,旨在解决这类问题。

【讨论】:

  • 您可以修改它以显示如何将结果写入捆绑到生成的蛋/包/whatnot 中的构建工件,只是为了完整并回答问题的两个方面(如何计算答案,以及如何将其捆绑到您的 python 项目中)。
【解决方案2】:

直接从 django 偷来的:

def get_svn_revision(path=None):
    rev = None
    if path is None:
        path = MODULE.__path__[0]
    entries_path = '%s/.svn/entries' % path

    if os.path.exists(entries_path):
        entries = open(entries_path, 'r').read()
        # Versions >= 7 of the entries file are flat text.  The first line is
        # the version number. The next set of digits after 'dir' is the revision.
        if re.match('(\d+)', entries):
            rev_match = re.search('\d+\s+dir\s+(\d+)', entries)
            if rev_match:
                rev = rev_match.groups()[0]
        # Older XML versions of the file specify revision as an attribute of
        # the first entries node.
        else:
            from xml.dom import minidom
            dom = minidom.parse(entries_path)
            rev = dom.getElementsByTagName('entry')[0].getAttribute('revision')

    if rev:
        return u'SVN-%s' % rev
    return u'SVN-unknown'

酌情调整。您可能希望将 MODULE 更改为您的代码模块之一的名称。

即使目标系统没有安装 subversion,此代码也能正常工作。

【讨论】:

    【解决方案3】:

    Python 直接绑定到 libsvn,因此您根本不需要调用命令行客户端。详情请见this blog post

    编辑:你基本上可以做这样的事情:

    from svn import fs, repos, core
    repository = repos.open(root_path)
    fs_ptr = repos.fs(repository)
    youngest_revision_number = fs.youngest_rev(fs_ptr)
    

    【讨论】:

    • 是的,但这并不能让您访问 svnversion 中的所有逻辑——在这种情况下,这完全正确。
    【解决方案4】:

    我使用了一种与此非常相似的技术,以便在我的 shell 中显示当前的 subversion 修订号:

    svnRev=$(echo "$(svn info)" | grep "^Revision" | awk -F": " '{print $2};')
    echo $svnRev
    

    对我来说效果很好。

    为什么每次整个存储库的版本号递增时都希望 python 文件发生变化?如果一个来自 repo,另一个来自 tarball,这将使两个文件之间的差异变得烦人..

    【讨论】:

    • 我想 BMH 不想在每个文件中都使用它,而是希望有一个详细说明当前系统版本的位置 - 请查看本页右下角的示例。
    【解决方案5】:

    如果您想在一个源文件中有一个变量可以设置为当前工作副本修订版,并且不会在 subversion 上重播并且在您运行程序时工作副本实际可用,那么SubWCRev我是你的解决方案。

    似乎还有一个名为SVNWCRev的linux端口

    两者都使用工作副本的最高提交级别替换 $WCREV$。也可以提供其他信息。

    【讨论】:

      【解决方案6】:

      根据 CesarB 的回复和 Charles 提供的链接,我做了以下事情:

      try:
        from subprocess import Popen, PIPE
        _p = Popen(["svnversion", "."], stdout=PIPE)
        REVISION= _p.communicate()[0]
        _p = None # otherwise we get a wild exception when Django auto-reloads
      except Exception, e:
        print "Could not get revision number: ", e
        REVISION="Unknown"
      

      Golly Python 很酷。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-21
        相关资源
        最近更新 更多