English 中文(简体)
在Xcode中插入Subversion版本号
原标题:
  • 时间:2008-12-16 18:31:56
  •  标签:

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

有没有一种简单的方式可以使用一些构建文件将修订号获取到应用程序中,以便更改修订号不会更改版本化文件?我想也许我可以创建一个临时源文件,该文件将与其他文件链接并提供一个获取修订号的函数。但我不知道如何做到这一点。

我对其他解决方案并不是特别感兴趣,比如 agvtool。 我所要的只是在应用程序中可用的修订版本号,不需要太多魔法。

最佳回答

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

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

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

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

问题回答

为了后人,我做了类似于zoul为iPhone应用程序的事情,通过向我的项目添加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

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

对于Mac应用程序,我根据这篇文章制定了我的方法,而是创建了一个buildnumber.xcconfig文件。 在目标的构建设置中,我更改了对话框右下角的Based On值为buildnumber.xcconfig。在Info.plist中,我编辑了以下行:

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

为了使我的关于对话框显示类似于版本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

这可能不是最干净的方式,因为在构建新版本时需要进行清洗周期,以便在应用程序中采用新版本,但它可以工作。

作为一个新的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}周围的双引号。这些是为那些决定将其项目放在名称中带有空格的目录结构中的用户所需的。

希望这能帮助其他人!

当我尝试为我的iPhone应用程序做类似的事情时,我发现了这个网页,并认为分享我决定采用的代码可能有所帮助。我想在我的目标信息(例如0.9.5)中设置一个基础版本号,然后在其末尾附加我的SVN修订号。我需要将这个存储在CFBundleVersion中,以便AdHoc用户可以通过iTunes更新,即使我忘记在我的目标信息面板中将版本号修改。这就是为什么我不能使用“revision.h”方法,否则它表现得非常好。以下是我最终决定采用的代码,我将其放在“复制Bundle资源”构建阶段后的“运行脚本”阶段:

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。

希望这能帮到其他人!

# 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/([	 ]+<key>CFBundleVersion</key>
[	 ]+<string>.+)[BUILD](</string>)/$1$version$2/;
$info =~ s/([	 ]+<key>CFBundleVersion</key>
[	 ]+<string>)[BUILD](</string>)/$1$version$2/;

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

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

如果您正在使用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:`"

另一版本,用 Apple Script 编写。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




相关问题