在post_install脚本中修改XCScheme并写回磁盘
Modify XCScheme and write it back to disk in post_install script
我正在我的 Podfile
中编写一个 post_install
脚本,以便在我 运行 示例项目中的单元测试时能够从我的框架收集代码覆盖率报告。这是我得到的:
post_install do |installer|
pods_project = installer.pods_project
shared_data_dir = Xcodeproj::XCScheme.shared_data_dir(pods_project.path)
scheme_filename = "BonMot.xcscheme"
scheme = Xcodeproj::XCScheme.new File.join(shared_data_dir, scheme_filename)
test_action = scheme.test_action
test_action.code_coverage_enabled = true
scheme.test_action = test_action
puts "now scheme is #{scheme}"
scheme.save!
end
当我打印方案时,我可以确认代码覆盖率收集已启用,当我检查文件的修改日期时,它已更新为当前时间,尽管这很容易解释为我 运行宁 pod install
。代码覆盖选项 而不是 被写回 BonMot.xcscheme
文件。为什么不呢?
您正在使用 installer.pods_project
,我相信这是 Pods.xcodeproj
项目。
您的 BonMot.xcscheme
方案可能在您的应用程序项目中,而不是您的 pods 项目中。
因此,如果是这种情况,您的代码所做的是它可能会创建一个全新的 Pods.xcodeproj/xcshareddata/xcschemes/BonMot.xcscheme
文件,更改其代码覆盖条目并保存它,而不是更改现有的 BonMotApp.xcodeproj/xcshareddata/xcschemes/BonMot.xcscheme
方案。
您可能希望 puts scheme.path
和 puts pods_project.path
对其进行调试并确保更改您期望的内容。
要引用您的应用项目,您可以使用类似的东西:
app_project = aggregate_targets.map(&:user_project_path).uniq.first
如果你真的想修改包含在 Pods
项目中的方案,该方案可能没有命名 BonMot
我相信这是你的应用程序的名称,除非那是通过 CocoaPods 在您的工作区中作为 Development Pod 引入的框架。
完整解释:
那是因为即使在实践中我从未见过它在任何地方使用过,CocoaPods 允许您一次将 pods 集成到多个用户项目中。通常你只有一个 xcodeproj,但你确实可以在你的 target … do
块中直接指定 xcodeproj
来指示目标所属的特定 Xcode 项目,从而整合你的 pods在不同项目的目标中。
因此这一行将询问每个 Pod 的 aggregate_target
(聚合 pods 特定应用程序目标的 pod 目标)它属于哪个用户项目,然后我们删除重复项用户项目列表。然后在实践中我们通常(99.9% 的时间)只有一个应用程序项目,我们可以获得该列表中的第一个也是唯一一个条目。
看起来 post_install
使用方案还为时过早。
CocoaPods 安装程序在 "Generating Pods project" step and there is recreate_user_schemes
call 期间在 run_podfile_post_install_hooks
之后立即调用 write_pod_project
方法。所以你的方案在安装过程中每次都被重写。
我不喜欢我的解决方案非常匹配,但它对我有用:
post_install do |installer|
orig_share_development_pod_schemes = installer.method :share_development_pod_schemes
installer.define_singleton_method :share_development_pod_schemes do
orig_share_development_pod_schemes.call
# do what you want with schemes
end
end
更新(CocoaPods 1.2.0 及更新版本)
由于解决方案是基于实现细节的,因此在 CocoaPods 1.2.0 发布后它就被破坏了。保持相同的方向我可能会建议重新定义的新方法:
post_install do |installer|
orig_write_lockfiles = installer.method :write_lockfiles
installer.define_singleton_method :write_lockfiles do
# do what you want with schemes
orig_write_lockfiles.call
end
end
更新(CocoaPods 1.10.0 及更新版本)
终于,我们有了一个解决方案,无需依赖新的实现 post_integrate_hook
API:
post_integrate do |installer|
# do what you want with schemes
end
我正在我的 Podfile
中编写一个 post_install
脚本,以便在我 运行 示例项目中的单元测试时能够从我的框架收集代码覆盖率报告。这是我得到的:
post_install do |installer|
pods_project = installer.pods_project
shared_data_dir = Xcodeproj::XCScheme.shared_data_dir(pods_project.path)
scheme_filename = "BonMot.xcscheme"
scheme = Xcodeproj::XCScheme.new File.join(shared_data_dir, scheme_filename)
test_action = scheme.test_action
test_action.code_coverage_enabled = true
scheme.test_action = test_action
puts "now scheme is #{scheme}"
scheme.save!
end
当我打印方案时,我可以确认代码覆盖率收集已启用,当我检查文件的修改日期时,它已更新为当前时间,尽管这很容易解释为我 运行宁 pod install
。代码覆盖选项 而不是 被写回 BonMot.xcscheme
文件。为什么不呢?
您正在使用 installer.pods_project
,我相信这是 Pods.xcodeproj
项目。
您的 BonMot.xcscheme
方案可能在您的应用程序项目中,而不是您的 pods 项目中。
因此,如果是这种情况,您的代码所做的是它可能会创建一个全新的 Pods.xcodeproj/xcshareddata/xcschemes/BonMot.xcscheme
文件,更改其代码覆盖条目并保存它,而不是更改现有的 BonMotApp.xcodeproj/xcshareddata/xcschemes/BonMot.xcscheme
方案。
您可能希望 puts scheme.path
和 puts pods_project.path
对其进行调试并确保更改您期望的内容。
要引用您的应用项目,您可以使用类似的东西:
app_project = aggregate_targets.map(&:user_project_path).uniq.first
如果你真的想修改包含在 Pods
项目中的方案,该方案可能没有命名 BonMot
我相信这是你的应用程序的名称,除非那是通过 CocoaPods 在您的工作区中作为 Development Pod 引入的框架。
完整解释:
那是因为即使在实践中我从未见过它在任何地方使用过,CocoaPods 允许您一次将 pods 集成到多个用户项目中。通常你只有一个 xcodeproj,但你确实可以在你的 target … do
块中直接指定 xcodeproj
来指示目标所属的特定 Xcode 项目,从而整合你的 pods在不同项目的目标中。
因此这一行将询问每个 Pod 的 aggregate_target
(聚合 pods 特定应用程序目标的 pod 目标)它属于哪个用户项目,然后我们删除重复项用户项目列表。然后在实践中我们通常(99.9% 的时间)只有一个应用程序项目,我们可以获得该列表中的第一个也是唯一一个条目。
看起来 post_install
使用方案还为时过早。
CocoaPods 安装程序在 "Generating Pods project" step and there is recreate_user_schemes
call 期间在 run_podfile_post_install_hooks
之后立即调用 write_pod_project
方法。所以你的方案在安装过程中每次都被重写。
我不喜欢我的解决方案非常匹配,但它对我有用:
post_install do |installer|
orig_share_development_pod_schemes = installer.method :share_development_pod_schemes
installer.define_singleton_method :share_development_pod_schemes do
orig_share_development_pod_schemes.call
# do what you want with schemes
end
end
更新(CocoaPods 1.2.0 及更新版本)
由于解决方案是基于实现细节的,因此在 CocoaPods 1.2.0 发布后它就被破坏了。保持相同的方向我可能会建议重新定义的新方法:
post_install do |installer|
orig_write_lockfiles = installer.method :write_lockfiles
installer.define_singleton_method :write_lockfiles do
# do what you want with schemes
orig_write_lockfiles.call
end
end
更新(CocoaPods 1.10.0 及更新版本)
终于,我们有了一个解决方案,无需依赖新的实现 post_integrate_hook
API:
post_integrate do |installer|
# do what you want with schemes
end