在Xcode中插入Subversion版本号

时间:2008-12-16 18:31:57

标签: xcode svn

我想将当前的Subversion版本号(由svnversion报告)插入到我的Xcode项目中。我设法将修订号插入Info.plist中的$PROJECT_DIR,但这不是一个好的解决方案,因为该文件是版本化的。我尝试将修订版插入到构建目录中的Info.plist,但是在代码签名阶段我遇到了一个错误(这是一个iPhone应用程序)。

是否有一种简单的方法可以使用某些构建文件将修订号放入应用程序中,以便更改版本不会更改版本化文件?我想也许我可以创建一个临时源文件,该文件将与其他文件链接并提供获取修订号的功能。但我不知道该怎么做。

我对其他解决方案不太感兴趣,即。 agvtool。我想要的只是应用程序可用的修订版号,没有太大的魔力。

7 个答案:

答案 0 :(得分:37)

有一个更简单的解决方案:使用/usr/libexec/PlistBuddy,包含在Leopard的echo -n ${TARGET_BUILD_DIR}/${INFOPLIST_PATH} \ | xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `svnversion -n`" 中。有关详细信息,请参阅PlistBuddy

PlistBuddy可以在Xcode中的Run Script构建阶段使用,并且可以仅用于影响已处理的plist文件。只需将它放在复制资源阶段之后,您甚至不必每次都清理目标以使其运行。您甚至不必将值打印到头文件中,并使SVN忽略它。

{{1}}

假设您在代码签名发生之前添加了构建阶段,那么您的plist应使用替换值进行签名。

答案 1 :(得分:10)

对于后代,我通过在我的项目中添加一个revision.h,然后将以下内容添加为运行脚本构建阶段,为iPhone应用程序做了类似于zoul的操作:

REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "#define kRevisionNumber @\"$REV\"" > ${PROJECT_DIR}/revision.h

我这样做是为了获取一个简单的修订号,而不是svnversion在zoul的解决方案中产生的更详细的字符串。

对于Mac应用程序,我将方法基于this post,而是创建了buildnumber.xcconfig文件。在目标的构建设置下,我将对话框右下角的“基于”值更改为buildnumber.xcconfig。在Info.plist中,我编辑了以下几行:

<key>CFBundleVersion</key>
<string>${BUILD_NUMBER}</string>
<key>CFBundleShortVersionString</key>
<string>Version 1.0</string>

这样我的About对话框将显示类似于Version 1.0(1234)的版本字符串,其中1234是Subversion版本号。最后,我使用以下代码创建了一个Run Script构建阶段:

REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig

这可能不是最干净的方式,因为它需要一个干净的循环才能构建新版本以在应用程序中保留,但它可以工作。

答案 2 :(得分:8)

作为Stack Overflow的新用户,我无法对Quinn的帖子发表评论,但如果您使用的是一次有多个项目的SVN存储库,我会做一些小改动以使他的解决方案更加准确

使用他的方法,返回的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}

使用-c标志将以下列形式收集代码库的活动分支/标记/主干中的最后一次提交,然后将您不想存储的位作为修订版号删除。

另外,请注意$ {TARGET_BUILD_DIR}周围的双引号。那些决定将项目放在名称中带空格的目录结构中的用户需要这些。

希望这有助于其他人!

答案 3 :(得分:8)

我尝试为我的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 $4,$5}'`
/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}

它应该将svnversion的结果附加到基本Info.plist中设置的任何结尾作为版本。通过这种方式,您可以在信息plist中使用0.9.5之类的内容,并在最后添加.189修订版号,最终版本号为0.9.5.189

希望这有助于其他人!

答案 4 :(得分:2)

# 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 "$0: 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 = "" . $1);

die "$0: No Subversion revision found" unless $version;

open(FH, "$INFO") or die "$0: $INFO: $!";
my $info = join("", <FH>);
close(FH);

#$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>.+)\[BUILD\](<\/string>)/$1$version$2/;
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>)\[BUILD\](<\/string>)/$1$version$2/;

open(FH, ">$INFO") or die "$0: $INFO: $!";
print FH $info;
close(FH);

答案 5 :(得分:2)

由于我无法对Quinn的回答发表评论:

如果您使用的是MacPorts svn客户端,可能需要在我的情况下包含svnversion命令的完整路径,/ opt / local / bin / svnversion。我还在svnversion中添加了-c选项。

另外,如果您只对混合版本的第二个版本号感兴趣,请在调用中添加“cut”命令,如下所示:

echo -n "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" \
| xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `/opt/local/bin/svnversion -nc | cut -f2 -d:`"

答案 6 :(得分:0)

另一个版本,用Apple Script编写。可以更改previousValue的Regexp,目前它仅支持XX.XX.XX格式的版本(major,minor,svn rev)。

/usr/bin/osascript

运行
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