为何执行bundle exec fastlane android时会运行iOS平台块的代码?
核心原因
Fastfile本质是可直接运行的Ruby代码,所有代码默认从上到下顺序执行。platform块并不是带执行隔离沙箱的逻辑边界,它只是Fastlane提供的一个用于注册平台路由规则的DSL方法,和你直觉上“选择哪个平台就只执行对应块内所有代码”的预期有本质区别。
完整执行流程对应你的输出逐行解释
- Fastlane启动后,首先会全量加载并执行整个Fastfile的Ruby代码,这个阶段完全不判断你后续要调用哪个平台的lane,只负责把所有平台定义、lane路由、钩子规则注册到内存的配置表里。
- 加载到最外层的
puts "STEP >> FASTFILE"时,代码立刻执行,输出第一行日志。 - 加载到
platform :ios的方法调用时,Fastlane会临时把当前的DSL注册上下文切换到ios平台,立刻执行这个块闭包里的所有代码:- 碰到块里的
puts "STEP >> PLATFORM :IOS",这是普通Ruby语句,没有被嵌套在任何延迟执行的逻辑里,立刻执行输出——这就是你看到的非预期输出的来源 - 碰到块里的
lane :build do ... end时,因为当前上下文是ios平台,就把这个build lane的代码块存储到ios平台的路由配置中,不会立刻执行块内部的逻辑
- 碰到块里的
- ios平台块执行完毕,代码继续往下加载,碰到
platform :android的方法调用时,临时把DSL注册上下文切换到android平台,同样立刻执行块里的所有代码:- 块里的
puts "STEP >> PLATFORM :ANDROID"普通语句立刻执行,输出对应日志 - 块里的
lane :build do ... end代码块存储到android平台的路由配置中,不立刻执行
- 块里的
- 加载到
before_all钩子定义时,把这个钩子的代码块存储到全局执行队列中,不立刻执行。 - 整个Fastfile加载完成、所有路由规则注册完毕后,Fastlane才开始解析你输入的命令,匹配到目标是「android平台的build lane」,这时候才会依次执行全局的
before_all钩子、匹配到的android build lane的内部代码块,输出最后两行日志。
为什么lane内部的代码不会乱执行
你写在lane块里的所有逻辑,都属于被DSL注册后延迟执行的内容,只有当“平台标识+lane名称”和你输入的命令完全匹配时才会被触发。这也是你观察到的“lane调用逻辑正常,只有对应平台的build lane会运行”的根本原因。
正确的写法参考
如果需要某段平台专属的初始化逻辑仅在对应平台的lane执行时才运行,绝对不要把普通可执行代码写在platform块的顶层,要把逻辑放到对应平台专属的钩子内部(比如该平台自己的before_all钩子),示例如下:
fastlane_version '2.176.0' puts "STEP >> FASTFILE" before_all do |lane, options| puts "STEP >> BEFORE_ALL" end platform :ios do before_all do # 平台专属初始化逻辑,仅在执行ios平台lane时才会运行 puts "STEP >> PLATFORM :IOS" end lane :build do |options| puts "STEP >> PLATFORM :IOS >> LANE :BUILD" end end platform :android do before_all do puts "STEP >> PLATFORM :ANDROID" end lane :build do |options| puts "STEP >> PLATFORM :ANDROID >> LANE :BUILD" end end
调整后再执行android构建命令时,ios平台块内的初始化代码就不会再被触发,输出顺序也会符合预期。
内容的提问来源于stack exchange,提问作者Wannes
相关产品推荐
相关产品推荐

