tripleCC/cocoapods-bin

有subspec的pod代码拉不下来

Closed this issue · 14 comments

假设有两个pod,分别为A和B,A没有subspec,B有subspec
这时候拉取就会出问题了。
use_binaries_with_spec_selector! do |spec|
spec.name == 'A'

这样是想A拉取二进制,B拉取源码。
但这种情况下,B无法拉取代码,源码没有,二进制也没有,是空的。

反过来可以
use_binaries_with_spec_selector! do |spec|
spec.name == 'B'

这样是没有问题的。

或者A和B都拉取源码 或者都拉取二进制,也是没有问题的

但是A拉二进制,B拉源码,就会出问题

并未复现你的问题,最好有 demo 工程可以看下
需要注意如果有 subspec ,使用 use_binaries_with_spec_selector! 时,判断条件应使用
spec.name.start_with? '组件名'

spec.name == '组件名' 并不包含此组件的所有 subspec

可以使用 set_use_source_pods 语句

并未复现你的问题,最好有 demo 工程可以看下
需要注意如果有 subspec ,使用 use_binaries_with_spec_selector! 时,判断条件应使用
spec.name.start_with? '组件名'

spec.name == '组件名' 并不包含此组件的所有 subspec

可以使用 set_use_source_pods 语句

因为都是私有pod,没法提供。。
跟start_with?没什么关系,use_binaries_with_spec_selector!里面包含了其他pod就会有问题,B pod就会是空的

有看到这句:

Copying B from /Users/allen/Library/Caches/CocoaPods/Pods/Release/B/1.1.12-335f1
to Pods/B

/Users/allen/Library/Caches/CocoaPods/Pods/Release/B/1.1.12-335f1内容也是存在的,但是Pods/B里面就是空的。

用set_use_source_pods也是有同样的问题
先用,use_binaries! 然后再 set_use_source_pods['B']
B也是拉不到代码的,是个空的pod

如果只用use_binaries! 是没有问题的,A和B都是二进制的方式存在
什么都不设置也是没问题的,A和B都是源码的方式存在
只在use_binaries_with_spec_selector!里面设置B 也是没问题的,B以二进制的方式存在,A源码
use_binaries_with_spec_selector!包含了A就有问题了,B pod就是空了

我的工程也有 subspec ,切换时也没遇到你说的问题
能看下 gem list cocoapods 结果么

我的工程也有 subspec ,切换时也没遇到你说的问题
能看下 gem list cocoapods 结果么

*** LOCAL GEMS ***

cocoapods (1.7.1, 1.7.0, 1.7.0.rc.1, 1.5.3)
cocoapods-bin (0.1.17)
cocoapods-core (1.7.1, 1.7.0, 1.7.0.rc.1, 1.5.3)
cocoapods-deintegrate (1.0.4, 1.0.2)
cocoapods-downloader (1.2.2, 1.2.1)
cocoapods-packager (1.5.0)
cocoapods-plugins (1.0.0)
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.3.1, 1.3.0)
cocoapods-try (1.1.0)

在这种拉不到代码的情况下,屏幕输出的是:

  • 开始处理 B 1.1.12 组件

而正常情况下,是会输出:

  • 开始处理 B 1.1.12 组件
  • 开始处理 B/sub1 1.1.12 组件.
  • 开始处理 B/sub2 1.1.12 组件.

B 的二进制 spec 是不是没有 subspec ?

B 的二进制 spec 是不是没有 subspec ?

对的,这个有影响?

拉二进制是可以的,就是use_binaries_with_spec_selector! 返回了除B 库外的东西,B就拉不到源码了。
use_binaries_with_spec_selector! do |spec|
spec.name == 'helloword'(这里随便写个字符串,都会造成B库拉不到源码)

源码的subspec 需要是二进制的 subspec 的子集,一般都会新建二进制 subspec Binary
你变更下 B 的二进制 subspec 看看

因为分析依赖时,如果配置了 use_binaries? / use_binaries_selector,插件会预先使用二进制私有源给 CocoaPods 分析,那么 B 就没有 subspec 了,即使 B 指定的是源码
这里我无法做到分析时就决定哪个组件来自哪种源,只能让分析统一采用一种源,二进制或源码.因为 CocoaPods 是通过加入私有源的先后顺序来分析依赖的,如果插件采用源码,那我让源码私有源排在前面,如果插件采用二进制,那我让二进制私有源排在前面,等 CocoaPods 通过私有源分析完之后,插件才会替换具体的 spec
回到你这个问题,B 源码有 subspec,二进制没有,那么采用二进制的情况下,CocoaPods 分析的 spec 是 B 的二进制版本,而二进制版本的 B 是没有 subspec 的,等分析完成后,插件也拿不到 B 的 subspec 从而无法进行替换

如果是这个问题,我在 README 中注明下

源码的subspec 需要是二进制的 subspec 的子集,一般都会新建二进制 subspec Binary

可是我要使用的是pod B的源码版本,即使二进制不存在应该也是能拉下来才对。 为什么要源码的subspec 需要是二进制的 subspec 的子集?

如果二进制版本不存在,结果会是正确的,因为 CocoaPods 在二进制私有源里面找不到,就去找源码的
你可以考虑下这种情况:

A 
s.subspec AS1
s.subspec AS2

B 
s.dependency 'A/AS1'

这种情况下,如果 A 的二进制 spec 没有 AS1,那么当 B 依赖 A 的二进制版本时,分析依赖时会直接报找不到 subspec

如果二进制版本不存在,结果会是正确的,因为 CocoaPods 在二进制私有源里面找不到,就去找源码的
你可以考虑下这种情况:

A 
s.subspec AS1
s.subspec AS2

B 
s.dependency 'A/AS1'

这种情况下,如果 A 的二进制 spec 没有 AS1,那么当 B 依赖 A 的二进制版本时,将会直接报找不到 subspec

关键是我指定B要拉源码版本,源码版本是存在的,为什么会去找二进制的源?而且也没有s.dependency 'A/AS1'的情况,我的 A pod 和 B pod是完全独立的

上面已经说明了:

这里我无法做到分析时就决定哪个组件来自哪种源,只能让分析统一采用一种源,二进制或源码.因为 CocoaPods 是通过加入私有源的先后顺序来分析依赖的,如果插件采用源码,那我让源码私有源排在前面,如果插件采用二进制,那我让二进制私有源排在前面,等 CocoaPods 通过私有源分析完之后,插件才会替换具体的 spec

即使 B 采用源码,在上面那种机制下,CocoaPods 分析时优先采用二进制版本的 podspec
插件做的事情是,在 CocoaPods 分析完成后,把它分析出的二进制版本 podspec 换成源码版本的 podspec,但是如果源码有 subspec 而二进制没有,那么就会出现丢失的情况

还有上面的例子可能不是很恰当,我的意思是,如果你有其他组件依赖 A/AS1 ,切换到 A 的二进制时会报错,关注点不在 A 和 B 的依赖上

确实如此,就是二进制也要有subspec才行,不然切到源码会出错