在 Xcode 中插入 Subversion 修订号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/372218/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert Subversion revision number in Xcode
提问by zoul
I would like to insert the current Subversion revision number (as reported by svnversion
) into my Xcode project. I managed to insert the revision number into the Info.plist
in the $PROJECT_DIR
, but this is not a good solution, since the file is versioned. I tried to insert the revision into the Info.plist
in the build directory, but then I get an error during the code signing phase (this is an iPhone application).
我想将当前的 Subversion 修订号(由 报告svnversion
)插入到我的 Xcode 项目中。我设法将修订号插入到Info.plist
中$PROJECT_DIR
,但这不是一个好的解决方案,因为该文件是版本化的。我试图将修订版插入到Info.plist
构建目录中,但随后在代码签名阶段出现错误(这是一个 iPhone 应用程序)。
Is there a simple way to get the revision number into the application using some build files, so that the changing revision does not change versioned files? I thought maybe I?could create a temporary source file that would link with the others and provide a?function to get the revision number. But I don't know how to do that.
是否有一种简单的方法可以使用一些构建文件将修订号输入到应用程序中,以便更改的修订版不会更改版本化文件?我想也许我可以创建一个临时源文件来与其他文件链接并提供一个函数来获取修订号。但我不知道该怎么做。
I am not much interested in other solutions, ie. the agvtool
. All I want is the revision number available to the application, without too much magic.
我对其他解决方案不太感兴趣,即。的agvtool
。我想要的是应用程序可用的修订号,没有太多的魔力。
回答by Quinn Taylor
There's a much simpler solution: using PlistBuddy, included at /usr/libexec/PlistBuddy
in Leopard. See my answer to a related SO questionfor details.
有一个更简单的解决方案:使用PlistBuddy,包含/usr/libexec/PlistBuddy
在 Leopard 中。有关详细信息,请参阅我对相关 SO 问题的回答。
PlistBuddy can be used in a Run Script build phase from within Xcode, and can be used to only affect the processed plist file. Just put it after the Copy Resources phase, and you don't even have to clean the target for it to run each time. You don't even have to print the value to a header file and make SVN ignore it, either.
PlistBuddy 可以在 Xcode 中的 Run Script 构建阶段使用,并且只能用于影响已处理的 plist 文件。只需将它放在复制资源阶段之后,您甚至不必每次都清理目标以使其运行。您甚至不必将值打印到头文件并使 SVN 忽略它。
echo -n ${TARGET_BUILD_DIR}/${INFOPLIST_PATH} \
| xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `svnversion -n`"
Assuming you add the build phase before code signing occurs, your plist should be signed with the substituted value.
假设您在代码签名发生之前添加构建阶段,您的 plist 应该使用替换值进行签名。
回答by Brad Larson
For posterity, I did something similar to zoul for iPhone applications, by adding a revision.h to my project, then adding the following as a Run Script build phase:
对于后代,我为 iPhone 应用程序做了一些类似于 zoul 的事情,通过在我的项目中添加一个 revision.h,然后添加以下作为运行脚本构建阶段:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "#define kRevisionNumber @\"$REV\"" > ${PROJECT_DIR}/revision.h
I did this to grab a simple revision number, as opposed to the more detailed string that svnversion produces in zoul's solution.
我这样做是为了获取一个简单的修订号,而不是 svnversion 在 zoul 的解决方案中生成的更详细的字符串。
For Mac applications, I based my approach on this post, and instead created a buildnumber.xcconfig file. Under the build settings for the target, I changed the Based On value in the lower-right-hand corner of the dialog to buildnumber.xcconfig. Within the Info.plist, I edited the following lines:
对于 Mac 应用程序,我的方法基于这篇文章,而是创建了一个 buildnumber.xcconfig 文件。在目标的构建设置下,我将对话框右下角的“基于”值更改为 buildnumber.xcconfig。在 Info.plist 中,我编辑了以下几行:
<key>CFBundleVersion</key>
<string>${BUILD_NUMBER}</string>
<key>CFBundleShortVersionString</key>
<string>Version 1.0</string>
So that my About dialog would display a version string similar to Version 1.0 (1234), where 1234 is the Subversion revision number. Finally, I created a Run Script build phase with the following code:
这样我的“关于”对话框将显示类似于版本 1.0 (1234) 的版本字符串,其中 1234 是 Subversion 修订号。最后,我使用以下代码创建了一个运行脚本构建阶段:
REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig
This may not be the cleanest way, as it requires a clean cycle before building for the new revision to take hold in the application, but it works.
这可能不是最干净的方法,因为它需要一个干净的循环才能在应用程序中建立新的修订版,但它确实有效。
回答by George Walters II
As a new user to Stack Overflow, I can't comment on Quinn's post, but I have a small change to make his solution a bit more accurate if you're using a SVN repository that has multiple projects going on at once.
作为 Stack Overflow 的新用户,我无法对 Quinn 的帖子发表评论,但如果您使用同时进行多个项目的 SVN 存储库,我有一个小改动可以使他的解决方案更加准确。
Using his approach, the svnversion number that is returned is the last check-in for the entire repository, not necessarily your code base. This tweak allows for the update to be specific to your code base.
使用他的方法,返回的 svnversion 编号是整个存储库的最后一次签入,不一定是您的代码库。此调整允许更新特定于您的代码库。
REV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $REV" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
Using the -c flag will gather the last commit done in the active branch/tag/trunk for your codebase in the form of :, then chop off the bits you don't want to store as the Revision number.
使用 -c 标志将以 : 的形式为您的代码库收集在活动分支/标签/主干中完成的最后一次提交,然后切掉您不想存储为修订号的位。
Also, notice the double quotes around the ${TARGET_BUILD_DIR}. Those are needed for users that decide to place their project in a directory structure with spaces in the name.
另外,请注意 ${TARGET_BUILD_DIR} 周围的双引号。对于决定将项目放置在名称中带有空格的目录结构中的用户来说,这些是必需的。
Hope this helps others!
希望这对其他人有帮助!
回答by Brian Robbins
I found this page when trying to do a similar thing for my iPhone app and thought it might be helpful to share the code I decided on. I was trying to have a base version number set in my Target Info (for example 0.9.5) but then append my SVN revision number at the end of it. I needed this stored in CFBundleVersion so that AdHoc users would be able to update via iTunes even if I didn't remember to rev the version number in my Target Info pane. That's why I couldn't use the "revision.h" method which otherwise worked beautifully. Here's the final code I settled on which I've placed as a Run Script phase just after the "Copy Bundle Resources" build phase:
我在尝试为我的 iPhone 应用程序做类似的事情时发现了这个页面,并认为分享我决定的代码可能会有所帮助。我试图在我的目标信息中设置一个基本版本号(例如 0.9.5),然后在它的末尾附加我的 SVN 修订号。我需要将其存储在 CFBundleVersion 中,以便 AdHoc 用户能够通过 iTunes 进行更新,即使我不记得在“目标信息”窗格中修改版本号。这就是为什么我不能使用“revision.h”方法,否则它可以很好地工作。这是我确定的最终代码,我在“复制捆绑资源”构建阶段之后将其放置为运行脚本阶段:
BASEVERNUM=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${INFOPLIST_FILE}" | sed 's/,/, /g'`
REV=`svnversion -n`
SVNDATE=`LC_ALL=C svn info | awk '/^Last Changed Date:/ {print ,}'`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASEVERNUM.$REV" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
/usr/libexec/PlistBuddy -c "Set :BuildDateString $SVNDATE" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
It should append the results of svnversion to the end of whatever is set in the base Info.plist as the version. This way you can have something like 0.9.5 in your info plist and still have the .189 revision number appended at the end, giving a final version number of 0.9.5.189
它应该将 svnversion 的结果附加到基本 Info.plist 中作为版本设置的任何内容的末尾。通过这种方式,您可以在信息 plist 中包含类似 0.9.5 的内容,并且仍然在末尾附加 .189 修订号,最终版本号为 0.9.5.189
Hope this helps someone else!
希望这对其他人有帮助!
回答by Brian Robbins
# Xcode auto-versioning script for Subversion
# by Axel Andersson, modified by Daniel Jalkut to add
# "--revision HEAD" to the svn info line, which allows
# the latest revision to always be used.
#
# modified by JM Marino to change only [BUILD] motif
# into CFBundleGetInfoString key.
#
# HOW TO USE IT: just add [BUILD] motif to your Info.plist key :
# CFBundleVersion
#
# EXAMPLE: version 1.3.0 copyright 2003-2009 by JM Marino
# with [BUILD] into CFBundleVersion key
use strict;
die "echo -n "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" \
| xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `/opt/local/bin/svnversion -nc | cut -f2 -d:`"
: Must be run from Xcode" unless $ENV{"BUILT_PRODUCTS_DIR"};
# Get the current subversion revision number and use it to set the CFBundleVersion value
#my $REV = `/usr/local/bin/svnversion -n ./`;
my $REV = `/usr/bin/svnversion -n ./`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Contents/Info.plist";
my $version = $REV;
# (Match the last group of digits without optional letter M | S):
($version =~ m/(\d+)[MS]*$/) && ($version = "" . );
die "set myVersion to do shell script "svn info | grep \"^Revision:\""
set myVersion to do shell script "echo " & quoted form of myVersion & "| sed 's/Revision: \([0-9]\)/\1/'" as string
set myFile to do shell script "echo ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
set theOutputFolder to myFile as string
set thePListPath to POSIX path of (theOutputFolder & "Info.plist")
tell application "System Events"
tell property list file thePListPath
tell contents
set previousValue to value of property list item "CFBundleVersion"
set previousValue to do shell script "echo " & quoted form of previousValue & "| sed 's/\([0-9]*\.[0-9]*\)\(\.[0-9]*\)*/\1/'" as string
set value of property list item "CFBundleVersion" to (previousValue & "." & myVersion)
end tell
end tell
end tell
: No Subversion revision found" unless $version;
open(FH, "$INFO") or die "##代码##: $INFO: $!";
my $info = join("", <FH>);
close(FH);
#$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>.+)\[BUILD\](<\/string>)/$version/;
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>)\[BUILD\](<\/string>)/$version/;
open(FH, ">$INFO") or die "##代码##: $INFO: $!";
print FH $info;
close(FH);
回答by Gereon
Since I can't comment on Quinn's answer:
由于我无法评论奎因的回答:
if you're using the MacPorts svn client, it may be necessary to include the full path of the svnversion command, /opt/local/bin/svnversion in my case. I also added the -c option to svnversion.
如果您使用的是 MacPorts svn 客户端,则可能需要包含 svnversion 命令的完整路径,在我的情况下为 /opt/local/bin/svnversion。我还在 svnversion 中添加了 -c 选项。
Also, if you're only interested in the second version number of mixed revisions, add a 'cut' command to the invocation, like this:
此外,如果您只对混合修订的第二个版本号感兴趣,请在调用中添加“cut”命令,如下所示:
##代码##回答by shader
Another version, written in the Apple Script. Regexp for the previousValue could be changed, currently it supports only versions in XX.XX.XX format (major, minor, svn rev).
另一个版本,用 Apple Script 编写。可以更改 previousValue 的正则表达式,目前它仅支持 XX.XX.XX 格式的版本(major、minor、svn rev)。
Run by /usr/bin/osascript
由......运营 /usr/bin/osascript