25

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

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

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

4

7 回答 7

37

有一个更简单的解决方案:使用Leopard中包含的PlistBuddy/usr/libexec/PlistBuddy。有关详细信息,请参阅我对相关 SO 问题的回答

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

echo -n ${TARGET_BUILD_DIR}/${INFOPLIST_PATH} \
    | xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `svnversion -n`"

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

于 2009-06-30T05:38:36.337 回答
10

对于后人,我为 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

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

对于 Mac 应用程序,我的方法基于这篇文章,而是创建了一个 buildnumber.xcconfig 文件。在目标的构建设置下,我将对话框右下角的 Based On 值更改为 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 修订号。最后,我使用以下代码创建了一个运行脚本构建阶段:

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

这可能不是最干净的方式,因为它需要一个干净的周期,然后才能构建新版本以在应用程序中占据一席之地,但它确实有效。

于 2009-01-05T22:50:35.727 回答
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} 周围的双引号。对于决定将项目放置在名称中带有空格的目录结构中的用户来说,这些是必需的。

希望这对其他人有帮助!

于 2009-12-07T22:16:54.807 回答
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 中设置为版本的任何内容的末尾。这样,您可以在 info plist 中包含类似 0.9.5 的内容,并且在末尾附加 .189 修订号,最终版本号为 0.9.5.189

希望这对其他人有帮助!

于 2010-01-13T00:35:36.953 回答
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);
于 2009-01-31T11:21:22.890 回答
2

由于我无法评论奎因的回答:

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

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

echo -n "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" \
| xargs -0 /usr/libexec/PlistBuddy -c "Set :CFBundleVersion `/opt/local/bin/svnversion -nc | cut -f2 -d:`"
于 2012-12-20T13:48:47.693 回答
0

另一个版本,用 Apple 脚本编写。previousValue 的正则表达式可以更改,目前它仅支持 XX.XX.XX 格式的版本(主要、次要、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
于 2010-01-14T10:31:14.047 回答