Xcode 4:使用Git repo commit版本在每个构建上更新CFBundleVersion

时间:2011-06-11 16:41:54

标签: xcode git

我正在将Xcode 4与Git结合使用,并希望在每个版本的Info.plist中增加CFBundleVersion。密钥CFBundleVersion的值应该更新为我对Git存储库的最后一次提交的数量。

我发现that python脚本运行良好,但遗憾的是它没有更新我的Xcode项目中的Info.plist - 它只是更新了“BUILT_PRODUCTS_DIR”中的Info.plist。

有没有人知道如何让Xcode 4获取最新提交的版本并将该信息放入项目的Info.plist中?

谢谢!

3 个答案:

答案 0 :(得分:7)

版本字符串的格式必须为[xx]。[yy]。[zz]其中x,y,z为数字。

我通过使用git tag为x和y(例如0.4)提供有意义的标记号来处理这个问题,然后通过脚本构建阶段,z获取自上一个标记以来的提交数,由git describe返回。

这是我从this one改编的脚本。它可以作为构建阶段直接添加到目标(shell/usr/bin/env ruby):

# add git tag + version number to Info.plist
version = `/usr/bin/env git describe`.chomp

puts "raw version "+version
version_fancy_re = /(\d*\.\d*)-?(\d*)-?/
version =~ version_fancy_re
commit_num = $2
if ( $2.empty? )
commit_num = "0"
end
fancy_version = ""+$1+"."+commit_num
puts "compatible: "+fancy_version

# backup
source_plist_path = File.join(ENV['PROJECT_DIR'], ENV['INFOPLIST_FILE'])
orig_plist = File.open( source_plist_path, "r").read;
File.open( source_plist_path+".bak", "w") { |file| file.write(orig_plist) }

# put in CFBundleVersion key
version_re = /([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>).*?(<\/string>)/
orig_plist =~ version_re
bundle_version_string = $1 + fancy_version + $2
orig_plist.gsub!(version_re, bundle_version_string)

# put in CFBundleShortVersionString key
version_re = /([\t ]+<key>CFBundleShortVersionString<\/key>\n[\t ]+<string>).*?(<\/string>)/
orig_plist =~ version_re
bundle_version_string = $1 + fancy_version + $2
orig_plist.gsub!(version_re, bundle_version_string)

# write
File.open(source_plist_path, "w") { |file| file.write(orig_plist) }
puts "Set version string to '#{fancy_version}'"

答案 1 :(得分:1)

这对我来说很完美

#!/usr/bin/ruby

require 'rubygems'
    begin
        require 'Plist'
        rescue LoadError => e
        puts "You need to install the 'Plist' gem: [sudo] gem install plist"
    exit 1
end

raise "Must be run from Xcode" unless ENV['XCODE_VERSION_ACTUAL']

GIT = "/usr/bin/env git"
PRODUCT_PLIST = File.join(ENV['BUILT_PRODUCTS_DIR'], ENV['INFOPLIST_PATH'])
HASH = `#{GIT} log -1 --pretty=format:%h`
BUNDLE_VERSION = "CFBundleVersion"

if File.file?(PRODUCT_PLIST) and HASH

    # update product plist
    `/usr/bin/plutil -convert xml1 \"#{PRODUCT_PLIST}\"`
    info = Plist::parse_xml(PRODUCT_PLIST)
    if info
        info[BUNDLE_VERSION] = HASH
        info["GCGitCommitHash"] = HASH
        info.save_plist(PRODUCT_PLIST)
    end
    `/usr/bin/plutil -convert binary1 \"#{PRODUCT_PLIST}\"`

    # log
    puts "updated #{BUNDLE_VERSION} to #{HASH}"
    puts "HEAD: #{HASH}"
end

答案 2 :(得分:0)

@damian感谢您使用的脚本。

但在那之后我遇到了以下问题。在构建项目后每次提交后,我都会在git中进行更改。我有解决方案忽略plist文件,但我不希望这样。

现在我将你的脚本添加到git中的pre-commit钩子而不是xcode构建阶段。唯一的问题是我的脚本无法获得PROJECT_DIR和INFOPLIST_FILE所以我不得不在scipt中编写硬编码。我找不到如何从xcode项目中获取env变量。

效果很好:))